Skip to content

Commit

Permalink
[WIP] WebAssembly JavaScript Module integration
Browse files Browse the repository at this point in the history
For concreteness, this patch specifies how the WebAssembly JavaScript
module integration proposal [1] could work in HTML. It is not yet ready
to merge, as the proposal is still in a relatively early state.

Note that this change depends on the ability for modules to block in the
evaluation phase, to permit WebAssembly module instantiation to yield,
as is necessary on some platforms where compilation work is performed
during the first instantiation. Such an ability to yield is provided by
the JavaScript top-level await proposal [2] and associated HTML
integration patch whatwg#4352.

[1] https://github.com/webassembly/esm-integration
[2] https://github.com/tc39/proposal-top-level-await
  • Loading branch information
littledan authored and takikawa committed Feb 9, 2022
1 parent 465a6b6 commit eb39f80
Showing 1 changed file with 154 additions and 29 deletions.
183 changes: 154 additions & 29 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -2493,6 +2493,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li><dfn data-x="body safely extract" data-x-href="https://fetch.spec.whatwg.org/#bodyinit-safely-extract">safely extracting a body</dfn></li>
<li><dfn data-x-href="https://fetch.spec.whatwg.org/#process-response-end-of-body">processResponseConsumeBody</dfn></li>
<li><dfn data-x-href="https://fetch.spec.whatwg.org/#fetch-processresponseendofbody">processResponseEndOfBody</dfn></li>
<li><dfn data-x-href="https://fetch.spec.whatwg.org/#concept-body-consume-body">consume body</dfn></li>
<li>
<dfn data-x="concept-response"
data-x-href="https://fetch.spec.whatwg.org/#concept-response">response</dfn> and its
Expand Down Expand Up @@ -4186,6 +4187,19 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<ul class="brief">
<li><dfn data-x-href="https://wicg.github.io/uuid/#dfn-generate-a-random-uuid">generating a random UUID</dfn></li>
</ul>
</dd>

<dt>WebAssembly JavaScript Module Integration</dt>

<dd>
<p>The following terms are defined in <cite>WebAssembly JavaScript Module Integration</cite>: <ref spec=WASMESM></p>

<ul class="brief">
<li><dfn data-x-href="https://webassembly.github.io/esm-integration/js-api/index.html#webassembly-module-record">WebAssembly Module Record</dfn></li>
<li><dfn data-x-href="https://webassembly.github.io/esm-integration/js-api/index.html#parse-a-webassembly-module">parse a WebAssembly module</dfn></li>
</ul>
</dd>

</dl>

<hr>
Expand Down Expand Up @@ -91620,6 +91634,9 @@ document.querySelector("button").addEventListener("click", bound);
<li><p>a <span>Synthetic Module Record</span>, for <span data-x="CSS module script">CSS module
scripts</span> and <span data-x="JSON module script">JSON module scripts</span></p></li>

<li><p>a <span>WebAssembly Module Record</span>, for <span data-x="WebAssembly module
script">WebAssembly module scripts</span>;</p></li>

<li><p>null, representing a parsing failure.</p></li>
</ul>
</dd>
Expand Down Expand Up @@ -91691,6 +91708,10 @@ document.querySelector("button").addEventListener("click", bound);
its <span data-x="concept-script-record">record</span> is a <span>Source Text Module
Record</span>.</p></li>

<li><p>A <span>module script</span> is a <dfn data-export="">WebAssembly module script</dfn> if
its <span data-x="concept-script-record">record</span> is a <span>WebAssembly Module
Record</span>.</p></li>

<li>
<p>A <span>module script</span> is a <dfn data-export="">CSS module script</dfn> if its <span
data-x="concept-script-record">record</span> is a <span>Synthetic Module Record</span>, and it
Expand Down Expand Up @@ -92705,6 +92726,22 @@ document.querySelector("button").addEventListener("click", bound);
<span>creating a JSON module script</span> given <var>source text</var> and <var>module map
settings object</var>.</p></li>

<li><p>If the <span>MIME type essence</span> of <var>MIME type</var> is
"<code>application/wasm</code>" and <var>module type</var> is "<code
data-x="">javascript</code>", then:</p>
<ol>
<li><p>Let <var>bufferPromise</var> be the result of running <span>consume body</span> on
<var>response</var> with <i>ArrayBuffer</i>.</p></li>

<li><p><span data-x="creating a WebAssembly module script">Create a WebAssembly module
script</span> given <var>bufferPromise</var>, <var>module map settings object</var>,
<var>response</var>'s <span data-x="concept-response-url">url</span>, and <var>options</var>.
Wait until the algorithm asynchronously completes with <var>result</var>.</p></li>

