@@ -229,6 +229,9 @@ overhead.
229
229
<!-- YAML
230
230
added: v0.3.1
231
231
changes:
232
+ - version: REPLACEME
233
+ pr-url: https://github.com/nodejs/node/pull/54394
234
+ description: The `contextObject` argument now accepts `vm.constants.VANILLA_CONTEXT`.
232
235
- version: v14.6.0
233
236
pr-url: https://github.com/nodejs/node/pull/34023
234
237
description: The `microtaskMode` option is supported now.
@@ -240,8 +243,9 @@ changes:
240
243
description: The `breakOnSigint` option is supported now.
241
244
-->
242
245
243
- * ` contextObject ` {Object} An object that will be [ contextified] [ ] . If
244
- ` undefined ` , a new object will be created.
246
+ * ` contextObject ` {Object|vm.constants.VANILLA\_ CONTEXT|undefined}
247
+ Either [ ` vm.constants.VANILLA_CONTEXT ` ] [ ] or an object that will be [ contextified] [ ] .
248
+ If ` undefined ` , an empty contextified object will be created for backwards compatibility.
245
249
* ` options ` {Object}
246
250
* ` displayErrors ` {boolean} When ` true ` , if an [ ` Error ` ] [ ] occurs
247
251
while compiling the ` code ` , the line of code causing the error is attached
@@ -275,7 +279,9 @@ changes:
275
279
` breakOnSigint ` scopes in that case.
276
280
* Returns: {any} the result of the very last statement executed in the script.
277
281
278
- First contextifies the given ` contextObject ` , runs the compiled code contained
282
+ First contextifies the given ` contextObject ` (or
283
+ creates a new ` contextObject ` if passed as ` undefined ` ), or creates a new
284
+ vanilla context (if it's ` vm.constants.VANILLA_CONTEXT ` ), runs the compiled code contained
279
285
by the ` vm.Script ` object within the created context, and returns the result.
280
286
Running code does not have access to local scope.
281
287
@@ -295,6 +301,12 @@ contexts.forEach((context) => {
295
301
296
302
console .log (contexts);
297
303
// Prints: [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]
304
+
305
+ // This would throw if the context is created from a contextified object.
306
+ // vm.constants.VANILLA_CONTEXT allows creating vanilla contexts with ordinary
307
+ // global objects that can be freezed.
308
+ const freezeScript = new vm.Script (' Object.freeze(globalThis); globalThis;' );
309
+ const freezedContext = freezeScript .runInNewContext (vm .constants .VANILLA_CONTEXT );
298
310
```
299
311
300
312
### ` script.runInThisContext([options]) `
@@ -1072,6 +1084,10 @@ For detailed information, see
1072
1084
<!-- YAML
1073
1085
added: v0.3.1
1074
1086
changes:
1087
+ - version:
1088
+ - REPLACEME
1089
+ pr-url: https:// github.com/nodejs/node/pull/54394
1090
+ description: The `contextObject` argument now accepts `vm.constants.VANILLA_CONTEXT`.
1075
1091
- version:
1076
1092
- v21.7.0
1077
1093
- v20.12.0
@@ -1094,7 +1110,9 @@ changes:
1094
1110
description: The `codeGeneration` option is supported now.
1095
1111
-->
1096
1112
1097
- * `contextObject` {Object }
1113
+ * `contextObject` {Object | vm .constants .VANILLA \_CONTEXT | undefined }
1114
+ Either [` vm.constants.VANILLA_CONTEXT` ][] or an object that will be [contextified][].
1115
+ If ` undefined` , an empty contextified object will be created for backwards compatibility.
1098
1116
* ` options` {Object }
1099
1117
* ` name` {string} Human- readable name of the newly created context.
1100
1118
** Default: ** ` 'VM Context i'` , where ` i` is an ascending numerical index of
@@ -1124,10 +1142,10 @@ changes:
1124
1142
[Support of dynamic ` import()` in compilation APIs][].
1125
1143
* Returns: {Object } contextified object.
1126
1144
1127
- If given a ` contextObject` , the ` vm.createContext()` method will [prepare that
1145
+ If the given ` contextObject` is an object , the ` vm.createContext()` method will [prepare that
1128
1146
object][contextified] and return a reference to it so that it can be used in
1129
1147
calls to [` vm.runInContext()` ][] or [` script.runInContext()` ][]. Inside such
1130
- scripts, the ` contextObject ` will be the global object , retaining all of its
1148
+ scripts, the global object will be wrapped by the ` contextObject ` , retaining all of its
1131
1149
existing properties but also having the built- in objects and functions any
1132
1150
standard [global object][] has . Outside of scripts run by the vm module , global
1133
1151
variables will remain unchanged.
@@ -1152,6 +1170,12 @@ console.log(global.globalVar);
1152
1170
If ` contextObject` is omitted (or passed explicitly as ` undefined` ), a new ,
1153
1171
empty [contextified][] object will be returned.
1154
1172
1173
+ The global object wrapped as a [contextified][] object has some particularities compared to
1174
+ normal global objects . For example, it cannot be freezed . To create a vanilla context with an
1175
+ ordinary global object, pass [` vm.constants.VANILLA_CONTEXT` ][] as the ` contextObject` argument.
1176
+ The returned object will be the global object of the newly created context itself, without a
1177
+ contextified wrapper in between . See documentation of [` vm.constants.VANILLA_CONTEXT` ][] for details.
1178
+
1155
1179
The ` vm.createContext()` method is primarily useful for creating a single
1156
1180
context that can be used to run multiple scripts . For instance, if emulating a
1157
1181
web browser, the method can be used to create a single context representing a
@@ -1171,7 +1195,8 @@ added: v0.11.7
1171
1195
* Returns: {boolean}
1172
1196
1173
1197
Returns `true` if the given `object` object has been [contextified][] using
1174
- [`vm.createContext()`][].
1198
+ [`vm.createContext()`][], or if it' s the global object of a context created
1199
+ using [` vm.constants.VANILLA_CONTEXT` ][].
1175
1200
1176
1201
## ` vm.measureMemory([options])`
1177
1202
@@ -1332,6 +1357,10 @@ console.log(contextObject);
1332
1357
<!-- YAML
1333
1358
added: v0.3.1
1334
1359
changes:
1360
+ - version:
1361
+ - REPLACEME
1362
+ pr-url: https://github.com/nodejs/node/pull/54394
1363
+ description: The `contextObject` argument now accepts `vm.constants.VANILLA_CONTEXT`.
1335
1364
- version:
1336
1365
- v21.7.0
1337
1366
- v20.12.0
@@ -1356,8 +1385,9 @@ changes:
1356
1385
-->
1357
1386
1358
1387
* `code` {string} The JavaScript code to compile and run.
1359
- * ` contextObject` {Object } An object that will be [contextified][]. If
1360
- ` undefined` , a new object will be created.
1388
+ * `contextObject` {Object|vm.constants.VANILLA\_ CONTEXT|undefined}
1389
+ Either [`vm.constants.VANILLA_CONTEXT`][] or an object that will be [contextified][].
1390
+ If `undefined`, an empty contextified object will be created for backwards compatibility.
1361
1391
* `options` {Object|string}
1362
1392
* `filename` {string} Specifies the filename used in stack traces produced
1363
1393
by this script. **Default:** `' evalmachine.< anonymous> ' `.
@@ -1408,7 +1438,8 @@ changes:
1408
1438
* Returns: {any} the result of the very last statement executed in the script.
1409
1439
1410
1440
The ` vm.runInNewContext()` first contextifies the given ` contextObject` (or
1411
- creates a new `contextObject` if passed as `undefined`), compiles the `code`,
1441
+ creates a new ` contextObject` if passed as ` undefined` ), or creates a new
1442
+ vanilla context (if it' s `vm.constants.VANILLA_CONTEXT`), compiles the `code`,
1412
1443
runs it within the created context, then returns the result. Running code
1413
1444
does not have access to the local scope.
1414
1445
@@ -1428,6 +1459,11 @@ const contextObject = {
1428
1459
vm.runInNewContext(' count += 1 ; name = " kitty" ' , contextObject);
1429
1460
console.log(contextObject);
1430
1461
// Prints: { animal: ' cat' , count: 3, name: ' kitty' }
1462
+
1463
+ // This would throw if the context is created from a contextified object.
1464
+ // vm.constants.VANILLA_CONTEXT allows creating vanilla contexts with ordinary
1465
+ // global objects that can be freezed.
1466
+ const freezedContext = vm.runInNewContext(' Object .freeze (globalThis ); globalThis ;' , vm.constants.VANILLA_CONTEXT);
1431
1467
```
1432
1468
1433
1469
## `vm.runInThisContext(code[, options])`
@@ -1555,13 +1591,66 @@ According to the [V8 Embedder's Guide][]:
1555
1591
> JavaScript applications to run in a single instance of V8. You must explicitly
1556
1592
> specify the context in which you want any JavaScript code to be run.
1557
1593
1558
- When the method `vm.createContext()` is called, the `contextObject` argument
1559
- (or a newly-created object if `contextObject` is `undefined`) is associated
1560
- internally with a new instance of a V8 Context. This V8 Context provides the
1561
- `code` run using the `node:vm` module' s methods with an isolated global
1562
- environment within which it can operate . The process of creating the V8 Context
1563
- and associating it with the ` contextObject` is what this document refers to as
1564
- " contextifying" the object.
1594
+ When the method `vm.createContext()` is called with an object, the `contextObject` argument
1595
+ will be used to wrap the global object of a new instance of a V8 Context
1596
+ (if `contextObject` is `undefined`, a new object will be created from the current context
1597
+ before its contextified). This V8 Context provides the `code` run using the `node:vm`
1598
+ module' s methods with an isolated global environment within which it can operate.
1599
+ The process of creating the V8 Context and associating it with the ` contextObject`
1600
+ is what this document refers to as " contextifying" the object.
1601
+
1602
+ The contextifying would make the global object within the V8 context behave differently
1603
+ from a normal global object . For example, it is not reference equal to the ` globalThis`
1604
+ value in the context, and it cannot be freezed.
1605
+
1606
+ ` ` ` js
1607
+ const vm = require('node:vm');
1608
+
1609
+ // An undefined ` contextObject` option makes the global object contextified.
1610
+ let context = vm.createContext();
1611
+ console.log(vm.runInContext('globalThis', context) === context); // false
1612
+ // A contextified global object cannot be freezed.
1613
+ try {
1614
+ vm.runInContext('Object.freeze(globalThis);', context);
1615
+ } catch(e) {
1616
+ console.log(e); // TypeError: Cannot freeze
1617
+ }
1618
+ console.log(vm.runInContext('globalThis.foo = 1; foo;', context)); // 1
1619
+ ` ` `
1620
+
1621
+ To create a vanilla context with an ordinary global object, specify ` vm.constants.VANILLA_CONTEXT`
1622
+ as the ` contextObject` argument.
1623
+
1624
+ ### ` vm.constants.VANILLA_CONTEXT`
1625
+
1626
+ This constant, when used as the ` contextObject` argument in vm APIs, instructs Node .js to create
1627
+ a context without wrapping its global object with another object in the outer context . As a result,
1628
+ the global object inside the new context would behave more closely to an ordinary global object.
1629
+ For example, it can be freezed to prevent unintentional leakage to the global scope.
1630
+
1631
+ ` ` ` js
1632
+ const vm = require('node:vm');
1633
+
1634
+ // Use vm.constants.VANILLA_CONTEXT to freeze the global object.
1635
+ const freezedContext = vm.createContext(vm.constants.VANILLA_CONTEXT);
1636
+ vm.runInContext('Object.freeze(globalThis);', freezedContext);
1637
+ try {
1638
+ vm.runInContext('globalThis.foo = 1; foo;', freezedContext);
1639
+ } catch(e) {
1640
+ console.log(e); // Uncaught ReferenceError: foo is not defined
1641
+ }
1642
+ ` ` `
1643
+
1644
+ When used as the ` contextObject` argument to [` vm.createContext()` ][], the returned object
1645
+ is the global object of the context.
1646
+ The global object can also be modified from outside the context.
1647
+
1648
+ ` ` ` js
1649
+ const context = vm.createContext(vm.constants.VANILLA_CONTEXT);
1650
+ console.log(vm.runInContext('globalThis', context) === context); // true
1651
+ context.bar = 1;
1652
+ console.log(vm.runInContext('bar;', context)); // 1
1653
+ ` ` `
1565
1654
1566
1655
## Timeout interactions with asynchronous tasks and Promises
1567
1656
@@ -1851,6 +1940,7 @@ const { Script, SyntheticModule } = require('node:vm');
1851
1940
[` script .runInThisContext ()` ]: #scriptruninthiscontextoptions
1852
1941
[` url .origin ` ]: url.md#urlorigin
1853
1942
[` vm .compileFunction ()` ]: #vmcompilefunctioncode-params-options
1943
+ [` vm .constants .VANILLA_CONTEXT ` ]: #vmconstantsvanillacontext
1854
1944
[` vm .createContext ()` ]: #vmcreatecontextcontextobject-options
1855
1945
[` vm .runInContext ()` ]: #vmrunincontextcode-contextifiedobject-options
1856
1946
[` vm .runInThisContext ()` ]: #vmruninthiscontextcode-options
0 commit comments