summaryrefslogtreecommitdiff
path: root/src/wasm-binary.h
Commit message (Collapse)AuthorAgeFilesLines
* Implement table.copy (#6078)Alon Zakai2023-11-061-0/+2
| | | Helps #5951
* Typed Continuations: Add cont type (#5998)Frank Emrich2023-10-241-14/+15
| | | | | | | | | 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.
* Reuse existing function types for blocks (#6022)Thomas Lively2023-10-181-0/+2
| | | | | | | | | | | | | | | | | | | | | 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.
* [typed-cont] Add feature flag (#5996)Frank Emrich2023-10-051-0/+1
| | | | | | | This PR is part of a series that adds basic support for the [typed continuations proposal](https://github.com/wasmfx/specfx). This particular PR simply extends `FeatureSet` with a corresponding entry for this proposal.
* Implement table.fill (#5949)Thomas Lively2023-09-181-0/+2
| | | | | | | | 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.
* Replace I31New with RefI31 everywhere (#5930)Thomas Lively2023-09-131-3/+3
| | | | | | | | 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.
* Use standard GC encodings by default (#5873)Thomas Lively2023-09-121-4/+3
| | | | The legacy encodings remain available for now by defining USE_LEGACY_GC_ENCODINGS at build time.
* [NFC] Source maps: Simplify the code and add comments (#5912)Alon Zakai2023-09-061-16/+30
| | | | | | | | | | | | | | | Almost entirely trivial, except for this part: - if (nextDebugLocation.availablePos == 0 && - nextDebugLocation.previousPos <= pos) { + if (nextDebugLocation.availablePos == 0) { return; I believe removing the extra check has no effect. Removing it does not change anything in the test suite, and logically, if we set availablePos to 0 then we definitely want to return here - we set it to 0 to indicate there is nothing left to read, which is what the code after it does. As a result, we can remove the previousPos field entirely.
* Source maps: Fix locations without debug info between ones that do (#5906)Alon Zakai2023-08-301-4/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously we did nothing for instructions without debug info. So if we had one that did, followed by one that didn't, the one that didn't could get "smeared" with the debug info of the first. Source map locations are the start of segments, apparently, and so if we say a location has info then all others after it will as well, until the next segment. To fix that, add support for source map entries with just one field, the binary location. Such entries have no debug info (no file:line:col), and though the source maps spec is not very clear on this, this seems like the right way to prevent this problem: to stop a segment with debug info by starting a new one without, when we know we don't want that info any more. That is, before this PR we could have this: ;; file.cpp:10:1 (nop) ;; binary offset 5 in wasm (nop) ;; binary offset 6 in wasm and the second nop would get the same debug annotation, since we just have one source map segment, [5, file.cpp, 10, 1] // start at offset 5 in wasm With this PR, we emit: [5, file.cpp, 10, 1] // start at offset 5 in wasm; file.cpp:10:1 [6] // start at offset 6 in wasm; no debug info This does add 7% to source map sizes, however, since we add those 1-length segments now, but that seems unavoidable to fix this bug. To implement this, add a new field that says if the next location in the source map has debug info or not, and use that.
* Fix standard reference type encoding (#5905)Thomas Lively2023-08-281-2/+2
| | | | This bug was found by fuzzing Binaryen and V8 together with the standard GC encodings enabled.
* Rename multimemory flag (#5890)Ashley Nelson2023-08-211-1/+1
| | | Renaming the multimemory flag in Binaryen to match its naming in LLVM.
* Allow opting into standard GC encodings at compile time (#5868)Thomas Lively2023-08-101-49/+153
| | | | | | | | | | | Depending on whether preprocessor macros USE_STANDARD_GC_ENCODINGS and USE_LEGACY_GC_ENCODINGS are defined, use the standard or legacy encodings for GC types and instructions. Default to the latter for now. When WasmGC reaches phase 4, we will switch the default to be the standard encodings instead. After users have time to update, we will remove the legacy encodings entirely. Tested manually by building with USE_STANDARD_GC_ENCODINGS locally and seeing that all the tests pass except for some tests that depend on the specific binary encoding.
* Remove legacy WasmGC instructions (#5861)Thomas Lively2023-08-091-18/+0
| | | | | 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.
* Initial support for `final` types (#5803)Thomas Lively2023-07-061-4/+5
| | | | | | | | | | | | | | | | | | | | 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.
* Rename WasmBinaryBuilder to WasmBinaryReader (NFC) (#5767)Heejin Ahn2023-06-131-4/+4
| | | | | | 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`?
* Update br_on_cast binary and text format (#5762)Thomas Lively2023-06-121-6/+6
| | | | | | | | | | | | 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
* Revert "Update br_on_cast binary and text format (#5734)" (#5740)Alon Zakai2023-05-231-2/+6
| | | | | | | 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.
* Update br_on_cast binary and text format (#5734)Thomas Lively2023-05-191-6/+2
| | | | | | | | | | 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.
* [Strings] Adopt new instruction binary encoding (#5714)Jérôme Vouillon2023-05-121-10/+13
| | | | | | | | | | | 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).
* [NFC] Refactor each of ArrayNewSeg and ArrayInit into subclasses for ↵Alon Zakai2023-05-041-2/+2
| | | | | | | | | | | 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
* Implement array.fill, array.init_data, and array.init_elem (#5637)Thomas Lively2023-04-061-0/+5
| | | | | 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.
* Use Names instead of indices to identify segments (#5618)Thomas Lively2023-04-041-0/+10
| | | | | | | | | | 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.
* [Wasm GC] Remove RefIsFunc and RefIsI31 from the binary format (#5574)Alon Zakai2023-03-151-3/+0
| | | | We still support ref.is_func/i31 in the text format for now. After we verify that no users depend on that we can remove it as well.
* Parse and print `array.new_fixed` (#5527)Thomas Lively2023-02-281-1/+1
| | | | | | | | | 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.
* [NFC] Internally rename `ArrayInit` to `ArrayNewFixed` (#5526)Thomas Lively2023-02-281-2/+2
| | | | | | | | 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.
* Fix sourcemap nesting in reading and writing (#5504)JesseCodeBones2023-02-241-1/+6
| | | | The stack logic was incorrect, and led to source locations being emitted on parents instead of children.
* [Strings] Add experimental string.hash instruction (#5480)Alon Zakai2023-02-031-0/+1
| | | See WebAssembly/stringref#60
* [Strings] Add experimental StringNew variants (#5459)Alon Zakai2023-01-261-0/+3
| | | | | | 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.
* [Strings] Add string.compare (#5453)Alon Zakai2023-01-251-0/+1
| | | See WebAssembly/stringref#58
* [Wasm GC] Replace `HeapType::data` with `HeapType::struct_` (#5416)Thomas Lively2023-01-101-13/+9
| | | | | | `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.
* Represent ref.as_{func,data,i31} with RefCast (#5413)Thomas Lively2023-01-101-0/+1
| | | | | | | | | | | | | 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` (#5401)Thomas Lively2023-01-091-1/+2
| | | | | | | | | | | | | | | * 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.
* Support br_on_cast null (#5397)Thomas Lively2023-01-051-2/+2
| | | | | | | | | 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.
* Support `ref.test null` (#5368)Thomas Lively2022-12-211-2/+2
| | | This new variant of ref.test returns 1 if the input is null.
* Use non-nullable ref.cast for non-nullable input (#5335)Thomas Lively2022-12-091-5/+5
| | | | | | | | | | | | 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.
* Add standard versions of WasmGC casts (#5331)Thomas Lively2022-12-071-1/+9
| | | | | | | 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.
* Use C++17's [[maybe_unused]]. NFC (#5309)Sam Clegg2022-12-021-8/+4
|
* Rename UserSection -> CustomSection. NFC (#5288)Sam Clegg2022-11-221-7/+7
| | | This reflects that naming used in the spec.
* Revert "Revert "Make `call_ref` type annotations mandatory (#5246)" (#5265)" ↵Thomas Lively2022-11-161-4/+2
| | | | | (#5266) This reverts commit 570007dbecf86db5ddba8d303896d841fc2b2d27.
* Revert "Make `call_ref` type annotations mandatory (#5246)" (#5265)Thomas Lively2022-11-161-2/+4
| | | | | This reverts commit b2054b72b7daa89b7ad161c0693befad06a20c90. It looks like the necessary V8 change has not rolled out everywhere yet.
* Switch from `typedef` to `using` in C++ code. NFC (#5258)Sam Clegg2022-11-151-5/+5
| | | | This is more modern and (IMHO) easier to read than that old C typedef syntax.
* Make `call_ref` type annotations mandatory (#5246)Thomas Lively2022-11-151-4/+2
| | | | 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.
* Implement `array.new_data` and `array.new_elem` (#5214)Thomas Lively2022-11-071-0/+3
| | | | | | | | | 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.
* Parse and emit `array.len` without a type annotation (#5151)Thomas Lively2022-10-181-1/+2
| | | Test that we can still parse the old annotated form as well.
* Implement `array` basic heap type (#5148)Thomas Lively2022-10-181-0/+2
| | | | | | | | | `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`.
* Support null characters in string.const expressions (#5123)Thomas Lively2022-10-111-1/+1
| | | | Remove an obsolete error about null characters and test both binary and text round tripping of a string constant containing an escaped zero byte.
* Make `Name` a pointer, length pair (#5122)Thomas Lively2022-10-111-2/+2
| | | | | | | | | | | | | | | | | | | | | | | With the goal of supporting null characters (i.e. zero bytes) in strings. Rewrite the underlying interned `IString` to store a `std::string_view` rather than a `const char*`, reduce the number of map lookups necessary to intern a string, and present a more immutable interface. Most importantly, replace the `c_str()` method that returned a `const char*` with a `toString()` method that returns a `std::string`. This new method can correctly handle strings containing null characters. A `const char*` can still be had by calling `data()` on the `std::string_view`, although this usage should be discouraged. This change is NFC in spirit, although not in practice. It does not intend to support any particular new functionality, but it is probably now possible to use strings containing null characters in at least some cases. At least one parser bug is also incidentally fixed. Follow-on PRs will explicitly support and test strings containing nulls for particular use cases. The C API still uses `const char*` to represent strings. As strings containing nulls become better supported by the rest of Binaryen, this will no longer be sufficient. Updating the C and JS APIs to use pointer, length pairs is left as future work.
* Implement bottom heap types (#5115)Thomas Lively2022-10-071-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | These types, `none`, `nofunc`, and `noextern` are uninhabited, so references to them can only possibly be null. To simplify the IR and increase type precision, introduce new invariants that all `ref.null` instructions must be typed with one of these new bottom types and that `Literals` have a bottom type iff they represent null values. These new invariants requires several additional changes. First, it is now possible that the `ref` or `target` child of a `StructGet`, `StructSet`, `ArrayGet`, `ArraySet`, or `CallRef` instruction has a bottom reference type, so it is not possible to determine what heap type annotation to emit in the binary or text formats. (The bottom types are not valid type annotations since they do not have indices in the type section.) To fix that problem, update the printer and binary emitter to emit unreachables instead of the instruction with undetermined type annotation. This is a valid transformation because the only possible value that could flow into those instructions in that case is null, and all of those instructions trap on nulls. That fix uncovered a latent bug in the binary parser in which new unreachables within unreachable code were handled incorrectly. This bug was not previously found by the fuzzer because we generally stop emitting code once we encounter an instruction with type `unreachable`. Now, however, it is possible to emit an `unreachable` for instructions that do not have type `unreachable` (but are known to trap at runtime), so we will continue emitting code. See the new test/lit/parse-double-unreachable.wast for details. Update other miscellaneous code that creates `RefNull` expressions and null `Literals` to maintain the new invariants as well.
* Warn on too many parameters for Web VMs (#5119)Alon Zakai2022-10-061-1/+2
| | | Fixes emscripten-core/emscripten#17988
* Emit call_ref with a type annotation (#5079)Thomas Lively2022-09-231-1/+2
| | | | | | | Emit call_ref instructions with type annotations and a temporary opcode. Also implement support for parsing optional type annotations on call_ref in the text and binary formats. This is part of a multi-part graceful update to switch Binaryen and all of its users over to using the type-annotated version of call_ref without there being any breakage.