From 2a99bd3755427b9c3e9147c4a7182b078b0dd08c Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Thu, 20 Mar 2025 18:13:02 -0700 Subject: [PATCH 1/8] ESM Phase Imports import() & new Worker() support for WA.Module --- document/js-api/index.bs | 11 ++++++++++ document/web-api/index.bs | 45 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/document/js-api/index.bs b/document/js-api/index.bs index 42e50e6f1..4047b8059 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -2384,6 +2384,17 @@ WebAssembly Module Records have the following methods: +
+ +

ModuleSourcesEqual ( |otherRecord| ) Concrete Method

+1. If |otherRecord| is not a WebAssemly Module Record, return false. +1. Let |record| be this WebAssembly Module Record. +1. Let |module| be |record|.\[[ModuleSource]]. +1. Let |otherModule| be |otherRecord|.\[[ModuleSource]]. +1. Return true if |module|.\[[Bytes]] is equal to |otherModule|.\[[Bytes]], and false otherwise. + +
+

GetModuleSourceKind ( ) Concrete Method

diff --git a/document/web-api/index.bs b/document/web-api/index.bs index 83d8288d8..1a826acdc 100644 --- a/document/web-api/index.bs +++ b/document/web-api/index.bs @@ -155,15 +155,54 @@ The [=serialization steps=], given |value|, |serialized|, and |forStorage|, are: 1. Set |serialized|.\[[AgentCluster]] to the [=current Realm=]'s corresponding [=agent cluster=]. + 1. Let |rooted| be false. + + 1. If |value|.\[[ModuleRecord]] is not empty and |value|.\[[ModuleRecord]].\[[HostDefined]] is not empty, + + 1. Let |moduleScript| be |value|.\[[ModuleRecord]].\[[HostDefined]]. + + 1. Set |rooted| to |moduleScript|'s [=rooted source=] boolean. + + 1. If |rooted| is true then, + + 1. Set |serialized|.\[[Rooted]] to true. + + 1. Set |serialized|.\[[BaseURL]] to |moduleScript|'s base URL. + + 1. If |rooted| is false, + + 1. Set |serialized|.\[[Rooted]] to false. + + 1. Set |serialized|.\[[BaseURL]] to null. + The [=deserialization steps=], given |serialized|, |value|, and |targetRealm| are: 1. Let |bytes| be the [=sub-deserialization=] of |serialized|.\[[Bytes]]. - 1. Set |value|.\[[Bytes]] to |bytes|. + 1. Let |rooted| be the [=sub-deserialization=] of |serialized|.\[[Rooted]]. + + 1. Let |baseURL| be the [=sub-deserialization=] of |serialized|.\[[BaseURL]]. + + 1. If |rooted| is false then, + + 1. Set |value|.\[[Bytes]] to |bytes|. + + 1. If |targetRealm|'s corresponding [=agent cluster=] is not |serialized|.\[[AgentCluster]], then throw a "DataCloneError" {{DOMException}}. + + 1. [=Compile a WebAssembly module=] from |bytes| and set |value|.\[[Module]] to the result. + + 1. Otherwise, + + 1. Let |settings| be the [=current settings object=]. + + 1. Let |fetchOptions| be the [=default script fetch options=]. + + 1. Let |moduleScript| be the result of [=creating a WebAssembly module script=] given |bytes|, |settings|, |baseURL|, |fetchOptions|, true. + + 1. [=Parse a WebAssembly module=] given |bytes|, [=current Realm=] and |moduleScript| and set |value|.\[[Module]] to the result. - 1. If |targetRealm|'s corresponding [=agent cluster=] is not |serialized|.\[[AgentCluster]], then throw a "DataCloneError" {{DOMException}}. + 1. Assert: there was no compile error as this same module was previously compiled successfully. - 1. [=Compile a WebAssembly module=] from |bytes| and set |value|.\[[Module]] to the result. Engines should attempt to share/reuse internal compiled code when performing a structured serialization, although in corner cases like CPU upgrade or browser From 27f5ba06b34aedae8330eafea6c5074e2c6cd4a7 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Thu, 20 Mar 2025 18:43:34 -0700 Subject: [PATCH 2/8] add definitions --- document/web-api/index.bs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/document/web-api/index.bs b/document/web-api/index.bs index 1a826acdc..91724a8bc 100644 --- a/document/web-api/index.bs +++ b/document/web-api/index.bs @@ -66,7 +66,11 @@ urlPrefix: https://webassembly.github.io/spec/js-api/; spec: WASMJS text: asynchronously compile a webassembly module; url: #asynchronously-compile-a-webassembly-module text: instantiate a promise of a module; url: #instantiate-a-promise-of-a-module text: Exported Function; url: #exported-function -url:https://html.spec.whatwg.org/#cors-same-origin;text:CORS-same-origin;type:dfn;spec:HTML +urlPrefix: https://html.spec.whatwg.org/; spec: HTML; type: dfn + text: rooted source; url: #concept-script-rooted-source + text: default script fetch options; url: #default-script-fetch-options + text: current settings object; url: #current-settings-object + text: CORS-same-origin; url: #cors-same-origin url:https://fetch.spec.whatwg.org/#concept-body-consume-body;text:consume body;type:dfn;spec:FETCH url:https://w3c.github.io/webappsec-secure-contexts/#environment-settings-object-contextually-secure; text:contextually secure; type: dfn; spec: SECURECONTEXTS @@ -167,7 +171,7 @@ The [=serialization steps=], given |value|, |serialized|, and |forStorage|, are: 1. Set |serialized|.\[[Rooted]] to true. - 1. Set |serialized|.\[[BaseURL]] to |moduleScript|'s base URL. + 1. Set |serialized|.\[[BaseURL]] to |moduleScript|'s [=base URL=]. 1. If |rooted| is false, From 4ef9225559eb5a1b38923be3f34b803d1b617f07 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Thu, 20 Mar 2025 19:10:39 -0700 Subject: [PATCH 3/8] rework spec orderings for consistency --- document/js-api/index.bs | 15 +++++---------- document/web-api/index.bs | 26 +++++++++++--------------- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/document/js-api/index.bs b/document/js-api/index.bs index 4047b8059..b96e02f5d 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -2305,16 +2305,11 @@ Note: While this specification is not yet merged into the main Wasm specificatio WebAssembly Module Records are a subclass of [=Cyclic Module Record=] which contain WebAssembly code.
-To parse a WebAssembly module given a byte sequence |bytes|, a Realm |realm| and object |hostDefined|, perform the following steps. - -1. Let |stableBytes| be a [=get a copy of the buffer source|copy of the bytes held by the buffer=] |bytes|. -1. [=Compile a WebAssembly module|Compile the WebAssembly module=] |stableBytes| and store the result as |module|. -1. If |module| is [=error=], throw a {{CompileError}} exception. -1. Let |builtinSetNames| be « "js-string" ». -1. Let |importedStringModule| be "wasm:js/string-constants". -1. [=Construct a WebAssembly module object=] from |module|, |bytes|, |builtinSetNames| and |importedStringModule|, and let |module| be the result. +To create a WebAssembly Module Record given a WebAssembly module object |moduleObject|, a Realm |realm| and object |hostDefined|, perform the following steps. + +1. Assert: |moduleObject|.\[[ModuleRecord]] is not defined. 1. Let |requestedModules| be a set. -1. For each (|moduleName|, |name|, |type|) in [=module_imports=](|module|.\[[Module]]), +1. For each (|moduleName|, name, type) in [=module_imports=](|moduleObject|.\[[Module]]), 1. If |moduleName| starts with the prefix "wasm-js:", 1. Throw a {{LinkError}} exception. 1. If |name| starts with the prefix "wasm:" or "wasm-js:", @@ -2348,7 +2343,7 @@ To parse a WebAssembly module given a byte sequence |by \[[AsyncParentModules]]: « », \[[PendingAsyncDependencies]]: ~empty~, }. -1. Set |module|.\[[ModuleRecord]] to |moduleRecord|. +1. Set |moduleObject|.\[[ModuleRecord]] to |moduleRecord|. 1. Return |moduleRecord|. Note: From HTML, it's not observable when [=parse a WebAssembly module=] begins, so any work perfomed in compilation may be performed off-thread. diff --git a/document/web-api/index.bs b/document/web-api/index.bs index 91724a8bc..c8046c790 100644 --- a/document/web-api/index.bs +++ b/document/web-api/index.bs @@ -71,6 +71,7 @@ urlPrefix: https://html.spec.whatwg.org/; spec: HTML; type: dfn text: default script fetch options; url: #default-script-fetch-options text: current settings object; url: #current-settings-object text: CORS-same-origin; url: #cors-same-origin + text: creating a WebAssembly Module Script; url: #creating-a-webassembly-module-script url:https://fetch.spec.whatwg.org/#concept-body-consume-body;text:consume body;type:dfn;spec:FETCH url:https://w3c.github.io/webappsec-secure-contexts/#environment-settings-object-contextually-secure; text:contextually secure; type: dfn; spec: SECURECONTEXTS @@ -181,32 +182,27 @@ The [=serialization steps=], given |value|, |serialized|, and |forStorage|, are: The [=deserialization steps=], given |serialized|, |value|, and |targetRealm| are: - 1. Let |bytes| be the [=sub-deserialization=] of |serialized|.\[[Bytes]]. - - 1. Let |rooted| be the [=sub-deserialization=] of |serialized|.\[[Rooted]]. + 1. If |targetRealm|'s corresponding [=agent cluster=] is not |serialized|.\[[AgentCluster]], then throw a "DataCloneError" {{DOMException}}. - 1. Let |baseURL| be the [=sub-deserialization=] of |serialized|.\[[BaseURL]]. + 1. Let |bytes| be the [=sub-deserialization=] of |serialized|.\[[Bytes]]. - 1. If |rooted| is false then, + 1. Set |value|.\[[Bytes]] to |bytes|. + + 1. [=Compile a WebAssembly module=] from |bytes| and set |value|.\[[Module]] to the result. - 1. Set |value|.\[[Bytes]] to |bytes|. + 1. Assert: there was no compile error as this same module was previously compiled successfully. - 1. If |targetRealm|'s corresponding [=agent cluster=] is not |serialized|.\[[AgentCluster]], then throw a "DataCloneError" {{DOMException}}. + 1. Let |rooted| be the [=sub-deserialization=] of |serialized|.\[[Rooted]]. - 1. [=Compile a WebAssembly module=] from |bytes| and set |value|.\[[Module]] to the result. + 1. If |rooted| is true then, - 1. Otherwise, + 1. Let |baseURL| be the [=sub-deserialization=] of |serialized|.\[[BaseURL]]. 1. Let |settings| be the [=current settings object=]. 1. Let |fetchOptions| be the [=default script fetch options=]. - 1. Let |moduleScript| be the result of [=creating a WebAssembly module script=] given |bytes|, |settings|, |baseURL|, |fetchOptions|, true. - - 1. [=Parse a WebAssembly module=] given |bytes|, [=current Realm=] and |moduleScript| and set |value|.\[[Module]] to the result. - - 1. Assert: there was no compile error as this same module was previously compiled successfully. - + 1. Let moduleScript be the result of [=creating a WebAssembly module script=] given |value|, |settings|, |baseURL|, |fetchOptions|, true. Engines should attempt to share/reuse internal compiled code when performing a structured serialization, although in corner cases like CPU upgrade or browser From b8b8518693fa6b02e5be00ff50f779d0b07ef92e Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Thu, 20 Mar 2025 19:37:36 -0700 Subject: [PATCH 4/8] corrections --- document/js-api/index.bs | 4 ++-- document/web-api/index.bs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/document/js-api/index.bs b/document/js-api/index.bs index b96e02f5d..7fd763692 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -2327,7 +2327,7 @@ To create a WebAssembly Module Record given a WebAssembly modu \[[Realm]]: |realm|, \[[Environment]]: ~empty~, \[[Namespace]]: ~empty~, - \[[ModuleSource]]: |module|, + \[[ModuleSource]]: |moduleObject|, \[[HostDefined]]: |hostDefined|, \[[Status]]: "new", @@ -2346,7 +2346,7 @@ To create a WebAssembly Module Record given a WebAssembly modu 1. Set |moduleObject|.\[[ModuleRecord]] to |moduleRecord|. 1. Return |moduleRecord|. -Note: From HTML, it's not observable when [=parse a WebAssembly module=] begins, so any work perfomed in compilation may be performed off-thread. +Note: From HTML, it's not observable when [=create a WebAssembly Module Record=] begins, so any work perfomed in compilation may be performed off-thread.
diff --git a/document/web-api/index.bs b/document/web-api/index.bs index c8046c790..efe5f73a7 100644 --- a/document/web-api/index.bs +++ b/document/web-api/index.bs @@ -162,7 +162,7 @@ The [=serialization steps=], given |value|, |serialized|, and |forStorage|, are: 1. Let |rooted| be false. - 1. If |value|.\[[ModuleRecord]] is not empty and |value|.\[[ModuleRecord]].\[[HostDefined]] is not empty, + 1. If |value|.\[[ModuleRecord]] is not null and |value|.\[[ModuleRecord]].\[[HostDefined]] is not empty, 1. Let |moduleScript| be |value|.\[[ModuleRecord]].\[[HostDefined]]. @@ -202,7 +202,7 @@ The [=deserialization steps=], given |serialized|, |value|, and |targetRealm| ar 1. Let |fetchOptions| be the [=default script fetch options=]. - 1. Let moduleScript be the result of [=creating a WebAssembly module script=] given |value|, |settings|, |baseURL|, |fetchOptions|, true. + 1. Let moduleScript be the result of [=creating a WebAssembly module script=] given |value|.\[[Module]], |settings|, |baseURL|, |fetchOptions|, true. Engines should attempt to share/reuse internal compiled code when performing a structured serialization, although in corner cases like CPU upgrade or browser From 5904670c5f7ec3d96ed6ebcef454ccf47ce5857a Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Fri, 21 Mar 2025 10:51:05 -0700 Subject: [PATCH 5/8] finish up restructure --- document/js-api/index.bs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/document/js-api/index.bs b/document/js-api/index.bs index 7fd763692..e09bfc655 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -809,6 +809,7 @@ In addition, the interface object for {{Module}} must have as its \[[Prototype]] 1. Set **this**.\[[Bytes]] to |stableBytes|. 1. Set **this**.\[[BuiltinSets]] to |builtinSetNames|. 1. Set **this**.\[[ImportedStringModule]] to |importedStringModule|. + 1. Set **this**.\[[ModuleRecord]] to null. Note: Some implementations enforce a size limitation on |bytes|. Use of this API is discouraged, in favor of asynchronous APIs.
@@ -2307,7 +2308,7 @@ Note: While this specification is not yet merged into the main Wasm specificatio
To create a WebAssembly Module Record given a WebAssembly module object |moduleObject|, a Realm |realm| and object |hostDefined|, perform the following steps. -1. Assert: |moduleObject|.\[[ModuleRecord]] is not defined. +1. Assert: |moduleObject|.\[[ModuleRecord]] is null. 1. Let |requestedModules| be a set. 1. For each (|moduleName|, name, type) in [=module_imports=](|moduleObject|.\[[Module]]), 1. If |moduleName| starts with the prefix "wasm-js:", From 3734de3727c943b0b525c6aa2536238c31df1749 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Mon, 24 Mar 2025 11:37:18 -0700 Subject: [PATCH 6/8] Apply suggestions from code review Co-authored-by: Anne van Kesteren --- document/web-api/index.bs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/document/web-api/index.bs b/document/web-api/index.bs index efe5f73a7..dd30d12ce 100644 --- a/document/web-api/index.bs +++ b/document/web-api/index.bs @@ -162,7 +162,7 @@ The [=serialization steps=], given |value|, |serialized|, and |forStorage|, are: 1. Let |rooted| be false. - 1. If |value|.\[[ModuleRecord]] is not null and |value|.\[[ModuleRecord]].\[[HostDefined]] is not empty, + 1. If |value|.\[[ModuleRecord]] is not null and |value|.\[[ModuleRecord]].\[[HostDefined]] is not empty: 1. Let |moduleScript| be |value|.\[[ModuleRecord]].\[[HostDefined]]. @@ -174,7 +174,7 @@ The [=serialization steps=], given |value|, |serialized|, and |forStorage|, are: 1. Set |serialized|.\[[BaseURL]] to |moduleScript|'s [=base URL=]. - 1. If |rooted| is false, + 1. If |rooted| is false: 1. Set |serialized|.\[[Rooted]] to false. @@ -194,7 +194,7 @@ The [=deserialization steps=], given |serialized|, |value|, and |targetRealm| ar 1. Let |rooted| be the [=sub-deserialization=] of |serialized|.\[[Rooted]]. - 1. If |rooted| is true then, + 1. If |rooted| is true: 1. Let |baseURL| be the [=sub-deserialization=] of |serialized|.\[[BaseURL]]. From cf9d9caf9f58df92b0853d2b4e1fb8c2c9650d81 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Mon, 24 Mar 2025 12:18:42 -0700 Subject: [PATCH 7/8] Update document/web-api/index.bs --- document/web-api/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/document/web-api/index.bs b/document/web-api/index.bs index dd30d12ce..a3fec4237 100644 --- a/document/web-api/index.bs +++ b/document/web-api/index.bs @@ -202,7 +202,7 @@ The [=deserialization steps=], given |serialized|, |value|, and |targetRealm| ar 1. Let |fetchOptions| be the [=default script fetch options=]. - 1. Let moduleScript be the result of [=creating a WebAssembly module script=] given |value|.\[[Module]], |settings|, |baseURL|, |fetchOptions|, true. + 1. [=Create a WebAssembly module script=] given |value|.\[[Module]], |settings|, |baseURL|, |fetchOptions|, and true. Engines should attempt to share/reuse internal compiled code when performing a structured serialization, although in corner cases like CPU upgrade or browser From 312066a55cd33784e1261685cb957c5dd89c76e8 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Mon, 24 Mar 2025 12:22:05 -0700 Subject: [PATCH 8/8] update reference --- document/web-api/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/document/web-api/index.bs b/document/web-api/index.bs index a3fec4237..67cf4038d 100644 --- a/document/web-api/index.bs +++ b/document/web-api/index.bs @@ -71,7 +71,7 @@ urlPrefix: https://html.spec.whatwg.org/; spec: HTML; type: dfn text: default script fetch options; url: #default-script-fetch-options text: current settings object; url: #current-settings-object text: CORS-same-origin; url: #cors-same-origin - text: creating a WebAssembly Module Script; url: #creating-a-webassembly-module-script + text: create a WebAssembly Module Script; url: #creating-a-webassembly-module-script url:https://fetch.spec.whatwg.org/#concept-body-consume-body;text:consume body;type:dfn;spec:FETCH url:https://w3c.github.io/webappsec-secure-contexts/#environment-settings-object-contextually-secure; text:contextually secure; type: dfn; spec: SECURECONTEXTS