Skip to content
This repository was archived by the owner on Apr 16, 2020. It is now read-only.

Commit 03565b4

Browse files
committed
wasm modules as dynamic modules with import support
1 parent dcd8a46 commit 03565b4

File tree

6 files changed

+33
-65
lines changed

6 files changed

+33
-65
lines changed

lib/internal/modules/cjs/loader.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ Module.prototype.load = function(filename) {
643643
url,
644644
new ModuleJob(ESMLoader, url, async () => {
645645
return createDynamicModule(
646-
['default'], url, (reflect) => {
646+
[], ['default'], url, (reflect) => {
647647
reflect.exports.default.set(exports);
648648
});
649649
})

lib/internal/modules/esm/create_dynamic_module.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
'use strict';
22

3-
const { ArrayPrototype } = primordials;
3+
const { ArrayPrototype, JSON, Object } = primordials;
44

55
const debug = require('internal/util/debuglog').debuglog('esm');
66

7-
const createDynamicModule = (exports, url = '', evaluate) => {
7+
const createDynamicModule = (imports, exports, url = '', evaluate) => {
88
debug('creating ESM facade for %s with exports: %j', url, exports);
99
const names = ArrayPrototype.map(exports, (name) => `${name}`);
1010

1111
const source = `
12+
${ArrayPrototype.join(ArrayPrototype.map(imports, (impt, index) =>
13+
`import * as $import_${index} from ${JSON.stringify(impt)};
14+
import.meta.imports[${JSON.stringify(impt)}] = $import_${index};`), '\n')
15+
}
1216
${ArrayPrototype.join(ArrayPrototype.map(names, (name) =>
1317
`let $${name};
1418
export { $${name} as ${name} };
@@ -22,19 +26,22 @@ import.meta.done();
2226
`;
2327
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
2428
const m = new ModuleWrap(source, `${url}`);
25-
m.link(() => 0);
26-
m.instantiate();
2729

2830
const readyfns = new Set();
2931
const reflect = {
30-
namespace: m.namespace(),
31-
exports: {},
32+
namespace: undefined,
33+
exports: Object.create(null),
3234
onReady: (cb) => { readyfns.add(cb); },
3335
};
3436

37+
if (imports.length)
38+
reflect.imports = Object.create(null);
39+
3540
callbackMap.set(m, {
3641
initializeImportMeta: (meta, wrap) => {
3742
meta.exports = reflect.exports;
43+
if (reflect.imports)
44+
meta.imports = reflect.imports;
3845
meta.done = () => {
3946
evaluate(reflect);
4047
reflect.onReady = (cb) => cb(reflect);

lib/internal/modules/esm/create_wasm_module.js

Lines changed: 0 additions & 47 deletions
This file was deleted.

lib/internal/modules/esm/loader.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ class Loader {
153153
loaderInstance = async (url) => {
154154
debug(`Translating dynamic ${url}`);
155155
const { exports, execute } = await this._dynamicInstantiate(url);
156-
return createDynamicModule(exports, url, (reflect) => {
156+
return createDynamicModule([], exports, url, (reflect) => {
157157
debug(`Loading dynamic ${url}`);
158158
execute(reflect.exports);
159159
});

lib/internal/modules/esm/translators.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
const {
66
JSON,
7+
Object,
78
SafeMap,
89
StringPrototype
910
} = primordials;
@@ -17,8 +18,6 @@ const CJSModule = require('internal/modules/cjs/loader');
1718
const internalURLModule = require('internal/url');
1819
const createDynamicModule = require(
1920
'internal/modules/esm/create_dynamic_module');
20-
const createWASMModule = require(
21-
'internal/modules/esm/create_wasm_module');
2221
const fs = require('fs');
2322
const { fileURLToPath, URL } = require('url');
2423
const { debuglog } = require('internal/util/debuglog');
@@ -76,11 +75,11 @@ translators.set('commonjs', async function commonjsStrategy(url, isMain) {
7675
];
7776
if (module && module.loaded) {
7877
const exports = module.exports;
79-
return createDynamicModule(['default'], url, (reflect) => {
78+
return createDynamicModule([], ['default'], url, (reflect) => {
8079
reflect.exports.default.set(exports);
8180
});
8281
}
83-
return createDynamicModule(['default'], url, () => {
82+
return createDynamicModule([], ['default'], url, () => {
8483
debug(`Loading CJSModule ${url}`);
8584
// We don't care about the return val of _load here because Module#load
8685
// will handle it for us by checking the loader registry and filling the
@@ -101,7 +100,7 @@ translators.set('builtin', async function builtinStrategy(url) {
101100
}
102101
module.compileForPublicLoader(true);
103102
return createDynamicModule(
104-
[...module.exportKeys, 'default'], url, (reflect) => {
103+
[], [...module.exportKeys, 'default'], url, (reflect) => {
105104
debug(`Loading BuiltinModule ${url}`);
106105
module.reflect = reflect;
107106
for (const key of module.exportKeys)
@@ -120,7 +119,7 @@ translators.set('json', async function jsonStrategy(url) {
120119
let module = CJSModule._cache[modulePath];
121120
if (module && module.loaded) {
122121
const exports = module.exports;
123-
return createDynamicModule(['default'], url, (reflect) => {
122+
return createDynamicModule([], ['default'], url, (reflect) => {
124123
reflect.exports.default.set(exports);
125124
});
126125
}
@@ -140,7 +139,7 @@ translators.set('json', async function jsonStrategy(url) {
140139
throw err;
141140
}
142141
CJSModule._cache[modulePath] = module;
143-
return createDynamicModule(['default'], url, (reflect) => {
142+
return createDynamicModule([], ['default'], url, (reflect) => {
144143
debug(`Parsing JSONModule ${url}`);
145144
reflect.exports.default.set(module.exports);
146145
});
@@ -151,11 +150,21 @@ translators.set('wasm', async function(url) {
151150
const pathname = fileURLToPath(url);
152151
const buffer = await readFileAsync(pathname);
153152
debug(`Translating WASMModule ${url}`);
153+
let compiled;
154154
try {
155-
const compiled = await WebAssembly.compile(buffer);
156-
return createWASMModule(compiled, url);
155+
compiled = await WebAssembly.compile(buffer);
157156
} catch (err) {
158157
err.message = pathname + ': ' + err.message;
159158
throw err;
160159
}
160+
161+
const imports =
162+
WebAssembly.Module.imports(compiled).map(({ module }) => module);
163+
const exports = WebAssembly.Module.exports(compiled).map(({ name }) => name);
164+
165+
return createDynamicModule(imports, exports, url, (reflect) => {
166+
const { exports } = new WebAssembly.Instance(compiled, reflect.imports);
167+
for (const expt of Object.keys(exports))
168+
reflect.exports[expt].set(exports[expt]);
169+
});
161170
});

node.gyp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@
149149
'lib/internal/modules/cjs/loader.js',
150150
'lib/internal/modules/esm/loader.js',
151151
'lib/internal/modules/esm/create_dynamic_module.js',
152-
'lib/internal/modules/esm/create_wasm_module.js',
153152
'lib/internal/modules/esm/default_resolve.js',
154153
'lib/internal/modules/esm/module_job.js',
155154
'lib/internal/modules/esm/module_map.js',

0 commit comments

Comments
 (0)