• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# VM (executing JavaScript)
2
3<!--introduced_in=v0.10.0-->
4
5> Stability: 2 - Stable
6
7<!--name=vm-->
8
9<!-- source_link=lib/vm.js -->
10
11The `vm` module enables compiling and running code within V8 Virtual
12Machine contexts. **The `vm` module is not a security mechanism. Do
13not use it to run untrusted code**.
14
15JavaScript code can be compiled and run immediately or
16compiled, saved, and run later.
17
18A common use case is to run the code in a different V8 Context. This means
19invoked code has a different global object than the invoking code.
20
21One can provide the context by [_contextifying_][contextified] an
22object. The invoked code treats any property in the context like a
23global variable. Any changes to global variables caused by the invoked
24code are reflected in the context object.
25
26```js
27const vm = require('vm');
28
29const x = 1;
30
31const context = { x: 2 };
32vm.createContext(context); // Contextify the object.
33
34const code = 'x += 40; var y = 17;';
35// `x` and `y` are global variables in the context.
36// Initially, x has the value 2 because that is the value of context.x.
37vm.runInContext(code, context);
38
39console.log(context.x); // 42
40console.log(context.y); // 17
41
42console.log(x); // 1; y is not defined.
43```
44
45## Class: `vm.Script`
46<!-- YAML
47added: v0.3.1
48-->
49
50Instances of the `vm.Script` class contain precompiled scripts that can be
51executed in specific contexts.
52
53### `new vm.Script(code[, options])`
54<!-- YAML
55added: v0.3.1
56changes:
57  - version: v10.6.0
58    pr-url: https://github.com/nodejs/node/pull/20300
59    description: The `produceCachedData` is deprecated in favour of
60                 `script.createCachedData()`.
61  - version: v5.7.0
62    pr-url: https://github.com/nodejs/node/pull/4777
63    description: The `cachedData` and `produceCachedData` options are
64                 supported now.
65-->
66
67* `code` {string} The JavaScript code to compile.
68* `options` {Object|string}
69  * `filename` {string} Specifies the filename used in stack traces produced
70    by this script. **Default:** `'evalmachine.<anonymous>'`.
71  * `lineOffset` {number} Specifies the line number offset that is displayed
72    in stack traces produced by this script. **Default:** `0`.
73  * `columnOffset` {number} Specifies the first-line column number offset that
74    is displayed in stack traces produced by this script. **Default:** `0`.
75  * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or
76    `TypedArray`, or `DataView` with V8's code cache data for the supplied
77     source. When supplied, the `cachedDataRejected` value will be set to
78     either `true` or `false` depending on acceptance of the data by V8.
79  * `produceCachedData` {boolean} When `true` and no `cachedData` is present, V8
80    will attempt to produce code cache data for `code`. Upon success, a
81    `Buffer` with V8's code cache data will be produced and stored in the
82    `cachedData` property of the returned `vm.Script` instance.
83    The `cachedDataProduced` value will be set to either `true` or `false`
84    depending on whether code cache data is produced successfully.
85    This option is **deprecated** in favor of `script.createCachedData()`.
86    **Default:** `false`.
87  * `importModuleDynamically` {Function} Called during evaluation of this module
88    when `import()` is called. If this option is not specified, calls to
89    `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
90    This option is part of the experimental modules API. We do not recommend
91    using it in a production environment.
92    * `specifier` {string} specifier passed to `import()`
93    * `script` {vm.Script}
94    * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is
95      recommended in order to take advantage of error tracking, and to avoid
96      issues with namespaces that contain `then` function exports.
97
98If `options` is a string, then it specifies the filename.
99
100Creating a new `vm.Script` object compiles `code` but does not run it. The
101compiled `vm.Script` can be run later multiple times. The `code` is not bound to
102any global object; rather, it is bound before each run, just for that run.
103
104### `script.createCachedData()`
105<!-- YAML
106added: v10.6.0
107-->
108
109* Returns: {Buffer}
110
111Creates a code cache that can be used with the `Script` constructor's
112`cachedData` option. Returns a `Buffer`. This method may be called at any
113time and any number of times.
114
115```js
116const script = new vm.Script(`
117function add(a, b) {
118  return a + b;
119}
120
121const x = add(1, 2);
122`);
123
124const cacheWithoutX = script.createCachedData();
125
126script.runInThisContext();
127
128const cacheWithX = script.createCachedData();
129```
130
131### `script.runInContext(contextifiedObject[, options])`
132<!-- YAML
133added: v0.3.1
134changes:
135  - version: v6.3.0
136    pr-url: https://github.com/nodejs/node/pull/6635
137    description: The `breakOnSigint` option is supported now.
138-->
139
140* `contextifiedObject` {Object} A [contextified][] object as returned by the
141  `vm.createContext()` method.
142* `options` {Object}
143  * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs
144    while compiling the `code`, the line of code causing the error is attached
145    to the stack trace. **Default:** `true`.
146  * `timeout` {integer} Specifies the number of milliseconds to execute `code`
147    before terminating execution. If execution is terminated, an [`Error`][]
148    will be thrown. This value must be a strictly positive integer.
149  * `breakOnSigint` {boolean} If `true`, receiving `SIGINT`
150    (<kbd>Ctrl</kbd>+<kbd>C</kbd>) will terminate execution and throw an
151    [`Error`][]. Existing handlers for the event that have been attached via
152    `process.on('SIGINT')` are disabled during script execution, but continue to
153    work after that. **Default:** `false`.
154* Returns: {any} the result of the very last statement executed in the script.
155
156Runs the compiled code contained by the `vm.Script` object within the given
157`contextifiedObject` and returns the result. Running code does not have access
158to local scope.
159
160The following example compiles code that increments a global variable, sets
161the value of another global variable, then execute the code multiple times.
162The globals are contained in the `context` object.
163
164```js
165const vm = require('vm');
166
167const context = {
168  animal: 'cat',
169  count: 2
170};
171
172const script = new vm.Script('count += 1; name = "kitty";');
173
174vm.createContext(context);
175for (let i = 0; i < 10; ++i) {
176  script.runInContext(context);
177}
178
179console.log(context);
180// Prints: { animal: 'cat', count: 12, name: 'kitty' }
181```
182
183Using the `timeout` or `breakOnSigint` options will result in new event loops
184and corresponding threads being started, which have a non-zero performance
185overhead.
186
187### `script.runInNewContext([contextObject[, options]])`
188<!-- YAML
189added: v0.3.1
190changes:
191  - version: v14.6.0
192    pr-url: https://github.com/nodejs/node/pull/34023
193    description: The `microtaskMode` option is supported now.
194  - version: v10.0.0
195    pr-url: https://github.com/nodejs/node/pull/19016
196    description: The `contextCodeGeneration` option is supported now.
197  - version: v6.3.0
198    pr-url: https://github.com/nodejs/node/pull/6635
199    description: The `breakOnSigint` option is supported now.
200-->
201
202* `contextObject` {Object} An object that will be [contextified][]. If
203  `undefined`, a new object will be created.
204* `options` {Object}
205  * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs
206    while compiling the `code`, the line of code causing the error is attached
207    to the stack trace. **Default:** `true`.
208  * `timeout` {integer} Specifies the number of milliseconds to execute `code`
209    before terminating execution. If execution is terminated, an [`Error`][]
210    will be thrown. This value must be a strictly positive integer.
211  * `breakOnSigint` {boolean} If `true`, receiving `SIGINT`
212    (<kbd>Ctrl</kbd>+<kbd>C</kbd>) will terminate execution and throw an
213    [`Error`][]. Existing handlers for the event that have been attached via
214    `process.on('SIGINT')` are disabled during script execution, but continue to
215    work after that. **Default:** `false`.
216  * `contextName` {string} Human-readable name of the newly created context.
217    **Default:** `'VM Context i'`, where `i` is an ascending numerical index of
218    the created context.
219  * `contextOrigin` {string} [Origin][origin] corresponding to the newly
220    created context for display purposes. The origin should be formatted like a
221    URL, but with only the scheme, host, and port (if necessary), like the
222    value of the [`url.origin`][] property of a [`URL`][] object. Most notably,
223    this string should omit the trailing slash, as that denotes a path.
224    **Default:** `''`.
225  * `contextCodeGeneration` {Object}
226    * `strings` {boolean} If set to false any calls to `eval` or function
227      constructors (`Function`, `GeneratorFunction`, etc) will throw an
228      `EvalError`. **Default:** `true`.
229    * `wasm` {boolean} If set to false any attempt to compile a WebAssembly
230      module will throw a `WebAssembly.CompileError`. **Default:** `true`.
231  * `microtaskMode` {string} If set to `afterEvaluate`, microtasks (tasks
232    scheduled through `Promise`s and `async function`s) will be run immediately
233    after the script has run. They are included in the `timeout` and
234    `breakOnSigint` scopes in that case.
235* Returns: {any} the result of the very last statement executed in the script.
236
237First contextifies the given `contextObject`, runs the compiled code contained
238by the `vm.Script` object within the created context, and returns the result.
239Running code does not have access to local scope.
240
241The following example compiles code that sets a global variable, then executes
242the code multiple times in different contexts. The globals are set on and
243contained within each individual `context`.
244
245```js
246const vm = require('vm');
247
248const script = new vm.Script('globalVar = "set"');
249
250const contexts = [{}, {}, {}];
251contexts.forEach((context) => {
252  script.runInNewContext(context);
253});
254
255console.log(contexts);
256// Prints: [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]
257```
258
259### `script.runInThisContext([options])`
260<!-- YAML
261added: v0.3.1
262changes:
263  - version: v6.3.0
264    pr-url: https://github.com/nodejs/node/pull/6635
265    description: The `breakOnSigint` option is supported now.
266-->
267
268* `options` {Object}
269  * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs
270    while compiling the `code`, the line of code causing the error is attached
271    to the stack trace. **Default:** `true`.
272  * `timeout` {integer} Specifies the number of milliseconds to execute `code`
273    before terminating execution. If execution is terminated, an [`Error`][]
274    will be thrown. This value must be a strictly positive integer.
275  * `breakOnSigint` {boolean} If `true`, receiving `SIGINT`
276    (<kbd>Ctrl</kbd>+<kbd>C</kbd>) will terminate execution and throw an
277    [`Error`][]. Existing handlers for the event that have been attached via
278    `process.on('SIGINT')` are disabled during script execution, but continue to
279    work after that. **Default:** `false`.
280* Returns: {any} the result of the very last statement executed in the script.
281
282Runs the compiled code contained by the `vm.Script` within the context of the
283current `global` object. Running code does not have access to local scope, but
284*does* have access to the current `global` object.
285
286The following example compiles code that increments a `global` variable then
287executes that code multiple times:
288
289```js
290const vm = require('vm');
291
292global.globalVar = 0;
293
294const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' });
295
296for (let i = 0; i < 1000; ++i) {
297  script.runInThisContext();
298}
299
300console.log(globalVar);
301
302// 1000
303```
304
305## Class: `vm.Module`
306<!-- YAML
307added:
308 - v13.0.0
309 - v12.16.0
310-->
311
312> Stability: 1 - Experimental
313
314This feature is only available with the `--experimental-vm-modules` command
315flag enabled.
316
317The `vm.Module` class provides a low-level interface for using
318ECMAScript modules in VM contexts. It is the counterpart of the `vm.Script`
319class that closely mirrors [Module Record][]s as defined in the ECMAScript
320specification.
321
322Unlike `vm.Script` however, every `vm.Module` object is bound to a context from
323its creation. Operations on `vm.Module` objects are intrinsically asynchronous,
324in contrast with the synchronous nature of `vm.Script` objects. The use of
325'async' functions can help with manipulating `vm.Module` objects.
326
327Using a `vm.Module` object requires three distinct steps: creation/parsing,
328linking, and evaluation. These three steps are illustrated in the following
329example.
330
331This implementation lies at a lower level than the [ECMAScript Module
332loader][]. There is also no way to interact with the Loader yet, though
333support is planned.
334
335```mjs
336import vm from 'vm';
337
338const contextifiedObject = vm.createContext({
339  secret: 42,
340  print: console.log,
341});
342
343// Step 1
344//
345// Create a Module by constructing a new `vm.SourceTextModule` object. This
346// parses the provided source text, throwing a `SyntaxError` if anything goes
347// wrong. By default, a Module is created in the top context. But here, we
348// specify `contextifiedObject` as the context this Module belongs to.
349//
350// Here, we attempt to obtain the default export from the module "foo", and
351// put it into local binding "secret".
352
353const bar = new vm.SourceTextModule(`
354  import s from 'foo';
355  s;
356  print(s);
357`, { context: contextifiedObject });
358
359// Step 2
360//
361// "Link" the imported dependencies of this Module to it.
362//
363// The provided linking callback (the "linker") accepts two arguments: the
364// parent module (`bar` in this case) and the string that is the specifier of
365// the imported module. The callback is expected to return a Module that
366// corresponds to the provided specifier, with certain requirements documented
367// in `module.link()`.
368//
369// If linking has not started for the returned Module, the same linker
370// callback will be called on the returned Module.
371//
372// Even top-level Modules without dependencies must be explicitly linked. The
373// callback provided would never be called, however.
374//
375// The link() method returns a Promise that will be resolved when all the
376// Promises returned by the linker resolve.
377//
378// Note: This is a contrived example in that the linker function creates a new
379// "foo" module every time it is called. In a full-fledged module system, a
380// cache would probably be used to avoid duplicated modules.
381
382async function linker(specifier, referencingModule) {
383  if (specifier === 'foo') {
384    return new vm.SourceTextModule(`
385      // The "secret" variable refers to the global variable we added to
386      // "contextifiedObject" when creating the context.
387      export default secret;
388    `, { context: referencingModule.context });
389
390    // Using `contextifiedObject` instead of `referencingModule.context`
391    // here would work as well.
392  }
393  throw new Error(`Unable to resolve dependency: ${specifier}`);
394}
395await bar.link(linker);
396
397// Step 3
398//
399// Evaluate the Module. The evaluate() method returns a promise which will
400// resolve after the module has finished evaluating.
401
402// Prints 42.
403await bar.evaluate();
404```
405
406```cjs
407const vm = require('vm');
408
409const contextifiedObject = vm.createContext({
410  secret: 42,
411  print: console.log,
412});
413
414(async () => {
415  // Step 1
416  //
417  // Create a Module by constructing a new `vm.SourceTextModule` object. This
418  // parses the provided source text, throwing a `SyntaxError` if anything goes
419  // wrong. By default, a Module is created in the top context. But here, we
420  // specify `contextifiedObject` as the context this Module belongs to.
421  //
422  // Here, we attempt to obtain the default export from the module "foo", and
423  // put it into local binding "secret".
424
425  const bar = new vm.SourceTextModule(`
426    import s from 'foo';
427    s;
428    print(s);
429  `, { context: contextifiedObject });
430
431  // Step 2
432  //
433  // "Link" the imported dependencies of this Module to it.
434  //
435  // The provided linking callback (the "linker") accepts two arguments: the
436  // parent module (`bar` in this case) and the string that is the specifier of
437  // the imported module. The callback is expected to return a Module that
438  // corresponds to the provided specifier, with certain requirements documented
439  // in `module.link()`.
440  //
441  // If linking has not started for the returned Module, the same linker
442  // callback will be called on the returned Module.
443  //
444  // Even top-level Modules without dependencies must be explicitly linked. The
445  // callback provided would never be called, however.
446  //
447  // The link() method returns a Promise that will be resolved when all the
448  // Promises returned by the linker resolve.
449  //
450  // Note: This is a contrived example in that the linker function creates a new
451  // "foo" module every time it is called. In a full-fledged module system, a
452  // cache would probably be used to avoid duplicated modules.
453
454  async function linker(specifier, referencingModule) {
455    if (specifier === 'foo') {
456      return new vm.SourceTextModule(`
457        // The "secret" variable refers to the global variable we added to
458        // "contextifiedObject" when creating the context.
459        export default secret;
460      `, { context: referencingModule.context });
461
462      // Using `contextifiedObject` instead of `referencingModule.context`
463      // here would work as well.
464    }
465    throw new Error(`Unable to resolve dependency: ${specifier}`);
466  }
467  await bar.link(linker);
468
469  // Step 3
470  //
471  // Evaluate the Module. The evaluate() method returns a promise which will
472  // resolve after the module has finished evaluating.
473
474  // Prints 42.
475  await bar.evaluate();
476})();
477```
478
479### `module.dependencySpecifiers`
480
481* {string[]}
482
483The specifiers of all dependencies of this module. The returned array is frozen
484to disallow any changes to it.
485
486Corresponds to the `[[RequestedModules]]` field of [Cyclic Module Record][]s in
487the ECMAScript specification.
488
489### `module.error`
490
491* {any}
492
493If the `module.status` is `'errored'`, this property contains the exception
494thrown by the module during evaluation. If the status is anything else,
495accessing this property will result in a thrown exception.
496
497The value `undefined` cannot be used for cases where there is not a thrown
498exception due to possible ambiguity with `throw undefined;`.
499
500Corresponds to the `[[EvaluationError]]` field of [Cyclic Module Record][]s
501in the ECMAScript specification.
502
503### `module.evaluate([options])`
504
505* `options` {Object}
506  * `timeout` {integer} Specifies the number of milliseconds to evaluate
507    before terminating execution. If execution is interrupted, an [`Error`][]
508    will be thrown. This value must be a strictly positive integer.
509  * `breakOnSigint` {boolean} If `true`, receiving `SIGINT`
510    (<kbd>Ctrl</kbd>+<kbd>C</kbd>) will terminate execution and throw an
511    [`Error`][]. Existing handlers for the event that have been attached via
512    `process.on('SIGINT')` are disabled during script execution, but continue to
513    work after that. **Default:** `false`.
514* Returns: {Promise} Fulfills with `undefined` upon success.
515
516Evaluate the module.
517
518This must be called after the module has been linked; otherwise it will reject.
519It could be called also when the module has already been evaluated, in which
520case it will either do nothing if the initial evaluation ended in success
521(`module.status` is `'evaluated'`) or it will re-throw the exception that the
522initial evaluation resulted in (`module.status` is `'errored'`).
523
524This method cannot be called while the module is being evaluated
525(`module.status` is `'evaluating'`).
526
527Corresponds to the [Evaluate() concrete method][] field of [Cyclic Module
528Record][]s in the ECMAScript specification.
529
530### `module.identifier`
531
532* {string}
533
534The identifier of the current module, as set in the constructor.
535
536### `module.link(linker)`
537
538* `linker` {Function}
539  * `specifier` {string} The specifier of the requested module:
540    ```mjs
541    import foo from 'foo';
542    //              ^^^^^ the module specifier
543    ```
544
545  * `referencingModule` {vm.Module} The `Module` object `link()` is called on.
546  * Returns: {vm.Module|Promise}
547* Returns: {Promise}
548
549Link module dependencies. This method must be called before evaluation, and
550can only be called once per module.
551
552The function is expected to return a `Module` object or a `Promise` that
553eventually resolves to a `Module` object. The returned `Module` must satisfy the
554following two invariants:
555
556* It must belong to the same context as the parent `Module`.
557* Its `status` must not be `'errored'`.
558
559If the returned `Module`'s `status` is `'unlinked'`, this method will be
560recursively called on the returned `Module` with the same provided `linker`
561function.
562
563`link()` returns a `Promise` that will either get resolved when all linking
564instances resolve to a valid `Module`, or rejected if the linker function either
565throws an exception or returns an invalid `Module`.
566
567The linker function roughly corresponds to the implementation-defined
568[HostResolveImportedModule][] abstract operation in the ECMAScript
569specification, with a few key differences:
570
571* The linker function is allowed to be asynchronous while
572  [HostResolveImportedModule][] is synchronous.
573
574The actual [HostResolveImportedModule][] implementation used during module
575linking is one that returns the modules linked during linking. Since at
576that point all modules would have been fully linked already, the
577[HostResolveImportedModule][] implementation is fully synchronous per
578specification.
579
580Corresponds to the [Link() concrete method][] field of [Cyclic Module
581Record][]s in the ECMAScript specification.
582
583### `module.namespace`
584
585* {Object}
586
587The namespace object of the module. This is only available after linking
588(`module.link()`) has completed.
589
590Corresponds to the [GetModuleNamespace][] abstract operation in the ECMAScript
591specification.
592
593### `module.status`
594
595* {string}
596
597The current status of the module. Will be one of:
598
599* `'unlinked'`: `module.link()` has not yet been called.
600
601* `'linking'`: `module.link()` has been called, but not all Promises returned
602  by the linker function have been resolved yet.
603
604* `'linked'`: The module has been linked successfully, and all of its
605  dependencies are linked, but `module.evaluate()` has not yet been called.
606
607* `'evaluating'`: The module is being evaluated through a `module.evaluate()` on
608  itself or a parent module.
609
610* `'evaluated'`: The module has been successfully evaluated.
611
612* `'errored'`: The module has been evaluated, but an exception was thrown.
613
614Other than `'errored'`, this status string corresponds to the specification's
615[Cyclic Module Record][]'s `[[Status]]` field. `'errored'` corresponds to
616`'evaluated'` in the specification, but with `[[EvaluationError]]` set to a
617value that is not `undefined`.
618
619## Class: `vm.SourceTextModule`
620<!-- YAML
621added: v9.6.0
622-->
623
624> Stability: 1 - Experimental
625
626This feature is only available with the `--experimental-vm-modules` command
627flag enabled.
628
629* Extends: {vm.Module}
630
631The `vm.SourceTextModule` class provides the [Source Text Module Record][] as
632defined in the ECMAScript specification.
633
634### `new vm.SourceTextModule(code[, options])`
635
636* `code` {string} JavaScript Module code to parse
637* `options`
638  * `identifier` {string} String used in stack traces.
639    **Default:** `'vm:module(i)'` where `i` is a context-specific ascending
640    index.
641  * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or
642    `TypedArray`, or `DataView` with V8's code cache data for the supplied
643     source. The `code` must be the same as the module from which this
644     `cachedData` was created.
645  * `context` {Object} The [contextified][] object as returned by the
646    `vm.createContext()` method, to compile and evaluate this `Module` in.
647  * `lineOffset` {integer} Specifies the line number offset that is displayed
648    in stack traces produced by this `Module`. **Default:** `0`.
649  * `columnOffset` {integer} Specifies the first-line column number offset that
650    is displayed in stack traces produced by this `Module`. **Default:** `0`.
651  * `initializeImportMeta` {Function} Called during evaluation of this `Module`
652    to initialize the `import.meta`.
653    * `meta` {import.meta}
654    * `module` {vm.SourceTextModule}
655  * `importModuleDynamically` {Function} Called during evaluation of this module
656    when `import()` is called. If this option is not specified, calls to
657    `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
658    * `specifier` {string} specifier passed to `import()`
659    * `module` {vm.Module}
660    * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is
661      recommended in order to take advantage of error tracking, and to avoid
662      issues with namespaces that contain `then` function exports.
663
664Creates a new `SourceTextModule` instance.
665
666Properties assigned to the `import.meta` object that are objects may
667allow the module to access information outside the specified `context`. Use
668`vm.runInContext()` to create objects in a specific context.
669
670```mjs
671import vm from 'vm';
672
673const contextifiedObject = vm.createContext({ secret: 42 });
674
675const module = new vm.SourceTextModule(
676  'Object.getPrototypeOf(import.meta.prop).secret = secret;',
677  {
678    initializeImportMeta(meta) {
679      // Note: this object is created in the top context. As such,
680      // Object.getPrototypeOf(import.meta.prop) points to the
681      // Object.prototype in the top context rather than that in
682      // the contextified object.
683      meta.prop = {};
684    }
685  });
686// Since module has no dependencies, the linker function will never be called.
687await module.link(() => {});
688await module.evaluate();
689
690// Now, Object.prototype.secret will be equal to 42.
691//
692// To fix this problem, replace
693//     meta.prop = {};
694// above with
695//     meta.prop = vm.runInContext('{}', contextifiedObject);
696```
697
698```cjs
699const vm = require('vm');
700const contextifiedObject = vm.createContext({ secret: 42 });
701(async () => {
702  const module = new vm.SourceTextModule(
703    'Object.getPrototypeOf(import.meta.prop).secret = secret;',
704    {
705      initializeImportMeta(meta) {
706        // Note: this object is created in the top context. As such,
707        // Object.getPrototypeOf(import.meta.prop) points to the
708        // Object.prototype in the top context rather than that in
709        // the contextified object.
710        meta.prop = {};
711      }
712    });
713  // Since module has no dependencies, the linker function will never be called.
714  await module.link(() => {});
715  await module.evaluate();
716  // Now, Object.prototype.secret will be equal to 42.
717  //
718  // To fix this problem, replace
719  //     meta.prop = {};
720  // above with
721  //     meta.prop = vm.runInContext('{}', contextifiedObject);
722})();
723```
724
725### `sourceTextModule.createCachedData()`
726<!-- YAML
727added: v13.7.0
728-->
729
730* Returns: {Buffer}
731
732Creates a code cache that can be used with the `SourceTextModule` constructor's
733`cachedData` option. Returns a `Buffer`. This method may be called any number
734of times before the module has been evaluated.
735
736```js
737// Create an initial module
738const module = new vm.SourceTextModule('const a = 1;');
739
740// Create cached data from this module
741const cachedData = module.createCachedData();
742
743// Create a new module using the cached data. The code must be the same.
744const module2 = new vm.SourceTextModule('const a = 1;', { cachedData });
745```
746
747## Class: `vm.SyntheticModule`
748<!-- YAML
749added:
750 - v13.0.0
751 - v12.16.0
752-->
753
754> Stability: 1 - Experimental
755
756This feature is only available with the `--experimental-vm-modules` command
757flag enabled.
758
759* Extends: {vm.Module}
760
761The `vm.SyntheticModule` class provides the [Synthetic Module Record][] as
762defined in the WebIDL specification. The purpose of synthetic modules is to
763provide a generic interface for exposing non-JavaScript sources to ECMAScript
764module graphs.
765
766```js
767const vm = require('vm');
768
769const source = '{ "a": 1 }';
770const module = new vm.SyntheticModule(['default'], function() {
771  const obj = JSON.parse(source);
772  this.setExport('default', obj);
773});
774
775// Use `module` in linking...
776```
777
778### `new vm.SyntheticModule(exportNames, evaluateCallback[, options])`
779<!-- YAML
780added:
781 - v13.0.0
782 - v12.16.0
783-->
784
785* `exportNames` {string[]} Array of names that will be exported from the module.
786* `evaluateCallback` {Function} Called when the module is evaluated.
787* `options`
788  * `identifier` {string} String used in stack traces.
789   **Default:** `'vm:module(i)'` where `i` is a context-specific ascending
790    index.
791  * `context` {Object} The [contextified][] object as returned by the
792    `vm.createContext()` method, to compile and evaluate this `Module` in.
793
794Creates a new `SyntheticModule` instance.
795
796Objects assigned to the exports of this instance may allow importers of
797the module to access information outside the specified `context`. Use
798`vm.runInContext()` to create objects in a specific context.
799
800### `syntheticModule.setExport(name, value)`
801<!-- YAML
802added:
803 - v13.0.0
804 - v12.16.0
805-->
806
807* `name` {string} Name of the export to set.
808* `value` {any} The value to set the export to.
809
810This method is used after the module is linked to set the values of exports. If
811it is called before the module is linked, an [`ERR_VM_MODULE_STATUS`][] error
812will be thrown.
813
814```mjs
815import vm from 'vm';
816
817const m = new vm.SyntheticModule(['x'], () => {
818  m.setExport('x', 1);
819});
820
821await m.link(() => {});
822await m.evaluate();
823
824assert.strictEqual(m.namespace.x, 1);
825```
826
827```cjs
828const vm = require('vm');
829(async () => {
830  const m = new vm.SyntheticModule(['x'], () => {
831    m.setExport('x', 1);
832  });
833  await m.link(() => {});
834  await m.evaluate();
835  assert.strictEqual(m.namespace.x, 1);
836})();
837```
838
839## `vm.compileFunction(code[, params[, options]])`
840<!-- YAML
841added: v10.10.0
842changes:
843  - version: v14.3.0
844    pr-url: https://github.com/nodejs/node/pull/33364
845    description: Removal of `importModuleDynamically` due to compatibility
846                 issues.
847  - version:
848    - v14.1.0
849    - v13.14.0
850    pr-url: https://github.com/nodejs/node/pull/32985
851    description: The `importModuleDynamically` option is now supported.
852-->
853
854* `code` {string} The body of the function to compile.
855* `params` {string[]} An array of strings containing all parameters for the
856  function.
857* `options` {Object}
858  * `filename` {string} Specifies the filename used in stack traces produced
859    by this script. **Default:** `''`.
860  * `lineOffset` {number} Specifies the line number offset that is displayed
861    in stack traces produced by this script. **Default:** `0`.
862  * `columnOffset` {number} Specifies the first-line column number offset that
863    is displayed in stack traces produced by this script. **Default:** `0`.
864  * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or
865    `TypedArray`, or `DataView` with V8's code cache data for the supplied
866     source.
867  * `produceCachedData` {boolean} Specifies whether to produce new cache data.
868    **Default:** `false`.
869  * `parsingContext` {Object} The [contextified][] object in which the said
870    function should be compiled in.
871  * `contextExtensions` {Object[]} An array containing a collection of context
872    extensions (objects wrapping the current scope) to be applied while
873    compiling. **Default:** `[]`.
874* Returns: {Function}
875
876Compiles the given code into the provided context (if no context is
877supplied, the current context is used), and returns it wrapped inside a
878function with the given `params`.
879
880## `vm.createContext([contextObject[, options]])`
881<!-- YAML
882added: v0.3.1
883changes:
884  - version: v14.6.0
885    pr-url: https://github.com/nodejs/node/pull/34023
886    description: The `microtaskMode` option is supported now.
887  - version: v10.0.0
888    pr-url: https://github.com/nodejs/node/pull/19398
889    description: The first argument can no longer be a function.
890  - version: v10.0.0
891    pr-url: https://github.com/nodejs/node/pull/19016
892    description: The `codeGeneration` option is supported now.
893-->
894
895* `contextObject` {Object}
896* `options` {Object}
897  * `name` {string} Human-readable name of the newly created context.
898    **Default:** `'VM Context i'`, where `i` is an ascending numerical index of
899    the created context.
900  * `origin` {string} [Origin][origin] corresponding to the newly created
901    context for display purposes. The origin should be formatted like a URL,
902    but with only the scheme, host, and port (if necessary), like the value of
903    the [`url.origin`][] property of a [`URL`][] object. Most notably, this
904    string should omit the trailing slash, as that denotes a path.
905    **Default:** `''`.
906  * `codeGeneration` {Object}
907    * `strings` {boolean} If set to false any calls to `eval` or function
908      constructors (`Function`, `GeneratorFunction`, etc) will throw an
909      `EvalError`. **Default:** `true`.
910    * `wasm` {boolean} If set to false any attempt to compile a WebAssembly
911      module will throw a `WebAssembly.CompileError`. **Default:** `true`.
912  * `microtaskMode` {string} If set to `afterEvaluate`, microtasks (tasks
913    scheduled through `Promise`s and `async function`s) will be run immediately
914    after a script has run through [`script.runInContext()`][].
915    They are included in the `timeout` and `breakOnSigint` scopes in that case.
916* Returns: {Object} contextified object.
917
918If given a `contextObject`, the `vm.createContext()` method will [prepare
919that object][contextified] so that it can be used in calls to
920[`vm.runInContext()`][] or [`script.runInContext()`][]. Inside such scripts,
921the `contextObject` will be the global object, retaining all of its existing
922properties but also having the built-in objects and functions any standard
923[global object][] has. Outside of scripts run by the vm module, global variables
924will remain unchanged.
925
926```js
927const vm = require('vm');
928
929global.globalVar = 3;
930
931const context = { globalVar: 1 };
932vm.createContext(context);
933
934vm.runInContext('globalVar *= 2;', context);
935
936console.log(context);
937// Prints: { globalVar: 2 }
938
939console.log(global.globalVar);
940// Prints: 3
941```
942
943If `contextObject` is omitted (or passed explicitly as `undefined`), a new,
944empty [contextified][] object will be returned.
945
946The `vm.createContext()` method is primarily useful for creating a single
947context that can be used to run multiple scripts. For instance, if emulating a
948web browser, the method can be used to create a single context representing a
949window's global object, then run all `<script>` tags together within that
950context.
951
952The provided `name` and `origin` of the context are made visible through the
953Inspector API.
954
955## `vm.isContext(object)`
956<!-- YAML
957added: v0.11.7
958-->
959
960* `object` {Object}
961* Returns: {boolean}
962
963Returns `true` if the given `object` object has been [contextified][] using
964[`vm.createContext()`][].
965
966## `vm.measureMemory([options])`
967
968<!-- YAML
969added: v13.10.0
970-->
971
972> Stability: 1 - Experimental
973
974Measure the memory known to V8 and used by all contexts known to the
975current V8 isolate, or the main context.
976
977* `options` {Object} Optional.
978  * `mode` {string} Either `'summary'` or `'detailed'`. In summary mode,
979    only the memory measured for the main context will be returned. In
980    detailed mode, the measure measured for all contexts known to the
981    current V8 isolate will be returned.
982    **Default:** `'summary'`
983  * `execution` {string} Either `'default'` or `'eager'`. With default
984    execution, the promise will not resolve until after the next scheduled
985    garbage collection starts, which may take a while (or never if the program
986    exits before the next GC). With eager execution, the GC will be started
987    right away to measure the memory.
988    **Default:** `'default'`
989* Returns: {Promise} If the memory is successfully measured the promise will
990  resolve with an object containing information about the memory usage.
991
992The format of the object that the returned Promise may resolve with is
993specific to the V8 engine and may change from one version of V8 to the next.
994
995The returned result is different from the statistics returned by
996`v8.getHeapSpaceStatistics()` in that `vm.measureMemory()` measure the
997memory reachable by each V8 specific contexts in the current instance of
998the V8 engine, while the result of `v8.getHeapSpaceStatistics()` measure
999the memory occupied by each heap space in the current V8 instance.
1000
1001```js
1002const vm = require('vm');
1003// Measure the memory used by the main context.
1004vm.measureMemory({ mode: 'summary' })
1005  // This is the same as vm.measureMemory()
1006  .then((result) => {
1007    // The current format is:
1008    // {
1009    //   total: {
1010    //      jsMemoryEstimate: 2418479, jsMemoryRange: [ 2418479, 2745799 ]
1011    //    }
1012    // }
1013    console.log(result);
1014  });
1015
1016const context = vm.createContext({ a: 1 });
1017vm.measureMemory({ mode: 'detailed', execution: 'eager' })
1018  .then((result) => {
1019    // Reference the context here so that it won't be GC'ed
1020    // until the measurement is complete.
1021    console.log(context.a);
1022    // {
1023    //   total: {
1024    //     jsMemoryEstimate: 2574732,
1025    //     jsMemoryRange: [ 2574732, 2904372 ]
1026    //   },
1027    //   current: {
1028    //     jsMemoryEstimate: 2438996,
1029    //     jsMemoryRange: [ 2438996, 2768636 ]
1030    //   },
1031    //   other: [
1032    //     {
1033    //       jsMemoryEstimate: 135736,
1034    //       jsMemoryRange: [ 135736, 465376 ]
1035    //     }
1036    //   ]
1037    // }
1038    console.log(result);
1039  });
1040```
1041
1042## `vm.runInContext(code, contextifiedObject[, options])`
1043<!-- YAML
1044added: v0.3.1
1045changes:
1046  - version: v6.3.0
1047    pr-url: https://github.com/nodejs/node/pull/6635
1048    description: The `breakOnSigint` option is supported now.
1049-->
1050
1051* `code` {string} The JavaScript code to compile and run.
1052* `contextifiedObject` {Object} The [contextified][] object that will be used
1053  as the `global` when the `code` is compiled and run.
1054* `options` {Object|string}
1055  * `filename` {string} Specifies the filename used in stack traces produced
1056    by this script. **Default:** `'evalmachine.<anonymous>'`.
1057  * `lineOffset` {number} Specifies the line number offset that is displayed
1058    in stack traces produced by this script. **Default:** `0`.
1059  * `columnOffset` {number} Specifies the first-line column number offset that
1060    is displayed in stack traces produced by this script. **Default:** `0`.
1061  * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs
1062    while compiling the `code`, the line of code causing the error is attached
1063    to the stack trace. **Default:** `true`.
1064  * `timeout` {integer} Specifies the number of milliseconds to execute `code`
1065    before terminating execution. If execution is terminated, an [`Error`][]
1066    will be thrown. This value must be a strictly positive integer.
1067  * `breakOnSigint` {boolean} If `true`, receiving `SIGINT`
1068    (<kbd>Ctrl</kbd>+<kbd>C</kbd>) will terminate execution and throw an
1069    [`Error`][]. Existing handlers for the event that have been attached via
1070    `process.on('SIGINT')` are disabled during script execution, but continue to
1071    work after that. **Default:** `false`.
1072  * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or
1073    `TypedArray`, or `DataView` with V8's code cache data for the supplied
1074     source. When supplied, the `cachedDataRejected` value will be set to
1075     either `true` or `false` depending on acceptance of the data by V8.
1076  * `produceCachedData` {boolean} When `true` and no `cachedData` is present, V8
1077    will attempt to produce code cache data for `code`. Upon success, a
1078    `Buffer` with V8's code cache data will be produced and stored in the
1079    `cachedData` property of the returned `vm.Script` instance.
1080    The `cachedDataProduced` value will be set to either `true` or `false`
1081    depending on whether code cache data is produced successfully.
1082    This option is **deprecated** in favor of `script.createCachedData()`.
1083    **Default:** `false`.
1084  * `importModuleDynamically` {Function} Called during evaluation of this module
1085    when `import()` is called. If this option is not specified, calls to
1086    `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
1087    This option is part of the experimental modules API. We do not recommend
1088    using it in a production environment.
1089    * `specifier` {string} specifier passed to `import()`
1090    * `script` {vm.Script}
1091    * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is
1092      recommended in order to take advantage of error tracking, and to avoid
1093      issues with namespaces that contain `then` function exports.
1094* Returns: {any} the result of the very last statement executed in the script.
1095
1096The `vm.runInContext()` method compiles `code`, runs it within the context of
1097the `contextifiedObject`, then returns the result. Running code does not have
1098access to the local scope. The `contextifiedObject` object *must* have been
1099previously [contextified][] using the [`vm.createContext()`][] method.
1100
1101If `options` is a string, then it specifies the filename.
1102
1103The following example compiles and executes different scripts using a single
1104[contextified][] object:
1105
1106```js
1107const vm = require('vm');
1108
1109const contextObject = { globalVar: 1 };
1110vm.createContext(contextObject);
1111
1112for (let i = 0; i < 10; ++i) {
1113  vm.runInContext('globalVar *= 2;', contextObject);
1114}
1115console.log(contextObject);
1116// Prints: { globalVar: 1024 }
1117```
1118
1119## `vm.runInNewContext(code[, contextObject[, options]])`
1120<!-- YAML
1121added: v0.3.1
1122changes:
1123  - version: v14.6.0
1124    pr-url: https://github.com/nodejs/node/pull/34023
1125    description: The `microtaskMode` option is supported now.
1126  - version: v10.0.0
1127    pr-url: https://github.com/nodejs/node/pull/19016
1128    description: The `contextCodeGeneration` option is supported now.
1129  - version: v6.3.0
1130    pr-url: https://github.com/nodejs/node/pull/6635
1131    description: The `breakOnSigint` option is supported now.
1132-->
1133
1134* `code` {string} The JavaScript code to compile and run.
1135* `contextObject` {Object} An object that will be [contextified][]. If
1136  `undefined`, a new object will be created.
1137* `options` {Object|string}
1138  * `filename` {string} Specifies the filename used in stack traces produced
1139    by this script. **Default:** `'evalmachine.<anonymous>'`.
1140  * `lineOffset` {number} Specifies the line number offset that is displayed
1141    in stack traces produced by this script. **Default:** `0`.
1142  * `columnOffset` {number} Specifies the first-line column number offset that
1143    is displayed in stack traces produced by this script. **Default:** `0`.
1144  * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs
1145    while compiling the `code`, the line of code causing the error is attached
1146    to the stack trace. **Default:** `true`.
1147  * `timeout` {integer} Specifies the number of milliseconds to execute `code`
1148    before terminating execution. If execution is terminated, an [`Error`][]
1149    will be thrown. This value must be a strictly positive integer.
1150  * `breakOnSigint` {boolean} If `true`, receiving `SIGINT`
1151    (<kbd>Ctrl</kbd>+<kbd>C</kbd>) will terminate execution and throw an
1152    [`Error`][]. Existing handlers for the event that have been attached via
1153    `process.on('SIGINT')` are disabled during script execution, but continue to
1154    work after that. **Default:** `false`.
1155  * `contextName` {string} Human-readable name of the newly created context.
1156    **Default:** `'VM Context i'`, where `i` is an ascending numerical index of
1157    the created context.
1158  * `contextOrigin` {string} [Origin][origin] corresponding to the newly
1159    created context for display purposes. The origin should be formatted like a
1160    URL, but with only the scheme, host, and port (if necessary), like the
1161    value of the [`url.origin`][] property of a [`URL`][] object. Most notably,
1162    this string should omit the trailing slash, as that denotes a path.
1163    **Default:** `''`.
1164  * `contextCodeGeneration` {Object}
1165    * `strings` {boolean} If set to false any calls to `eval` or function
1166      constructors (`Function`, `GeneratorFunction`, etc) will throw an
1167      `EvalError`. **Default:** `true`.
1168    * `wasm` {boolean} If set to false any attempt to compile a WebAssembly
1169      module will throw a `WebAssembly.CompileError`. **Default:** `true`.
1170  * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or
1171    `TypedArray`, or `DataView` with V8's code cache data for the supplied
1172     source. When supplied, the `cachedDataRejected` value will be set to
1173     either `true` or `false` depending on acceptance of the data by V8.
1174  * `produceCachedData` {boolean} When `true` and no `cachedData` is present, V8
1175    will attempt to produce code cache data for `code`. Upon success, a
1176    `Buffer` with V8's code cache data will be produced and stored in the
1177    `cachedData` property of the returned `vm.Script` instance.
1178    The `cachedDataProduced` value will be set to either `true` or `false`
1179    depending on whether code cache data is produced successfully.
1180    This option is **deprecated** in favor of `script.createCachedData()`.
1181    **Default:** `false`.
1182  * `importModuleDynamically` {Function} Called during evaluation of this module
1183    when `import()` is called. If this option is not specified, calls to
1184    `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
1185    This option is part of the experimental modules API. We do not recommend
1186    using it in a production environment.
1187    * `specifier` {string} specifier passed to `import()`
1188    * `script` {vm.Script}
1189    * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is
1190      recommended in order to take advantage of error tracking, and to avoid
1191      issues with namespaces that contain `then` function exports.
1192  * `microtaskMode` {string} If set to `afterEvaluate`, microtasks (tasks
1193    scheduled through `Promise`s and `async function`s) will be run immediately
1194    after the script has run. They are included in the `timeout` and
1195    `breakOnSigint` scopes in that case.
1196* Returns: {any} the result of the very last statement executed in the script.
1197
1198The `vm.runInNewContext()` first contextifies the given `contextObject` (or
1199creates a new `contextObject` if passed as `undefined`), compiles the `code`,
1200runs it within the created context, then returns the result. Running code
1201does not have access to the local scope.
1202
1203If `options` is a string, then it specifies the filename.
1204
1205The following example compiles and executes code that increments a global
1206variable and sets a new one. These globals are contained in the `contextObject`.
1207
1208```js
1209const vm = require('vm');
1210
1211const contextObject = {
1212  animal: 'cat',
1213  count: 2
1214};
1215
1216vm.runInNewContext('count += 1; name = "kitty"', contextObject);
1217console.log(contextObject);
1218// Prints: { animal: 'cat', count: 3, name: 'kitty' }
1219```
1220
1221## `vm.runInThisContext(code[, options])`
1222<!-- YAML
1223added: v0.3.1
1224changes:
1225  - version: v6.3.0
1226    pr-url: https://github.com/nodejs/node/pull/6635
1227    description: The `breakOnSigint` option is supported now.
1228-->
1229
1230* `code` {string} The JavaScript code to compile and run.
1231* `options` {Object|string}
1232  * `filename` {string} Specifies the filename used in stack traces produced
1233    by this script. **Default:** `'evalmachine.<anonymous>'`.
1234  * `lineOffset` {number} Specifies the line number offset that is displayed
1235    in stack traces produced by this script. **Default:** `0`.
1236  * `columnOffset` {number} Specifies the first-line column number offset that
1237    is displayed in stack traces produced by this script. **Default:** `0`.
1238  * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs
1239    while compiling the `code`, the line of code causing the error is attached
1240    to the stack trace. **Default:** `true`.
1241  * `timeout` {integer} Specifies the number of milliseconds to execute `code`
1242    before terminating execution. If execution is terminated, an [`Error`][]
1243    will be thrown. This value must be a strictly positive integer.
1244  * `breakOnSigint` {boolean} If `true`, receiving `SIGINT`
1245    (<kbd>Ctrl</kbd>+<kbd>C</kbd>) will terminate execution and throw an
1246    [`Error`][]. Existing handlers for the event that have been attached via
1247    `process.on('SIGINT')` are disabled during script execution, but continue to
1248    work after that. **Default:** `false`.
1249  * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or
1250    `TypedArray`, or `DataView` with V8's code cache data for the supplied
1251     source. When supplied, the `cachedDataRejected` value will be set to
1252     either `true` or `false` depending on acceptance of the data by V8.
1253  * `produceCachedData` {boolean} When `true` and no `cachedData` is present, V8
1254    will attempt to produce code cache data for `code`. Upon success, a
1255    `Buffer` with V8's code cache data will be produced and stored in the
1256    `cachedData` property of the returned `vm.Script` instance.
1257    The `cachedDataProduced` value will be set to either `true` or `false`
1258    depending on whether code cache data is produced successfully.
1259    This option is **deprecated** in favor of `script.createCachedData()`.
1260    **Default:** `false`.
1261  * `importModuleDynamically` {Function} Called during evaluation of this module
1262    when `import()` is called. If this option is not specified, calls to
1263    `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
1264    This option is part of the experimental modules API. We do not recommend
1265    using it in a production environment.
1266    * `specifier` {string} specifier passed to `import()`
1267    * `script` {vm.Script}
1268    * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is
1269      recommended in order to take advantage of error tracking, and to avoid
1270      issues with namespaces that contain `then` function exports.
1271* Returns: {any} the result of the very last statement executed in the script.
1272
1273`vm.runInThisContext()` compiles `code`, runs it within the context of the
1274current `global` and returns the result. Running code does not have access to
1275local scope, but does have access to the current `global` object.
1276
1277If `options` is a string, then it specifies the filename.
1278
1279The following example illustrates using both `vm.runInThisContext()` and
1280the JavaScript [`eval()`][] function to run the same code:
1281
1282<!-- eslint-disable prefer-const -->
1283```js
1284const vm = require('vm');
1285let localVar = 'initial value';
1286
1287const vmResult = vm.runInThisContext('localVar = "vm";');
1288console.log(`vmResult: '${vmResult}', localVar: '${localVar}'`);
1289// Prints: vmResult: 'vm', localVar: 'initial value'
1290
1291const evalResult = eval('localVar = "eval";');
1292console.log(`evalResult: '${evalResult}', localVar: '${localVar}'`);
1293// Prints: evalResult: 'eval', localVar: 'eval'
1294```
1295
1296Because `vm.runInThisContext()` does not have access to the local scope,
1297`localVar` is unchanged. In contrast, [`eval()`][] *does* have access to the
1298local scope, so the value `localVar` is changed. In this way
1299`vm.runInThisContext()` is much like an [indirect `eval()` call][], e.g.
1300`(0,eval)('code')`.
1301
1302## Example: Running an HTTP server within a VM
1303
1304When using either [`script.runInThisContext()`][] or
1305[`vm.runInThisContext()`][], the code is executed within the current V8 global
1306context. The code passed to this VM context will have its own isolated scope.
1307
1308In order to run a simple web server using the `http` module the code passed to
1309the context must either call `require('http')` on its own, or have a reference
1310to the `http` module passed to it. For instance:
1311
1312```js
1313'use strict';
1314const vm = require('vm');
1315
1316const code = `
1317((require) => {
1318  const http = require('http');
1319
1320  http.createServer((request, response) => {
1321    response.writeHead(200, { 'Content-Type': 'text/plain' });
1322    response.end('Hello World\\n');
1323  }).listen(8124);
1324
1325  console.log('Server running at http://127.0.0.1:8124/');
1326})`;
1327
1328vm.runInThisContext(code)(require);
1329```
1330
1331The `require()` in the above case shares the state with the context it is
1332passed from. This may introduce risks when untrusted code is executed, e.g.
1333altering objects in the context in unwanted ways.
1334
1335## What does it mean to "contextify" an object?
1336
1337All JavaScript executed within Node.js runs within the scope of a "context".
1338According to the [V8 Embedder's Guide][]:
1339
1340> In V8, a context is an execution environment that allows separate, unrelated,
1341> JavaScript applications to run in a single instance of V8. You must explicitly
1342> specify the context in which you want any JavaScript code to be run.
1343
1344When the method `vm.createContext()` is called, the `contextObject` argument
1345(or a newly-created object if `contextObject` is `undefined`) is associated
1346internally with a new instance of a V8 Context. This V8 Context provides the
1347`code` run using the `vm` module's methods with an isolated global environment
1348within which it can operate. The process of creating the V8 Context and
1349associating it with the `contextObject` is what this document refers to as
1350"contextifying" the object.
1351
1352## Timeout interactions with asynchronous tasks and Promises
1353
1354`Promise`s and `async function`s can schedule tasks run by the JavaScript
1355engine asynchronously. By default, these tasks are run after all JavaScript
1356functions on the current stack are done executing.
1357This allows escaping the functionality of the `timeout` and
1358`breakOnSigint` options.
1359
1360For example, the following code executed by `vm.runInNewContext()` with a
1361timeout of 5 milliseconds schedules an infinite loop to run after a promise
1362resolves. The scheduled loop is never interrupted by the timeout:
1363
1364```js
1365const vm = require('vm');
1366
1367function loop() {
1368  console.log('entering loop');
1369  while (1) console.log(Date.now());
1370}
1371
1372vm.runInNewContext(
1373  'Promise.resolve().then(() => loop());',
1374  { loop, console },
1375  { timeout: 5 }
1376);
1377// This is printed *before* 'entering loop' (!)
1378console.log('done executing');
1379```
1380
1381This can be addressed by passing `microtaskMode: 'afterEvaluate'` to the code
1382that creates the `Context`:
1383
1384```js
1385const vm = require('vm');
1386
1387function loop() {
1388  while (1) console.log(Date.now());
1389}
1390
1391vm.runInNewContext(
1392  'Promise.resolve().then(() => loop());',
1393  { loop, console },
1394  { timeout: 5, microtaskMode: 'afterEvaluate' }
1395);
1396```
1397
1398In this case, the microtask scheduled through `promise.then()` will be run
1399before returning from `vm.runInNewContext()`, and will be interrupted
1400by the `timeout` functionality. This applies only to code running in a
1401`vm.Context`, so e.g. [`vm.runInThisContext()`][] does not take this option.
1402
1403Promise callbacks are entered into the microtask queue of the context in which
1404they were created. For example, if `() => loop()` is replaced with just `loop`
1405in the above example, then `loop` will be pushed into the global microtask
1406queue, because it is a function from the outer (main) context, and thus will
1407also be able to escape the timeout.
1408
1409If asynchronous scheduling functions such as `process.nextTick()`,
1410`queueMicrotask()`, `setTimeout()`, `setImmediate()`, etc. are made available
1411inside a `vm.Context`, functions passed to them will be added to global queues,
1412which are shared by all contexts. Therefore, callbacks passed to those functions
1413are not controllable through the timeout either.
1414
1415[Cyclic Module Record]: https://tc39.es/ecma262/#sec-cyclic-module-records
1416[ECMAScript Module Loader]: esm.md#esm_modules_ecmascript_modules
1417[Evaluate() concrete method]: https://tc39.es/ecma262/#sec-moduleevaluation
1418[GetModuleNamespace]: https://tc39.es/ecma262/#sec-getmodulenamespace
1419[HostResolveImportedModule]: https://tc39.es/ecma262/#sec-hostresolveimportedmodule
1420[Link() concrete method]: https://tc39.es/ecma262/#sec-moduledeclarationlinking
1421[Module Record]: https://www.ecma-international.org/ecma-262/#sec-abstract-module-records
1422[Source Text Module Record]: https://tc39.es/ecma262/#sec-source-text-module-records
1423[Synthetic Module Record]: https://heycam.github.io/webidl/#synthetic-module-records
1424[V8 Embedder's Guide]: https://v8.dev/docs/embed#contexts
1425[`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`]: errors.md#ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING
1426[`ERR_VM_MODULE_STATUS`]: errors.md#ERR_VM_MODULE_STATUS
1427[`Error`]: errors.md#errors_class_error
1428[`URL`]: url.md#url_class_url
1429[`eval()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
1430[`script.runInContext()`]: #vm_script_runincontext_contextifiedobject_options
1431[`script.runInThisContext()`]: #vm_script_runinthiscontext_options
1432[`url.origin`]: url.md#url_url_origin
1433[`vm.createContext()`]: #vm_vm_createcontext_contextobject_options
1434[`vm.runInContext()`]: #vm_vm_runincontext_code_contextifiedobject_options
1435[`vm.runInThisContext()`]: #vm_vm_runinthiscontext_code_options
1436[contextified]: #vm_what_does_it_mean_to_contextify_an_object
1437[global object]: https://es5.github.io/#x15.1
1438[indirect `eval()` call]: https://es5.github.io/#x10.4.2
1439[origin]: https://developer.mozilla.org/en-US/docs/Glossary/Origin
1440