Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use WebAssembly.instantiateStreaming instead of WebAssembly.compileStreaming #6433

Closed
linclark opened this issue Feb 1, 2018 · 50 comments
Closed

Comments

@linclark
Copy link

linclark commented Feb 1, 2018

Unfortunately there are performance issues with WebAssembly.compileStreaming on iOS. On iOS devices, there is a limited amount of faster memory. Because of this, the engine doesn't know which kind of memory to compile for until instantiate is called.

If I understand correctly, for the JSC engine compileStreaming will just do a memcopy of the .wasm. It's only when instantiate is called that the Memory object is created. Then the engine knows whether it will be using the fast memory, or just a normal malloc'd Memory that needs bounds checks. At this point, it can generate the code appropriately.

Because of this, we plan to recommend that all bundlers use instantiateStreaming instead. Does this cause any issues for webpack?

@sokra
Copy link
Member

sokra commented Feb 6, 2018

yes there are multiple issues with that:


Pre-knowledge:

webpack tries to treat WASM like ESM.
We try to apply all rules/assumptions that apply to ESM to WASM too.
We assume that in future the WASM JS API may be superseeded by a integration of WASM into the ESM module graph.

This means the imports section in the WASM file is resolved like import statements in ESM and the export section is treated like export in ESM.

WASM modules also have a start section, which is executed when the WASM is instantiated.

In the WASM JS API imports are passed via importsObject to the instantiate method.


The ESM spec specifies multiple phases. One phase is the ModuleEvaluation. In this phase all modules are evaulated in the well defined order. This phase is synchronous. All modules evaluate in the same "tick".

When WASM are in the module graph this means:

  1. the start section is executed in the same "tick"
  2. all dependencies of the WASM are executed in the same "tick"
  3. the ESM importing the WASM is executed in the same "tick"

This behavior is not possible when using the Promise-version of instantiate. A Promise always delays it's fulfillment into another "tick".

It's only possible when using a sync version of instantiate (WebAssembly.Instance).

Note: Technically there could be a WASM without start section and without dependencies. In this case this doesn't apply. But we can't assume this is always the case.


webpack wants to download and compile the WASM in parallel to downloading the JS code. Using instantiateStreaming won't allow this (when the WASM has dependencies), because instantiate requires passing a importsObject. Creating the importsObject requires evaluating all dependencies/imports of the WASM, so these dependencies need to be downloaded before starting to download the WASM.

When using compileStreaming + new WebAssembly.Instance parallel download and compile is possible, because compileStreaming doesn't require an importsObject. The importsObject can be created when WASM and JS download has finished.


I also want to quote the WebAssembly spec. It states that compilation happens in a background thread in compile and instantiation happens on the main thread.

It's not clearly stated but in my optinion JSC's behavior is not spec-comform.


Other notes:

WASM also lacks the ability to use live bindings of imported identifiers. Instead the importsObject is spec'ed to be copied. This could have weird problems with circular dependencies and WASM.

It would be great to support getters in the importsObject and the be able to get the exports before the start section is executed.

@TheLarkInn
Copy link
Member

cc @jsbastien @flagxor @rossberg I wanted to surface this to you all in hopes maybe we can bring this up for the next WASM CG Meeting if discussions are involved. Primarily around the above concerns.

@jfbastien
Copy link

This is worth discussing at the next CG meeting. @TheLarkInn, would you mind adding to the agenda (once it's posted... we just had the meeting today so I haven't created the agenda yet)?

To answer a few points:

  1. I think treating WebAssembly like ECMAScript modules is the right thing to do. The JSC implementation uses exactly the same C++ code under the hood, so our behavior should match up very well. Same as ESM, export are handled when the JS object is created (but before execution returns), import is handled at "link" time, and start is called during "evaluate" (after tables and memories have been initialized). That's what I think WebAssembly should standardize as ESM integration.
  2. IIUC the main issue you're encountering is that you can't inject yourself between object creation and link, correct? ESM just do it by construction, so even circular imports work.
  3. I assume that having the import object as an extra indirection layer is a no-go (especially if you link wasm-wasm with i64)?

Interesting points on the spec. It's not final and I don't think this wording is accurate. It cannot mandate parallelism (unless parallel == 1 is OK). It does not mandate that all compilation be performed (disallowing any future compilation), and cannot either because that would prevent having an interpreter or tiering (so Chakra and SpiderMonkey would then not conform either).

@kmiller68
Copy link

@sokra For what it's worth, the original design of Wasm actually differs from what is in the initial spec. See the pull request on the design: WebAssembly/design#1018. I'm not sure where this got lost in the transition to the formal spec but I'll file an issue.

@TheLarkInn
Copy link
Member

@kmiller68, so are you saying both methods can be used in paralell?

@lukewagner
Copy link

To discourage devs from using the sync WebAssembly.Instance and Module ctors (which, do sync compilation on various engines), Chrome currently throws when these constructors are called with modules bigger than an internal limit (4kb, last I saw). So that, combined with the fact that it's the worst-case load-time behavior for JSC, means sync new Instance should not be used by bundlers.