<li><p>Set <var>module script</var> to <var>result</var>.</p></li>
</ol>
</li>

<li>
<p><span data-x="map set">Set</span> <var>moduleMap</var>[(<var>url</var>,
<var>moduleType</var>)] to <var>module script</var>, and asynchronously complete this algorithm
Expand Down Expand Up @@ -92890,36 +92927,12 @@ document.querySelector("button").addEventListener("click", bound);
we only asked for "<code data-x="">type</code>" assertions in
<span>HostGetSupportedImportAssertions</span>.</p></li>

<li id="validate-requested-module-specifiers">
<p><span data-x="list iterate">For each</span> <span>ModuleRequest record</span>
<var>requested</var> of <var>result</var>.[[RequestedModules]]:</p>

<ol>
<li><p>Let <var>url</var> be the result of <span data-x="resolve a module specifier">resolving
a module specifier</span> given <var>script</var>'s <span data-x="concept-script-base-url">base
URL</span> and <var>requested</var>.[[Specifier]].</p></li>

<li><p>Let <var>moduleType</var> be the result of running the <span>module type from module
request</span> steps given <var>requested</var>.</p></li>
<li><p>Run the <span>validate requested module specifiers</span> steps given <var>result</var>
and <var>script</var>.</p>

<li>
<p>If <var>url</var> is failure, or if the result of running the <span>module type
allowed</span> steps given <var>moduleType</var> and <var>settings</var> is false, then:</p>
<ol>
<li><p>Let <var>error</var> be a new <code>TypeError</code> exception.</p></li>

<li><p>Set <var>script</var>'s <span data-x="concept-script-parse-error">parse error</span>
to <var>error</var>.</p></li>

<li><p>Return <var>script</var>.</p></li>
</ol>
</li>
</ol>

<p class="note">This step is essentially validating all of the requested module specifiers and
type assertions. We treat a module with unresolvable module specifiers or unsupported type
assertions the same as one that cannot be parsed; in both cases, a syntactic issue makes it
impossible to ever contemplate linking the module later.</p>
<p>If these steps throw an exception, set <var>script</var>'s <span
data-x="concept-script-parse-error">parse error</span> to that exception, and return
<var>script</var>.</p>
</li>

<li><p>Set <var>script</var>'s <span data-x="concept-script-record">record</span> to
Expand Down Expand Up @@ -92996,6 +93009,109 @@ document.querySelector("button").addEventListener("click", bound);
<li><p>Return <var>script</var>.</p></li>
</ol>

<p>To <dfn data-x="creating a WebAssembly module script">create a WebAssembly module script</dfn>,
given a promise that will resolve with an <code data-x="idl-ArrayBuffer">ArrayBuffer</code>
<var>bufferPromise</var>, an <span>environment settings object</span> <var>settings</var>, a
<span>URL</span> <var>baseURL</var>, and some <span>script fetch options</span>
<var>options</var>, run these steps. The algorithm will asynchronously complete with a new
<span>WebAssembly module script</span>.</p>

<ol>
<li><p>If <span data-x="concept-environment-noscript">scripting is disabled</span> for
<var>settings</var>, then set <var>bufferPromise</var> to a promise resolved with an empty
<code data-x="idl-ArrayBuffer">ArrayBuffer</code>.</p></li>
<!-- REVIEW NOTE: this will cause a parse error, because it doesn't have the magic bytes. -->

<li><p>Let <var>script</var> be a new <span>WebAssembly module script</span> that this algorithm
will subsequently initialize.</p></li>

<li><p>Set <var>script</var>'s <span>settings object</span> to <var>settings</var>.</p></li>

<li><p>Set <var>script</var>'s <span data-x="concept-script-base-url">base URL</span> to
<var>baseURL</var>.</p></li>

<li><p>Set <var>script</var>'s <span data-x="concept-script-script-fetch-options">fetch
options</span> to <var>options</var>.</p></li>

<li><p>Set <var>script</var>'s <span data-x="concept-script-parse-error">parse error</span> and
<span data-x="concept-script-error-to-rethrow">error to rethrow</span> to null.</p></li>

<li>
<p>Upon fulfillment of <var>bufferPromise</var> with <var>buffer</var>:</p>

<ol>
<li>
<p>Let <var>module</var> be the result of <span>parse a WebAssembly module</span> given
<var>buffer</var>, <var>settings</var>'s <span data-x="environment settings object's
Realm">Realm</span>, and <var>script</var>.</p>

