• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const {
4  Error,
5  ObjectDefineProperty,
6  ObjectGetOwnPropertyDescriptor,
7  ObjectSetPrototypeOf,
8  SafeArrayIterator,
9  SafeSet,
10  StringPrototypeStartsWith,
11  StringPrototypeSlice,
12} = primordials;
13
14const binding = internalBinding('mksnapshot');
15const { BuiltinModule } = require('internal/bootstrap/loaders');
16const {
17  compileSerializeMain,
18} = binding;
19
20const {
21  getOptionValue,
22} = require('internal/options');
23
24const {
25  readFileSync,
26} = require('fs');
27
28const supportedModules = new SafeSet(new SafeArrayIterator([
29  // '_http_agent',
30  // '_http_client',
31  // '_http_common',
32  // '_http_incoming',
33  // '_http_outgoing',
34  // '_http_server',
35  '_stream_duplex',
36  '_stream_passthrough',
37  '_stream_readable',
38  '_stream_transform',
39  '_stream_wrap',
40  '_stream_writable',
41  // '_tls_common',
42  // '_tls_wrap',
43  'assert',
44  'assert/strict',
45  // 'async_hooks',
46  'buffer',
47  // 'child_process',
48  // 'cluster',
49  'console',
50  'constants',
51  'crypto',
52  // 'dgram',
53  // 'diagnostics_channel',
54  'dns',
55  // 'dns/promises',
56  // 'domain',
57  'events',
58  'fs',
59  'fs/promises',
60  // 'http',
61  // 'http2',
62  // 'https',
63  // 'inspector',
64  // 'module',
65  // 'net',
66  'os',
67  'path',
68  'path/posix',
69  'path/win32',
70  // 'perf_hooks',
71  'process',
72  'punycode',
73  'querystring',
74  // 'readline',
75  // 'repl',
76  'stream',
77  'stream/promises',
78  'string_decoder',
79  'sys',
80  'timers',
81  'timers/promises',
82  // 'tls',
83  // 'trace_events',
84  // 'tty',
85  'url',
86  'util',
87  'util/types',
88  'v8',
89  // 'vm',
90  // 'worker_threads',
91  'zlib',
92]));
93
94const warnedModules = new SafeSet();
95function supportedInUserSnapshot(id) {
96  return supportedModules.has(id);
97}
98
99function requireForUserSnapshot(id) {
100  let normalizedId = id;
101  if (StringPrototypeStartsWith(id, 'node:')) {
102    normalizedId = StringPrototypeSlice(id, 5);
103  }
104  if (!BuiltinModule.canBeRequiredByUsers(normalizedId) ||
105      (id !== normalizedId &&
106        !BuiltinModule.canBeRequiredWithoutScheme(normalizedId))) {
107    // eslint-disable-next-line no-restricted-syntax
108    const err = new Error(
109      `Cannot find module '${id}'. `,
110    );
111    err.code = 'MODULE_NOT_FOUND';
112    throw err;
113  }
114  if (!supportedInUserSnapshot(normalizedId)) {
115    if (!warnedModules.has(normalizedId)) {
116      process.emitWarning(
117        `built-in module ${id} is not yet supported in user snapshots`);
118      warnedModules.add(normalizedId);
119    }
120  }
121
122  return require(normalizedId);
123}
124
125function main() {
126  const {
127    prepareMainThreadExecution,
128  } = require('internal/process/pre_execution');
129
130  prepareMainThreadExecution(true, false);
131
132  const file = process.argv[1];
133  const path = require('path');
134  const filename = path.resolve(file);
135  const dirname = path.dirname(filename);
136  const source = readFileSync(file, 'utf-8');
137  const serializeMainFunction = compileSerializeMain(filename, source);
138
139  const {
140    initializeCallbacks,
141    namespace: {
142      addSerializeCallback,
143      addDeserializeCallback,
144    },
145  } = require('internal/v8/startup_snapshot');
146  initializeCallbacks();
147
148  let stackTraceLimitDesc;
149  addDeserializeCallback(() => {
150    if (stackTraceLimitDesc !== undefined) {
151      ObjectDefineProperty(Error, 'stackTraceLimit', stackTraceLimitDesc);
152    }
153  });
154
155  if (getOptionValue('--inspect-brk')) {
156    internalBinding('inspector').callAndPauseOnStart(
157      serializeMainFunction, undefined,
158      requireForUserSnapshot, filename, dirname);
159  } else {
160    serializeMainFunction(requireForUserSnapshot, filename, dirname);
161  }
162
163  addSerializeCallback(() => {
164    stackTraceLimitDesc = ObjectGetOwnPropertyDescriptor(Error, 'stackTraceLimit');
165
166    if (stackTraceLimitDesc !== undefined) {
167      // We want to use null-prototype objects to not rely on globally mutable
168      // %Object.prototype%.
169      ObjectSetPrototypeOf(stackTraceLimitDesc, null);
170      process._rawDebug('Deleting Error.stackTraceLimit from the snapshot. ' +
171                        'It will be re-installed after deserialization');
172      delete Error.stackTraceLimit;
173    }
174  });
175}
176
177main();
178