summaryrefslogtreecommitdiff
path: root/src/wasm/wasm.cpp
Commit message (Collapse)AuthorAgeFilesLines
...
* [Wasm GC] Add static variants of ref.test, ref.cast, and br_on_cast* (#4163)Alon Zakai2021-09-201-5/+20
| | | | | | | | | | | | These variants take a HeapType that is the type we intend to cast to, and do not take an RTT. These are intended to be more statically optimizable. For now though this PR just implements the minimum to get them parsing and to get through the optimizer without crashing. Spec: https://docs.google.com/document/d/1afthjsL_B9UaMqCA5ekgVmOm75BVFu6duHNsN9-gnXw/edit# See #4149
* Support new dylink.0 custom section format (#4141)Sam Clegg2021-09-111-0/+1
| | | | | | | See also: spec change: https://github.com/WebAssembly/tool-conventions/pull/170 llvm change: https://reviews.llvm.org/D109595 wabt change: https://github.com/WebAssembly/wabt/pull/1707 emscripten change: https://github.com/emscripten-core/emscripten/pull/15019
* [Wasm GC] ArrayInit support (#4138)Alon Zakai2021-09-101-0/+14
| | | | | | | array.init is like array.new_with_rtt except that it takes as arguments the values to initialize the array with (as opposed to a size and an optional initial value). Spec: https://docs.google.com/document/d/1afthjsL_B9UaMqCA5ekgVmOm75BVFu6duHNsN9-gnXw/edit#
* [Wasm GC] Fix getSentType() of BrOn with an unreachable input (#3993)Alon Zakai2021-07-161-0/+8
| | | | Without this fix, DCE would end up calling getHeapType() on the unreachable input, which hits an assertion as it has no heap type.
* Preserve Function HeapTypes (#3952)Thomas Lively2021-06-301-6/+6
| | | | | | | | | When using nominal types, func.ref of two functions with identical signatures but different HeapTypes will yield different types. To preserve these semantics, Functions need to track their HeapTypes, not just their Signatures. This PR replaces the Signature field in Function with a HeapType field and adds new utility methods to make it almost as simple to update and query the function HeapType as it was to update and query the Function Signature.
* Remove (attr 0) from tag text format (#3946)Heejin Ahn2021-06-191-1/+0
| | | | | | | | This attribute is always 0 and reserved for future use. In Binayren's unofficial text format we were writing this field as `(attr 0)`, but we have recently come to the conclusion that this is not necessary. Relevant discussion: https://github.com/WebAssembly/exception-handling/pull/160#discussion_r653254680
* [EH] Replace event with tag (#3937)Heejin Ahn2021-06-181-17/+15
| | | | | | | | | | | We recently decided to change 'event' to 'tag', and to 'event section' to 'tag section', out of the rationale that the section contains a generalized tag that references a type, which may be used for something other than exceptions, and the name 'event' can be confusing in the web context. See - https://github.com/WebAssembly/exception-handling/issues/159#issuecomment-857910130 - https://github.com/WebAssembly/exception-handling/pull/161
* Rename wasm-delegations[-fields].h to def files (NFC) (#3941)Heejin Ahn2021-06-181-1/+1
| | | | | | | | | | | These files are special in that they use define symbols that are not defined within those files or other files included in those files; they are supposed to be defined in source files that include these headers. This has caused clang-tidy to fail every time these files have changed because they are not compilable per se. This PR solves the problem by changing their extension to `def`, which is also used in LLVM codebase. LLVM has dozens of files like this whose extension is `def`, which makes these not checked by clang-tidy.
* [Wasm GC] Add negated BrOn* operations (#3913)Alon Zakai2021-06-021-7/+42
| | | | | | They are basically the flip versions. The only interesting part in the impl is that their returned typed and sent types are different. Spec: https://docs.google.com/document/d/1DklC3qVuOdLHSXB5UXghM_syCh-4cMinQ50ICiXnK3Q/edit
* [Wasm GC] Add experimental array.copy (#3911)Alon Zakai2021-05-271-0/+12
| | | | | | | | Spec for it is here: https://docs.google.com/document/d/1DklC3qVuOdLHSXB5UXghM_syCh-4cMinQ50ICiXnK3Q/edit# Also reorder some things in wasm.h that were not in the canonical order (that has no effect, but it is confusing to read).
* [Wasm GC] Fix StructSet::finalize on an unreachable value (#3874)Alon Zakai2021-05-101-1/+1
| | | | | | Also fix printing of unreachable StructSets, which must handle the case of an unreachable reference, which means we do not know the RTT, and so we must print a replacement for the StructSet somehow. Emit a block with drops, fixing the old behavior which was missing the drops.
* [Wasm GC] Fix the type of ref.as_func, which should be non-nullable (#3821)Alon Zakai2021-04-201-1/+1
|
* Remove renaming of __wasm_call_ctors (#3811)Sam Clegg2021-04-151-1/+0
| | | See https://github.com/emscripten-core/emscripten/issues/13893
* Rename SIMD extending load instructions (#3798)Daniel Wirtz2021-04-121-6/+6
| | | | | | | | | Renames the SIMD instructions * LoadExtSVec8x8ToVecI16x8 -> Load8x8SVec128 * LoadExtUVec8x8ToVecI16x8 -> Load8x8UVec128 * LoadExtSVec16x4ToVecI32x4 -> Load16x4SVec128 * LoadExtUVec16x4ToVecI32x4 -> Load16x4UVec128 * LoadExtSVec32x2ToVecI64x2 -> Load32x2SVec128 * LoadExtUVec32x2ToVecI64x2 -> Load32x2UVec128
* Rename various SIMD load instructions (#3795)Daniel Wirtz2021-04-111-6/+6
| | | | | | | | | Renames the SIMD instructions * LoadSplatVec8x16 -> Load8SplatVec128 * LoadSplatVec16x8 -> Load16SplatVec128 * LoadSplatVec32x4 -> Load32SplatVec128 * LoadSplatVec64x2 -> Load64SplatVec128 * Load32Zero -> Load32ZeroVec128 * Load64Zero -> Load64ZeroVec128
* Add v128.load/storeN_lane SIMD instructions to C/JS API (#3784)Daniel Wirtz2021-04-081-16/+16
| | | | | | | | | | | Adds C/JS APIs for the SIMD instructions * Load8LaneVec128 (was LoadLaneVec8x16) * Load16LaneVec128 (was LoadLaneVec16x8) * Load32LaneVec128 (was LoadLaneVec32x4) * Load64LaneVec128 (was LoadLaneVec64x2) * Store8LaneVec128 (was StoreLaneVec8x16) * Store16LaneVec128 (was StoreLaneVec16x8) * Store32LaneVec128 (was StoreLaneVec32x4) * Store64LaneVec128 (was StoreLaneVec64x2)
* Update SIMD names and opcodes (#3771)Thomas Lively2021-04-051-28/+15
| | | | Also removes experimental SIMD instructions that were not included in the final spec proposal.
* Catch bad tuple.extract index in parser (#3766)Thomas Lively2021-03-311-0/+1
| | | | Previously an out-of-bounds index would result in an out-of-bounds read during finalization of the tuple.extract expression.
* LUBs (#3731)Thomas Lively2021-03-291-20/+7
| | | | | | | This is a partial revert of #3669, which removed the old implementation of Type::getLeastUpperBound that did not correctly handle recursive types. The new implementation in this PR uses a TypeBuilder to construct LUBs and for recursive types, it returns a temporary HeapType that has not yet been fully constructed to break what would otherwise be infinite recursions.
* [Wasm GC] Add support for non-nullable types, all except for locals (#3710)Alon Zakai2021-03-231-27/+8
| | | | | | | | | | | | | | | | | | | | | | After this PR we still do not support non-nullable locals. But we no longer turn all types into nullable upon load. In particular, we support non-nullable types on function parameters and struct fields, etc. This should be enough to experiment with optimizations in both binaryen and in VMs regarding non- nullability (since we expect that optimizing VMs can do well inside functions anyhow; it's non-nullability across calls and from data that the VM can't be expected to think about). Let is handled as before, by lowering it into gets and sets. In addition, we turn non-nullable locals into nullable ones, and add a ref.as_non_null on all their gets (to keep the type identical there). This is used not just for loading code with a let but also is needed after inlining. Most of the code changes here are removing FIXMEs for allowing non-nullable types. But there is also code to handle the issues mentioned above. Most of the test updates are removing extra nulls that we added before when we turned all types nullable. A few tests had actual issues, though, and also some new tests are added to cover the code changes here.
* Remove LUB calculation (#3669)Thomas Lively2021-03-111-15/+30
| | | | | | | | Since correct LUB calculation for recursive types is complicated, stop depending on LUBs throughout the code base. This also fixes a validation bug in which the validator required blocks to be typed with the LUB of all the branch types, when in fact any upper bound should have been valid. In addition to fixing that bug, this PR simplifies the code for break handling by not storing redundant information about the arity of types.
* [reference-types] Support passive elem segments (#3572)Abbas Mashayekh2021-03-051-5/+29
| | | | | | | | | | | Passive element segments do not belong to any table, so the link between Table and elem needs to be weaker; i.e. an elem may have a table in case of active segments, or simply be a collection of function references in case of passive/declarative segments. This PR takes Table::Segment out and turns it into a first class module element just like tables and functions. It also implements early support for parsing, printing, encoding and decoding passive/declarative elem segments.
* [EH] Support reading/writing of delegate (#3561)Heejin Ahn2021-02-121-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This adds support for reading/writing of the new `delegate` instruction in the folded wast format, the stack IR format, the poppy IR format, and the binary format in Binaryen. We don't have a formal spec written down yet, but please refer to WebAssembly/exception-handling#137 and WebAssembly/exception-handling#146 for the informal semantics. In the current version of spec `delegate` is basically a rethrow, but with branch-like immediate argument so that it can bypass other catches/delegates in between. `delegate` is not represented as a new `Expression`, but it is rather an option within a `Try` class, like `catch`/`catch_all`. One special thing about `delegate` is, even though it is written _within_ a `try` in the folded wat format, like ```wasm (try (do ... ) (delegate $l) ) ``` In the unfolded wat format or in the binary format, `delegate` serves as a scope end instruction so there is no separate `end`: ```wasm try ... delegate $l ``` `delegate` semantically targets an outer `catch` or `delegate`, but we write `delegate` target as a `try` label because we only give labels to block-like scoping expressions. So far we have not given `Try` a label and used inner blocks or a wrapping block in case a branch targets the `try`. But in case of `delegate`, it can syntactically only target `try` and if it targets blocks or loops it is a validation failure. So after discussions in #3497, we give `Try` a label but this label can only be targeted by `delegate`s. Unfortunately this makes parsing and writing of `Try` expression somewhat complicated. Also there is one special case; if the immediate argument of `try` is the same as the depth of control flow stack, this means the 'delegate' delegates to the caller. To handle this case this adds a fake label `DELEGATE_CALLER_TARGET`, and when writing it back to the wast format writes it as an immediate value, unlike other cases in which we write labels. This uses `DELEGATE_FIELD_SCOPE_NAME_DEF/USE` to represent `try`'s label and `delegate`'s target. There are many cases that `try` and `delegate`'s labels need to be treated in the same way as block and branch labels, such as for hashing or comparing. But there are routines in which we automatically assume all label uses are branches. I thought about adding a new kind of defines such as `DELEGATE_FIELD_TRY_NAME_DEF/USE`, but I think it will also involve some duplication of existing routines or classes. So at the moment this PR chooses to use the existing `DELEGATE_FIELD_SCOPE_NAME_DEF/USE` for `try` and `delegate` labels and makes only necessary amount of changes in branch-utils. We can revisit this decision later if necessary. Many of changes to the existing test cases are because now all `try`s are automatically assigned a label. They will be removed in `RemoveUnusedNames` pass in the same way as block labels if not targeted by any delegates. This only supports reading and writing and has not been tested against any optimization passes yet. --- Original unfolded wat file to generate test/try-delegate.wasm: ```wasm (module (event $e) (func try try delegate 0 catch $e end) (func try try catch $e i32.const 0 drop try delegate 1 end catch $e end ) ) ```
* [reference-types] remove single table restriction in IR (#3517)Abbas Mashayekh2021-02-091-0/+22
| | | Adds support for modules with multiple tables. Adds a field for the table name to `CallIndirect` and updates the C/JS APIs accordingly.
* Prototype i32x4.widen_i8x16_{s,u} (#3535)Thomas Lively2021-02-011-0/+5
| | | | | | | | As proposed in https://github.com/WebAssembly/simd/pull/395. Note that the other instructions in the proposal have not been implemented in LLVM or in V8, so there is no need to implement them in Binaryen right now either. This PR introduces a new expression class for the new instructions because they uniquely take an immediate argument identifying which portion of the input vector to widen.
* [GC] br_on_null (#3528)Alon Zakai2021-02-011-1/+12
| | | | | | | | | | | This is only partial support, as br_on_null also has an extra optional value in the spec. Implementing that is cumbersome in binaryen, and there is ongoing spec discussions about it (see https://github.com/WebAssembly/function-references/issues/45 ), so for now we only support the simple case without the default value. Also fix prefixed opcodes to be LEBs in RefAs, which was noticed here as the change here made it noticeable whether the values were int8 or LEBs.
* [GC] ref.as_non_null (#3527)Alon Zakai2021-01-281-0/+4
| | | | | | This is different than the other RefAs variants in that it is part of the typed functions proposal, and not GC. But it is part of GC prototype 3. Note: This is not useful to us yet as we don't support non-nullable types.
* [GC] Add br_on_func/data/i31 (#3525)Alon Zakai2021-01-281-4/+18
| | | | | | | | This expands the existing BrOnCast into BrOn that can also handle the func/data/i31 variants. This is not as elegant as RefIs / RefAs in that BrOnCast has an extra rtt field, but I think it is still the best option. We already have optional fields on Break (the value and condition), so making rtt optional is not odd. And it allows us to share all the behavior of br_on_* which aside from the cast or the check itself, is identical - returning the value if the branch is not taken, etc.
* [GC] Update br_on_cast: the text format also no longer has a heap type (#3523)Alon Zakai2021-01-271-1/+1
| | | | | | | As a result, we cannot handle a br_on_cast with an unreachable RTT. The binary format solves the problem by ignoring unreachable code, and this makes the text format do the same. A nice benefit of this is that we can remove the castType extra field.
* Simplfy getExpressionName (#3522)Alon Zakai2021-01-271-157/+9
| | | | | | | | | | This used to return a simple name like "if" for an If, but it is redundant with our proper printing logic. This PR turns it into a trivial helper that just prints out the name of the class, so it now prints "If" with a capital. That is useful for some logging, like in Metrics I think it is clearer than it was earlier (since we are actually counting the classes, and our old emitting of text-format-like names are just confusing, as we emitted "binary" there which is not valid). Also replace some usages of that method with proper printing.
* [GC] ref.as_* (#3520)Alon Zakai2021-01-271-0/+31
| | | | | | | | These are similar to is, but instead of returning an i32 answer, they trap on an invalid value, and return it otherwise. These could in theory be in a single RefDoThing, with opcodes for both As and Is, but as the return values are different, that would be a little odd, and the name would be less clear.
* [GC] ref.is_func/data/i31 (#3519)Alon Zakai2021-01-261-0/+6
|
* [GC] RefIsNull => RefIs. (#3516)Alon Zakai2021-01-261-3/+8
| | | | | | | | This internal refactoring prepares us for ref.is_func/data/i31, by renaming the node and adding an "op" field. For now that field must always be "Null" which means it is a ref.is_null. This adjusts the C API to match the new IR shape. The high-level JS API is unchanged.
* Remove exnref and br_on_exn (#3505)Heejin Ahn2021-01-221-10/+0
| | | This removes `exnref` type and `br_on_exn` instruction.
* Prototype additional f64x2 conversions (#3501)Thomas Lively2021-01-191-0/+6
| | | | As proposed in https://github.com/WebAssembly/simd/pull/383, with opcodes coordinated with the WIP V8 prototype.
* Basic EH instrucion support for the new spec (#3487)Heejin Ahn2021-01-151-3/+9
| | | | | | | | | | | | | | | | | | | | This updates `try`-`catch`-`catch_all` and `rethrow` instructions to match the new spec. `delegate` is not included. Now `Try` contains not a single `catchBody` expression but a vector of catch bodies and events. This updates most existing routines, optimizations, and tests modulo the interpreter and the CFG traversal. Because the interpreter has not been updated yet, the EH spec test is temporarily disabled in check.py. Also, because the CFG traversal for EH is not yet updated, several EH tests in `rse_all-features.wast`, which uses CFG traversal, are temporarily commented out. Also added a few more tests in existing EH test functions in test/passes. In the previous spec, `catch` was catching all exceptions so it was assumed that anything `try` body throws is caught by its `catch`, but now we can assume the same only if there is a `catch_all`. Newly added tests test cases when there is a `catch_all` and cases there are only `catch`es separately.
* Prototype prefetch instructions (#3467)Thomas Lively2021-01-061-0/+6
| | | | As proposed in https://github.com/WebAssembly/simd/pull/352, using the opcodes used in the LLVM and V8 implementations.
* Prototype SIMD extending pairwise add instructions (#3466)Thomas Lively2021-01-051-2/+4
| | | | | | As proposed in https://github.com/WebAssembly/simd/pull/380, using the opcodes used in LLVM and V8. Since these opcodes overlap with the opcodes of i64x2.all_true and i64x2.any_true, which have long since been removed from the SIMD proposal, this PR also removes those instructions.
* [GC] Add br_on_cast (#3451)Alon Zakai2020-12-171-3/+26
| | | | | | | | | | | | | | | | The tricky part here, as pointed out by aheejin in my previous attempt, is that we need to know the type of the value we send if the branch is taken. We can normally calculate that from the rtt parameter's type - we are casting to that RTT, so we know what type that is - but if the rtt is unreachable, that's a problem. To fix that, store the cast type on BrOnCast instructions. This includes a test with a br_on_cast that succeeds and sends the cast value, one that fails and passes through the uncast value, and also of one with an unreachable RTT. This includes a fix for Precompute, as noticed by that new test. If a break is taken, with a ref as a value, we can't precompute it - for the same reasons we can't precompute a ref in general, that it is a pointer to possibly shared data.
* Refactor printing code so that printing Expressions always works (#3450)Alon Zakai2020-12-171-7/+1
| | | | | | | | This avoids needing to add include wasm-printing if a file doesn't already have it. To achieve that, add the std::ostream hooks in wasm.h, and also use them when possible, removing the need for the special WasmPrinter object. Also stop printing in "full" (print types on each line) in error messages by default. The user can still get that, as always, using BINARYEN_PRINT_FULL=1 in the env.
* More refactoring of branch utility code to remove boilerplate. (#3448)Alon Zakai2020-12-161-99/+35
| | | | | | | | | | | | | | | | | | | This is almost NFC, but it may emit slightly different IR in cases that don't matter much. Specifically, (block (result i32) ;; can also be unreachable (unreachable) (i32.const 1) ) That can be finalized to have type unreachable or i32, as both are valid. After this PR we should consistently do the same thing in all places. (Either option would be ok - we prefer to keep the type if there is one.) In practice, DCE will remove all the dead code anyhow, leaving no difference to matter. However, the IR is different without DCE, and that may be noticeable in an unoptimized build - but it should have no effect on behavior, just on the binary.
* Use enums for mutability and nullability (#3443)Thomas Lively2020-12-141-4/+4
| | | | | Previously we were using bools for both of these concepts, but using enums makes the code clearer. In particular, the PR removes many instances of `/*nullability=*/ true`.
* Prototype SIMD instructions implemented in LLVM (#3440)Thomas Lively2020-12-111-0/+5
| | | | | | - i64x2.eq (https://github.com/WebAssembly/simd/pull/381) - i64x2 widens (https://github.com/WebAssembly/simd/pull/290) - i64x2.bitmask (https://github.com/WebAssembly/simd/pull/368) - signselect ops (https://github.com/WebAssembly/simd/pull/124)
* [GC] Add ref.test and ref.cast (#3439)Alon Zakai2020-12-111-2/+17
| | | | This adds enough to read and write them and test that, but leaves interpreter support for later.
* [GC] Add Array operations (#3436)Alon Zakai2020-12-101-5/+36
| | | | | | | | | | | | | | array.new/get/set/len - pretty straightforward after structs and all the infrastructure for them. Also fixes validation of the unnecessary heapType param in the text and binary formats in structs as well as arrays. Fixes printing of packed types in type names, which emitted i32 for them. That broke when we emitted the same name for an array of i8 and i32 as in the new testing here. Also fix a bug in Field::operator< which was wrong for packed types; again, this was easy to notice with the new testing.
* [GC] Add struct.new and start to test interesting execution (#3433)Alon Zakai2020-12-091-3/+15
| | | | | | | | | | | | | | With struct.new read/write support, we can start to do interesting things! This adds a test of creating a struct and seeing that references behave like references, that is, if we write to the value X refers to, and if Y refers to the same thing, when reading from Y's value we see the change as well. The test is run through all of -O1, which uncovered a minor issue in Precompute: We can't try to precompute a reference type, as we can't replace a reference with a value. Note btw that the test shows the optimizer properly running CoalesceLocals on reference types, merging two locals.
* [GC] Add basic RTT support (#3432)Alon Zakai2020-12-081-2/+13
| | | | | | | | | | | | | | | | This adds rtt.canon and rtt.sub together with RTT type support that is necessary for them. Together this lets us test roundtripping the instructions and types. Also fixes a missing traversal over globals in collectHeapTypes, which the example from the GC docs requires, as the RTTs are in globals there. This does not yet add full interpreter support and other things. It disables initial contents on GC in the fuzzer, to avoid the fuzzer breaking. Renames the binary ID for exnref, which is being removed from the spec, and which overlaps with the binary ID for rtt.
* [GC] Add struct.set (#3430)Alon Zakai2020-12-071-3/+10
| | | | | | | | | | Mostly straightforward after struct.get. This renames the value field in struct.get to ref. I think this makes more sense because struct.set has both a reference to a thing, and a value to set onto that thing. So calling the former ref seems more consistent, giving us ref, value. This mirrors load/store for example where we use ptr, value, and ref is playing the role of ptr here basically.
* [GC] Add struct.get instruction parsing and execution (#3429)Alon Zakai2020-12-071-1/+9
| | | | | | | | | | | | | | | | | | | | This is the first instruction that uses a GC Struct or Array, so it's where we start to actually need support in the interpreter for those values, which is added here. GC data is modeled as a gcData field on a Literal, which is just a Literals. That is, both a struct and an array are represented as an array of values. The type which is alongside would indicate if it's a struct or an array. Note that the data is referred to using a shared_ptr so it should "just work", but we'll only be able to really test that once we add struct.new and so can verify that references are by reference and not value, etc. As the first instruction to care about i8/16 types (which are only possible in a Struct or Array) this adds support for parsing and emitting them. This PR includes fuzz fixes for some minor things the fuzzer found, including some bad printing of not having ResultTypeName in necessary places (found by the text format roundtripping fuzzer).
* [TypedFunctionReferences] Enable call_ref in fuzzer, and fix minor misc fuzz ↵Alon Zakai2020-11-251-2/+0
| | | | | | | | | | | | | | | | | | | | bugs (#3401) * Count signatures in tuple locals. * Count nested signature types (confirming @aheejin was right, that was missing). * Inlining was using the wrong type. * OptimizeInstructions should return -1 for unhandled types, not error. * The fuzzer should check for ref types as well, not just typed function references, similar to what GC does. * The fuzzer now creates a function if it has no other option for creating a constant expression of a function type, then does a ref.func of that. * Handle unreachability in call_ref binary reading. * S-expression parsing fixes in more places, and add a tiny fuzzer for it. * Switch fuzzer test to just have the metrics, and not print all the fuzz output which changes a lot. Also fix noprint handling which only worked on binaries before. * Fix Properties::getLiteral() to use the specific function type properly, and make Literal's function constructor require that, to prevent future bugs. * Turn all input types into nullable types, for now.