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

Support WebAssembly Core Specification 2.0 #484

Closed
codefromthecrypt opened this issue Apr 19, 2022 · 5 comments · Fixed by #644
Closed

Support WebAssembly Core Specification 2.0 #484

codefromthecrypt opened this issue Apr 19, 2022 · 5 comments · Fixed by #644

Comments

@codefromthecrypt
Copy link
Contributor

codefromthecrypt commented Apr 19, 2022

Right now, we support WebAssembly Core Specification 1.0 and a few features that were marked finished, but not in a spec yet. While not recommendation phase, yet, there is a draft for 2.0 which helps us group which features will be in it. I think we can assume no more or less features will end up in that version.

https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/appendix/changes.html#release-1-1

Change Status Feature Proposal
Sign extension instructions sign-extension-ops
Non-trapping float-to-int conversions nontrapping-float-to-int-conversions
Multiple values multi-value
Reference types reference-types
Table instructions reference-types
Multiple tables reference-types
Bulk memory and table instructions bulk-memory-operations
Vector instructions simd
@codefromthecrypt
Copy link
Contributor Author

PS if anyone needs 2.0, please comment what tools you are using that target 2.0 and what use case and priority (timeline) it is for you. If you can workaround meanwhile with one of the features (as opposed to all of them), please note that too!

@codefromthecrypt codefromthecrypt mentioned this issue Apr 25, 2022
13 tasks
@codefromthecrypt
Copy link
Contributor Author

ok revised the description

mathetake added a commit that referenced this issue May 3, 2022
This commit adds support for multiple tables per module.
Notably, if the WithFeatureReferenceTypes is enabled,
call_indirect, table.init and table.copy instructions
can reference non-zero indexed tables.

part of #484

Signed-off-by: Takeshi Yoneda <[email protected]>
@codefromthecrypt
Copy link
Contributor Author

codefromthecrypt commented May 4, 2022

TL;DR: we audited the new value types: externref and i128 and decided to continue use of encoding any and all value types as uint64 (for the purpose of api.Function.Call).

This means anyone invoking an exported function that has a vector ops parameter (i128) needs to split the 128bit vector (ex. i32x4) into two 64bit vectors (ex. 32x4[0,1], i32x4[2,3]). Based on research, we think this is an edge case and can help anyone with this if they ask.


We had lots of chats over the last couple days on how to handle the value types added to WebAssembly 2.0. The concern is the host function boundaries, and that can be split into two

  • define host function: How to declare parameters for host functions using new value types
  • call function: How to call exported functions whose signature includes new value types.

The new types are:

  • externref which is a possibly nil opaque reference to a host pointer. In go, 64 bits should work.
  • I128 currently only used for vectors (ex. v128.const) which are N (possibly 1) values packed into 128 bits. Ex. i32x4.

The biggest deal here is how important the i128bit type is to be represented as a single unit in our exported API, as opposed to split into two uint64s, representing the high and low 64bits. Remember for this discussion, the only use of this in WebAssembly 2.0 is vector instructions. There are no other proposals included in WebAssembly 2.0 that would use these.

The first question: is this a problem internally?, and it isn't. Function types are knowable before use, so it is not difficult to track how many units of 64bits should be pushed or popped from a stack. We also don't forsee any problem in JIT accessing these values.

Next, should we define host function type parameter binding for an i128? Remember this is as opposed to func hostFunc(vectorHi, vectorLo uint64) which is awkward.. Should we allow the same inbound as a single parameter, ex vector []byte or vector [16]byte? Do we have to decide this now, knowing the only use is vector ops? The decision made here is to defer it until a user asks concretely for code that uses vector ops and needs to be written as a host function. We feel changing the parser later can be done compatibly anyway and solving this in a use-case bound way is better than guessing.

Finally, and the biggest decision is do we break the function call API over this? It currently uses exclusively uint64 for parameter and return type. Ex. Call(ctx context.Context, params ...uint64) ([]uint64, error). It would be confusing to pass a different number of values than the signature suggests (in order to materialize one parameter as a 128bit vector). Similar to the host function definition problem, we also think that in the context of 2.0, where only vector types use 128-bit values, this can be punted. Meanwhile we can instruct with docs or an API how to construct 2 units give 128bits. Again similar to the problem described in the above paragraph, we don't know how a user would choose to represent the 128-bit value until they do, and they might have chosen to represent it as two uint64 anyway!

Moreover, we expect to eventually make a codegen solution for function call binding. In that case there are even less cause for concern about this as only generated code would deal with invoking "Call". However, we still need to learn if anyone would ever use i128bit for vector ops outside wasm (in a host function), and guessing ahead of time would result in tech debt.

mathetake added a commit that referenced this issue May 10, 2022
This commit completes the reference-types proposal implementation.

Notably, this adds support for 
* `ref.is_null`, `ref.func`, `ref.is_null` instructions
* `table.get`, `table.set`, `table.grow`, `table.size` and `table.fill` instructions
* `Externref` and `Funcref` types (including invocation via uint64 encoding).

part of #484

Signed-off-by: Takeshi Yoneda <[email protected]>
@mathetake
Copy link
Member

ok now the left is SMID proposal impl! 👯

mathetake added a commit that referenced this issue May 12, 2022
This commit enables WebAssembly 2.0 Core Specification tests.
In order to pass the tests, this fixes several places mostly on the
validation logic.

Note that SIMD instructions are not implemented yet.

part of #484

Signed-off-by: Takeshi Yoneda <[email protected]>
Co-authored-by: Crypt Keeper <[email protected]>
mathetake added a commit that referenced this issue May 16, 2022
This commit implements the v128.const, i32x4.add and i64x2.add in
interpreter mode and this adds support for the vector value types in the
locals and globals.

Notably, the vector type values can be passed and returned by exported functions
as well as host functions via two-uint64 encodings as described in #484 (comment).

Note: implementation of these instructions on JIT will be done in subsequent PR.

part of #484

Signed-off-by: Takeshi Yoneda <[email protected]>
mathetake added a commit that referenced this issue Jun 1, 2022
This implements various SIMD instructions related to
load, store, and lane manipulations for all engines.

Notablely, now our engines pass the following specification tests:

* simd_address.wast
* simd_const.wast
* simd_align.wast
* simd_laod16_lane.wast
* simd_laod32_lane.wast
* simd_laod64_lane.wast
* simd_laod8_lane.wast
* simd_lane.wast
* simd_load_extend.wast
* simd_load_splat.wast
* simd_load_zero.wast
* simd_store.wast
* simd_store16_lane.wast
* simd_store32_lane.wast
* simd_store64_lane.wast
* simd_store8_lane.wast

part of #484


Signed-off-by: Takeshi Yoneda <[email protected]>
Co-authored-by: Adrian Cole <[email protected]>
@mathetake
Copy link
Member

mathetake commented Jun 21, 2022

#644 completes arm64 backend for SIMD, therefore closing this long-standing issue!

mathetake added a commit that referenced this issue Jun 21, 2022
This completes the implementation of arm64 backend for SIMD instructions.
Notably, now the arm64 compiler passes 100% of WebAssemby 2.0 draft
specification tests.

Combined with the completion of the interpreter and amd64 backend (#624),
this finally resolves #484. Therefore, this also documents that wazero is
100% compatible with WebAssembly 1.0 and 2.0.

Signed-off-by: Takeshi Yoneda <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants