11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst {
41cb0ef41Sopenharmony_ci  validateFunction,
51cb0ef41Sopenharmony_ci} = require('internal/validators');
61cb0ef41Sopenharmony_ciconst {
71cb0ef41Sopenharmony_ci  codes: {
81cb0ef41Sopenharmony_ci    ERR_NOT_BUILDING_SNAPSHOT,
91cb0ef41Sopenharmony_ci    ERR_DUPLICATE_STARTUP_SNAPSHOT_MAIN_FUNCTION,
101cb0ef41Sopenharmony_ci  },
111cb0ef41Sopenharmony_ci} = require('internal/errors');
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ciconst {
141cb0ef41Sopenharmony_ci  setSerializeCallback,
151cb0ef41Sopenharmony_ci  setDeserializeCallback,
161cb0ef41Sopenharmony_ci  setDeserializeMainFunction: _setDeserializeMainFunction,
171cb0ef41Sopenharmony_ci} = internalBinding('mksnapshot');
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_cifunction isBuildingSnapshot() {
201cb0ef41Sopenharmony_ci  // For now this is the only way to build a snapshot.
211cb0ef41Sopenharmony_ci  return require('internal/options').getOptionValue('--build-snapshot');
221cb0ef41Sopenharmony_ci}
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_cifunction throwIfNotBuildingSnapshot() {
251cb0ef41Sopenharmony_ci  if (!isBuildingSnapshot()) {
261cb0ef41Sopenharmony_ci    throw new ERR_NOT_BUILDING_SNAPSHOT();
271cb0ef41Sopenharmony_ci  }
281cb0ef41Sopenharmony_ci}
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ciconst deserializeCallbacks = [];
311cb0ef41Sopenharmony_cilet deserializeCallbackIsSet = false;
321cb0ef41Sopenharmony_cifunction runDeserializeCallbacks() {
331cb0ef41Sopenharmony_ci  while (deserializeCallbacks.length > 0) {
341cb0ef41Sopenharmony_ci    const { 0: callback, 1: data } = deserializeCallbacks.shift();
351cb0ef41Sopenharmony_ci    callback(data);
361cb0ef41Sopenharmony_ci  }
371cb0ef41Sopenharmony_ci}
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_cifunction addDeserializeCallback(callback, data) {
401cb0ef41Sopenharmony_ci  throwIfNotBuildingSnapshot();
411cb0ef41Sopenharmony_ci  validateFunction(callback, 'callback');
421cb0ef41Sopenharmony_ci  if (!deserializeCallbackIsSet) {
431cb0ef41Sopenharmony_ci    // TODO(joyeecheung): when the main function handling is done in JS,
441cb0ef41Sopenharmony_ci    // the deserialize callbacks can always be invoked. For now only
451cb0ef41Sopenharmony_ci    // store it in C++ when it's actually used to avoid unnecessary
461cb0ef41Sopenharmony_ci    // C++ -> JS costs.
471cb0ef41Sopenharmony_ci    setDeserializeCallback(runDeserializeCallbacks);
481cb0ef41Sopenharmony_ci    deserializeCallbackIsSet = true;
491cb0ef41Sopenharmony_ci  }
501cb0ef41Sopenharmony_ci  deserializeCallbacks.push([callback, data]);
511cb0ef41Sopenharmony_ci}
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ciconst serializeCallbacks = [];
541cb0ef41Sopenharmony_cifunction runSerializeCallbacks() {
551cb0ef41Sopenharmony_ci  while (serializeCallbacks.length > 0) {
561cb0ef41Sopenharmony_ci    const { 0: callback, 1: data } = serializeCallbacks.shift();
571cb0ef41Sopenharmony_ci    callback(data);
581cb0ef41Sopenharmony_ci  }
591cb0ef41Sopenharmony_ci}
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_cifunction addSerializeCallback(callback, data) {
621cb0ef41Sopenharmony_ci  throwIfNotBuildingSnapshot();
631cb0ef41Sopenharmony_ci  validateFunction(callback, 'callback');
641cb0ef41Sopenharmony_ci  serializeCallbacks.push([callback, data]);
651cb0ef41Sopenharmony_ci}
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_cifunction initializeCallbacks() {
681cb0ef41Sopenharmony_ci  // Only run the serialize callbacks in snapshot building mode, otherwise
691cb0ef41Sopenharmony_ci  // they throw.
701cb0ef41Sopenharmony_ci  if (isBuildingSnapshot()) {
711cb0ef41Sopenharmony_ci    setSerializeCallback(runSerializeCallbacks);
721cb0ef41Sopenharmony_ci  }
731cb0ef41Sopenharmony_ci}
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_cilet deserializeMainIsSet = false;
761cb0ef41Sopenharmony_cifunction setDeserializeMainFunction(callback, data) {
771cb0ef41Sopenharmony_ci  throwIfNotBuildingSnapshot();
781cb0ef41Sopenharmony_ci  // TODO(joyeecheung): In lib/internal/bootstrap/node.js, create a default
791cb0ef41Sopenharmony_ci  // main function to run the lib/internal/main scripts and make sure that
801cb0ef41Sopenharmony_ci  // the main function set in the snapshot building process takes precedence.
811cb0ef41Sopenharmony_ci  validateFunction(callback, 'callback');
821cb0ef41Sopenharmony_ci  if (deserializeMainIsSet) {
831cb0ef41Sopenharmony_ci    throw new ERR_DUPLICATE_STARTUP_SNAPSHOT_MAIN_FUNCTION();
841cb0ef41Sopenharmony_ci  }
851cb0ef41Sopenharmony_ci  deserializeMainIsSet = true;
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci  _setDeserializeMainFunction(function deserializeMain() {
881cb0ef41Sopenharmony_ci    const {
891cb0ef41Sopenharmony_ci      prepareMainThreadExecution,
901cb0ef41Sopenharmony_ci      markBootstrapComplete,
911cb0ef41Sopenharmony_ci    } = require('internal/process/pre_execution');
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci    // This should be in sync with run_main_module.js until we make that
941cb0ef41Sopenharmony_ci    // a built-in main function.
951cb0ef41Sopenharmony_ci    // TODO(joyeecheung): make a copy of argv[0] and insert it as argv[1].
961cb0ef41Sopenharmony_ci    prepareMainThreadExecution(false);
971cb0ef41Sopenharmony_ci    markBootstrapComplete();
981cb0ef41Sopenharmony_ci    callback(data);
991cb0ef41Sopenharmony_ci  });
1001cb0ef41Sopenharmony_ci}
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_cimodule.exports = {
1031cb0ef41Sopenharmony_ci  initializeCallbacks,
1041cb0ef41Sopenharmony_ci  runDeserializeCallbacks,
1051cb0ef41Sopenharmony_ci  // Exposed to require('v8').startupSnapshot
1061cb0ef41Sopenharmony_ci  namespace: {
1071cb0ef41Sopenharmony_ci    addDeserializeCallback,
1081cb0ef41Sopenharmony_ci    addSerializeCallback,
1091cb0ef41Sopenharmony_ci    setDeserializeMainFunction,
1101cb0ef41Sopenharmony_ci    isBuildingSnapshot,
1111cb0ef41Sopenharmony_ci  },
1121cb0ef41Sopenharmony_ci};
113