diff options
author | Gus Caplan <me@gus.host> | 2019-09-09 12:20:16 -0500 |
---|---|---|
committer | Rich Trott <rtrott@gmail.com> | 2019-10-02 15:54:35 -0700 |
commit | 5e7946fe79193633e9a78aae48548635cbc11023 (patch) | |
tree | 4ef3ab236df6aa8d570e22453dbe56b37487ad63 /doc | |
parent | 6ba9471f6fcaaf377f22621c4d193d30e3877566 (diff) | |
download | node-new-5e7946fe79193633e9a78aae48548635cbc11023.tar.gz |
vm: refactor SourceTextModule
- Removes redundant `instantiate` method
- Refactors `link` to match the spec linking steps more accurately
- Removes URL validation from SourceTextModule specifiers
- DRYs some dynamic import logic
Closes: https://github.com/nodejs/node/issues/29030
Co-Authored-By: Michaël Zasso <targos@protonmail.com>
PR-URL: https://github.com/nodejs/node/pull/29776
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
Diffstat (limited to 'doc')
-rw-r--r-- | doc/api/errors.md | 10 | ||||
-rw-r--r-- | doc/api/vm.md | 103 |
2 files changed, 32 insertions, 81 deletions
diff --git a/doc/api/errors.md b/doc/api/errors.md index 34412648b3..4e76673723 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -1984,11 +1984,6 @@ than the parent module. Linked modules must share the same context. The linker function returned a module for which linking has failed. -<a id="ERR_VM_MODULE_NOT_LINKED"></a> -### ERR_VM_MODULE_NOT_LINKED - -The module must be successfully linked before instantiation. - <a id="ERR_VM_MODULE_NOT_MODULE"></a> ### ERR_VM_MODULE_NOT_MODULE @@ -2275,6 +2270,11 @@ removed: v10.0.0 Used when a given value is out of the accepted range. +<a id="ERR_VM_MODULE_NOT_LINKED"></a> +### ERR_VM_MODULE_NOT_LINKED + +The module must be successfully linked before instantiation. + <a id="ERR_ZLIB_BINDING_CLOSED"></a> ### ERR_ZLIB_BINDING_CLOSED <!-- YAML diff --git a/doc/api/vm.md b/doc/api/vm.md index 18ebd10a63..601b8c3052 100644 --- a/doc/api/vm.md +++ b/doc/api/vm.md @@ -322,9 +322,9 @@ intrinsically asynchronous, in contrast with the synchronous nature of `vm.Script` objects. With the help of async functions, however, manipulating `vm.SourceTextModule` objects is fairly straightforward. -Using a `vm.SourceTextModule` object requires four distinct steps: -creation/parsing, linking, instantiation, and evaluation. These four steps are -illustrated in the following example. +Using a `vm.SourceTextModule` object requires three distinct steps: +creation/parsing, linking, and evaluation. These three steps are illustrated in +the following example. This implementation lies at a lower level than the [ECMAScript Module loader][]. There is also currently no way to interact with the Loader, though @@ -391,15 +391,6 @@ const contextifiedSandbox = vm.createContext({ secret: 42 }); // Step 3 // - // Instantiate the top-level Module. - // - // Only the top-level Module needs to be explicitly instantiated; its - // dependencies will be recursively instantiated by instantiate(). - - bar.instantiate(); - - // Step 4 - // // Evaluate the Module. The evaluate() method returns a Promise with a single // property "result" that contains the result of the very last statement // executed in the Module. In the case of `bar`, it is `s;`, which refers to @@ -417,8 +408,9 @@ const contextifiedSandbox = vm.createContext({ secret: 42 }); * `code` {string} JavaScript Module code to parse * `options` - * `url` {string} URL used in module resolution and stack traces. **Default:** - `'vm:module(i)'` where `i` is a context-specific ascending index. + * `identifier` {string} String used in stack traces. + **Default:** `'vm:module(i)'` where `i` is a context-specific ascending + index. * `context` {Object} The [contextified][] object as returned by the `vm.createContext()` method, to compile and evaluate this `Module` in. * `lineOffset` {integer} Specifies the line number offset that is displayed @@ -465,7 +457,6 @@ const contextifiedSandbox = vm.createContext({ secret: 42 }); }); // Since module has no dependencies, the linker function will never be called. await module.link(() => {}); - module.instantiate(); await module.evaluate(); // Now, Object.prototype.secret will be equal to 42. @@ -516,7 +507,7 @@ in the ECMAScript specification. Evaluate the module. -This must be called after the module has been instantiated; otherwise it will +This must be called after the module has been linked; otherwise it will throw an error. It could be called also when the module has already been evaluated, in which case it will do one of the following two things: @@ -531,23 +522,6 @@ This method cannot be called while the module is being evaluated Corresponds to the [Evaluate() concrete method][] field of [Source Text Module Record][]s in the ECMAScript specification. -### module.instantiate() - -Instantiate the module. This must be called after linking has completed -(`linkingStatus` is `'linked'`); otherwise it will throw an error. It may also -throw an exception if one of the dependencies does not provide an export the -parent module requires. - -However, if this function succeeded, further calls to this function after the -initial instantiation will be no-ops, to be consistent with the ECMAScript -specification. - -Unlike other methods operating on `Module`, this function completes -synchronously and returns nothing. - -Corresponds to the [Instantiate() concrete method][] field of [Source Text -Module Record][]s in the ECMAScript specification. - ### module.link(linker) * `linker` {Function} @@ -563,7 +537,7 @@ Module Record][]s in the ECMAScript specification. * Returns: {vm.SourceTextModule|Promise} * Returns: {Promise} -Link module dependencies. This method must be called before instantiation, and +Link module dependencies. This method must be called before evaluation, and can only be called once per module. The function is expected to return a `Module` object or a `Promise` that @@ -571,9 +545,9 @@ eventually resolves to a `Module` object. The returned `Module` must satisfy the following two invariants: * It must belong to the same context as the parent `Module`. -* Its `linkingStatus` must not be `'errored'`. +* Its `status` must not be `'errored'`. -If the returned `Module`'s `linkingStatus` is `'unlinked'`, this method will be +If the returned `Module`'s `status` is `'unlinked'`, this method will be recursively called on the returned `Module` with the same provided `linker` function. @@ -587,37 +561,22 @@ specification, with a few key differences: * The linker function is allowed to be asynchronous while [HostResolveImportedModule][] is synchronous. -* The linker function is executed during linking, a Node.js-specific stage - before instantiation, while [HostResolveImportedModule][] is called during - instantiation. The actual [HostResolveImportedModule][] implementation used during module -instantiation is one that returns the modules linked during linking. Since at +linking is one that returns the modules linked during linking. Since at that point all modules would have been fully linked already, the [HostResolveImportedModule][] implementation is fully synchronous per specification. -### module.linkingStatus - -* {string} - -The current linking status of `module`. It will be one of the following values: - -* `'unlinked'`: `module.link()` has not yet been called. -* `'linking'`: `module.link()` has been called, but not all Promises returned by - the linker function have been resolved yet. -* `'linked'`: `module.link()` has been called, and all its dependencies have - been successfully linked. -* `'errored'`: `module.link()` has been called, but at least one of its - dependencies failed to link, either because the callback returned a `Promise` - that is rejected, or because the `Module` the callback returned is invalid. +Corresponds to the [Link() concrete method][] field of [Source Text Module +Record][]s in the ECMAScript specification. ### module.namespace * {Object} -The namespace object of the module. This is only available after instantiation -(`module.instantiate()`) has completed. +The namespace object of the module. This is only available after linking +(`module.link()`) has completed. Corresponds to the [GetModuleNamespace][] abstract operation in the ECMAScript specification. @@ -628,21 +587,13 @@ specification. The current status of the module. Will be one of: -* `'uninstantiated'`: The module is not instantiated. It may because of any of - the following reasons: - - * The module was just created. - * `module.instantiate()` has been called on this module, but it failed for - some reason. - - This status does not convey any information regarding if `module.link()` has - been called. See `module.linkingStatus` for that. +* `'unlinked'`: `module.link()` has not yet been called. -* `'instantiating'`: The module is currently being instantiated through a - `module.instantiate()` call on itself or a parent module. +* `'linking'`: `module.link()` has been called, but not all Promises returned + by the linker function have been resolved yet. -* `'instantiated'`: The module has been instantiated successfully, but - `module.evaluate()` has not yet been called. +* `'linked'`: The module has been linked successfully, and all of its + dependencies are linked, but `module.evaluate()` has not yet been called. * `'evaluating'`: The module is being evaluated through a `module.evaluate()` on itself or a parent module. @@ -656,11 +607,11 @@ Other than `'errored'`, this status string corresponds to the specification's `'evaluated'` in the specification, but with `[[EvaluationError]]` set to a value that is not `undefined`. -### module.url +### module.identifier * {string} -The URL of the current module, as set in the constructor. +The identifier of the current module, as set in the constructor. ## vm.compileFunction(code[, params[, options]]) <!-- YAML @@ -1127,11 +1078,11 @@ queues. [`vm.runInContext()`]: #vm_vm_runincontext_code_contextifiedsandbox_options [`vm.runInThisContext()`]: #vm_vm_runinthiscontext_code_options [ECMAScript Module Loader]: esm.html#esm_ecmascript_modules -[Evaluate() concrete method]: https://tc39.github.io/ecma262/#sec-moduleevaluation -[GetModuleNamespace]: https://tc39.github.io/ecma262/#sec-getmodulenamespace -[HostResolveImportedModule]: https://tc39.github.io/ecma262/#sec-hostresolveimportedmodule -[Instantiate() concrete method]: https://tc39.github.io/ecma262/#sec-moduledeclarationinstantiation -[Source Text Module Record]: https://tc39.github.io/ecma262/#sec-source-text-module-records +[Evaluate() concrete method]: https://tc39.es/ecma262/#sec-moduleevaluation +[GetModuleNamespace]: https://tc39.es/ecma262/#sec-getmodulenamespace +[HostResolveImportedModule]: https://tc39.es/ecma262/#sec-hostresolveimportedmodule +[Link() concrete method]: https://tc39.es/ecma262/#sec-moduledeclarationlinking +[Source Text Module Record]: https://tc39.es/ecma262/#sec-source-text-module-records [V8 Embedder's Guide]: https://v8.dev/docs/embed#contexts [contextified]: #vm_what_does_it_mean_to_contextify_an_object [global object]: https://es5.github.io/#x15.1 |