Skip to content

Commit

Permalink
add vm.Module linker hook to hookContext
Browse files Browse the repository at this point in the history
  • Loading branch information
devsnek committed May 16, 2018
1 parent d668912 commit e93d419
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 0 deletions.
5 changes: 5 additions & 0 deletions doc/api/esm.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ A hook context consists of the following properties:
useful if resolve is not hooked.
- `specifier` {string} The specifier of the module to import.
- `parentURL` {string} The URL of the module that requested the specifier.
- `vmModuleLinkHook` {object} This value can be passed to [`module.link`][] to
allow linking the import requests of a [`vm.Module`][] instance to the
loader.

### Resolve hook

Expand Down Expand Up @@ -269,6 +272,8 @@ With the list of module exports provided upfront, the `execute` function will
then be called at the exact point of module evaluation order for that module
in the import tree.

[`module.link`]: vm.html#vm_module_link_linker
[`vm.Module`]: vm.html#vm_class_vm_module
[Node.js EP for ES Modules]: https://github.com/nodejs/node-eps/blob/master/002-es-modules.md
[addons]: addons.html
[dynamic instantiate hook]: #esm_dynamic_instantiate_hook
3 changes: 3 additions & 0 deletions doc/api/vm.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ that point all modules would have been fully linked already, the
[HostResolveImportedModule][] implementation is fully synchronous per
specification.

The linker may also be passed from [`hookContext.vmModuleLinkhook`][].

## Class: vm.Script
<!-- YAML
added: v0.3.1
Expand Down Expand Up @@ -893,6 +895,7 @@ associating it with the `sandbox` object is what this document refers to as
[`Error`]: errors.html#errors_class_error
[`URL`]: url.html#url_class_url
[`eval()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
[`hookContext.vmModuleLinkHook`]: esm.html#esm_hook_context
[`script.runInContext()`]: #vm_script_runincontext_contextifiedsandbox_options
[`script.runInThisContext()`]: #vm_script_runinthiscontext_options
[`url.origin`]: url.html#url_url_origin
Expand Down
5 changes: 5 additions & 0 deletions lib/internal/modules/esm/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const defaultResolve = require('internal/modules/esm/default_resolve');
const createDynamicModule = require(
'internal/modules/esm/create_dynamic_module');
const translators = require('internal/modules/esm/translators');
const { vmModuleLinkHookMap } = require('internal/vm/module');

const FunctionBind = Function.call.bind(Function.prototype.bind);

Expand Down Expand Up @@ -47,9 +48,13 @@ class Loader {
this._dynamicInstantiate = undefined;

// Set up context passed to hooks
const k = Object.freeze(Object.create(null));
vmModuleLinkHookMap.set(k, this);

this.hookContext = Object.assign(Object.create(null), {
defaultResolve,
resolve: (specifier, parentURL) => this.resolve(specifier, parentURL),
vmModuleLinkHook: k,
});
}

Expand Down
15 changes: 15 additions & 0 deletions lib/internal/vm/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const {
const { SafePromise } = require('internal/safe_globals');
const { validateInt32, validateUint32 } = require('internal/validators');

const vmModuleLinkHookMap = new WeakMap();

const {
ModuleWrap,
kUninstantiated,
Expand Down Expand Up @@ -151,6 +153,15 @@ class Module {
}

async link(linker) {
const linkingFromLoader = vmModuleLinkHookMap.has(linker);
if (linkingFromLoader) {
const loader = vmModuleLinkHookMap.get(linker);
linker = (specifier, parent) =>
loader.getModuleJob(specifier, parent.url)
.then((j) => j.modulePromise)
.then((r) => r.module);
}

if (typeof linker !== 'function')
throw new ERR_INVALID_ARG_TYPE('linker', 'function', linker);
if (linkingStatusMap.get(this) !== 'unlinked')
Expand All @@ -163,6 +174,9 @@ class Module {

const promises = wrap.link(async (specifier) => {
const m = await linker(specifier, this);
if (linkingFromLoader) {
return m;
}
if (!m || !wrapMap.has(m))
throw new ERR_VM_MODULE_NOT_MODULE();
if (m.context !== this.context)
Expand Down Expand Up @@ -246,4 +260,5 @@ module.exports = {
Module,
initImportMetaMap,
wrapToModuleMap,
vmModuleLinkHookMap,
};

0 comments on commit e93d419

Please sign in to comment.