Skip to content

Commit

Permalink
vm: rename vm.Module to vm.SourceTextModule
Browse files Browse the repository at this point in the history
At the last TC39 meeting, a new type of Module Records backed by
JavaScript source called Dynamic Module Records was discussed, and
it is now at Stage 1. Regardless of whether that proposal makes it
all the way into the spec, SourceTextModule is indeed a more
descriptive and accurate name for what this class represents.

PR-URL: #22007
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Jan Krems <jan.krems@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Yuta Hiroto <hello@hiroppy.me>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: John-David Dalton <john.david.dalton@gmail.com>
Reviewed-By: Bradley Farias <bradley.meck@gmail.com>
  • Loading branch information
devsnek authored and targos committed Aug 1, 2018
1 parent 02e665c commit 9a88fe4
Show file tree
Hide file tree
Showing 14 changed files with 86 additions and 81 deletions.
2 changes: 1 addition & 1 deletion doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -1811,7 +1811,7 @@ The module must be successfully linked before instantiation.
<a id="ERR_VM_MODULE_NOT_MODULE"></a>
### ERR_VM_MODULE_NOT_MODULE

The fulfilled value of a linking promise is not a `vm.Module` object.
The fulfilled value of a linking promise is not a `vm.SourceTextModule` object.

<a id="ERR_VM_MODULE_STATUS"></a>
### ERR_VM_MODULE_STATUS
Expand Down
44 changes: 22 additions & 22 deletions doc/api/vm.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ console.log(x); // 1; y is not defined.
**The vm module is not a security mechanism. Do not use it to run untrusted
code**.

## Class: vm.Module
## Class: vm.SourceTextModule
<!-- YAML
added: v9.6.0
-->
Expand All @@ -53,20 +53,20 @@ added: v9.6.0
*This feature is only available with the `--experimental-vm-modules` command
flag enabled.*

The `vm.Module` class provides a low-level interface for using ECMAScript
modules in VM contexts. It is the counterpart of the `vm.Script` class that
closely mirrors [Source Text Module Record][]s as defined in the ECMAScript
specification.
The `vm.SourceTextModule` class provides a low-level interface for using
ECMAScript modules in VM contexts. It is the counterpart of the `vm.Script`
class that closely mirrors [Source Text Module Record][]s as defined in the
ECMAScript specification.

Unlike `vm.Script` however, every `vm.Module` object is bound to a context from
its creation. Operations on `vm.Module` objects are intrinsically asynchronous,
in contrast with the synchronous nature of `vm.Script` objects. With the help
of async functions, however, manipulating `vm.Module` objects is fairly
straightforward.
Unlike `vm.Script` however, every `vm.SourceTextModule` object is bound to a
context from its creation. Operations on `vm.SourceTextModule` objects are
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.Module` 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 four distinct steps:
creation/parsing, linking, instantiation, and evaluation. These four 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
Expand All @@ -80,15 +80,15 @@ const contextifiedSandbox = vm.createContext({ secret: 42 });
(async () => {
// Step 1
//
// Create a Module by constructing a new `vm.Module` object. This parses the
// provided source text, throwing a `SyntaxError` if anything goes wrong. By
// default, a Module is created in the top context. But here, we specify
// `contextifiedSandbox` as the context this Module belongs to.
// Create a Module by constructing a new `vm.SourceTextModule` object. This
// parses the provided source text, throwing a `SyntaxError` if anything goes
// wrong. By default, a Module is created in the top context. But here, we
// specify `contextifiedSandbox` as the context this Module belongs to.
//
// Here, we attempt to obtain the default export from the module "foo", and
// put it into local binding "secret".

const bar = new vm.Module(`
const bar = new vm.SourceTextModule(`
import s from 'foo';
s;
`, { context: contextifiedSandbox });
Expand Down Expand Up @@ -118,7 +118,7 @@ const contextifiedSandbox = vm.createContext({ secret: 42 });

