Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion document/js-api/index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,14 @@ To <dfn>instantiate imported strings</dfn> with module |module| and |importedStr

<div algorithm="read-the-imports">
To <dfn>read the imports</dfn> from a WebAssembly module |module| from imports object |importObject|, enabled builtins |builtinSetNames|, and |importedStringModule|, perform the following steps:
1. If [=module_imports=](|module|) [=list/is empty|is not empty=], and |importObject| is missing, throw a {{TypeError}} exception.
1. If |importObject| is missing,
1. [=list/iterate|For each=] |import| of [=module_imports=](|module|),
1. Let |moduleName| be |import|[0].
1. If |importedStringModule| is not null and |moduleName| equals |importedStringModule|,
1. [=iteration/continue=].
1. If [=find a builtin|finding a builtin=] for |import| and |builtinSetNames| is not null,
1. [=iteration/continue=].
1. Throw a {{TypeError}} exception.
1. Let |builtinOrStringImports| be the ordered map «[ ]».
1. [=list/iterate|For each=] |builtinSetName| of |builtinSetNames|,
1. Let |builtinSetQualifiedName| be |builtinSetName| prefixed with "wasm:"
Expand All @@ -502,8 +509,10 @@ To <dfn>instantiate imported strings</dfn> with module |module| and |importedStr
1. If |builtinOrStringImports|[|moduleName|] [=map/exists=],
1. Let |o| be |builtinOrStringImports|[|moduleName|].
1. If |o| [=is not an Object=] or if [=?=] [$HasProperty$](|o|, |componentName|) is false,
1. Assert: |importObject| is not missing.
1. Set |o| to [=?=] [$Get$](|importObject|, |moduleName|).
1. Else,
1. Assert: |importObject| is not missing.
1. Let |o| be [=?=] [$Get$](|importObject|, |moduleName|).
1. If |o| [=is not an Object=], throw a {{TypeError}} exception.
1. Let |v| be [=?=] [$Get$](|o|, |componentName|).
Expand Down Expand Up @@ -551,6 +560,13 @@ To <dfn>instantiate imported strings</dfn> with module |module| and |importedStr
Note: This algorithm only verifies the right kind of JavaScript values are passed.
The verification of WebAssembly type requirements is deferred to the
"[=instantiate the core of a WebAssembly module=]" algorithm.

Note: |importObject| is required only for an import that is not supplied by an
enabled builtin or by the imported string constants module. If it is missing,
the opening check throws unless every import is supplied that way. Each such
import is then an own property of the object in |builtinOrStringImports| for
its module name, so the [$Get$](|importObject|, |moduleName|) steps are not
reached.
</div>

<div algorithm>
Expand Down
53 changes: 53 additions & 0 deletions test/js-api/js-string/imports.any.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,56 @@ test(() => {
// reflection.
assert_equals(imports.length, 0);
});

function moduleWithBuiltin() {
const builder = new WasmModuleBuilder();
builder.addImport(
"wasm:js-string",
"test",
{params: [kWasmExternRef], results: [kWasmI32]});
return new WebAssembly.Module(builder.toBuffer(), {builtins: ["js-string"]});
}

test(() => {
const instance = new WebAssembly.Instance(moduleWithBuiltin());
assert_equals(typeof instance.exports, "object");
}, "A builtin-only module can be instantiated without an importObject");

test(() => {
const instance = new WebAssembly.Instance(moduleWithBuiltin(), undefined);
assert_equals(typeof instance.exports, "object");
}, "A builtin-only module can be instantiated with undefined importObject");

promise_test(async () => {
const instance = await WebAssembly.instantiate(moduleWithBuiltin());
assert_equals(typeof instance.exports, "object");
}, "WebAssembly.instantiate accepts a builtin-only module without an importObject");

test(() => {
const builder = new WasmModuleBuilder();
builder.addImportedGlobal("strings", "hi", kWasmExternRef, false);
builder.addExportOfKind("hi", kExternalGlobal, 0);
const module = new WebAssembly.Module(builder.toBuffer(), {
importedStringConstants: "strings",
});
const instance = new WebAssembly.Instance(module);
assert_equals(instance.exports.hi.value, "hi");
}, "Imported string constants do not require an importObject");

test(() => {
const builder = new WasmModuleBuilder();
builder.addImport(
"wasm:js-string",
"test",
{params: [kWasmExternRef], results: [kWasmI32]});
builder.addImport("env", "f", {params: [], results: []});
const module = new WebAssembly.Module(builder.toBuffer(), {builtins: ["js-string"]});
assert_throws_js(TypeError, () => new WebAssembly.Instance(module));
}, "A non-builtin import still requires an importObject");

test(() => {
const builder = new WasmModuleBuilder();
builder.addImport("wasm:js-string", "not-a-builtin", {params: [], results: []});
const module = new WebAssembly.Module(builder.toBuffer(), {builtins: ["js-string"]});
assert_throws_js(TypeError, () => new WebAssembly.Instance(module));
}, "An unknown import from a builtin module requires an importObject");
Loading