arsingContext, contextExtensions,
  params, hostDefinedOptionId, importModuleDynamically) {
  const result = compileFunction(
    code,
    filename,
    lineOffset,
    columnOffset,
    cachedData,
    produceCachedData,
    parsingContext,
    contextExtensions,
    params,
    hostDefinedOptionId,
  );

  if (produceCachedData) {
    result.function.cachedDataProduced = result.cachedDataProduced;
  }

  if (result.cachedData) {
    result.function.cachedData = result.cachedData;
  }

  if (typeof result.cachedDataRejected === 'boolean') {
    result.function.cachedDataRejected = result.cachedDataRejected;
  }

  if (importModuleDynamically !== undefined) {
    registerImportModuleDynamically(result.function, importModuleDynamically);
  }

  return result;
}

function makeContextifyScript(code,
                              filename,
                              lineOffset,
                              columnOffset,
                              cachedData,
                              produceCachedData,
                              parsingContext,
                              hostDefinedOptionId,
                              importModuleDynamically) {
  let script;
  // Calling `ReThrow()` on a native TryCatch does not generate a new
  // abort-on-uncaught-exception check. A dummy try/catch in JS land
  // protects against that.
  try { // eslint-disable-line no-useless-catch
    script = new ContextifyScript(code,
                                  filename,
                                  lineOffset,
                                  columnOffset,
                                  cachedData,
                                  produceCachedData,
                                  parsingContext,
                                  hostDefinedOptionId);
  } catch (e) {
    throw e; /* node-do-not-add-exception-line */
  }

  if (importModuleDynamically !== undefined) {
    registerImportModuleDynamically(script, importModuleDynamically);
  }
  return script;
}

// Internal version of vm.Script.prototype.runInThisContext() which skips
// argument validation.
function runScriptInThisContext(script, displayErrors, breakOnFirstLine) {
  return ReflectApply(
    runInContext,
    script,
    [
      null,                // sandbox - use current context
      -1,                  // timeout
      displayErrors,       // displayErrors
      false,               // breakOnSigint
      breakOnFirstLine,    // breakOnFirstLine
    ],
  );
}

module.exports = {
  getHostDefinedOptionId,
  internalCompileFunction,
  isContext,
  makeContextifyScript,
  registerImportModuleDynamically,
  runScriptInThisContext,
};