<p class="note">Passing <var>script</var> as the last parameter here ensures
<var>result</var>.[[HostDefined]] will be <var>script</var>.</p>

<p>If this algorithm throws an exception, set <var>script</var>'s <span
data-x="concept-script-parse-error">parse error</span> to that exception, and asynchronously
complete this algorithm with <var>script</var>.</p>
</li>

<li><p>Run the <span>validate requested module specifiers</span> steps given <var>module</var>
and <var>script</var>.</p>

</li>

<li><p>Set <var>script</var>'s <span data-x="concept-script-record">record</span> to
<var>module</var>.</p></li>

<li><p>Asynchronously complete this algorithm with <var>script</var>.</p></li>
</ol>
</li>

<li>
<p>Upon rejection of <var>bufferPromise</var> with <var>reason</var>:</p>
<ol>
<li><p>Set <var>script</var>'s <span data-x="concept-script-parse-error">parse error</span> to
<var>reason</var>.</p></li>

<li><p>Asynchronously complete this algorithm with <var>script</var>.</p></li>
</ol>
</li>
</ol>

<p>The <dfn id="validate-requested-module-specifiers">validate requested module specifiers</dfn>
steps, given a module record <var>record</var> and a script <var>script</var>, are as
follows:</p>

<ol>
<li>
<p><span data-x="list iterate">For each</span> <span>ModuleRequest record</span>
<var>requested</var> of <var>record</var>.[[RequestedModules]]:</p>

<ol>
<li><p>Let <var>url</var> be the result of <span data-x="resolve a module specifier">resolving
a module specifier</span> given <var>script</var>'s <span data-x="concept-script-base-url">base
URL</span> and <var>requested</var>.[[Specifier]].</p></li>

<li><p>Let <var>moduleType</var> be the result of running the <span>module type from module
request</span> steps given <var>requested</var>.</p></li>

<li>
<p>If <var>url</var> is failure, or if the result of running the <span>module type
allowed</span> steps given <var>moduleType</var> and <var>settings</var> is false, then:</p>

<ol>
<li><p>Let <var>error</var> be a new <code>TypeError</code> exception.</p></li>

<li><p>Throw <var>error</var>.</p></li>
</ol>
</li>
</ol>
</li>
</ol>

<p class="note">These steps are essentially validating all of the requested module specifiers and
type assertions. We treat a module with unresolvable module specifiers or unsupported type
assertions the same as one that cannot be parsed; in both cases, a syntactic issue makes it
impossible to ever contemplate linking the module later.</p>

<p>The <dfn>module type from module request</dfn> steps, given a <span>ModuleRequest
Record</span> <var>moduleRequest</var>, are as follows:</p>

Expand Down Expand Up @@ -126668,6 +126784,9 @@ INSERT INTERFACES HERE
<dt><dfn><code>application/xml</code></dfn></dt>
<dd>XML <ref spec=XML> <ref spec=RFC7303></dd>

<dt><dfn><code>application/wasm</code></dfn></dt>
<dd>WebAssembly <ref spec=WASM></dd>

<dt><dfn><code>image/gif</code></dfn></dt>
<dd>GIF images <ref spec=GIF></dd>

Expand Down Expand Up @@ -127314,6 +127433,12 @@ INSERT INTERFACES HERE
<dt id="refsWASMJS">[WASMJS]</dt>
<dd>(Non-normative) <cite><a href="https://webassembly.github.io/spec/js-api/">WebAssembly JavaScript Interface</a></cite>, D. Ehrenberg. W3C.</dd>

<dt id="refsWASM">[WASM]</dt>
<dd><cite><a href="https://webassembly.github.io/spec/core/bikeshed/index.html">WebAssembly Core Specification</a></cite>, A. Rossberg. W3C.</dd>

<dt id="refsWASMESM">[WASMESM]</dt>
<dd><cite><a href="https://webassembly.github.io/esm-integration/js-api/index.html">WebAssembly JavaScript Module Integration</a></cite>, L. Clark, D. Ehrenberg. W3C.</dd>

<dt id="refsWCAG">[WCAG]</dt>
<dd>(Non-normative) <cite><a href="https://w3c.github.io/wcag/guidelines/">Web Content Accessibility Guidelines (WCAG)</a></cite>, A. Kirkpatrick, J. O Connor, A. Campbell, M. Cooper. W3C.</dd>

Expand Down

0 comments on commit eb39f80

Please sign in to comment.