The ESM spec specifies multiple phases. One phase is the ModuleEvaluation. In this phase all modules are evaulated in the well defined order. This phase is synchronous. All modules evaluate in the same "tick".

I wasn't aware of this spec requirement, but you seem to be quite right!

So given these two constraints, could WebPack:

  1. rewrite the .wasm to remove the start section and add the start function as an export
  2. call WebAssembly.instantiateStreaming() during the instantiation phase
  3. call the previously-start function synchronously during the evaluation phase

To break most cycles involving functions, I would imagine instantiateStreaming being passed shim functions that call the real imported function via a mutable var that gets filled in later.

The main problems with this are:

  1. direct .wasm->.wasm imports (and avoiding serializing instantiateStreaming requrests)
  2. non-function (i.e., memory, table, global) wasm imports (for which the above shim-calling-a-var trick won't work)

While there are future JS API extensions we've discussed that could address some of these cases, I think it might be ok for a bundler to simply reject these cases (i.e., issue a build error) for now:

  • the point of treating a .wasm as an ESM is to use it from JS; wasm-to-wasm linkage is achieved more efficiently via static linking (lld) or LTO; dynamic linking isn't well-supported atm
  • as long as dynamic linking isn't well supported, .wasm modules either define their own memory/table or import them directly from a generated glue ESM; there isn't inter-.wasm Memory/Table sharing

However, if these cases are or become important, I think they could be made to work, with some effort; happy to talk more about that.

@sokra
Copy link
Member

sokra commented Feb 15, 2018

rewrite the .wasm to remove the start section and add the start function as an export

I also thought about that, but that only works great when WASM has no dependencies.

shim functions
direct .wasm->.wasm imports

Shim function would really defeat future performance improvements in JS engines. I think wasm-to-wasm calls will get optimized in engines soon. The benefit of not going through the JS stack is big (afaik at least for v8). (cc @mstarzinger)

non-function

This would break a lot of good stuff in WASM. No memory sharing, no tables...


In my opinion this is not a good way to go. I guess I'll stay with the sync Instance call for now. (Maybe using instantiateStreaming for WASM without start and only function imports from JS.) I hope browsers will allow sync Instance > 4kb. I mean they can still do off-thread compilation in compile and off-thread lazy optimization after instantiation... This works for JS why should it be a problem for WASM.

@lukewagner
Copy link

I also thought about that, but that only works great when WASM has no dependencies.

Are there any problems in addition to what is already being discussed?

Shim function would really defeat future performance improvements in JS engines. I think wasm-to-wasm calls will get optimized in engines soon. The benefit of not going through the JS stack is big (afaik at least for v8). (cc @mstarzinger)

When I mentioned shim functions, this was for JS↔wasm imports; and even then they weren't always necessary; just to break cycles. I gave some reasons above why I don't expect wasm↔wasm imports to be common at the bundler stage; have you seen any indications otherwise?

By the time wasm↔wasm imports have become common, we can have increased the expressiveness of JS API (in ways already proposed, e.g., allowing instantiate to accept Promises for imported values) or simply have native ESM-wasm integration.

non-function

This would break a lot of good stuff in WASM. No memory sharing, no tables...

Similarly, until dynamic linking starts being used, every module (or .wasm+.js glue pair) will have its own memory/table, so I don't think we need to worry about multiple .wasm's sharing the same memory/table in the initial support.

That being said, if you wanted to do extra work and support this, it would be possible with another simple .wasm rewrite: convert the module that defines the memory/table to instead import and then create the memory/table in the JS glue code so they can be imported.


I guess I'll stay with the sync Instance call for now. (Maybe using instantiateStreaming for WASM without start and only function imports from JS.) I hope browsers will allow sync Instance > 4kb.

Then in practice WebPack wasm integration won't work on Chrome and will have worst-case load-time performance on Safari; that seems pretty unattractive. I think it's important not to let the perfect be the enemy of the good here: we're talking about very simple configurations of .wasm modules for the first few years that could easily and optimally use today's instantiateStreaming.

@jdalton
Copy link
Contributor

jdalton commented Feb 15, 2018

@lukewagner The 4 kB limit is a super bummer.
Do you know if that applies to the API exposed in Node too?

@lukewagner
Copy link

Sorry, I don't

@jdalton
Copy link
Contributor

jdalton commented Feb 15, 2018

For my use case I need the synchronous form for CJS to allow migrating to the asynchronous ESM form. But without the synchronous option I can't really offer the ESM form any time soon since there's no migration path.

The 4 kB limit seems odd since the file is already downloaded, so not blocking for network. It's just CPU crunching which could be done in something like a web worker.

Update:

Grabbing some larger wasm payloads, 15 kB and 41 kB, I was able to get output from:

WebAssembly.Module.exports(new WebAssembly.Module(fs.readFileSync("./large.wasm")))

Which I'm guessing means there is no restriction there (a good thing).

@rossberg
Copy link

@jdalton, a web worker only helps if it can run concurrently, which necessitates an asynchronous API.

Still, not everybody is happy with the 4kB limit for synchronous compilation. Web platform folks felt very strongly about it, though. I don't actually know if V8 activates it on Node as well.

@jdalton
Copy link
Contributor

jdalton commented Feb 15, 2018

A web worker can run the synchronous Module call off the UI thread. I think the 4 kB limit is a step too far. We get it, synchronous isn't ideal, but it has a place. Putting a blocker in it like this is stop-energy that hinders adoption and worse fosters bad feels among those folks with the ecosystem impact to encourage or discourage further adoption.

@rossberg
Copy link

What's the point of off-loading to another thread when the UI thread has to block on that other thread finishing?

Agreed with the rest.

@jdalton
Copy link
Contributor

jdalton commented Feb 15, 2018

What's the point of off-loading to another thread when the UI thread has to block on that other thread finishing?

I'm not going to bikeshed various web worker implementations. You get the gist, it's gravy when you can offload to another thread for crunching.

Agreed with the rest.

🙌

@lukewagner
Copy link

@jdalton Just confirmed also; I guess it's a browser-only limitation.

@sokra
Copy link
Member

sokra commented Feb 19, 2018

When I mentioned shim functions, this was for JS↔wasm imports; and even then they weren't always necessary; just to break cycles.

cycles are not the problem in this case (they are another problem).

Consider a part of you application is loaded on demand and contains WASM (this is always the case with webpack when using WASM). Assuming the WASM module depends on some other JS module in that part of the application.

When the user requests that part of the application I want to start downloading the JS and the WASM. I also want to prepare the WASM to be used. This could happen in parallel.

Now the problem with instanciateStreaming. You need to pass all imports to instanciateStreaming. But these imports do come from the JS module which should be loaded in parallel. I could solve this with shim functions, but I always need them.

Using compileStreaming + sync Instance make parallel download and compilation possible.

I gave some reasons above why I don't expect wasm↔wasm imports to be common at the bundler stage; have you seen any indications otherwise?

I my opinion this it not uncommon. I imagine the WASM future as many small WASM modules interleaved with JS modules. WASM to WASM is possible and great, because you could pass complex binary objects between them instead of converting to JS values. Many WASM modules can share a memory WASM module (which gives you alloc and free) and pass pointer around. WASM-to-WASM is great and we shouldn't limit or prevent it.

as long as dynamic linking isn't well supported

Everything for dynamic linking with imports and exports are in place. Any performance issues left with this could be easily solved. In my option this is the way to go.

I favor dynamic linking over static linking because:

  • Code Splitting works great with ti
  • Static linking can be an optimization on top of the dependency graph and dynamic linking

Dynamic linking should be the way you author WASM.

Are there any problems in addition to what is already being discussed?

You may use WASM from CommonJS, conditionally:

if(Math.random() < 0.5)
  require("./something.wasm");

This must execute sync. In this case webpack calls compileStreaming while chunk load and new Instance when the module is actually used.

Are there any problems in addition to what is already being discussed?


My conclusion:

The ESM spec requires sync evaluation, that's only possible with new WASM.Instance, while keeping the full WASM feature set.

Either the ESM spec is changed to allow async evaluation, which is don't recommend.

Or the WASM implementations are changed to allow and support sync instantiate. The WASM spec doesn't have to be changed, it already allows sync instantiate.

Or we give up on the approach to make WASM like ESM.

@rossberg
Copy link

@sokra:

Now the problem with instanciateStreaming. You need to pass all imports to instanciateStreaming. But these imports do come from the JS module which should be loaded in parallel. I could solve this with shim functions, but I always need them.

We have discussed generalising the instantiate function to allow its import object to be a collection of promises of individual objects (or even allow the individual entities to be promises). That should solve the parallel compilation use case without requiring shims.

@lukewagner
Copy link

Ah, ok, I was imagining the JS file that called instantiateStreaming also contained all the JS code (it had already been downloaded), but it sounds like these are in separate files, so I see why function shims would always be needed.

Now the problem with instanciateStreaming. You need to pass all imports to instanciateStreaming.
But these imports do come from the JS module which should be loaded in parallel. I could solve this > with shim functions, but I always need them.

Agreed with @rossberg here, using shims as a polyfill.

I my opinion this it not uncommon. I imagine the WASM future as many small WASM modules interleaved with JS modules. WASM to WASM is possible and great, because you could pass complex binary objects between them instead of converting to JS values. Many WASM modules can share a memory WASM module (which gives you alloc and free) and pass pointer around.

It's not possible to take two arbitrary wasm modules and have them share memory and tables; they have to be specifically compiled (probably with the same toolchain for the same language) to work this way. This is because these wasm modules must carefully coordinate use of linear memory and table index space to avoid clobbering each other and also coordinate and basic impl details like malloc/free. Right now, there is not a non-experimental toolchain that does this that I know of.

Moreover, even when this is possible, I don't think it will be common for multiple wasm ESMs to share memory because it is, I think, a quite good thing for unrelated modules to have separate memories/tables: otherwise there will be subtle corruption bugs that only surface when particular modules are used together, leaks will be hard to track down, and OOMs on 32-bit devices will be more likely due to larger memories. It will probably be a good idea in the future to use dynamic linking to factor out common runtime code (e.g., libc, libm), but in that case it is only the Module being shared between Instances, not the Memory or Table.

Everything for dynamic linking with imports and exports are in place.

Not in the toolchain: it may be possible at the bundler level but, right now, there is not a non-experimental toolchain that will actually emit dynamically-linked wasm code.


Why can't we go with the shims? I think they'll work fine w/ very little overhead (probably zero overhead once the Promise-taking instantiateStreaming is present).

@TheLarkInn
Copy link
Member

TheLarkInn commented Feb 20, 2018 via email

@lukewagner
Copy link

Practically speaking, dynamic linking of unrelated modules (i.e., modules that aren't compiled all together as part of the same program/app/system) requires a stable source-language ABI which doesn't exist for any of compile-to-wasm language I've seen (and probably shouldn't until ABI-affecting wasm features like multiple return values and exception handling land). So I think that's the entire story for the next 1-2 years unless something totally new pops up.

But even after that, I think modules should default to being standalone and defining their own memory. The benefits are basically the same as those for having a microkernel OS architecture:

  • if there is a crash/leak/corruption, it's easy to diagnose who is at fault
  • encourages JS-friendly API using types that don't require sharing memory (like streams, strings, things that copy) instead of low-level APIs that require the JS client to immediately worry about "which address space is this i32 relative to? do I have ownership of this memory and need to free it (and how)?"

We can definitely hypothesize situations where it would be more efficient for modules to share memory, but there are a couple different ways to go about fixing that and it's not clear that a brute-force type of dynamic linking is the right way. It's be useful to have the use cases present to help guide us through this design space since it's inherently in optimization territory.

@sokra
Copy link
Member

sokra commented Feb 20, 2018

Ok I created an extra challenge.

Here is a test case which I believe is impossible to solve without sync Instance.

https://github.com/webpack/webpack/pull/6529/files

The dependency graph looks like this:

a -> tracker
  -> b -> tracker
  -> wasm -> tracker
          -> c

Which results in the following evaluation order according to the ESM: tracker, b, c, wasm, a (all in the same tick)

Feel free to "compile" the test case anyway you like and try using instanciateStreaming. Even when Promises as imports would be allowed, it won't work in my opinion.

But maybe you surprise me with a clever approach and I was wrong.

@mathiasbynens
Copy link
Contributor

FWIW, using WebAssembly.instantiateStreaming where applicable matches Google’s official recommendation on how to load WebAssembly modules efficiently.

@jdalton
Copy link
Contributor

jdalton commented Apr 13, 2018

@mathiasbynens I think that's great for general consumption, however I believe the root issue here is that webpack itself is using synchronous APIs in a more responsible manner (in workers?) and is only being blocked by an arbitrary 4kB limit imposed by Chrome browser specifically. (It's been a while so things might have shifted)

