@@ -228,6 +228,9 @@ overhead.
228228<!-- YAML
229229added: v0.3.1
230230changes:
231+ - version: REPLACEME
232+ pr-url: https://github.com/nodejs/node/pull/54394
233+ description: The `contextObject` argument now accepts `vm.constants.DONT_CONTEXTIFY`.
231234 - version: v14.6.0
232235 pr-url: https://github.com/nodejs/node/pull/34023
233236 description: The `microtaskMode` option is supported now.
@@ -239,8 +242,9 @@ changes:
239242 description: The `breakOnSigint` option is supported now.
240243-->
241244
242- * ` contextObject ` {Object} An object that will be [ contextified] [ ] . If
243- ` undefined ` , a new object will be created.
245+ * ` contextObject ` {Object|vm.constants.DONT\_ CONTEXTIFY|undefined}
246+ Either [ ` vm.constants.DONT_CONTEXTIFY ` ] [ ] or an object that will be [ contextified] [ ] .
247+ If ` undefined ` , an empty contextified object will be created for backwards compatibility.
244248* ` options ` {Object}
245249 * ` displayErrors ` {boolean} When ` true ` , if an [ ` Error ` ] [ ] occurs
246250 while compiling the ` code ` , the line of code causing the error is attached
@@ -274,9 +278,16 @@ changes:
274278 ` breakOnSigint ` scopes in that case.
275279* Returns: {any} the result of the very last statement executed in the script.
276280
277- First contextifies the given ` contextObject ` , runs the compiled code contained
278- by the ` vm.Script ` object within the created context, and returns the result.
279- Running code does not have access to local scope.
281+ This method is a shortcut to ` script.runInContext(vm.createContext(options), options) ` .
282+ It does several things at once:
283+
284+ 1 . Creates a new context.
285+ 2 . If ` contextObject ` is an object, [ contextifies] [ contextified ] it with the new context.
286+ If ` contextObject ` is undefined, creates a new object and [ contextifies] [ contextified ] it.
287+ If ` contextObject ` is [ ` vm.constants.DONT_CONTEXTIFY ` ] [ ] , don't [ contextify] [ contextified ] anything.
288+ 3 . Runs the compiled code contained by the ` vm.Script ` object within the created context. The code
289+ does not have access to the scope in which this method is called.
290+ 4 . Returns the result.
280291
281292The following example compiles code that sets a global variable, then executes
282293the code multiple times in different contexts. The globals are set on and
@@ -294,6 +305,12 @@ contexts.forEach((context) => {
294305
295306console .log (contexts);
296307// Prints: [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]
308+
309+ // This would throw if the context is created from a contextified object.
310+ // vm.constants.DONT_CONTEXTIFY allows creating contexts with ordinary
311+ // global objects that can be frozen.
312+ const freezeScript = new vm.Script (' Object.freeze(globalThis); globalThis;' );
313+ const frozenContext = freezeScript .runInNewContext (vm .constants .DONT_CONTEXTIFY );
297314```
298315
299316### ` script.runInThisContext([options]) `
@@ -1063,6 +1080,10 @@ For detailed information, see
10631080<!-- YAML
10641081added: v0.3.1
10651082changes:
1083+ - version:
1084+ - REPLACEME
1085+ pr-url: https:// github.com/nodejs/node/pull/54394
1086+ description: The `contextObject` argument now accepts `vm.constants.DONT_CONTEXTIFY`.
10661087 - version:
10671088 - v20.12.0
10681089 pr-url: https:// github.com/nodejs/node/pull/51244
@@ -1083,7 +1104,9 @@ changes:
10831104 description: The `codeGeneration` option is supported now.
10841105-->
10851106
1086- * `contextObject` {Object }
1107+ * `contextObject` {Object | vm .constants .DONT \_CONTEXTIFY | undefined }
1108+ Either [` vm.constants.DONT_CONTEXTIFY` ][] or an object that will be [contextified][].
1109+ If ` undefined` , an empty contextified object will be created for backwards compatibility.
10871110* ` options` {Object }
10881111 * ` name` {string} Human- readable name of the newly created context.
10891112 ** Default: ** ` 'VM Context i'` , where ` i` is an ascending numerical index of
@@ -1113,10 +1136,10 @@ changes:
11131136 [Support of dynamic ` import()` in compilation APIs][].
11141137* Returns: {Object } contextified object.
11151138
1116- If given a ` contextObject` , the ` vm.createContext()` method will [prepare that
1139+ If the given ` contextObject` is an object , the ` vm.createContext()` method will [prepare that
11171140object][contextified] and return a reference to it so that it can be used in
11181141calls to [` vm.runInContext()` ][] or [` script.runInContext()` ][]. Inside such
1119- scripts, the ` contextObject ` will be the global object , retaining all of its
1142+ scripts, the global object will be wrapped by the ` contextObject ` , retaining all of its
11201143existing properties but also having the built- in objects and functions any
11211144standard [global object][] has . Outside of scripts run by the vm module , global
11221145variables will remain unchanged.
@@ -1141,6 +1164,11 @@ console.log(global.globalVar);
11411164If ` contextObject` is omitted (or passed explicitly as ` undefined` ), a new ,
11421165empty [contextified][] object will be returned.
11431166
1167+ When the global object in the newly created context is [contextified][], it has some quirks
1168+ compared to ordinary global objects . For example, it cannot be frozen . To create a context
1169+ without the contextifying quirks, pass [` vm.constants.DONT_CONTEXTIFY` ][] as the ` contextObject`
1170+ argument . See the documentation of [` vm.constants.DONT_CONTEXTIFY` ][] for details.
1171+
11441172The ` vm.createContext()` method is primarily useful for creating a single
11451173context that can be used to run multiple scripts . For instance, if emulating a
11461174web browser, the method can be used to create a single context representing a
@@ -1160,7 +1188,8 @@ added: v0.11.7
11601188* Returns: {boolean}
11611189
11621190Returns `true` if the given `object` object has been [contextified][] using
1163- [`vm.createContext()`][].
1191+ [`vm.createContext()`][], or if it' s the global object of a context created
1192+ using [` vm.constants.DONT_CONTEXTIFY` ][].
11641193
11651194## ` vm.measureMemory([options])`
11661195
@@ -1320,6 +1349,10 @@ console.log(contextObject);
13201349<!-- YAML
13211350added: v0.3.1
13221351changes:
1352+ - version:
1353+ - REPLACEME
1354+ pr-url: https://github.com/nodejs/node/pull/54394
1355+ description: The `contextObject` argument now accepts `vm.constants.DONT_CONTEXTIFY`.
13231356 - version:
13241357 - v20.12.0
13251358 pr-url: https://github.com/nodejs/node/pull/51244
@@ -1343,8 +1376,9 @@ changes:
13431376-->
13441377
13451378* `code` {string} The JavaScript code to compile and run.
1346- * ` contextObject` {Object } An object that will be [contextified][]. If
1347- ` undefined` , a new object will be created.
1379+ * `contextObject` {Object|vm.constants.DONT\_ CONTEXTIFY|undefined}
1380+ Either [`vm.constants.DONT_CONTEXTIFY`][] or an object that will be [contextified][].
1381+ If `undefined`, an empty contextified object will be created for backwards compatibility.
13481382* `options` {Object|string}
13491383 * `filename` {string} Specifies the filename used in stack traces produced
13501384 by this script. **Default:** `' evalmachine.< anonymous> ' `.
@@ -1394,13 +1428,21 @@ changes:
13941428 ` breakOnSigint` scopes in that case.
13951429* Returns: {any} the result of the very last statement executed in the script.
13961430
1397- The `vm.runInNewContext()` first contextifies the given `contextObject` (or
1398- creates a new `contextObject` if passed as `undefined`), compiles the `code`,
1399- runs it within the created context, then returns the result. Running code
1400- does not have access to the local scope.
1401-
1431+ This method is a shortcut to
1432+ ` (new vm.Script(code, options)).runInContext(vm.createContext(options), options)` .
14021433If ` options` is a string, then it specifies the filename.
14031434
1435+ It does several things at once:
1436+
1437+ 1. Creates a new context.
1438+ 2. If ` contextObject` is an object, [contextifies][contextified] it with the new context.
1439+ If ` contextObject` is undefined , creates a new object and [contextifies][contextified] it.
1440+ If ` contextObject` is [` vm.constants.DONT_CONTEXTIFY` ][], don' t [contextify][contextified] anything.
1441+ 3. Compiles the code as a`vm.Script`
1442+ 4. Runs the compield code within the created context. The code does not have access to the scope in
1443+ which this method is called.
1444+ 5. Returns the result.
1445+
14041446The following example compiles and executes code that increments a global
14051447variable and sets a new one. These globals are contained in the `contextObject`.
14061448
@@ -1415,6 +1457,11 @@ const contextObject = {
14151457vm.runInNewContext(' count += 1 ; name = " kitty" ' , contextObject);
14161458console.log(contextObject);
14171459// Prints: { animal: ' cat' , count: 3, name: ' kitty' }
1460+
1461+ // This would throw if the context is created from a contextified object.
1462+ // vm.constants.DONT_CONTEXTIFY allows creating contexts with ordinary global objects that
1463+ // can be frozen.
1464+ const frozenContext = vm.runInNewContext(' Object .freeze (globalThis ); globalThis ;' , vm.constants.DONT_CONTEXTIFY);
14181465```
14191466
14201467## `vm.runInThisContext(code[, options])`
@@ -1541,13 +1588,85 @@ According to the [V8 Embedder's Guide][]:
15411588> JavaScript applications to run in a single instance of V8. You must explicitly
15421589> specify the context in which you want any JavaScript code to be run.
15431590
1544- When the method `vm.createContext()` is called, the `contextObject` argument
1545- (or a newly-created object if `contextObject` is `undefined`) is associated
1546- internally with a new instance of a V8 Context. This V8 Context provides the
1547- `code` run using the `node:vm` module' s methods with an isolated global
1548- environment within which it can operate . The process of creating the V8 Context
1549- and associating it with the ` contextObject` is what this document refers to as
1550- " contextifying" the object.
1591+ When the method `vm.createContext()` is called with an object, the `contextObject` argument
1592+ will be used to wrap the global object of a new instance of a V8 Context
1593+ (if `contextObject` is `undefined`, a new object will be created from the current context
1594+ before its contextified). This V8 Context provides the `code` run using the `node:vm`
1595+ module' s methods with an isolated global environment within which it can operate.
1596+ The process of creating the V8 Context and associating it with the ` contextObject`
1597+ in the outer context is what this document refers to as " contextifying" the object.
1598+
1599+ The contextifying would introduce some quirks to the ` globalThis` value in the context.
1600+ For example, it cannot be frozen, and it is not reference equal to the ` contextObject`
1601+ in the outer context.
1602+
1603+ ` ` ` js
1604+ const vm = require('node:vm');
1605+
1606+ // An undefined ` contextObject` option makes the global object contextified.
1607+ const context = vm.createContext();
1608+ console.log(vm.runInContext('globalThis', context) === context); // false
1609+ // A contextified global object cannot be frozen.
1610+ try {
1611+ vm.runInContext('Object.freeze(globalThis);', context);
1612+ } catch (e) {
1613+ console.log(e); // TypeError: Cannot freeze
1614+ }
1615+ console.log(vm.runInContext('globalThis.foo = 1; foo;', context)); // 1
1616+ ` ` `
1617+
1618+ To create a context with an ordinary global object and get access to a global proxy in
1619+ the outer context with fewer quirks, specify ` vm.constants.DONT_CONTEXTIFY` as the
1620+ ` contextObject` argument.
1621+
1622+ ### ` vm.constants.DONT_CONTEXTIFY`
1623+
1624+ This constant, when used as the ` contextObject` argument in vm APIs, instructs Node .js to create
1625+ a context without wrapping its global object with another object in a Node .js - specific manner.
1626+ As a result, the ` globalThis` value inside the new context would behave more closely to an ordinary
1627+ one.
1628+
1629+ ` ` ` js
1630+ const vm = require('node:vm');
1631+
1632+ // Use vm.constants.DONT_CONTEXTIFY to freeze the global object.
1633+ const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);
1634+ vm.runInContext('Object.freeze(globalThis);', context);
1635+ try {
1636+ vm.runInContext('bar = 1; bar;', context);
1637+ } catch (e) {
1638+ console.log(e); // Uncaught ReferenceError: bar is not defined
1639+ }
1640+ ` ` `
1641+
1642+ When ` vm.constants.DONT_CONTEXTIFY` is used as the ` contextObject` argument to [` vm.createContext()` ][],
1643+ the returned object is a proxy- like object to the global object in the newly created context with
1644+ fewer Node .js - specific quirks . It is reference equal to the ` globalThis` value in the new context ,
1645+ can be modified from outside the context, and can be used to access built- ins in the new context directly.
1646+
1647+ ` ` ` js
1648+ const vm = require('node:vm');
1649+
1650+ const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);
1651+
1652+ // Returned object is reference equal to globalThis in the new context.
1653+ console.log(vm.runInContext('globalThis', context) === context); // true
1654+
1655+ // Can be used to access globals in the new context directly.
1656+ console.log(context.Array); // [Function: Array]
1657+ vm.runInContext('foo = 1;', context);
1658+ console.log(context.foo); // 1
1659+ context.bar = 1;
1660+ console.log(vm.runInContext('bar;', context)); // 1
1661+
1662+ // Can be frozen and it affects the inner context.
1663+ Object.freeze(context);
1664+ try {
1665+ vm.runInContext('baz = 1; baz;', context);
1666+ } catch (e) {
1667+ console.log(e); // Uncaught ReferenceError: baz is not defined
1668+ }
1669+ ` ` `
15511670
15521671## Timeout interactions with asynchronous tasks and Promises
15531672
@@ -1837,6 +1956,7 @@ const { Script, SyntheticModule } = require('node:vm');
18371956[` script .runInThisContext ()` ]: #scriptruninthiscontextoptions
18381957[` url .origin ` ]: url.md#urlorigin
18391958[` vm .compileFunction ()` ]: #vmcompilefunctioncode-params-options
1959+ [` vm .constants .DONT_CONTEXTIFY ` ]: #vmconstantsdont_contextify
18401960[` vm .createContext ()` ]: #vmcreatecontextcontextobject-options
18411961[` vm .runInContext ()` ]: #vmrunincontextcode-contextifiedobject-options
18421962[` vm .runInThisContext ()` ]: #vmruninthiscontextcode-options
0 commit comments