2022-04-18 04:36:36 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const {
|
|
|
|
validateFunction,
|
|
|
|
} = require('internal/validators');
|
|
|
|
const {
|
2023-04-29 16:50:42 +00:00
|
|
|
codes: {
|
2024-04-23 17:05:38 +00:00
|
|
|
ERR_DUPLICATE_STARTUP_SNAPSHOT_MAIN_FUNCTION,
|
2023-04-29 16:50:42 +00:00
|
|
|
ERR_NOT_BUILDING_SNAPSHOT,
|
2023-05-05 20:14:54 +00:00
|
|
|
ERR_NOT_SUPPORTED_IN_SNAPSHOT,
|
2023-04-29 16:50:42 +00:00
|
|
|
},
|
2022-04-18 04:36:36 +00:00
|
|
|
} = require('internal/errors');
|
|
|
|
|
|
|
|
const {
|
|
|
|
setSerializeCallback,
|
|
|
|
setDeserializeCallback,
|
|
|
|
setDeserializeMainFunction: _setDeserializeMainFunction,
|
2023-05-05 20:14:54 +00:00
|
|
|
isBuildingSnapshotBuffer,
|
2022-04-18 04:36:36 +00:00
|
|
|
} = internalBinding('mksnapshot');
|
|
|
|
|
|
|
|
function isBuildingSnapshot() {
|
2023-05-05 20:01:02 +00:00
|
|
|
return isBuildingSnapshotBuffer[0];
|
2022-04-18 04:36:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function throwIfNotBuildingSnapshot() {
|
|
|
|
if (!isBuildingSnapshot()) {
|
|
|
|
throw new ERR_NOT_BUILDING_SNAPSHOT();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-05 20:14:54 +00:00
|
|
|
function throwIfBuildingSnapshot(reason) {
|
|
|
|
if (isBuildingSnapshot()) {
|
|
|
|
throw new ERR_NOT_SUPPORTED_IN_SNAPSHOT(reason);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-18 04:36:36 +00:00
|
|
|
const deserializeCallbacks = [];
|
|
|
|
let deserializeCallbackIsSet = false;
|
|
|
|
function runDeserializeCallbacks() {
|
|
|
|
while (deserializeCallbacks.length > 0) {
|
|
|
|
const { 0: callback, 1: data } = deserializeCallbacks.shift();
|
|
|
|
callback(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function addDeserializeCallback(callback, data) {
|
|
|
|
throwIfNotBuildingSnapshot();
|
|
|
|
validateFunction(callback, 'callback');
|
|
|
|
if (!deserializeCallbackIsSet) {
|
|
|
|
// TODO(joyeecheung): when the main function handling is done in JS,
|
|
|
|
// the deserialize callbacks can always be invoked. For now only
|
|
|
|
// store it in C++ when it's actually used to avoid unnecessary
|
|
|
|
// C++ -> JS costs.
|
|
|
|
setDeserializeCallback(runDeserializeCallbacks);
|
|
|
|
deserializeCallbackIsSet = true;
|
|
|
|
}
|
|
|
|
deserializeCallbacks.push([callback, data]);
|
|
|
|
}
|
|
|
|
|
|
|
|
const serializeCallbacks = [];
|
2024-09-25 12:51:41 +00:00
|
|
|
const afterUserSerializeCallbacks = []; // Callbacks to run after user callbacks
|
2022-04-18 04:36:36 +00:00
|
|
|
function runSerializeCallbacks() {
|
|
|
|
while (serializeCallbacks.length > 0) {
|
|
|
|
const { 0: callback, 1: data } = serializeCallbacks.shift();
|
|
|
|
callback(data);
|
|
|
|
}
|
2024-09-25 12:51:41 +00:00
|
|
|
while (afterUserSerializeCallbacks.length > 0) {
|
|
|
|
const { 0: callback, 1: data } = afterUserSerializeCallbacks.shift();
|
|
|
|
callback(data);
|
|
|
|
}
|
2022-04-18 04:36:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function addSerializeCallback(callback, data) {
|
|
|
|
throwIfNotBuildingSnapshot();
|
|
|
|
validateFunction(callback, 'callback');
|
|
|
|
serializeCallbacks.push([callback, data]);
|
|
|
|
}
|
|
|
|
|
2024-09-25 12:51:41 +00:00
|
|
|
function addAfterUserSerializeCallback(callback, data) {
|
|
|
|
afterUserSerializeCallbacks.push([callback, data]);
|
|
|
|
}
|
|
|
|
|
2022-04-18 04:36:36 +00:00
|
|
|
function initializeCallbacks() {
|
|
|
|
// Only run the serialize callbacks in snapshot building mode, otherwise
|
|
|
|
// they throw.
|
|
|
|
if (isBuildingSnapshot()) {
|
|
|
|
setSerializeCallback(runSerializeCallbacks);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let deserializeMainIsSet = false;
|
|
|
|
function setDeserializeMainFunction(callback, data) {
|
|
|
|
throwIfNotBuildingSnapshot();
|
|
|
|
// TODO(joyeecheung): In lib/internal/bootstrap/node.js, create a default
|
|
|
|
// main function to run the lib/internal/main scripts and make sure that
|
|
|
|
// the main function set in the snapshot building process takes precedence.
|
|
|
|
validateFunction(callback, 'callback');
|
|
|
|
if (deserializeMainIsSet) {
|
|
|
|
throw new ERR_DUPLICATE_STARTUP_SNAPSHOT_MAIN_FUNCTION();
|
|
|
|
}
|
|
|
|
deserializeMainIsSet = true;
|
|
|
|
|
|
|
|
_setDeserializeMainFunction(function deserializeMain() {
|
|
|
|
const {
|
2022-07-28 06:58:00 +00:00
|
|
|
prepareMainThreadExecution,
|
2023-02-28 11:14:11 +00:00
|
|
|
markBootstrapComplete,
|
2022-07-28 06:58:00 +00:00
|
|
|
} = require('internal/process/pre_execution');
|
2022-04-18 04:36:36 +00:00
|
|
|
|
|
|
|
// This should be in sync with run_main_module.js until we make that
|
|
|
|
// a built-in main function.
|
2023-04-10 16:15:03 +00:00
|
|
|
// TODO(joyeecheung): make a copy of argv[0] and insert it as argv[1].
|
|
|
|
prepareMainThreadExecution(false);
|
2022-04-18 04:36:36 +00:00
|
|
|
markBootstrapComplete();
|
|
|
|
callback(data);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
initializeCallbacks,
|
|
|
|
runDeserializeCallbacks,
|
2023-05-05 20:14:54 +00:00
|
|
|
throwIfBuildingSnapshot,
|
2022-04-18 04:36:36 +00:00
|
|
|
// Exposed to require('v8').startupSnapshot
|
|
|
|
namespace: {
|
|
|
|
addDeserializeCallback,
|
|
|
|
addSerializeCallback,
|
|
|
|
setDeserializeMainFunction,
|
2023-02-28 11:14:11 +00:00
|
|
|
isBuildingSnapshot,
|
|
|
|
},
|
2024-09-25 12:51:41 +00:00
|
|
|
addAfterUserSerializeCallback,
|
2022-04-18 04:36:36 +00:00
|
|
|
};
|