Skip to content

Commit

Permalink
[jsapi] Normative: Always queue a task during asynchronous instantiation
Browse files Browse the repository at this point in the history
JSC will have to do asynchronous compilation work during some instantiations.
To be consistent, this PR always queues a task to complete instantiation,
except through the synchronous Instance(module) API, to ensure consistency
across platforms.

This patch also cleans up the specification in various surrounding ways:
- Include notes about APIs whose use is discouraged/may be limited

Closes WebAssembly#741
See also webpack/webpack#6433
  • Loading branch information
littledan authored and Ms2ger committed Mar 18, 2019
1 parent 9947b1e commit 9258c3f
Showing 1 changed file with 20 additions and 13 deletions.
33 changes: 20 additions & 13 deletions document/js-api/index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -415,17 +415,19 @@ A {{Module}} object represents a single WebAssembly module. Each {{Module}} obje
1. Let |module| be |moduleObject|.\[[Module]].
1. [=Read the imports=] of |module| with imports |importObject|, and let |imports| be the result.
If this operation throws an exception, catch it, [=reject=] |promise| with the exception, and return |promise|.
1. [=Queue a task=] to perform the following steps:
1. [=Instantiate the core of a WebAssembly module=] |module| with |imports|, and let |instance| be the result.
If this throws an exception, catch it, [=reject=] |promise| with the exception, and terminate these substeps.
1. [=Create an instance object=] from |module| and |instance|, and let the result be |instanceObject|.
If this throws an exception, catch it, [=reject=] |promise| with the exception, and terminate these substeps.
1. [=Resolve=] |promise| with |instanceObject|.
1. Run the following steps [=in parallel=]:
1. [=Queue a task=] to perform the following steps:
Note: Implementation-specific work may be performed here.
1. [=Instantiate the core of a WebAssembly module=] |module| with |imports|, and let |instance| be the result.
If this throws an exception, catch it, [=reject=] |promise| with the exception, and terminate these substeps.
1. [=Create an instance object=] from |module| and |instance|, and let the result be |instanceObject|.
If this throws an exception, catch it, [=reject=] |promise| with the exception, and terminate these substeps.
1. [=Resolve=] |promise| with |instanceObject|.
1. Return |promise|.
</div>

<div algorithm="instantiate">
To <dfn>instantiate a WebAssembly module</dfn> from a {{Module}} |moduleObject| and imports |importObject|, perform the following steps:
To <dfn>synchronously instantiate a WebAssembly module</dfn> from a {{Module}} |moduleObject| and imports |importObject|, perform the following steps:
1. Let |module| be |moduleObject|.\[[Module]].
1. [=Read the imports=] of |module| with imports |importObject|, and let |imports| be the result.
1. [=Instantiate the core of a WebAssembly module=] |module| with |imports|, and let |instance| be the result.
Expand All @@ -438,14 +440,15 @@ A {{Module}} object represents a single WebAssembly module. Each {{Module}} obje

1. Let |promise| be [=a new promise=]
1. [=Upon fulfillment=] of |promiseOfModule| with value |module|:
1. [=instantiate a WebAssembly module|Instantiate the WebAssembly module=] |module| importing |importObject|, and let |instance| be the result. If this throws an exception, catch it, [=reject=] |promise| with the exception, and abort these substeps.
1. Let |result| be a {{WebAssemblyInstantiatedSource}} dictionary with {{WebAssemblyInstantiatedSource/module}} set to |module| and {{WebAssemblyInstantiatedSource/instance}} set to |instance|.
1. [=Resolve=] |promise| with |result|.
1. [=asynchronously instantiate a WebAssembly module|Instantiate the WebAssembly module=] |module| importing |importObject|, and let |innerPromise| be the result.
1. [=Upon fulfillment=] of |innerPromise| with value |instance|.
1. Let |result| be a {{WebAssemblyInstantiatedSource}} dictionary with {{WebAssemblyInstantiatedSource/module}} set to |module| and {{WebAssemblyInstantiatedSource/instance}} set to |instance|.
1. [=Resolve=] |promise| with |result|.
1. [=Upon rejection=] of |innerPromise| with reason |reason|:
1. [=Reject=] |promise| with |reason|.
1. [=Upon rejection=] of |promiseOfModule| with reason |reason|:
1. [=Reject=] |promise| with |reason|.
1. Return |promise|.

Note: It would be valid to perform certain parts of the instantiation [=in parallel=], but several parts need to happen in the event loop, including JavaScript operations to access the |importObject| and execution of the start function.
</div>

<div algorithm>
Expand Down Expand Up @@ -541,6 +544,8 @@ interface Module {
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. [=Construct a WebAssembly module object=] from |module| and |stableBytes|, and return the result.

Note: Some implementations enforce a size limitation on |bytes|. Use of this API is discouraged, in favor of asynchronous APIs.
</div>

<h3 id="instances">Instances</h3>
Expand All @@ -553,7 +558,9 @@ interface Instance {
</pre>

<div algorithm>
The <dfn constructor for="Instance">Instance(|module|, |importObject|)</dfn> constructor, when invoked, [=instantiate a WebAssembly module|instantiates the WebAssembly module=] |module| importing |importObject| and returns the result.
The <dfn constructor for="Instance">Instance(|module|, |importObject|)</dfn> constructor, when invoked, [=synchronously instantiate a WebAssembly module|synchronously instantiates the WebAssembly module=] |module| importing |importObject| and returns the result.

Note: The use of this synchronous API is discouraged, as some implementations sometimes do long-running compilation work when instantiating.
</div>

<div algorithm>
Expand Down

0 comments on commit 9258c3f

Please sign in to comment.