Related: #6475 (comment).

@jfbastien
Copy link

jfbastien commented Apr 13, 2018

@jdalton AFAIK Chrome's 4kB limits on sync compilation should only be in effect for non-main-thread compilation. If that's not the case then it's a bug in Chrome.

@gahaas
Copy link

gahaas commented Apr 13, 2018

@jdalton Synchronous compilation should work in Chrome 66 on workers. There was indeed an issue but it got fixed.

@TheLarkInn
Copy link
Member

TheLarkInn commented Apr 13, 2018 via email

@gahaas
Copy link

gahaas commented Apr 13, 2018

@jdalton I mixed up issues. For me, already in Chrome 65 new WebAssembly.Module works in workers without size limit on the input. If you can send me an example where it does not work, I will investigate that issue.

FYI, I mixed it up with WebAssembly.compiledStreaming, which is only supported in Chrome 66 on workers.

@mathiasbynens
Copy link
Contributor

@jfbastien

AFAIK Chrome's 4kB limits on sync compilation should only be in effect for non-main-thread compilation.

The opposite is true: the 4 KB size limits only apply on the main thread. There are no limits in workers. https://cs.chromium.org/chromium/src/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc?l=437 (I guess you meant s/non-//?)

@jfbastien
Copy link

Yes.

@sokra
Copy link
Member

