| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
| |
This PR is part of a series that adds basic support for the [typed continuations proposal](https://github.com/wasmfx/specfx).
This PR adds continuation types, of the form `(cont $foo)` for some function type `$foo`.
The only notable changes affecting existing code are the following:
- This is the first `HeapType` which has another `HeapType` (rather than, say, a `Type`) as its immediate child. This required fixes to certain traversals that have a flag for being at the toplevel of a type.
- Some shared logic for parsing `HeapType`s has been factored out.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Type annotations on multivalue blocks (and loops, ifs, and trys) are type
indices that refer to function types in the type section. For these type
annotations, the identities of the function types does not matter. As long as
the referenced type has the correct parameters and results, it will be valid to
use.
Previously, when collecting module types, we always used the "default" function
type for multivalue control flow, i.e. we used a final function type with no
supertypes in a singleton rec group. However, in cases where the program already
contains another function type with the expected signature, using the default
type is unnecessary and bloats the type section.
Update the type collecting code to reuse existing function types for multivalue
control flow where possible rather than unconditionally adding the default
function type. Similarly, update the binary writer to use the first heap type
with the required signature when emitting annotations on multivalue control flow
structures. To make this all testable, update the printer to print the type
annotations as well, rather than just the result types. Since the parser was not
able to parse those newly emitted type annotations, update the parser as well.
|
|
|
|
| |
Instead of just reporting the reason and line + column, also log out the element
the error occurred at.
|
|
|
|
|
|
|
|
| |
This instruction was standardized as part of the bulk memory proposal, but we
never implemented it until now. Leave similar instructions like table.copy as
future work.
Fixes #5939.
|
|
|
|
|
|
|
| |
Remove support for the "struct_subtype", "array_subtype", "func_subtype", and
"extends" notations we used at various times to declare WasmGC types, leaving
only support for the standard text fromat for declaring types. Update all the
tests using the old formats and delete tests that existed solely to test the old
formats.
|
|
|
|
|
|
|
|
| |
Globally replace the source string "I31New" with "RefI31" in preparation for
renaming the instruction from "i31.new" to "ref.i31", as implemented in the spec
in https://github.com/WebAssembly/gc/pull/422. This would be NFC, except that it
also changes the string in the external-facing C APIs.
A follow-up PR will make the corresponding behavioral change.
|
|
|
|
| |
Remove the old forms of ref.test and ref.cast that took heap types instead of
ref types and remove the old array.init_static name for array.new_fixed.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Match the spec and parse the shorthand binary and text formats as final and emit
final types without supertypes using the shorthands as well. This is a
potentially-breaking change, since the text and binary shorthands can no longer
be used to define types that have subtypes.
Also make TypeBuilder entries final by default to better match the spec and
update the internal APIs to use the "open" terminology rather than "final"
terminology. Future changes will update the text format to use the standard "sub
open" rather than the current "sub final" keywords. The exception is the new wat
parser, which supporst "sub open" as of this change, since it didn't support
final types at all previously.
|
|
|
|
|
|
|
|
|
|
|
| |
* Allow new syntax for some stringref opcodes
Fixes #5607
* Update stringref text output
* Update tests with new syntax for stringref opcodes
Except in test/lit/strings.wat, to check that the legacy syntax still works.
|
|
|
|
|
|
|
|
|
|
|
| |
* Allow empty `then` and `else` clauses
* Allow standard syntax for `ref.test` and `ref.cast`
Fixes #5795
* Allow size immediate in `array.new_fixed`
Fixes #5769
|
|
|
|
|
|
|
|
|
|
| |
Previously CallRef::finalize() would never update the type of the CallRef, even
if the type of the call target had been refined to give a more precise result
type. Besides unnecessarily losing type information, this could also lead to
validation errors, since the validator checks that the type of CallRef matches
the result type of the target signature.
Fix the bug by updating CallRef's type based on its target signature in
CallRef::finalize() and add a test that depends on this refinalization.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The WasmGC spec will require that the target cast type of br_on_cast and
br_on_cast_fail be a subtype of the input type, but so far Binaryen has not
enforced this constraint, so it could produce invalid modules when optimizations
refined the input to a br_on_cast* such that it was no longer a supertype of the
cast target type.
Fix this problem by setting the cast target type to be the greatest lower bound
of the original cast target type and the current input type in
`BrOn::finalize()`. This maintains the invariant that the cast target type
should be a subtype of the input type and it also does not change cast behavior;
any value that could make the original cast succeed at runtime necessarily
inhabits both the original cast target type and the input type, so it also must
inhabit their greatest lower bound and will make the updated cast succeed as
well.
|
|
|
|
|
| |
Remove old, experimental instructions and type encodings that will not be
shipped as part of WasmGC. Updating the encodings and text format to match the
final spec is left as future work.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Implement support in the type system for final types, which are not allowed to
have any subtypes. Final types are syntactically different from similar
non-final types, so type canonicalization is made aware of finality. Similarly,
TypeMerging and TypeSSA are updated to work correctly in the presence of final
types as well.
Implement binary and text parsing and emitting of final types. Use the standard
text format to represent final types and interpret the non-standard
"struct_subtype" and friends as non-final. This allows a graceful upgrade path
for users currently using the non-standard text format, where they can update
their code to use final types correctly at the point when they update to use the
standard format. Once users have migrated to using the fully expanded standard
text format, we can update update Binaryen's parsers to interpret the MVP
shorthands as final types to match the spec without breaking those users.
To make it safe for V8 to independently start interpreting types declared
without `sub` as final, also reserve that shorthand encoding only for types that
have no strict subtypes.
|
|
|
|
|
|
| |
We have `WasmBinaryBuilder` that read binary into Binaryen IR and
`WasmBinaryWriter` that writes Binaryen IR to binary. To me
`WasmBinaryBuilder` sounds similar to `WasmBinaryWriter`, which builds
binary. How about renaming it to `WasmBinaryReader`?
|
|
|
|
|
|
|
|
|
|
|
|
| |
The final versions of the br_on_cast and br_on_cast_fail instructions have two
reference type annotations: one for the input type and one for the cast target
type. In the binary format, this is represented as a flags byte followed by two
encoded heap types. Upgrade all of the tests at once to use the new versions of
the instructions and drop support for the old instructions from the text parser.
Keep support in the binary parser to avoid breaking users, though. Drop some
binary tests of deprecated instruction encodings that would be more effort to
update than they're worth.
Re-land with fixes of #5734
|
|
|
|
|
|
|
| |
This reverts commit b7b1d0df29df14634d2c680d1d2c351b624b4fbb.
See comment at the end of #5734: It turns out that dropping the old opcodes causes
problems for current users, so let's revert this for now, and later we can figure out
how best to do the update.
|
|
|
|
|
|
|
|
|
|
| |
The final versions of the br_on_cast and br_on_cast_fail instructions have two
reference type annotations: one for the input type and one for the cast target
type. In the binary format, this is represented as a flags byte followed by two
encoded heap types. Since these instructions have been in flux for a while, do
not attempt to maintain backward compatibility with older versions of the
instructions. Instead, upgrade all of the tests at once to use the new versions
of the instructions. Drop some binary tests of deprecated instruction encodings
that would be more effort to update than they're worth.
|
|
|
|
|
|
|
|
|
|
|
| |
See WebAssembly/stringref#46.
This format is already adopted by V8: https://chromium-review.googlesource.com/c/v8/v8/+/3892695.
The text format is left unchanged (see #5607 for a discussion on the subject).
I have also added support for string.encode_lossy_utf8 and
string.encode_lossy_utf8 array (by allowing the replace policy for
Binaryen's string.encode_wtf8 instruction).
|
|
|
|
|
|
|
|
|
|
|
| |
Data/Elem (#5692)
ArrayNewSeg => ArrayNewSegData, ArrayNewSegElem
ArrayInit => ArrayInitData, ArrayInitElem
Basically we remove the opcode and use the class type to differentiate them.
This adds some code but it makes the representation simpler and more compact in
memory, and it will help with #5690
|
|
|
|
|
| |
These complement array.copy, which we already supported, as an initial complete
set of bulk array operations. Replace the WIP spec tests with the upstream spec
tests, lightly edited for compatibility with Binaryen.
|
|
|
|
|
|
|
|
|
|
| |
All top-level Module elements are identified and referred to by Name, but for
historical reasons element and data segments were referred to by index instead.
Fix this inconsistency by using Names to refer to segments from expressions that
use them. Also parse and print segment names like we do for other elements.
The C API is partially converted to use names instead of indices, but there are
still many functions that refer to data segments by index. Finishing the
conversion can be done in the future once it becomes necessary.
|
|
|
|
| |
The pretty-printer will still serialize these using the old
func_subtype, array_subtype, and struct_subtype syntax, though.
|
|
|
|
| |
This code predates our adoption of C++14 and can now be removed in favor of
`std::make_unique`, which should be more efficient.
|
|
|
|
|
|
|
|
|
| |
Add spec/bulk-array.wast, which contains an outline of the tests that will be
necessary for the upcoming bulk array instructions: array.copy (already
implemented), array.fill, array.init_data, and array.init_elem. Although the
test file does not actually contain any tests yet, it contains some setup code
defining types, globals, and element segments that the tests will use. Fix
miscellaneous bugs in parsing, validation, and printing to allow this setup code
to run without issues.
|
|
|
|
|
|
|
|
|
| |
This is a (more) standard name for `array.init_static`. (The full upstream name
in the spec repo is `array.new_canon_fixed`, but I'm still hoping we can drop
`canon` from all the instruction names and it doesn't appear elsewhere in
Binaryen).
Update all the existing tests to use the new name and add a test specifically to
ensure the old name continues parsing.
|
|
|
|
|
|
|
|
| |
To match the standard instruction name, rename the expression class without
changing any parsing or printing behavior. A follow-on PR will take care of the
functional side of this change while keeping support for parsing the old name.
This change will allow `ArrayInit` to be used as the expression class for the
upcoming `array.init_data` and `array.init_elem` instructions.
|
|
|
|
|
|
| |
string.from_code_point makes a string from an int code point.
string.new_utf8*_try makes a utf8 string and returns null on a UTF8 encoding
error rather than trap.
|
|
|
| |
See WebAssembly/stringref#58
|
|
|
|
|
|
| |
We cannot modify the input string safely. To avoid that, copy where needed.
Fixes #5440
|
|
|
|
|
|
| |
`struct` has replaced `data` in the upstream spec, so update Binaryen's types to
match. We had already supported `struct` as an alias for data, but now remove
support for `data` entirely. Also remove instructions like `ref.is_data` that
are deprecated and do not make sense without a `data` type.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
These operations are deprecated and directly representable as casts, so remove
their opcodes in the internal IR and parse them as casts instead. For now, add
logic to the printing and binary writing of RefCast to continue emitting the
legacy instructions to minimize test changes. The few test changes necessary are
because it is no longer valid to perform a ref.as_func on values outside the
func type hierarchy now that ref.as_func is subject to the ref.cast validation
rules.
RefAsExternInternalize, RefAsExternExternalize, and RefAsNonNull are left
unmodified. A future PR may remove RefAsNonNull as well, since it is also
expressible with casts.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Replace `RefIs` with `RefIsNull`
The other `ref.is*` instructions are deprecated and expressible in terms of
`ref.test`. Update binary and text parsing to parse those instructions as
`RefTest` expressions. Also update the printing and emitting of `RefTest`
expressions to emit the legacy instructions for now to minimize test changes and
make this a mostly non-functional change. Since `ref.is_null` is the only
`RefIs` instruction left, remove the `RefIsOp` field and rename the expression
class to `RefIsNull`.
The few test changes are due to the fact that `ref.is*` instructions are now
subject to `ref.test` validation, and in particular it is no longer valid to
perform a `ref.is_func` on a value outside of the `func` type hierarchy.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The `br_on{_non}_{data,i31,func}` operations are deprecated and directly
representable in terms of the new `br_on_cast` and `br_on_cast_fail`
instructions, so remove their dedicated IR opcodes in favor of representing them
as casts. `br_on_null` and `br_on_non_null` cannot be consolidated the same way
because their behavior is not directly representable in terms of `br_on_cast`
and `br_on_cast_fail`; when the cast to null bottom type succeeds, the null
check instructions implicitly drop the null value whereas the cast instructions
would propagate it.
Add special logic to the binary writer and printer to continue emitting the
deprecated instructions for now. This will allow us to update the test suite in
a separate future PR with no additional functional changes.
Some tests are updated because the validator no longer allows passing non-func
data to `br_on_func`. Doing so has not made sense since we separated the three
reference type hierarchies.
|
|
|
|
|
|
|
|
|
| |
As well as br_on_cast_fail null. Unlike the existing br_on_cast* instructions,
these new instructions treat the cast as succeeding when the input is a null.
Update the internal representation of the cast type in `BrOn` expressions to be
a `Type` rather than a `HeapType` so it will include nullability information.
Also update and improve `RemoveUnusedBrs` to handle the new instructions
correctly and optimize in more cases.
|
|
|
|
|
|
|
| |
This new cast configuration was not expressible with the legacy cast
instructions. Although it is valid in Wasm, do not allow nullable casts of
non-nullable references, since those would unnecessarily lose type information.
Convert such casts to be non-nullable during expression finalization.
|
|
|
| |
This new variant of ref.test returns 1 if the input is null.
|
|
|
|
|
|
|
|
|
| |
The latest upstream version of ref.cast is parameterized with a target reference
type, not just a heap type, because the nullability of the result is
parameterizable. As a first step toward implementing these new, more flexible
ref.cast instructions, change the internal representation of ref.cast to use the
expression type as the cast target rather than storing a separate heap type
field. For now require that the encoded semantics match the previously allowed
semantics, though, so that none of the optimization passes need to be updated.
|
|
|
|
|
|
|
|
|
|
|
|
| |
We switched from emitting the legacy `ref.cast_static` instruction to emitting
`ref.cast null` in #5331, but that wasn't quite correct. The legacy instruction
had polymorphic typing so that its output type was nullable if and only if its
input type was nullable. In contrast, `ref.cast null` always has a a nullable
output type.
Fix our output by instead emitting non-nullable `ref.cast` if the output should
be non-nullable. Parse `ref.cast` in binary and text forms as well. Since the IR
can only represent the legacy polymorphic semantics, disallow unsupported casts
from nullable to non-nullable references or vice versa for now.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Without this we hit an assert with no line number info (or in a no-asserts build,
bad things can happen). With this:
$ bin/wasm-opt -all ~/Downloads/crash.wat --nominal
[parse exception: Invalid ref for ref.as (at 155065:119)]
Fatal: error parsing wasm
(That can only happen for ref.as_non_null, as all the others do not have that
assert - their types do not depend on the child's type, so their finalize does not
error. Still, it is nice to validate earlier for them as well, so this PR handles them
all.)
|
|
|
|
|
|
|
| |
We previously supported only the non-standard cast instructions introduced when
we were experimenting with nominal types. Parse the names and opcodes of their
standard counterparts and switch to emitting the standard names and opcodes.
Port all of the tests to use the standard instructions, but add additional tests
showing that the non-standard versions are still parsed correctly.
|
|
|
|
|
|
|
|
| |
wasm-s-parser.cpp was detecting the end of type strings by looking for null
characters, but those null characters would be past the end of the relevant
string_view. Bring that code in line with similar code by checking the length of
the string_view instead. Fixes an assertion failure in MSVC debug mode.
Fixes #5312.
|
|
|
|
|
| |
(#5266)
This reverts commit 570007dbecf86db5ddba8d303896d841fc2b2d27.
|
|
|
|
|
| |
This reverts commit b2054b72b7daa89b7ad161c0693befad06a20c90.
It looks like the necessary V8 change has not rolled out everywhere yet.
|
|
|
|
| |
They were optional for a while to allow users to gracefully transition to using
them, but now make them mandatory to match the upstream WasmGC spec.
|
|
|
|
|
|
|
|
|
| |
In order to test them, fix the binary and text parsers to accept passive data
segments even if a module has no memory. In addition to parsing and emitting the
new instructions, also implement their validation and interpretation. Test the
interpretation directly with wasm-shell tests adapted from the upstream spec
tests. Running the upstream spec tests directly would require fixing too many
bugs in the legacy text parser, so it will have to wait for the new text parser
to be ready.
|
|
|
|
|
|
|
|
|
|
| |
Add parsing functions for `memarg`s, the offset and align fields of load and
store instructions. These fields are interesting because they are lexically
reserved words that need to be further parsed to extract their actual values. On
top of that, add support for parsing all of the load and store instructions.
This required fixing a buffer overflow problem in the generated parser code and
adding more information to the signatures of the SIMD load and store
instructions. `SIMDLoadStoreLane` instructions are particularly interesting
because they may require backtracking to parse correctly.
|
|
|
|
|
|
|
|
|
| |
Since gen-s-parser.py is essentially a giant table mapping instruction names to
the information necessary to construct the corresponding IR nodes, there should
be no need to further parse instruction names after the code generated by
gen-s-parser.py runs. However, memory instruction parsing still parsed
instruction names to get information such as size and default alignment. The new
parser does not have the ability to parse that information out of instruction
names, so put it in the gen-s-parser.py table instead.
|
|
|
| |
Test that we can still parse the old annotated form as well.
|
|
|
|
|
|
|
|
|
| |
`array` is the supertype of all defined array types and for now is a subtype of
`data`. (Once `data` becomes `struct` this will no longer be true.) Update the
binary and text parsing of `array.len` to ignore the obsolete type annotation
and update the binary emitting to emit a zero in place of the old type
annotation and the text printing to print an arbitrary heap type for the
annotation. A follow-on PR will add support for the newer unannotated version of
`array.len`.
|