summaryrefslogtreecommitdiff
path: root/test
Commit message (Collapse)AuthorAgeFilesLines
...
* [EH] Update C and binaryen.js API for delegate (#3565)Heejin Ahn2021-02-137-10/+117
| | | | | | | | | | This updates C and binaryen.js API to match the new `Try` structure to support `delegate`, added in #3561. Now `try` can take a name (which can be null) like a block, and also has an additional `delegateTarget` field argument which should only be used for try-delegate and otherwise null. This also adds several more variant of `makeTry` methods in wasm-builder. Some are for making try-delegate and some are for try-catch(_all).
* Print the features section in a comment (#3563)Alon Zakai2021-02-122-1/+3
|
* Allow specifying additional features past the features section (#3564)Alon Zakai2021-02-121-1/+8
| | | | | That is, if a wasm says "simd", it is ok to let the user specify simd as well as more features, and the the optimizer can perhaps do something with them.
* [EH] Support reading/writing of delegate (#3561)Heejin Ahn2021-02-1223-92/+639
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 ) ) ```
* finalize: strip segments that contain only EM_ASM/EM_JS data (#3557)Sam Clegg2021-02-123-5/+73
| | | | | | | If we find a data segment whose entire contents is EM_JS or EM_ASM strings then strip it from the binary. See: https://github.com/emscripten-core/emscripten/pull/13443
* StackSignature subtypes and LUBs (#3543)Thomas Lively2021-02-112-48/+180
| | | | | | | | Add a utility for calculating the least upper bounds of two StackSignatures, taking into account polymorphic unreachable behavior. This will important in the finalization and validation of Poppy IR blocks, where a block is allowed to directly produce fewer values than the branches that target it carry if the difference can be made up for by polymorphism due to an unreachable instruction in the block.
* Use correct table name in GenerateDynCalls (#3560)Thomas Lively2021-02-102-3/+37
| | | | | | | GenerateDynCalls was hardcoding the table name to use in the call_indirects in the dyncall thunks. The hardcoded name was different from the default name for imported tables, so the call_indirects referred to a nonexistent table when dynamic linking was enabled. This PR instead uses the name of table 0 when creating call_indirects for the dyncall thunks.
* Simplify asmConst handling. NFC. (#3558)Sam Clegg2021-02-097-19/+19
| | | | | | | | Support for multiple signatures per JS code string was removed in #2422. emscripten now only needs to know that address and the body of the JS function. See https://github.com/emscripten-core/emscripten/pull/13452.
* Poppify pass (#3541)Thomas Lively2021-02-092-0/+489
| | | | | | | | | | | | | | Adds a Poppify ("--poppify") pass for converting normal Binaryen IR to Poppy IR. Like the existing construction of Stacky IR, Poppify depends on the BinaryenIRWriter to drive the emitting of instructions in correct stack machine order. As instructions are "emitted," Poppify replaces their children with pops and collects them in a list. At the end of each scope, Poppify creates a block containing all the collected instructions for that scope and injects that block into the enclosing scope. All tuple globals and instructions dealing with tuples are also expanded to remove all tuples from the program. The validator currently fails to validate many valid Poppy IR patterns produced in the tests, but fixing that is left as follow-on work to keep this PR focused on the Poppify pass itself. For now the tests simply skip validation.
* [reference-types] remove single table restriction in IR (#3517)Abbas Mashayekh2021-02-0948-132/+454
| | | Adds support for modules with multiple tables. Adds a field for the table name to `CallIndirect` and updates the C/JS APIs accordingly.
* [GC] Support casts of function types (#3554)Alon Zakai2021-02-092-0/+82
| | | | | | | | | | | | | | | I had completely missed that the spec allows ref.cast etc. of function types, and not just data. Function types do not have an RTT, unlike GC data, but we can still cast them. A function reference has the canonical RTT of the signature for that type, so it's like a simplified case of the GC world, without a hierarchy of RTTs. As it turns out, our validation did not rule out rtt.canon of a function type, nor ref.cast of one, so we unintentionally already had all the support for this aside from the actual casting, which this PR adds. The addition is mostly trivial, except that we now need a Module in the base ExpressionRunner class, so that we can go from a function name to the actual function. This PR refactors things to allow that.
* Fix removal of EM_JS functions (#3552)Sam Clegg2021-02-081-0/+28
| | | | | | The algorithm was trying to remove all __em_js functions but it was using the names of functions rather than export names so it was failing to remove these functions unless the internal function names happened to match (this turns out of the true for build with debug names).
* [GC] Avoid replacing non-defaultable types in the fuzzer (#3549)Alon Zakai2021-02-082-55/+53
| | | | We can't arbitrarily replace a non-defaultable type, as it may lead to us needing a temp local for it (say, in a tuple).
* Add a test for memory.size in wasm2js (#3547)Alon Zakai2021-02-043-2/+13
| | | Support has been there all along, but we didn't have a reference test of it.
* [GC] Do not crash on unreachable inputs to struct.get/set (#3542)Alon Zakai2021-02-034-0/+27
| | | | | | | If the reference is unreachable then we cannot find the heap type to print in the text format. Instead of crashing or emitting something invalid, print a block instead - the block contains the children so they are emitted, and as the instruction was unreachable anyhow, this has no noticeable effect. It also parallels what we do in the binary format - skip unreachable code.
* Support Stack IR for new try-catch(_all) (#3538)Heejin Ahn2021-02-032-1/+9
| | | | | This adds missing stack IR printing support for the new form of try-catch-catch_all. Also uses `printMedium` when printing instructions consistently.
* [GC] dataref typing fixes (#3536)Alon Zakai2021-02-032-0/+33
| | | | | | | dataref was not noted as isRef, and we also did not handle the LUB for it, which caused validation errors. After these two fixes, it is possible to add a testcase that goes through the optimizer. View without whitespace as the LUB change has a lot of that.
* Prototype i32x4.widen_i8x16_{s,u} (#3535)Thomas Lively2021-02-016-32/+72
| | | | | | | | 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-014-12/+42
| | | | | | | | | | | 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] Don't emit i31ref in fuzzer (#3531)Alon Zakai2021-02-011-31/+32
| | | | | | | That type is non-nullable, so we need to disable it until we fully support that. Right now if we emit such locals we immediately get a validation error. With this change the fuzzer can run at least a few thousand iterations with no errors once more.
* [GC] ref.as_non_null (#3527)Alon Zakai2021-01-284-0/+16
| | | | | | 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-286-5/+131
| | | | | | | | 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-275-16/+22
| | | | | | | 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-2710-146/+146
| | | | | | | | | | 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-274-3/+59
| | | | | | | | 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-265-0/+84
|
* [GC] RefIsNull => RefIs. (#3516)Alon Zakai2021-01-265-21/+21
| | | | | | | | 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.
* Warn when running a pass not compatible with DWARF (#3506)Alon Zakai2021-01-261-0/+12
| | | | | | | | | | | | Previously the addDefault* methods would avoid adding opt passes that we know are incompatible with DWARF. However, that didn't handle the case of passes that are added in other ways. For example, when running Asyncify, emcc will run --flatten before, and that pass is not compatible with DWARF. This PR lets us warn on that by annotating the passes themselves. Then we use those annotation to either not run a pass at all (matching the previous behavior) or to show a warning when necessary. Fixes emscripten-core/emscripten#13288 . That is, concretely after this PR running asyncify + DWARF will show a warning to the user.
* Debug info handling for new EH try-catch (#3496)Alon Zakai2021-01-253-0/+545
| | | | | | | | We now have multiple catches in each try, and a possible catch-all. This changes our "extra delimiter" storage to store either an "else" (unchanged from before) or an arbitrary list of things - we use that for catches.
* Reorder i31ref and dataref (#3509)Heejin Ahn2021-01-239-31/+50
| | | | | | | | | | The binary spec (https://docs.google.com/document/d/1yAWU3dbs8kUa_wcnnirDxUu9nEBsNfq0Xo90OWx6yuo/edit#) lists `dataref` after `i31ref`, and `dataref` also comes after `i31ref` in its binary code in the value-increasing order. This reorders these two in wasm-type.h and other places, although in most of those places the order is irrelevant. This also adds C and JS API for `dataref`.
* Partially split up functions in optimize-instructions.wast (#3508)Thomas Lively2021-01-221-1609/+1722
| | | | | | | | | | FileCheck test cases are much more readable when their output assertions are close to the corresponding input lines. #3503 introduced a script for updating FileCheck assertions, but it only knows how to place input and output lines together at the function boundary, so smaller functions will produce more readable tests. optimize-instructions.wast has some very large functions that include many test cases, so this PR breaks up some of those functions into smaller functions to make the tests more readable. This PR only changes the first quarter of the file, leaving further improvements as future work.
* Remove exnref and br_on_exn (#3505)Heejin Ahn2021-01-2236-2009/+245
| | | This removes `exnref` type and `br_on_exn` instruction.
* Remove translate-to-fuzz_all-features.txt (#3504)Heejin Ahn2021-01-221-1143/+0
| | | This file has not been updated since #3401.
* Introduce a script for updating lit tests (#3503)Thomas Lively2021-01-2112-12650/+12620
| | | | And demonstrate its capabilities by porting all tests of the optimize-instructions pass to use lit and FileCheck.
* [GC] Add dataref type (#3500)Alon Zakai2021-01-217-17/+32
| | | | | This is not 100% of everything, but is enough to get tests passing, which includes full binary and text format support, getting all switches to compile without error, and some additions to InstrumentLocals.
* Update interpreter for new EH spec (#3498)Heejin Ahn2021-01-211-105/+118
| | | | | | | | | | | | | This updates the interpreter for the EH instructions (modulo `delegate`) to match the new spec. Before we had an `exnref` type so threw a `Literal` of `exnref` type which contained `ExceptionPackage`. But now that we don't have `exnref` anymore, so we add the contents of `ExceptionPackage` to `WasmException`, which is used only for the `ExpressionRunner` class hierarchy. `exnref` and `ExceptionPackage` will be removed in a followup CL. This allows nonzero depths for `rethrow` for now for testing; we disallowed that for safety measure, but given that there are no passes that modifies that field, I think the risk is low.
* CFG traversal for the new EH spec (#3494)Heejin Ahn2021-01-212-86/+300
| | | | | | | | | | | | | | | | | | | | | | This updates CFG traversal to match the new spec. Previously there was only a single `catch` block that caught all exceptions, so all throwing instructions needed to have a link to its innermost catch BB. But now we can have multiple catches per try, requiring all throwing instrutions to have an edge to all of those innermost catch BBs. Furthermore, if there are only `catch`es and not a `catch_all` in a try, throwing instructions can further unwind to outer catches until they find a `catch_all`. `unwindCatchStack` and `unwindExprStack` are necessary to track and make correct links between throwing instructions and their unwind destination BBs. `processCatchStack` is used to remember the catch BBs currently being processed, so that after processing all of them, we can make a link from each of those catch's last block to the continuation block after the try-catch. RSE test cases are updated because they use the CFG traversal. The tests there mainly test that if all possible CFG edge to a `local.set` sets the same value to a local, the `local.set` is redundant and thus can be removed.
* Simplify set/gets of vectors in binaryen.js (#3495)Heejin Ahn2021-01-201-8/+19
| | | | | This uses existing `getAllNested` function in `ExpressionWrapper` functions. Also adds `setAllNested` which works in the other direction and uses it within `ExpressionWrapper` functions.
* Prototype additional f64x2 conversions (#3501)Thomas Lively2021-01-195-0/+121
| | | | As proposed in https://github.com/WebAssembly/simd/pull/383, with opcodes coordinated with the WIP V8 prototype.
* wasm-reduce: Fix setting of feature flags after loading (#3493)Alon Zakai2021-01-152-0/+42
| | | | | We mistakenly did not set the flags to all, which meant that if the features section was not present, we'd not have the proper features set, leading to errors on writing.
* [GC] Read and lower Let instructions (#3485)Alon Zakai2021-01-152-0/+72
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For now we don't support non-nullability, and can therefore lower a let into simpler things. That is, (let $x = ... ;; ) => (block $x = ... ;; ) This lets us handle wasm binaries with let, so that we can optimize them (with the current downside of losing non-nullability). This is still not trivial to do, sadly, because the indexing of lets is somewhat odd in the binary. A let modifies the indexes of other things declared before it, which means that index "0" means different things at different times. And this is trickier for us because we add more locals as needed for tuples and stacky code. So this PR makes us track the absolute local indexes from which each let started to allocate its locals. The binary testcase was created from this wat using wasp: (module (type $vector (array (field (mut f64)))) (func $main (local $x i32) (local $y i32) (drop (local.get $x)) ;; 0 is the index appearing in the binary ;; first let (array.new_with_rtt $vector (f64.const 3.14159) (i32.const 1) (rtt.canon $vector) ) (let (local $v (ref $vector)) (drop (local.get $v)) ;; 0 (drop (local.get $x)) ;; 1 ;; another one, nested (array.new_with_rtt $vector (f64.const 1234) (i32.const 2) (rtt.canon $vector) ) (let (local $w (ref $vector)) (drop (local.get $v)) ;; 1 (drop (local.get $w)) ;; 0 (drop (local.get $x)) ;; 2 ) ) ;; another one, later (array.new_with_rtt $vector (f64.const 2.1828) (i32.const 3) (rtt.canon $vector) ) (let (local $v (ref $vector)) (drop (local.get $v)) ;; 0 (drop (local.get $x)) ;; 1 ) (drop (local.get $x)) ;; 0 ) )
* Reducer: Improve warning on scripts that ignore the input (#3490)Alon Zakai2021-01-151-0/+13
| | | | | | | | | | | | | The risk the warning checks for is giving the reducer a script that ignores the input. To do so it runs the command in the input, and runs it on a garbage file, and checks if the result is different. However, if the script does immediately fail on the input - because the input is a crash testcase or such - then this does not work, as the result on a garbage input may be the same error. To avoid that, also check what happens on a trivial valid wasm as input. Only show the warning if the result on the original input, on a garbage wasm, and on a trivial wasm, are all the same - in that case, likely the script really is ignoring the input.
* Basic EH instrucion support for the new spec (#3487)Heejin Ahn2021-01-1543-805/+1053
| | | | | | | | | | | | | | | | | | | | 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.
* [GC] RTT types are not defaultable (#3489)Alon Zakai2021-01-132-67/+27
| | | See WebAssembly/gc#175
* [GC] Fix casts of non-GC data (#3483)Alon Zakai2021-01-122-0/+21
| | | | | The code previously assumed it could always call getGCData, but that assumes the input is an array or a struct. It could also be an anyref etc. that contains something other than GC data.
* Remove extra-unreachable.wast (#3480)Heejin Ahn2021-01-124-395/+0
| | | | | | | This test seems to be added in #2266 to test custom unreachable generation in `BinaryenIRWriter`, but given that the `fromBinary` files only contain a single `unreachable` for the whole function, I don't think this test serves a lot of purpose. Also the custom unreachable generation logic in #2266 was largely replaced in #3110.
* [GC] More HeapType instead of Type (#3475)Alon Zakai2021-01-112-0/+16
| | | | | | | | To handle both nullable and non-nullable i31s and other heap types, we cannot just look at the isBasic case (which is just one of the two). This may fix this issue on the release builder: https://github.com/WebAssembly/binaryen/runs/1669944081?check_suite_focus=true but the issue does not reproduce locally, so I worry it is something else...
* [GC] Fix minor binary format issues of ordering and immediates (#3472)Alon Zakai2021-01-112-0/+6
| | | | | | | | | Noticed by comparing to V8 and Wasp. After this things are almost identical, but there is also at least https://bugs.chromium.org/p/v8/issues/detail?id=11300 Test updates are due to having an instruction with two operands of which one is unreachable. The new order puts the non-unreachable first, so it is not removed by round-tripping through the binary format like before (which removes all unreachable code).
* finalize: remove initializers from metadata output (#3479)Sam Clegg2021-01-1117-51/+0
| | | See https://github.com/emscripten-core/emscripten/pull/13208
* [GC] Validate that struct.set is to a mutable field. (#3473)Alon Zakai2021-01-086-37/+37
| | | | This required a few test fixes, to ensure we don't have invalid wasts with writes to immutable fields.