sokra commented May 13, 2018

This is fixed. We now use instantiateStreaming when possible. Falling back to compileStreaming + async instantiate for WASM-to-WASM dependency chains.

Falling back non-streaming variants when streaming is not supported by the browser.

@sokra sokra closed this as completed May 13, 2018
@sokra
Copy link
Member

sokra commented May 13, 2018

Note: adding Promise support to the importsObject would allow us to remove the compileStreaming + async instantiate fallback.

@cars10
Copy link

cars10 commented Jul 1, 2018

Can someone post an example about how to correctly import wasm now?

A simple

import * as wasm from 'hello_world.gc.wasm'

does not seem to work.

@xtuc
Copy link
Member

xtuc commented Jul 1, 2018

@cars10 do you have an error?

littledan added a commit to littledan/spec that referenced this issue Sep 7, 2018
On JSC, some compilation work takes place the first time that a
Module is instantiated. If the module is instantiated in an
asynchronous way, the work happens off the main thread. This patch
loosens the specification of WebAssembly module instantiation
to permit this specific type of delay.

Based on skimming the code (but not running tests), I believe that
the new specification matches 3/4 of the implementations I examined.
The one which might not fit is V8, which defers reading properties
of the import object to a microtask queue item at the beginning
of WebAssembly.instantiate(Module), unlike the others, which read it
synchronously.

