All files / lib/internal/v8 startup_snapshot.js

42.34% Statements 47/111
75% Branches 3/4
25% Functions 2/8
42.34% Lines 47/111

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 11224x 24x 24x 24x 24x 24x 24x 24x 24x 24x 24x 24x 24x 24x 24x 24x 24x 3774x 3774x 3774x 3774x 24x           24x 24x 24x 5206x 5206x       5206x 24x                           24x 24x                 24x           24x               24x 24x                                               24x 24x 24x 24x 24x 24x 24x 24x 24x 24x 24x 24x  
'use strict';
 
const {
  validateFunction,
} = require('internal/validators');
const {
  ERR_NOT_BUILDING_SNAPSHOT,
  ERR_DUPLICATE_STARTUP_SNAPSHOT_MAIN_FUNCTION
} = require('internal/errors');
 
const {
  setSerializeCallback,
  setDeserializeCallback,
  setDeserializeMainFunction: _setDeserializeMainFunction,
  markBootstrapComplete
} = internalBinding('mksnapshot');
 
function isBuildingSnapshot() {
  // For now this is the only way to build a snapshot.
  return require('internal/options').getOptionValue('--build-snapshot');
}
 
function throwIfNotBuildingSnapshot() {
  if (!isBuildingSnapshot()) {
    throw new ERR_NOT_BUILDING_SNAPSHOT();
  }
}
 
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 = [];
function runSerializeCallbacks() {
  while (serializeCallbacks.length > 0) {
    const { 0: callback, 1: data } = serializeCallbacks.shift();
    callback(data);
  }
  // Remove the hooks from the snapshot.
  require('v8').startupSnapshot = undefined;
}
 
function addSerializeCallback(callback, data) {
  throwIfNotBuildingSnapshot();
  validateFunction(callback, 'callback');
  serializeCallbacks.push([callback, data]);
}
 
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 {
      prepareMainThreadExecution
    } = require('internal/bootstrap/pre_execution');

    // This should be in sync with run_main_module.js until we make that
    // a built-in main function.
    prepareMainThreadExecution(true);
    markBootstrapComplete();
    callback(data);
  });
}
 
module.exports = {
  initializeCallbacks,
  runDeserializeCallbacks,
  // Exposed to require('v8').startupSnapshot
  namespace: {
    addDeserializeCallback,
    addSerializeCallback,
    setDeserializeMainFunction,
    isBuildingSnapshot
  }
};