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 #4352.

[1] https://github.com/webassembly/esm-integration
[2] https://github.com/tc39/proposal-top-level-await
  • Loading branch information
littledan committed Mar 2, 2019
1 parent 91902bd commit d7f9e27
Showing 1 changed file with 148 additions and 40 deletions.
188 changes: 148 additions & 40 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -2743,6 +2743,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<p>The following terms are defined in the WHATWG MIME Sniffing standard: <ref spec=MIMESNIFF></p>

<ul class="brief">
<li><dfn data-x-href="https://mimesniff.spec.whatwg.org/#mime-type-essence">essence</dfn></li>
<li><dfn data-x-href="https://mimesniff.spec.whatwg.org/#mime-type">MIME type</dfn></li>
<li><dfn data-x-href="https://mimesniff.spec.whatwg.org/#valid-mime-type">valid MIME type string</dfn></li>
<li><dfn data-x-href="https://mimesniff.spec.whatwg.org/#valid-mime-type-with-no-parameters">valid MIME type string with no parameters</dfn></li>
Expand Down Expand Up @@ -2783,6 +2784,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li>the <dfn data-x-href="https://fetch.spec.whatwg.org/#requestcredentials"><code>RequestCredentials</code></dfn> enumeration</li>
<li>the <dfn data-x-href="https://fetch.spec.whatwg.org/#requestdestination"><code>RequestDestination</code></dfn> enumeration</li>
<li>the <dfn data-x-href="https://fetch.spec.whatwg.org/#dom-global-fetch"><code>fetch()</code></dfn> method</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 @@ -4180,6 +4182,17 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
</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 @@ -86768,7 +86781,7 @@ interface <dfn>ApplicationCache</dfn> : <span>EventTarget</span> {

<h5>Definitions</h5>

<p>A <dfn data-x="concept-script" data-export="">script</dfn> is one of two possible <span
<p>A <dfn data-x="concept-script" data-export="">script</dfn> is one of three possible <span
data-x="struct">structs</span>. All scripts have:</p>

<dl>
Expand All @@ -86781,8 +86794,10 @@ interface <dfn>ApplicationCache</dfn> : <span>EventTarget</span> {

<dd><p>Either a <span>Script Record</span>, for <span data-x="classic script">classic
scripts</span>; a <span>Source Text Module Record</span>, for <span data-x="module
script">module scripts</span>; or null. In the former two cases, it represents a parsed script;
null represents a failure parsing.</p></dd>
script">module scripts</span>; a <span>WebAssembly Module Record</span> for <span
data-x="WebAssembly module script">WebAssembly module scripts</span>; or null. In the
former two cases, it represents a parsed script; in the third case, a parsed WebAssembly
module; null represents a failure parsing.</p></dd>

<dt>A <dfn data-dfn-for="script" data-export="" data-x="concept-script-parse-error">parse
error</dfn></dt>
Expand Down Expand Up @@ -86834,6 +86849,10 @@ interface <dfn>ApplicationCache</dfn> : <span>EventTarget</span> {
data-x="concept-script">script</span>. It has no additional <span data-x="struct
item">items</span>.</p>

<p>A <dfn data-export="">WebAssembly module script</dfn> is another type of <span
data-x="concept-script">script</span>. It has no additional <span data-x="struct
item">items</span>.</p>

<p>The <dfn>active script</dfn> is determined by the following algorithm:</p>

<ol>
Expand Down Expand Up @@ -87472,25 +87491,48 @@ interface <dfn>ApplicationCache</dfn> : <span>EventTarget</span> {

<li><p><var>response</var>'s <span data-x="concept-response-status">status</span> is not an
<span>ok status</span></p></li>
</ul>
</li>

<li>
<p>The result of <span data-x="extract a MIME type">extracting a MIME type</span> from
<var>response</var>'s <span data-x="concept-response-header-list">header list</span> is not a
<span>JavaScript MIME type</span></p>
<li>
<p>Let <var>type</var> be the result of <span data-x="extract a MIME type">extracting a
MIME type</span> from <var>response</var>'s <span data-x="concept-response-header-list">header
list</span>.</p>

<p class="note">For historical reasons, <span data-x="fetch a classic script">fetching a
classic script</span> does not include MIME type checking. In contrast, module scripts will
fail to load if they are not of a correct MIME type.</p>
</li>
</ul>
<p class="note">For historical reasons, <span data-x="fetch a classic script">fetching a
classic script</span> does not include MIME type checking. In contrast, module scripts'
interpretation is driven by their MIME type, and they will fail to load if they are not of
a supported MIME type.</p>
</li>

<li><p>Let <var>source text</var> be the result of <span data-x="UTF-8 decode">UTF-8
decoding</span> <var>response</var>'s <span data-x="concept-response-body">body</span>.</p></li>
<li><p>Let <var>module script</var> be null.</p></li>

<li><p>Let <var>module script</var> be the result of <span>creating a module script</span> given
<var>source text</var>, <var>module map settings object</var>, <var>response</var>'s <span
data-x="concept-response-url">url</span>, and <var>options</var>.</p></li>
<li>
<p>If <var>type</var> is a <span>JavaScript MIME type</span>, then:</p>

<ol>
<li><p>Let <var>source text</var> be the result of <span data-x="UTF-8 decode">UTF-8
decoding</span> <var>response</var>'s <span data-x="concept-response-body">body</span>.</p></li>

<li><p>Set <var>module script</var> to the result of <span>creating a module script</span> given
<var>source text</var>, <var>module map settings object</var>, <var>response</var>'s <span
data-x="concept-response-url">url</span>, and <var>options</var>.</p></li>
</ol>
</li>

<li>
<p>If <var>type</var>'s <span>essence</span> is "<code>application/wasm</code>", then:</p>

<ol>
<li><p>Let <var>buffer</var> be the result of running <span>consume body</span> on
<var>response</var> with <i>ArrayBuffer</i>.</p></li>

<li><p>Set <var>module script</var> to the result of <span>creating a WebAssembly module
script</span> given <var>buffer</var>, <var>module map settings object</var>,
<var>response</var>'s <span data-x="concept-response-url">url</span>, and
<var>options</var>.</p></li>
</ol>
</li>

<li>
<p><span data-x="map set">Set</span> <var>moduleMap</var>[<var>url</var>] to <var>module
Expand Down Expand Up @@ -87737,6 +87779,44 @@ interface <dfn>ApplicationCache</dfn> : <span>EventTarget</span> {
<li><p>Return <var>script</var>.</p></li>
</ol>

<p>To <dfn id="validate-requested-module-specifiers">validate requested module specifiers</dfn>
of a module record <var>record</var> for a script <var>script</var>:</p>

<ol>
<li>
<p><span data-x="list iterate">For each</span> string <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>.</p></li>

<li>
<p>If <var>url</var> is failure, 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.</p></li>
</ol>
</li>
</ol>

</li>

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

<p class="note">This algorithm is essentially validating all of the requested module specifiers. We
treat a module with unresolvable module specifiers the same as one that cannot be parsed; in
both cases, a syntactic issue makes it impossible to ever contemplate instantiating the module
later.</p>

<p>To <dfn data-x="creating a module script">create a module script</dfn>, given a
<span>JavaScript string</span> <var>source</var>, an <span>environment settings object</span>
<var>settings</var>, a <span>URL</span> <var>baseURL</var>, and some <span>script fetch
Expand Down Expand Up @@ -87781,37 +87861,56 @@ interface <dfn>ApplicationCache</dfn> : <span>EventTarget</span> {
</ol>
</li>

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

<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>.</p></li>
<li><p>Return <var>script</var>.</p></li>
</ol>

<li>
<p>If <var>url</var> is failure, then:</p>
<p>To <dfn data-x="creating a WebAssembly module script">create a WebAssembly module script</dfn>,
given an <code data-x="idl-ArrayBuffer">ArrayBuffer</code> <var>buffer</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>:</p>

<ol>
<li><p>Let <var>error</var> be a new <code>TypeError</code> exception.</p></li>
<ol>
<li><p>If <span data-x="concept-bc-noscript">scripting is disabled</span> for
<var>settings</var>'s <span>responsible browsing context</span>, then set <var>source</var> to
the empty string.</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>Let <var>script</var> be a new <span>WebAssembly module script</span> that this algorithm
will subsequently initialize.</p></li>

<li><p>Return <var>script</var>.</p></li>
</ol>
</li>
</ol>
<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>

<p class="note">This step is essentially validating all of the requested module specifiers. We
treat a module with unresolvable module specifiers the same as one that cannot be parsed; in
both cases, a syntactic issue makes it impossible to ever contemplate instantiating the module
later.</p>
<li>
<p>Let <var>module</var> be the result of <span>parse a WebAssembly module</span> given the
<code data-x="idl-ArrayBuffer">ArrayBuffer</code> <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, then catch it and perform the following steps:</p>

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

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

<li><p>Set <var>script</var>'s <span data-x="concept-script-record">record</span> to
<var>result</var>.</p></li>
<li><p><span>Validate requested module specifiers</span> of <var>module</var> with
<var>script</var>.</p></li>

<li><p>Return <var>script</var>.</p></li>
</ol>
Expand Down Expand Up @@ -121512,6 +121611,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 @@ -122108,6 +122210,12 @@ INSERT INTERFACES HERE
<dt id="refsUTR36">[UTR36]</dt>
<dd>(Non-normative) <cite><a href="https://www.unicode.org/reports/tr36/">UTR #36: Unicode Security Considerations</a></cite>, M. Davis, M. Suignard. Unicode Consortium.</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://www.w3.org/TR/WCAG20/">Web Content Accessibility Guidelines (WCAG) 2.0</a></cite>, B. Caldwell, M. Cooper, L. Reid, G. Vanderheiden. W3C.</dd>

Expand Down

0 comments on commit d7f9e27

Please sign in to comment.