The previous specification didn't match any implementations, as it
specified to queue an HTML task at the beginning of the
WebAssembly.instantiate(Module) method, which no implementation
actually did to my knowledge. Punting to a queue there doesn't really
serve any purpose and was simply an error in drafting the previous
specification.

Closes WebAssembly#741
See also webpack/webpack#6433
littledan added a commit to littledan/spec that referenced this issue Mar 1, 2019
On JSC, some compilation work takes place the first time that a
Module is instantiated. If the module is instantiated in an
asynchronous way, the work happens off the main thread. This patch
loosens the specification of WebAssembly module instantiation
to permit this specific type of delay.

Based on skimming the code (but not running tests), I believe that
the new specification matches 3/4 of the implementations I examined.
The one which might not fit is V8, which defers reading properties
of the import object to a microtask queue item at the beginning
of WebAssembly.instantiate(Module), unlike the others, which read it
synchronously.

The previous specification didn't match any implementations, as it
specified to queue an HTML task at the beginning of the
WebAssembly.instantiate(Module) method, which no implementation
actually did to my knowledge. Punting to a queue there doesn't really
serve any purpose and was simply an error in drafting the previous
specification.

Closes WebAssembly#741
See also webpack/webpack#6433
Ms2ger pushed a commit to Ms2ger/spec that referenced this issue Mar 18, 2019
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
Ms2ger pushed a commit to Ms2ger/spec that referenced this issue Mar 18, 2019
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
Ms2ger pushed a commit to littledan/spec that referenced this issue Mar 18, 2019
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
Ms2ger pushed a commit to littledan/spec that referenced this issue Sep 3, 2019
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
Ms2ger pushed a commit to littledan/spec that referenced this issue Sep 23, 2022
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
Ms2ger pushed a commit to WebAssembly/spec that referenced this issue Feb 17, 2023
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 #741
See also webpack/webpack#6433
Ms2ger pushed a commit to tomstuart/WebAssembly-spec that referenced this issue Feb 21, 2023
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
Ms2ger pushed a commit to WebAssembly/spec that referenced this issue Feb 21, 2023
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 #741
See also webpack/webpack#6433
rossberg pushed a commit to WebAssembly/multi-memory that referenced this issue Mar 1, 2023
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 #741
See also webpack/webpack#6433
dhil added a commit to effect-handlers/wasm-spec that referenced this issue Mar 17, 2023
* [spec] Add reference types to overview (WebAssembly#1394)

* [interpreter] Remove use of physical equality on characters (WebAssembly#1396)

* Merge SIMD proposal (WebAssembly#1391)

SIMD is [phase 5](WebAssembly/simd#507), merge all the changes back into main spec.

* Remove merge conflict marker

* [spec] Handle v128 in validation algorithm (WebAssembly#1399)

* [spec] Fix instruction table (WebAssembly#1402)

* Add tests for functions without end marker. NFC (WebAssembly#1405)

Inspired by this downstream test in wabt:
WebAssembly/wabt#1775

Fixes: WebAssembly#1404

* Describe correct tail call behavior across modules

Whether tail calls across module boundaries would guarantee tail call behavior was previously an open question, but @thibaudmichaud confirmed that they would guarantee tail call behavior in V8 in WebAssembly/tail-call#15 (comment).

* [interpreter] Fix a typo in README (WebAssembly#1406)

* Add a link to the proposals repo (WebAssembly#1409)

Fixes WebAssembly#1407.

* [spec] Add note regarding parameter names (WebAssembly#1412)

* Comments WIP

* Merge upstream (WebAssembly#55)

* Typo

* [spec] Clarifying note on text format (WebAssembly#1420)

Signed-off-by: Adrian Cole <[email protected]>
Co-authored-by: Andreas Rossberg <[email protected]>

* Eps

* Eps

* [test] Fix section size in binary test (WebAssembly#1424)

* Update document README to install six

* Disallow type recursion (WebAssembly#56)

* Fix import order

* Add --generate-js-only flag to test runner

This will return early right after generating JS from the wast test
files. It will not attempt to run the tests, or do the round trip
conversion from wasm <-> wast.

This is convenient for proposals to add tests without having to
update the reference interpreter with implementation, and generate those
tests to JS to run in other Wasm engines.

Fixes WebAssembly#1430.

* Remove use of let from func.bind test

* Add call3

* [spec] Fix missing mention of vectype (WebAssembly#1436)

Fixed WebAssembly#1435.

* [spec] Fix single-table limitation in module instantiation (WebAssembly#1434)

* [spec] Fix missing immediate on table.set (WebAssembly#1441)

* [docs] Update syntax in examples (WebAssembly#1442)

* Clarification in proposals README

* [interpreter] Tweak start section AST to match spec

* [spec] Bump release to 2 (WebAssembly#1443)

At yesterday's WG meeting, we decided to make a new release, now switching to the Evergreen model. For administrative and technical reasons having to do with W3C procedure, we decided to bump the release number to 2.

From now on, the standard will iterate at version 2 from the W3C's official perspective. We use minor release numbers internally to distinguish different iterations.

(@ericprud, I hope I understood correctly that the Bikeshed "level" also needed to be bumped to 2.)

* Remove test cases with let

* Sync wpt test (WebAssembly#1449)

* [spec] Fix typo (WebAssembly#1448)

* [proposals] Add missing start to example (WebAssembly#1454)

* [spec] "version 2.0" -> "release 2.0" (WebAssembly#1452)

* [spec] Fix typo (WebAssembly#1458)

* [test] Add assert_trap for unreached valid case (WebAssembly#1460)

* [interpreter] Name the type Utf8.unicode

* [spec] Fix binary format of data/elem tags to allow LEB (WebAssembly#1461)

* [spec] Fix typos in numeric operations (WebAssembly#1467)

* [spec] Fix syntax error in element segments validation rule (WebAssembly#1465)

* [spec] Fix typo in global instance syntax (WebAssembly#1466)

* [spec] Fix typos in module instantiation (WebAssembly#1468)

* [interpreter] Turn into a Dune package (WebAssembly#1459)

* [spec] Fix typos in instruction validation rules (WebAssembly#1462)

* [bib] Update latex .bib file for webassembly 2.0 (WebAssembly#1463)

* [spec] Add missing default for vector types (WebAssembly#1464)

* [spec] Fix typos in binary and text formats (WebAssembly#1469)

* [spec] Fix various typos (WebAssembly#1470)

* TypeError for Global constructor with v128

At the moment the spec requires a `LinkError` to be thrown when the `WebAssembly.Global` constructor is called for type `v128`. This was introduced in WebAssembly/simd#360, but according to the PR description, actually a `TypeError` should be thrown. The PR refers to https://github.com/WebAssembly/simd/blob/master/proposals/simd/SIMD.md#javascript-api-and-simd-values, and there a `TypeError` is required.

* [spec] Fix LEB opcodes in instruction index (WebAssembly#1475)

* [spec] Fix v128.loadX_splat in instruction index (WebAssembly#1477)

* [interpreter] Dune test suite (WebAssembly#1478)

* [interpreter] Fix warning flags for OCaml 4.13 (WebAssembly#1481)

* [interpreter] Simplify lexer and avoid table overflow on some architectures (WebAssembly#1482)

* [spec] Editorial nit (WebAssembly#1484)

* [interpreter] Produce error messages in encoder (WebAssembly#1488)

* [spec] Add missing close paren on table abbreviation (WebAssembly#1486)

Also remove an unnecessary space in the previous table abbreviation.

* [spec] Remove outdated note (WebAssembly#1491)

* Eps

* [interpreter] Factor data and element segments into abstract types (WebAssembly#1492)

* [spec] Update note on module initialization trapping (WebAssembly#1493)

* Fix type equality

* Fix typo

* [spec] Add note about control stack invariant to algorithm (WebAssembly#1498)

* [spec] Tweak tokenisation for text format (WebAssembly#1499)

* [test] Use still-illegal opcode (func-refs) (WebAssembly#1501)

* Fix minor typos and consistency issues in the validation algorithm. (WebAssembly#61)

* Add definition of defaultable types (WebAssembly#62)

No rules for locals yet, since those are still being discussed.

* Remove func.bind (WebAssembly#64)

* Implement 1a (WebAssembly#63)

* Subtyping on vector types & heap bottom check (WebAssembly#66)

* [interpreter] Bring AST closer to spec

* [spec] Fix typo (WebAssembly#1508)

* WIP

* Remove polymorphic variants

* Minor syntactic consistency fix (WebAssembly#68)

Change pseudo equality operator from `==` to `=`.

* Bump version

* [spec] Fix table.copy validation typo (WebAssembly#1511)

* More fixes

* Fix Latex

* Adjust intro

* Spec local initialization (WebAssembly#67)

* Add table initialiser (WebAssembly#65)

* [spec] Remove outdated note (WebAssembly#1491)

* [interpreter] Factor data and element segments into abstract types (WebAssembly#1492)

* [spec] Update note on module initialization trapping (WebAssembly#1493)

* [spec] Add note about control stack invariant to algorithm (WebAssembly#1498)

* [spec] Tweak tokenisation for text format (WebAssembly#1499)

* [test] Use still-illegal opcode (func-refs) (WebAssembly#1501)

* [spec] Fix typo (WebAssembly#1508)

* [spec] Fix table.copy validation typo (WebAssembly#1511)

* Merge fallout

* Latex fixes

* [spec] Minor copy edit (WebAssembly#1512)

* Spec changelog

* [spec] Trivial editorial fix

* Update embedding

* Oops

* Argh

* Rename Sem to Dyn

* Readd match.mli

* [interpreter] Build wast.js with Js_of_ocaml (WebAssembly#1507)

* [interpreter] Add flag for controlling call budget

* Spec zero byte

* Fix table/elem expansion (WebAssembly#71)

* Fix merge artefact

* Restrict init from stack-polymorphism (WebAssembly#75)

* [spec] Simplify exec rule for if (WebAssembly#1517)

* [spec] Formatting tweak (WebAssembly#1519)

* [spec] Fix typing rule in appendix (WebAssembly#1516)

* [spec] Fix “invertible” typo (WebAssembly#1520)

* [spec] Correct use of opdtype and stacktype (WebAssembly#1524)

* [spec] Add note to instruction index (WebAssembly#1528)

* Add type annotation to call_ref (WebAssembly#76)

* [spec] Tweak wording to avoid first person

* Eps

* Eps2

* Eps3

* Remove unneeded assumption type

* [spec/test] Fix scoping of non-imported globals (WebAssembly#1525)

* Fix test

* A couple of tests

* Performance improvement

* Typo

* Another typo

* [spec] Fix language config

* Fix null subtyping being wrong way around (WebAssembly#79)

* [spec] Fix naming typo (WebAssembly#1532)

* Defunctorise types again

* [spec] Add citation for WasmCert (WebAssembly#1533)

* [test] Fix async_index.js

* [test] Enable the i64 tests in imports.wast.

Fixes WebAssembly#1514.

* Minor tweak

* [js-api][web-api] Editorial: Fix some minor issues.

Fixes WebAssembly#1064.

* Update README.md (WebAssembly#1540)

Improve wording.

* [spec] Fix typo in element execution (WebAssembly#1544)

* [spec] Remove obsolete note (WebAssembly#1545)

* cccccc[klghketetivvtnnhvntikigrnueuhdkkukljgjuest/meta/generate_*.js: sync upstream JS with tests (WebAssembly#1546)

* [spec] Editorial tweak

* [test] test segment/table mismatch and externref segment (WebAssembly#1547)

* [interpreter] Remove duplicate token declarations (WebAssembly#1548)

* Update Soundness appendix (WebAssembly#72)

* [spec] Formatting eps

* Remove oboslete note in README (WebAssembly#82)

* Add `print_i64` to generated spec tests

WebAssembly@82a613d added `print_i64` to the standalone test files, but not to the ones generated by the spec interpreter.

* [test] Tweak binary-leb128 and simd_lane (WebAssembly#1555)

* [spec] Allow explicit keyword definitions (WebAssembly#1553)

Rather than describing keyword tokens as always being defined implicitly by terminal symbols in syntactic productions, describe them as being defined implicitly or explicitly. This accounts for the explicit definitions of `offset` and `align` phrases, which are lexically keywords, later in the chapter.

Fixes WebAssembly#1552.

* [js-api] editorial: adjust link for v128 type

* Factor local init tests to local_init.wast; add more (WebAssembly#84)

* Update JS API for no-frills

* [spec] Add missing case for declarative elem segments

Fixes WebAssembly#1562.

* [spec] Hotfix last accidental commit

* [spec] Fix hyperref (WebAssembly#1563)

* [spec] Bump sphinx version to fix Python problem

* [spec] Fix minor errors and inconsistencies (WebAssembly#1564)

* Spacing

* Fix a couple more superfluous brackets

* [spec] Eps

* [interpreter] Refactor parser to handle select & call_indirect correctly (WebAssembly#1567)

* [spec] Remove dead piece of grammar

* [test] elem.wast: force to use exprs in a element (WebAssembly#1561)

* Fix typos in SIMD exec/instructions

* Update interpreter README (WebAssembly#1571)

It previously stated that the formal spec did not exist, but the spec has existed for years now.

* [spec] Remove an obsolete exec step (WebAssembly#1580)

* [test] Optional tableidx for table.{get,set,size,grow,fill} (WebAssembly#1582)

* [spec] Fix abstract grammar for const immediate (WebAssembly#1577)

* [spec] Fix context composition in text format (WebAssembly#1578)

* [spec] Fix label shadowing (WebAssembly#1579)

* Try bumping OCaml

* Try bumping checkout

* Adjust for multi-return

* Tweak reduction rules

* Spec return_call_ref

* Fix

* Text format

* [spec] Fix typos in instruction index (WebAssembly#1584)

* [spec] Fix typo (WebAssembly#1587)

* [spec] Remove inconsistent newline (WebAssembly#1589)

* [interpreter] Remove legacy bigarray linking (WebAssembly#1593)

* [spec] Show scrolls for overflow math blocks (WebAssembly#1594)

* [interpreter] Run JS tests via node.js (WebAssembly#1595)

* [spec] Remove stray `x` indices (WebAssembly#1598)

* [spec] Style tweak for cross-refs

* [spec] Style eps (WebAssembly#1601)

* Separate subsumption from instr sequencing

* State principal types

* Add statements about glbs, lubs, and disjoint hierarchies

* Add missing bot

* [spec] Clarify that atoms can be symbolic (WebAssembly#1602)

* [test] Import v128 global (WebAssembly#1597)

* Update Overview.md

* [js-api] Expose everywhere

* [js-api] Try to clarify NaN/infinity handling. (WebAssembly#1535)

* [web-api] Correct MIME type check. (WebAssembly#1537)

Fixes WebAssembly#1138.

* [ci] Pin nodejs version to avoid fetching failures (WebAssembly#1603)

The issues appears to be related to actions/runner-images#7002.

Co-authored-by: Ms2ger <[email protected]>

* [spec] Add missing value to table.grow reduction rule (WebAssembly#1607)

* [test] Move SIMD linking test to simd dir (WebAssembly#1610)

* Editorial: Clarify the name of the instantiate algorithm.

* Add notes to discourage using synchronous APIs.

* [jsapi] Normative: Always queue a task during asynchronous instantiation

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

* [test] Exception -> Tag in wasm-module-builder.js

The section name has changed to the tag section a few years ago. This
adds the corresponding changes added in
WebAssembly/exception-handling#252 and
WebAssembly/exception-handling#256.

* [spec] Fix reduction rule for label (WebAssembly#1612)

Fix WebAssembly#1605.

* [spec] Clarifying note about canonical NaNs (WebAssembly#1614)

* [spec] Tweak crossref

* [test] Fix invalid section ID tests (WebAssembly#1615)

* [tests] Disable node run for now

* [spec] Don't check in generated index, to avoid spurious merge conflicts

* [spec] Rename script

* [ci] deactivate node run for now

* Fix uses of \to; compositionality

* Fix typo in text expansion

* Follow-up fix

* Fix compilation errors after merge.

This commit fixes the errors introduced by the merge of
function-references/main into this tree.

---------

Signed-off-by: Adrian Cole <[email protected]>
Co-authored-by: Andreas Rossberg <[email protected]>
Co-authored-by: Hans Höglund <[email protected]>
Co-authored-by: Ng Zhi An <[email protected]>
Co-authored-by: Ng Zhi An <[email protected]>
Co-authored-by: Sam Clegg <[email protected]>
Co-authored-by: Thomas Lively <[email protected]>
Co-authored-by: Gabor Greif <[email protected]>
Co-authored-by: Andreas Rossberg <[email protected]>
Co-authored-by: Crypt Keeper <[email protected]>
Co-authored-by: Andreas Rossberg <[email protected]>
Co-authored-by: Ng Zhi An <[email protected]>
Co-authored-by: Ben L. Titzer <[email protected]>
Co-authored-by: Keith Winstein <[email protected]>
Co-authored-by: gahaas <[email protected]>
Co-authored-by: r00ster <[email protected]>
Co-authored-by: Timothy McCallum <[email protected]>
Co-authored-by: Julien Cretin <[email protected]>
Co-authored-by: Julien Cretin <[email protected]>
Co-authored-by: Ole Krüger <[email protected]>
Co-authored-by: Jämes Ménétrey <[email protected]>
Co-authored-by: Ivan Panchenko <[email protected]>
Co-authored-by: Ethan Jones <[email protected]>
Co-authored-by: Ole Krüger <[email protected]>
Co-authored-by: aathan <[email protected]>
Co-authored-by: Alberto Fiori <[email protected]>
Co-authored-by: mnordine <[email protected]>
Co-authored-by: cosine <[email protected]>
Co-authored-by: ariez-xyz <[email protected]>
Co-authored-by: Surma <[email protected]>
Co-authored-by: Asumu Takikawa <[email protected]>
Co-authored-by: Ian Henderson <[email protected]>
Co-authored-by: Tom Stuart <[email protected]>
Co-authored-by: James Browning <[email protected]>
Co-authored-by: whirlicote <[email protected]>
Co-authored-by: Ms2ger <[email protected]>
Co-authored-by: Adam Lancaster <[email protected]>
Co-authored-by: Ömer Sinan Ağacan <[email protected]>
Co-authored-by: B Szilvasy <[email protected]>
Co-authored-by: Thomas Lively <[email protected]>
Co-authored-by: Michael Ficarra <[email protected]>
Co-authored-by: YAMAMOTO Takashi <[email protected]>
Co-authored-by: Thomas Lively <[email protected]>
Co-authored-by: candymate <[email protected]>
Co-authored-by: Bongjun Jang <[email protected]>
Co-authored-by: ShinWonho <[email protected]>
Co-authored-by: 서동휘 <[email protected]>
Co-authored-by: Jim Blandy <[email protected]>
Co-authored-by: Heejin Ahn <[email protected]>
Co-authored-by: Daniel Ehrenberg <[email protected]>
fgmccabe pushed a commit to WebAssembly/js-promise-integration that referenced this issue Mar 5, 2024
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 #741
See also webpack/webpack#6433
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.