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

Commit

Permalink
esm: experimental wasm modules
Browse files Browse the repository at this point in the history
This is a first pass at a loader for wasm modules.

It offers support for both named imports as well as deafult.
It may be possible to move some of this logic down to C++, but
I think the current implementation might be good enough. It doesn't
currently use the ESM cache, but AFAICT it isn't currently exposed.

Will dig in more with tests / examples / cache after initial
implementation gets feedback.
  • Loading branch information
MylesBorins committed Feb 28, 2019
1 parent c809f78 commit f0a4ff5
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 1 deletion.
11 changes: 11 additions & 0 deletions lib/internal/modules/esm/default_resolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const { realpathSync } = require('fs');
const { getOptionValue } = require('internal/options');
const preserveSymlinks = getOptionValue('--preserve-symlinks');
const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main');
const experimentalWasmModules = getOptionValue('--experimental-wasm-modules');
const { ERR_UNKNOWN_FILE_EXTENSION } = require('internal/errors').codes;
const { resolve: moduleWrapResolve } = internalBinding('module_wrap');
const { pathToFileURL, fileURLToPath } = require('internal/url');
Expand All @@ -30,6 +31,16 @@ const legacyExtensionFormatMap = {
'.node': 'cjs'
};

if (experimentalWasmModules) {
// This is a total hack
Object.assign(extensionFormatMap, {
'.wasm': 'wasm'
});
Object.assign(legacyExtensionFormatMap, {
'.wasm': 'wasm'
});
}

function resolve(specifier, parentURL) {
if (NativeModule.canBeRequiredByUsers(specifier)) {
return {
Expand Down
23 changes: 22 additions & 1 deletion lib/internal/modules/esm/translators.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const fs = require('fs');
const {
SafeMap,
} = primordials;
const { URL } = require('url');
const { fileURLToPath, URL } = require('url');
const { debuglog, promisify } = require('util');
const esmLoader = require('internal/process/esm_loader');

Expand Down Expand Up @@ -94,3 +94,24 @@ translators.set('builtin', async function(url) {
reflect.exports.default.set(module.exports);
});
});

// Strategy for loading a wasm module
translators.set('wasm', async function(url) {
const pathname = fileURLToPath(url);
const buffer = await readFileAsync(pathname);
debug(`Translating WASMModule ${url}`);
let result, keys;
try {
WebAssembly.validate(buffer);
result = await WebAssembly.instantiate(buffer, {});
keys = Object.keys(result.instance.exports);
} catch (err) {
err.message = pathname + ': ' + err.message;
throw err;
}
return createDynamicModule([...keys, 'default'], url, (reflect) => {
for (const key of keys)
reflect.exports[key].set(result.instance.exports[key]);
reflect.exports.default.set(result.instance.exports);
});
});
4 changes: 4 additions & 0 deletions src/node_options.cc
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
"experimental ES Module support and caching modules",
&EnvironmentOptions::experimental_modules,
kAllowedInEnvironment);
AddOption("--experimental-wasm-modules",
"experimental ES Module support for webassembly modules",
&EnvironmentOptions::experimental_wasm_modules,
kAllowedInEnvironment);
AddOption("--experimental-policy",
"use the specified file as a "
"security policy",
Expand Down
1 change: 1 addition & 0 deletions src/node_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class EnvironmentOptions : public Options {
public:
bool abort_on_uncaught_exception = false;
bool experimental_modules = false;
bool experimental_wasm_modules = false;
std::string module_type;
std::string experimental_policy;
bool experimental_repl_await = false;
Expand Down
9 changes: 9 additions & 0 deletions test/es-module/test-esm-wasm.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Flags: --experimental-modules --experimental-wasm-modules
/* eslint-disable node-core/required-modules */
import wasmMod from '../fixtures/simple.wasm'
import {add} from '../fixtures/simple.wasm';
import {strictEqual} from 'assert';

strictEqual(wasmMod.add(10, 20), 30);
strictEqual(add(10, 20), 30);
strictEqual(wasmMod.add, add);

0 comments on commit f0a4ff5

Please sign in to comment.