async function linker(specifier, referencingModule) {
if (specifier === 'foo') {
return new vm.Module(`
return new vm.SourceTextModule(`
// The "secret" variable refers to the global variable we added to
// "contextifiedSandbox" when creating the context.
export default secret;
Expand Down Expand Up @@ -155,7 +155,7 @@ const contextifiedSandbox = vm.createContext({ secret: 42 });
})();
```

### Constructor: new vm.Module(code[, options])
### Constructor: new vm.SourceTextModule(code[, options])

* `code` {string} JavaScript Module code to parse
* `options`
Expand All @@ -170,7 +170,7 @@ const contextifiedSandbox = vm.createContext({ secret: 42 });
* `initalizeImportMeta` {Function} Called during evaluation of this `Module`
to initialize the `import.meta`. This function has the signature `(meta,
module)`, where `meta` is the `import.meta` object in the `Module`, and
`module` is this `vm.Module` object.
`module` is this `vm.SourceTextModule` object.

Creates a new ES `Module` object.

Expand All @@ -185,7 +185,7 @@ const vm = require('vm');
const contextifiedSandbox = vm.createContext({ secret: 42 });

(async () => {
const module = new vm.Module(
const module = new vm.SourceTextModule(
'Object.getPrototypeOf(import.meta.prop).secret = secret;',
{
initializeImportMeta(meta) {
Expand Down
6 changes: 3 additions & 3 deletions lib/internal/process/esm_loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const { URL } = require('url');
const {
initImportMetaMap,
wrapToModuleMap
} = require('internal/vm/module');
} = require('internal/vm/source_text_module');

function normalizeReferrerURL(referrer) {
if (typeof referrer === 'string' && path.isAbsolute(referrer)) {
Expand All @@ -30,8 +30,8 @@ function initializeImportMetaObject(wrap, meta) {
} else {
const initializeImportMeta = initImportMetaMap.get(vmModule);
if (initializeImportMeta !== undefined) {
// This ModuleWrap belongs to vm.Module, initializer callback was
// provided.
// This ModuleWrap belongs to vm.SourceTextModule,
// initializer callback was provided.
initializeImportMeta(meta, vmModule);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,16 @@ const perContextModuleId = new WeakMap();
const wrapMap = new WeakMap();
const dependencyCacheMap = new WeakMap();
const linkingStatusMap = new WeakMap();
// vm.Module -> function
// vm.SourceTextModule -> function
const initImportMetaMap = new WeakMap();
// ModuleWrap -> vm.Module
// ModuleWrap -> vm.SourceTextModule
const wrapToModuleMap = new WeakMap();
const defaultModuleName = 'vm:module';

class Module {
// TODO(devsnek): figure out AbstractModule class or protocol
class SourceTextModule {
constructor(src, options = {}) {
emitExperimentalWarning('vm.Module');
emitExperimentalWarning('vm.SourceTextModule');

if (typeof src !== 'string')
throw new ERR_INVALID_ARG_TYPE('src', 'string', src);
Expand Down Expand Up @@ -230,7 +231,7 @@ class Module {

[customInspectSymbol](depth, options) {
let ctor = getConstructorOf(this);
ctor = ctor === null ? Module : ctor;
ctor = ctor === null ? SourceTextModule : ctor;

if (typeof depth === 'number' && depth < 0)
return options.stylize(`[${ctor.name}]`, 'special');
Expand All @@ -254,7 +255,7 @@ function validateInteger(prop, propName) {
}

module.exports = {
Module,
SourceTextModule,
initImportMetaMap,
wrapToModuleMap
};
6 changes: 4 additions & 2 deletions lib/vm.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,5 +308,7 @@ module.exports = {
isContext,
};

if (process.binding('config').experimentalVMModules)
module.exports.Module = require('internal/vm/module').Module;
if (process.binding('config').experimentalVMModules) {
const { SourceTextModule } = require('internal/vm/source_text_module');
module.exports.SourceTextModule = SourceTextModule;
}
2 changes: 1 addition & 1 deletion node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
'lib/internal/v8_prof_processor.js',
'lib/internal/validators.js',
'lib/internal/stream_base_commons.js',
'lib/internal/vm/module.js',
'lib/internal/vm/source_text_module.js',
'lib/internal/worker.js',
'lib/internal/streams/lazy_transform.js',
'lib/internal/streams/async_iterator.js',
Expand Down
4 changes: 2 additions & 2 deletions test/parallel/test-util-inspect-namespace.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
require('../common');
const assert = require('assert');

const { Module } = require('vm');
const { SourceTextModule } = require('vm');
const { inspect } = require('util');

(async () => {
const m = new Module('export const a = 1; export var b = 2');
const m = new SourceTextModule('export const a = 1; export var b = 2');
await m.link(() => 0);
m.instantiate();
assert.strictEqual(
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-util-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ for (const [ value, _method ] of [
}

(async () => {
const m = new vm.Module('');
const m = new vm.SourceTextModule('');
await m.link(() => 0);
m.instantiate();
await m.evaluate();
Expand Down
8 changes: 4 additions & 4 deletions test/parallel/test-vm-module-basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@

const common = require('../common');
const assert = require('assert');
const { Module, createContext } = require('vm');
const { SourceTextModule, createContext } = require('vm');

(async function test1() {
const context = createContext({
foo: 'bar',
baz: undefined,
typeofProcess: undefined,
});
const m = new Module(
const m = new SourceTextModule(
'baz = foo; typeofProcess = typeof process; typeof Object;',
{ context }
);
Expand All @@ -32,7 +32,7 @@ const { Module, createContext } = require('vm');
}());

(async () => {
const m = new Module(
const m = new SourceTextModule(
'global.vmResult = "foo"; Object.prototype.toString.call(process);'
);
await m.link(common.mustNotCall());
Expand All @@ -44,7 +44,7 @@ const { Module, createContext } = require('vm');
})();

(async () => {
const m = new Module('while (true) {}');
const m = new SourceTextModule('while (true) {}');
await m.link(common.mustNotCall());
m.instantiate();
await m.evaluate({ timeout: 500 })
Expand Down
4 changes: 2 additions & 2 deletions test/parallel/test-vm-module-dynamic-import.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
const common = require('../common');

const assert = require('assert');
const { Module, createContext } = require('vm');
const { SourceTextModule, createContext } = require('vm');

const finished = common.mustCall();

(async function() {
const m = new Module('import("foo")', { context: createContext() });
const m = new SourceTextModule('import("foo")', { context: createContext() });
await m.link(common.mustNotCall());
m.instantiate();
const { result } = await m.evaluate();
Expand Down
Loading

0 comments on commit 9a88fe4

Please sign in to comment.