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 11220x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 3809x 3809x 3809x 3809x 20x           20x 20x 20x 5249x 5249x       5249x 20x                           20x 20x                 20x           20x               20x 20x                                               20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x  
'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
  }
};