| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 2033a9f commit 0993fbe
16 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1639,6 +1639,43 @@ entry types were found. | |||
| 1639 | 1639 | ||
| 1640 | 1640 | Superseded by `ERR_OUT_OF_RANGE` | |
| 1641 | 1641 | ||
| 1642 | + <a id="ERR_VM_MODULE_ALREADY_LINKED"></a> | ||
| 1643 | + ### ERR_VM_MODULE_ALREADY_LINKED | ||
| 1644 | + | ||
| 1645 | + The module attempted to be linked is not eligible for linking, because of one of | ||
| 1646 | + the following reasons: | ||
| 1647 | + | ||
| 1648 | + - It has already been linked (`linkingStatus` is `'linked'`) | ||
| 1649 | + - It is being linked (`linkingStatus` is `'linking'`) | ||
| 1650 | + - Linking has failed for this module (`linkingStatus` is `'errored'`) | ||
| 1651 | + | ||
| 1652 | + <a id="ERR_VM_MODULE_DIFFERENT_CONTEXT"></a> | ||
| 1653 | + ### ERR_VM_MODULE_DIFFERENT_CONTEXT | ||
| 1654 | + | ||
| 1655 | + The module being returned from the linker function is from a different context | ||
| 1656 | + than the parent module. Linked modules must share the same context. | ||
| 1657 | + | ||
| 1658 | + <a id="ERR_VM_MODULE_LINKING_ERRORED"></a> | ||
| 1659 | + ### ERR_VM_MODULE_LINKING_ERRORED | ||
| 1660 | + | ||
| 1661 | + The linker function returned a module for which linking has failed. | ||
| 1662 | + | ||
| 1663 | + <a id="ERR_VM_MODULE_NOT_LINKED"></a> | ||
| 1664 | + ### ERR_VM_MODULE_NOT_LINKED | ||
| 1665 | + | ||
| 1666 | + The module must be successfully linked before instantiation. | ||
| 1667 | + | ||
| 1668 | + <a id="ERR_VM_MODULE_NOT_MODULE"></a> | ||
| 1669 | + ### ERR_VM_MODULE_NOT_MODULE | ||
| 1670 | + | ||
| 1671 | + The fulfilled value of a linking promise is not a `vm.Module` object. | ||
| 1672 | + | ||
| 1673 | + <a id="ERR_VM_MODULE_STATUS"></a> | ||
| 1674 | + ### ERR_VM_MODULE_STATUS | ||
| 1675 | + | ||
| 1676 | + The current module's status does not allow for this operation. The specific | ||
| 1677 | + meaning of the error depends on the specific function. | ||
| 1678 | + | ||
| 1642 | 1679 | <a id="ERR_ZLIB_BINDING_CLOSED"></a> | |
| 1643 | 1680 | ### ERR_ZLIB_BINDING_CLOSED | |
| 1644 | 1681 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -43,6 +43,322 @@ console.log(x); // 1; y is not defined. | |||
| 43 | 43 | *Note*: The vm module is not a security mechanism. | |
| 44 | 44 | **Do not use it to run untrusted code**. | |
| 45 | 45 | ||
| 46 | + ## Class: vm.Module | ||
| 47 | + <!-- YAML | ||
| 48 | + added: REPLACEME | ||
| 49 | + --> | ||
| 50 | + | ||
| 51 | + > Stability: 1 - Experimental | ||
| 52 | + | ||
| 53 | + *This feature is only available with the `--experimental-vm-modules` command | ||
| 54 | + flag enabled.* | ||
| 55 | + | ||
| 56 | + The `vm.Module` class provides a low-level interface for using ECMAScript | ||
| 57 | + modules in VM contexts. It is the counterpart of the `vm.Script` class that | ||
| 58 | + closely mirrors [Source Text Module Record][]s as defined in the ECMAScript | ||
| 59 | + specification. | ||
| 60 | + | ||
| 61 | + Unlike `vm.Script` however, every `vm.Module` object is bound to a context from | ||
| 62 | + its creation. Operations on `vm.Module` objects are intrinsically asynchronous, | ||
| 63 | + in contrast with the synchronous nature of `vm.Script` objects. With the help | ||
| 64 | + of async functions, however, manipulating `vm.Module` objects is fairly | ||
| 65 | + straightforward. | ||
| 66 | + | ||
| 67 | + Using a `vm.Module` object requires four distinct steps: creation/parsing, | ||
| 68 | + linking, instantiation, and evaluation. These four steps are illustrated in the | ||
| 69 | + following example. | ||
| 70 | + | ||
| 71 | + *Note*: This implementation lies at a lower level than the [ECMAScript Module | ||
| 72 | + loader][]. There is also currently no way to interact with the Loader, though | ||
| 73 | + support is planned. | ||
| 74 | + | ||
| 75 | + ```js | ||
| 76 | + const vm = require('vm'); | ||
| 77 | + | ||
| 78 | + const contextifiedSandbox = vm.createContext({ secret: 42 }); | ||
| 79 | + | ||
| 80 | + (async () => { | ||
| 81 | + // Step 1 | ||
| 82 | + // | ||
| 83 | + // Create a Module by constructing a new `vm.Module` object. This parses the | ||
| 84 | + // provided source text, throwing a `SyntaxError` if anything goes wrong. By | ||
| 85 | + // default, a Module is created in the top context. But here, we specify | ||
| 86 | + // `contextifiedSandbox` as the context this Module belongs to. | ||
| 87 | + // | ||
| 88 | + // Here, we attempt to obtain the default export from the module "foo", and | ||
| 89 | + // put it into local binding "secret". | ||
| 90 | + | ||
| 91 | + const bar = new vm.Module(` | ||
| 92 | + import s from 'foo'; | ||
| 93 | + s; | ||
| 94 | + `, { context: contextifiedSandbox }); | ||
| 95 | + | ||
| 96 | + | ||
| 97 | + // Step 2 | ||
| 98 | + // | ||
| 99 | + // "Link" the imported dependencies of this Module to it. | ||
| 100 | + // | ||
| 101 | + // The provided linking callback (the "linker") accepts two arguments: the | ||
| 102 | + // parent module (`bar` in this case) and the string that is the specifier of | ||
| 103 | + // the imported module. The callback is expected to return a Module that | ||
| 104 | + // corresponds to the provided specifier, with certain requirements documented | ||
| 105 | + // in `module.link()`. | ||
| 106 | + // | ||
| 107 | + // If linking has not started for the returned Module, the same linker | ||
| 108 | + // callback will be called on the returned Module. | ||
| 109 | + // | ||
| 110 | + // Even top-level Modules without dependencies must be explicitly linked. The | ||
| 111 | + // callback provided would never be called, however. | ||
| 112 | + // | ||
| 113 | + // The link() method returns a Promise that will be resolved when all the | ||
| 114 | + // Promises returned by the linker resolve. | ||
| 115 | + // | ||
| 116 | + // Note: This is a contrived example in that the linker function creates a new | ||
| 117 | + // "foo" module every time it is called. In a full-fledged module system, a | ||
| 118 | + // cache would probably be used to avoid duplicated modules. | ||
| 119 | + | ||
| 120 | + async function linker(referencingModule, specifier) { | ||
| 121 | + if (specifier === 'foo') { | ||
| 122 | + return new vm.Module(` | ||
| 123 | + // The "secret" variable refers to the global variable we added to | ||
| 124 | + // "contextifiedSandbox" when creating the context. | ||
| 125 | + export default secret; | ||
| 126 | + `, { context: referencingModule.context }); | ||
| 127 | + | ||
| 128 | + // Using `contextifiedSandbox` instead of `referencingModule.context` | ||
| 129 | + // here would work as well. | ||
| 130 | + } | ||
| 131 | + throw new Error(`Unable to resolve dependency: ${specifier}`); | ||
| 132 | + } | ||
| 133 | + await bar.link(linker); | ||
| 134 | + | ||
| 135 | + | ||
| 136 | + // Step 3 | ||
| 137 | + // | ||
| 138 | + // Instantiate the top-level Module. | ||
| 139 | + // | ||
| 140 | + // Only the top-level Module needs to be explicitly instantiated; its | ||
| 141 | + // dependencies will be recursively instantiated by instantiate(). | ||
| 142 | + | ||
| 143 | + bar.instantiate(); | ||
| 144 | + | ||
| 145 | + | ||
| 146 | + // Step 4 | ||
| 147 | + // | ||
| 148 | + // Evaluate the Module. The evaluate() method returns a Promise with a single | ||
| 149 | + // property "result" that contains the result of the very last statement | ||
| 150 | + // executed in the Module. In the case of `bar`, it is `s;`, which refers to | ||
| 151 | + // the default export of the `foo` module, the `secret` we set in the | ||
| 152 | + // beginning to 42. | ||
| 153 | + | ||
| 154 | + const { result } = await bar.evaluate(); | ||
| 155 | + | ||
| 156 | + console.log(result); | ||
| 157 | + // Prints 42. | ||
| 158 | + })(); | ||
| 159 | + ``` | ||
| 160 | + | ||
| 161 | + ### Constructor: new vm.Module(code[, options]) | ||
| 162 | + | ||
| 163 | + * `code` {string} JavaScript Module code to parse | ||
| 164 | + * `options` | ||
| 165 | + * `url` {string} URL used in module resolution and stack traces. **Default**: | ||
| 166 | + `'vm:module(i)'` where `i` is a context-specific ascending index. | ||
| 167 | + * `context` {Object} The [contextified][] object as returned by the | ||
| 168 | + `vm.createContext()` method, to compile and evaluate this Module in. | ||
| 169 | + * `lineOffset` {integer} Specifies the line number offset that is displayed | ||
| 170 | + in stack traces produced by this Module. | ||
| 171 | + * `columnOffset` {integer} Spcifies the column number offset that is displayed | ||
| 172 | + in stack traces produced by this Module. | ||
| 173 | + | ||
| 174 | + Creates a new ES `Module` object. | ||
| 175 | + | ||
| 176 | + ### module.dependencySpecifiers | ||
| 177 | + | ||
| 178 | + * {string[]} | ||
| 179 | + | ||
| 180 | + The specifiers of all dependencies of this module. The returned array is frozen | ||
| 181 | + to disallow any changes to it. | ||
| 182 | + | ||
| 183 | + Corresponds to the [[RequestedModules]] field of [Source Text Module Record][]s | ||
| 184 | + in the ECMAScript specification. | ||
| 185 | + | ||
| 186 | + ### module.error | ||
| 187 | + | ||
| 188 | + * {any} | ||
| 189 | + | ||
| 190 | + If the `module.status` is `'errored'`, this property contains the exception thrown | ||
| 191 | + by the module during evaluation. If the status is anything else, accessing this | ||
| 192 | + property will result in a thrown exception. | ||
| 193 | + | ||
| 194 | + *Note*: `undefined` cannot be used for cases where there is not a thrown | ||
| 195 | + exception due to possible ambiguity with `throw undefined;`. | ||
| 196 | + | ||
| 197 | + Corresponds to the [[EvaluationError]] field of [Source Text Module Record][]s | ||
| 198 | + in the ECMAScript specification. | ||
| 199 | + | ||
| 200 | + ### module.linkingStatus | ||
| 201 | + | ||
| 202 | + * {string} | ||
| 203 | + | ||
| 204 | + The current linking status of `module`. It will be one of the following values: | ||
| 205 | + | ||
| 206 | + - `'unlinked'`: `module.link()` has not yet been called. | ||
| 207 | + - `'linking'`: `module.link()` has been called, but not all Promises returned by | ||
| 208 | + the linker function have been resolved yet. | ||
| 209 | + - `'linked'`: `module.link()` has been called, and all its dependencies have | ||
| 210 | + been successfully linked. | ||
| 211 | + - `'errored'`: `module.link()` has been called, but at least one of its | ||
| 212 | + dependencies failed to link, either because the callback returned a Promise | ||
| 213 | + that is rejected, or because the Module the callback returned is invalid. | ||
| 214 | + | ||
| 215 | + ### module.namespace | ||
| 216 | + | ||
| 217 | + * {Object} | ||
| 218 | + | ||
| 219 | + The namespace object of the module. This is only available after instantiation | ||
| 220 | + (`module.instantiate()`) has completed. | ||
| 221 | + | ||
| 222 | + Corresponds to the [GetModuleNamespace][] abstract operation in the ECMAScript | ||
| 223 | + specification. | ||
| 224 | + | ||
| 225 | + ### module.status | ||
| 226 | + | ||
| 227 | + * {string} | ||
| 228 | + | ||
| 229 | + The current status of the module. Will be one of: | ||
| 230 | + | ||
| 231 | + - `'uninstantiated'`: The module is not instantiated. It may because of any of | ||
| 232 | + the following reasons: | ||
| 233 | + | ||
| 234 | + - The module was just created. | ||
| 235 | + - `module.instantiate()` has been called on this module, but it failed for | ||
| 236 | + some reason. | ||
| 237 | + | ||
| 238 | + This status does not convey any information regarding if `module.link()` has | ||
| 239 | + been called. See `module.linkingStatus` for that. | ||
| 240 | + | ||
| 241 | + - `'instantiating'`: The module is currently being instantiated through a | ||
| 242 | + `module.instantiate()` call on itself or a parent module. | ||
| 243 | + | ||
| 244 | + - `'instantiated'`: The module has been instantiated successfully, but | ||
| 245 | + `module.evaluate()` has not yet been called. | ||
| 246 | + | ||
| 247 | + - `'evaluating'`: The module is being evaluated through a `module.evaluate()` on | ||
| 248 | + itself or a parent module. | ||
| 249 | + | ||
| 250 | + - `'evaluated'`: The module has been successfully evaluated. | ||
| 251 | + | ||
| 252 | + - `'errored'`: The module has been evaluated, but an exception was thrown. | ||
| 253 | + | ||
| 254 | + Other than `'errored'`, this status string corresponds to the specification's | ||
| 255 | + [Source Text Module Record][]'s [[Status]] field. `'errored'` corresponds to | ||
| 256 | + `'evaluated'` in the specification, but with [[EvaluationError]] set to a value | ||
| 257 | + that is not `undefined`. | ||
| 258 | + | ||
| 259 | + ### module.url | ||
| 260 | + | ||
| 261 | + * {string} | ||
| 262 | + | ||
| 263 | + The URL of the current module, as set in the constructor. | ||
| 264 | + | ||
| 265 | + ### module.evaluate([options]) | ||
| 266 | + | ||
| 267 | + * `options` {Object} | ||
| 268 | + * `timeout` {number} Specifies the number of milliseconds to evaluate | ||
| 269 | + before terminating execution. If execution is interrupted, an [`Error`][] | ||
| 270 | + will be thrown. | ||
| 271 | + * `breakOnSigint` {boolean} If `true`, the execution will be terminated when | ||
| 272 | + `SIGINT` (Ctrl+C) is received. Existing handlers for the event that have | ||
| 273 | + been attached via `process.on("SIGINT")` will be disabled during script | ||
| 274 | + execution, but will continue to work after that. If execution is | ||
| 275 | + interrupted, an [`Error`][] will be thrown. | ||
| 276 | + * Returns: {Promise} | ||
| 277 | + | ||
| 278 | + Evaluate the module. | ||
| 279 | + | ||
| 280 | + This must be called after the module has been instantiated; otherwise it will | ||
| 281 | + throw an error. It could be called also when the module has already been | ||
| 282 | + evaluated, in which case it will do one of the following two things: | ||
| 283 | + | ||
| 284 | + - return `undefined` if the initial evaluation ended in success (`module.status` | ||
| 285 | + is `'evaluated'`) | ||
| 286 | + - rethrow the same exception the initial evaluation threw if the initial | ||
| 287 | + evaluation ended in an error (`module.status` is `'errored'`) | ||
| 288 | + | ||
| 289 | + This method cannot be called while the module is being evaluated | ||
| 290 | + (`module.status` is `'evaluating'`) to prevent infinite recursion. | ||
| 291 | + | ||
| 292 | + Corresponds to the [Evaluate() concrete method][] field of [Source Text Module | ||
| 293 | + Record][]s in the ECMAScript specification. | ||
| 294 | + | ||
| 295 | + ### module.instantiate() | ||
| 296 | + | ||
| 297 | + Instantiate the module. This must be called after linking has completed | ||
| 298 | + (`linkingStatus` is `'linked'`); otherwise it will throw an error. It may also | ||
| 299 | + throw an exception if one of the dependencies does not provide an export the | ||
| 300 | + parent module requires. | ||
| 301 | + | ||
| 302 | + However, if this function succeeded, further calls to this function after the | ||
| 303 | + initial instantiation will be no-ops, to be consistent with the ECMAScript | ||
| 304 | + specification. | ||
| 305 | + | ||
| 306 | + Unlike other methods operating on `Module`, this function completes | ||
| 307 | + synchronously and returns nothing. | ||
| 308 | + | ||
| 309 | + Corresponds to the [Instantiate() concrete method][] field of [Source Text | ||
| 310 | + Module Record][]s in the ECMAScript specification. | ||
| 311 | + | ||
| 312 | + ### module.link(linker) | ||
| 313 | + | ||
| 314 | + * `linker` {Function} | ||
| 315 | + * Returns: {Promise} | ||
| 316 | + | ||
| 317 | + Link module dependencies. This method must be called before instantiation, and | ||
| 318 | + can only be called once per module. | ||
| 319 | + | ||
| 320 | + Two parameters will be passed to the `linker` function: | ||
| 321 | + | ||
| 322 | + - `referencingModule` The `Module` object `link()` is called on. | ||
| 323 | + - `specifier` The specifier of the requested module: | ||
| 324 | + | ||
| 325 | + <!-- eslint-skip --> | ||
| 326 | + ```js | ||
| 327 | + import foo from 'foo'; | ||
| 328 | + // ^^^^^ the module specifier | ||
| 329 | + ``` | ||
| 330 | + | ||
| 331 | + The function is expected to return a `Module` object or a `Promise` that | ||
| 332 | + eventually resolves to a `Module` object. The returned `Module` must satisfy the | ||
| 333 | + following two invariants: | ||
| 334 | + | ||
| 335 | + - It must belong to the same context as the parent `Module`. | ||
| 336 | + - Its `linkingStatus` must not be `'errored'`. | ||
| 337 | + | ||
| 338 | + If the returned `Module`'s `linkingStatus` is `'unlinked'`, this method will be | ||
| 339 | + recursively called on the returned `Module` with the same provided `linker` | ||
| 340 | + function. | ||
| 341 | + | ||
| 342 | + `link()` returns a `Promise` that will either get resolved when all linking | ||
| 343 | + instances resolve to a valid `Module`, or rejected if the linker function either | ||
| 344 | + throws an exception or returns an invalid `Module`. | ||
| 345 | + | ||
| 346 | + The linker function roughly corresponds to the implementation-defined | ||
| 347 | + [HostResolveImportedModule][] abstract operation in the ECMAScript | ||
| 348 | + specification, with a few key differences: | ||
| 349 | + | ||
| 350 | + - The linker function is allowed to be asynchronous while | ||
| 351 | + [HostResolveImportedModule][] is synchronous. | ||
| 352 | + - The linker function is executed during linking, a Node.js-specific stage | ||
| 353 | + before instantiation, while [HostResolveImportedModule][] is called during | ||
| 354 | + instantiation. | ||
| 355 | + | ||
| 356 | + The actual [HostResolveImportedModule][] implementation used during module | ||
| 357 | + instantiation is one that returns the modules linked during linking. Since at | ||
| 358 | + that point all modules would have been fully linked already, the | ||
| 359 | + [HostResolveImportedModule][] implementation is fully synchronous per | ||
| 360 | + specification. | ||
| 361 | + | ||
| 46 | 362 | ## Class: vm.Script | |
| 47 | 363 | <!-- YAML | |
| 48 | 364 | added: v0.3.1 | |
@@ -518,8 +834,14 @@ associating it with the `sandbox` object is what this document refers to as | |||
| 518 | 834 | [`vm.createContext()`]: #vm_vm_createcontext_sandbox_options | |
| 519 | 835 | [`vm.runInContext()`]: #vm_vm_runincontext_code_contextifiedsandbox_options | |
| 520 | 836 | [`vm.runInThisContext()`]: #vm_vm_runinthiscontext_code_options | |
| 837 | + [GetModuleNamespace]: https://tc39.github.io/ecma262/#sec-getmodulenamespace | ||
| 838 | + [ECMAScript Module Loader]: esm.html#esm_ecmascript_modules | ||
| 839 | + [Evaluate() concrete method]: https://tc39.github.io/ecma262/#sec-moduleevaluation | ||
| 840 | + [HostResolveImportedModule]: https://tc39.github.io/ecma262/#sec-hostresolveimportedmodule | ||
| 841 | + [Instantiate() concrete method]: https://tc39.github.io/ecma262/#sec-moduledeclarationinstantiation | ||
| 521 | 842 | [V8 Embedder's Guide]: https://github.com/v8/v8/wiki/Embedder's%20Guide#contexts | |
| 522 | 843 | [contextified]: #vm_what_does_it_mean_to_contextify_an_object | |
| 523 | 844 | [global object]: https://es5.github.io/#x15.1 | |
| 524 | 845 | [indirect `eval()` call]: https://es5.github.io/#x10.4.2 | |
| 525 | 846 | [origin]: https://developer.mozilla.org/en-US/docs/Glossary/Origin | |
| 847 | + [Source Text Module Record]: https://tc39.github.io/ecma262/#sec-source-text-module-records | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -676,6 +676,15 @@ E('ERR_V8BREAKITERATOR', 'Full ICU data not installed. ' + | |||
| 676 | 676 | 'See https://github.com/nodejs/node/wiki/Intl'); | |
| 677 | 677 | E('ERR_VALID_PERFORMANCE_ENTRY_TYPE', | |
| 678 | 678 | 'At least one valid performance entry type is required'); | |
| 679 | + E('ERR_VM_MODULE_ALREADY_LINKED', 'Module has already been linked'); | ||
| 680 | + E('ERR_VM_MODULE_DIFFERENT_CONTEXT', | ||
| 681 | + 'Linked modules must use the same context'); | ||
| 682 | + E('ERR_VM_MODULE_LINKING_ERRORED', | ||
| 683 | + 'Linking has already failed for the provided module'); | ||
| 684 | + E('ERR_VM_MODULE_NOT_LINKED', | ||
| 685 | + 'Module must be linked before it can be instantiated'); | ||
| 686 | + E('ERR_VM_MODULE_NOT_MODULE', 'Provided module is not an instance of Module'); | ||
| 687 | + E('ERR_VM_MODULE_STATUS', 'Module status %s'); | ||
| 679 | 688 | E('ERR_ZLIB_BINDING_CLOSED', 'zlib binding closed'); | |
| 680 | 689 | E('ERR_ZLIB_INITIALIZATION_FAILED', 'Initialization failed'); | |
| 681 | 690 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments