summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-stack.cpp
Commit message (Collapse)AuthorAgeFilesLines
* [EH] Replace event with tag (#3937)Heejin Ahn2021-06-181-2/+2
| | | | | | | | | | | 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
* [Wasm GC] rtt.fresh_sub (#3936)Alon Zakai2021-06-171-1/+2
| | | | | | | | | | This is the same as rtt.sub, but creates a "new" rtt each time. See https://docs.google.com/document/d/1DklC3qVuOdLHSXB5UXghM_syCh-4cMinQ50ICiXnK3Q/edit# The old Literal implementation of rtts becomes a little more complex here, as it was designed for the original spec where only structure matters. It may be worth a complete redesign there, but for now as the spec is in flux I think the approach here is good enough.
* [Wasm GC] Add negated BrOn* operations (#3913)Alon Zakai2021-06-021-0/+15
| | | | | | 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/+6
| | | | | | | | 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).
* 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
* Update SIMD binary constants (#3799)Daniel Wirtz2021-04-121-60/+60
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Updates binary constants of SIMD instructions to match new opcodes: * I16x8LoadExtSVec8x8 -> V128Load8x8S * I16x8LoadExtUVec8x8 -> V128Load8x8U * I32x4LoadExtSVec16x4 -> V128Load16x4S * I32x4LoadExtUVec16x4 -> V128Load16x4U * I64x2LoadExtSVec32x2 -> V128Load32x2S * I64x2LoadExtUVec32x2 -> V128Load32x2U * V8x16LoadSplat -> V128Load8Splat * V16x8LoadSplat -> V128Load16Splat * V32x4LoadSplat -> V128Load32Splat * V64x2LoadSplat -> V128Load64Splat * V8x16Shuffle -> I8x16Shuffle * V8x16Swizzle -> I8x16Swizzle * V128AndNot -> V128Andnot * F32x4DemoteZeroF64x2 -> F32x4DemoteF64x2Zero * I8x16NarrowSI16x8 -> I8x16NarrowI16x8S * I8x16NarrowUI16x8 -> I8x16NarrowI16x8U * I16x8ExtAddPairWiseSI8x16 -> I16x8ExtaddPairwiseI8x16S * I16x8ExtAddPairWiseUI8x16 -> I16x8ExtaddPairwiseI8x16U * I32x4ExtAddPairWiseSI16x8 -> I32x4ExtaddPairwiseI16x8S * I32x4ExtAddPairWiseUI16x8 -> I32x4ExtaddPairwiseI16x8U * I16x8Q15MulrSatS -> I16x8Q15mulrSatS * I16x8NarrowSI32x4 -> I16x8NarrowI32x4S * I16x8NarrowUI32x4 -> I16x8NarrowI32x4U * I16x8ExtendLowSI8x16 -> I16x8ExtendLowI8x16S * I16x8ExtendHighSI8x16 -> I16x8ExtendHighI8x16S * I16x8ExtendLowUI8x16 -> I16x8ExtendLowI8x16U * I16x8ExtendHighUI8x16 -> I16x8ExtendHighI8x16U * I16x8ExtMulLowSI8x16 -> I16x8ExtmulLowI8x16S * I16x8ExtMulHighSI8x16 -> I16x8ExtmulHighI8x16S * I16x8ExtMulLowUI8x16 -> I16x8ExtmulLowI8x16U * I16x8ExtMulHighUI8x16 -> I16x8ExtmulHighI8x16U * I32x4ExtendLowSI16x8 -> I32x4ExtendLowI16x8S * I32x4ExtendHighSI16x8 -> I32x4ExtendHighI16x8S * I32x4ExtendLowUI16x8 -> I32x4ExtendLowI16x8U * I32x4ExtendHighUI16x8 -> I32x4ExtendHighI16x8U * I32x4DotSVecI16x8 -> I32x4DotI16x8S * I32x4ExtMulLowSI16x8 -> I32x4ExtmulLowI16x8S * I32x4ExtMulHighSI16x8 -> I32x4ExtmulHighI16x8S * I32x4ExtMulLowUI16x8 -> I32x4ExtmulLowI16x8U * I32x4ExtMulHighUI16x8 -> I32x4ExtmulHighI16x8U * I64x2ExtendLowSI32x4 -> I64x2ExtendLowI32x4S * I64x2ExtendHighSI32x4 -> I64x2ExtendHighI32x4S * I64x2ExtendLowUI32x4 -> I64x2ExtendLowI32x4U * I64x2ExtendHighUI32x4 -> I64x2ExtendHighI32x4U * I64x2ExtMulLowSI32x4 -> I64x2ExtmulLowI32x4S * I64x2ExtMulHighSI32x4 -> I64x2ExtmulHighI32x4S * I64x2ExtMulLowUI32x4 -> I64x2ExtmulLowI32x4U * I64x2ExtMulHighUI32x4 -> I64x2ExtmulHighI32x4U * F32x4PMin -> F32x4Pmin * F32x4PMax -> F32x4Pmax * F64x2PMin -> F64x2Pmin * F64x2PMax -> F64x2Pmax * I32x4TruncSatSF32x4 -> I32x4TruncSatF32x4S * I32x4TruncSatUF32x4 -> I32x4TruncSatF32x4U * F32x4ConvertSI32x4 -> F32x4ConvertI32x4S * F32x4ConvertUI32x4 -> F32x4ConvertI32x4U * I32x4TruncSatZeroSF64x2 -> I32x4TruncSatF64x2SZero * I32x4TruncSatZeroUF64x2 -> I32x4TruncSatF64x2UZero * F64x2ConvertLowSI32x4 -> F64x2ConvertLowI32x4S * F64x2ConvertLowUI32x4 -> F64x2ConvertLowI32x4U
* 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-8/+8
| | | | | | | | | | | 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-106/+50
| | | | Also removes experimental SIMD instructions that were not included in the final spec proposal.
* [Wasm GC] Avoid std::map<Type,..> in mapLocals (#3683)Alon Zakai2021-03-121-1/+1
| | | | | Works around #3682 With this, I can roundtrip a large real-world testcase.
* [Wasm GC] Properly handle "typeindex" in the binary format (#3663)Alon Zakai2021-03-091-9/+9
| | | | | | | | | We handled them as S63 instead of U32. That should be fine, as all U32 values fit in S63. But it is not strictly correct. The signed encoding may use an additional byte which is unnecessary, and there is an actual correctness issue where a U32 may be interpreted as a large negative S63 (because it sign extends a final bit that happens to be 1). May help #3656 but that testcase still does not pass even with this.
* Fix binary writing of local name indexes (#3649)Alon Zakai2021-03-041-13/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When writing a binary, we take the local indexes in the IR and turn them into the format in the binary, which clumps them by type. When writing the names section we should be aware of that ordering, but we never were, as noticed in #3499 This fixes that by saving the mapping of locals when we are emitting the name section, then using it when emitting the local names. This also fixes the order of the types themselves as part of the refactoring. We used to depend on the ordering of types to decide which to emit first, but that isn't good for at least two reasons. First, it hits #3648 - that order is not fully defined for recursive types. Also, it's not good for code size - we've ordered the locals in a way we think is best already (ReorderLocals pass). This PR makes us pick an order of types based on that, as much as possible, that is, when we see a type for the first time we append it to a list whose order we use. Test changes: Some are just because we use a different order than before, as in atomics64. But some are actual fixes, e.g. in heap-types where we now have (local $tv (ref null $vector)) which is indeed right - v there is for vector, and likewise m for matrix etc. - we just had wrong names before. Another example, we now have (local $local_externref externref) whereas before the name was funcref, and which was wrong... seems like the incorrectness was more common on reference types and GC types, which is why this was not noticed before. Fixes #3499 Makes part of #3648 moot.
* [Wasm Exceptions] Fix StackIR writing of nested delegates (#3599)Alon Zakai2021-02-231-0/+5
| | | | | | We were missing a pop of catchIndexStack at a Delegate. It ends the scope, so it should do that, like TryEnd does. Found by emscripten-core/emscripten#13485 on -O2.
* [EH] Make rethrow's target a try label (#3568)Heejin Ahn2021-02-181-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I was previously mistaken about `rethrow`'s argument rule and thought it only counted `catch`'s depth. But it turns out it follows the same rule `delegate`'s label: the immediate argument follows the same rule as when computing branch labels, but it only can target `try` labels (semantically it targets that `try`'s corresponding `catch`); otherwise it will be a validation failure. Unlike `delegate`, `rethrow`'s label denotes not where to rethrow, but which exception to rethrow. For example, ```wasm try $l0 catch ($l0) try $l1 catch ($l1) rethrow $l0 ;; rethrow the exception caught by 'catch ($l0)' end end ``` Refer to this comment for the more detailed informal semantics: https://github.com/WebAssembly/exception-handling/issues/146#issuecomment-777714491 --- This also reverts some of `delegateTarget` -> `exceptionTarget` changes done in #3562 in the validator. Label validation rules apply differently for `delegate` and `rethrow` for try-catch. For example, this is valid: ```wasm try $l0 try delegate $l0 catch ($l0) end ``` But this is NOT valid: ```wasm try $l0 catch ($l0) try delegate $l0 end ``` So `try`'s label should be used within try-catch range (not catch-end range) for `delegate`s. But for the `rethrow` the rule is different. For example, this is valid: ```wasm try $l0 catch ($l0) rethrow $l0 end ``` But this is NOT valid: ```wasm try $l0 rethrow $l0 catch ($l0) end ``` So the `try`'s label should be used within catch-end range instead.
* cleanup to allow binaryen to be built in more strict environments (#3566)walkingeyerobot2021-02-161-2/+2
|
* [EH] Support reading/writing of delegate (#3561)Heejin Ahn2021-02-121-1/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-2/+3
| | | Adds support for modules with multiple tables. Adds a field for the table name to `CallIndirect` and updates the C/JS APIs accordingly.
* Support Stack IR for new try-catch(_all) (#3538)Heejin Ahn2021-02-031-0/+4
| | | | | This adds missing stack IR printing support for the new form of try-catch-catch_all. Also uses `printMedium` when printing instructions consistently.
* Prototype i32x4.widen_i8x16_{s,u} (#3535)Thomas Lively2021-02-011-0/+13
| | | | | | | | 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-8/+10
| | | | | | | | | | | 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.
* Remove unnecessary breakStack pushes for if/try (NFC) (#3533)Heejin Ahn2021-02-021-9/+0
| | | | | | This break stack is maintained to compute branch depths, but it seems we don't need to push and pop for each of if and else block or every single catch/catch_all block; it would be sufficient to have just one stack entry for the whole try-catch or if-else.
* [GC] ref.as_non_null (#3527)Alon Zakai2021-01-281-0/+3
| | | | | | 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-3/+19
| | | | | | | | 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] ref.as_* (#3520)Alon Zakai2021-01-271-0/+16
| | | | | | | | 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/+9
|
* [GC] RefIsNull => RefIs. (#3516)Alon Zakai2021-01-261-2/+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.
* Debug info handling for new EH try-catch (#3496)Alon Zakai2021-01-251-3/+4
| | | | | | | | 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.
* [GC] Update GC binary format for prototype v3 (#3507)Alon Zakai2021-01-221-4/+0
| | | | | Some fields were removed, see https://docs.google.com/document/d/1yAWU3dbs8kUa_wcnnirDxUu9nEBsNfq0Xo90OWx6yuo/edit#
* Remove exnref and br_on_exn (#3505)Heejin Ahn2021-01-221-8/+0
| | | This removes `exnref` type and `br_on_exn` instruction.
* [GC] Add dataref type (#3500)Alon Zakai2021-01-211-0/+3
| | | | | 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.
* Prototype additional f64x2 conversions (#3501)Thomas Lively2021-01-191-0/+24
| | | | 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-8/+24
| | | | | | | | | | | | | | | | | | | | 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] Fix minor binary format issues of ordering and immediates (#3472)Alon Zakai2021-01-111-4/+0
| | | | | | | | | 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).
* Prototype prefetch instructions (#3467)Thomas Lively2021-01-061-0/+14
| | | | 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-8/+16
| | | | | | 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-4/+6
| | | | | | | | | | | | | | | | 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.
* Prototype SIMD instructions implemented in LLVM (#3440)Thomas Lively2020-12-111-0/+35
| | | | | | - 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/+4
| | | | 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-6/+23
| | | | | | | | | | | | | | 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-1/+7
| | | | | | | | | | | | | | 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/+4
| | | | | | | | | | | | | | | | 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/+4
| | | | | | | | | | 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/+13
| | | | | | | | | | | | | | | | | | | | 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] Implement call_ref (#3396)Alon Zakai2020-11-241-0/+5
| | | | | | | | Includes minimal support in various passes. Also includes actual optimization work in Directize, which was easy to add. Almost has fuzzer support, but the actual makeCallRef is just a stub so far. Includes s-parser support for parsing typed function references types.
* [TypedFunctionReferences] Add Typed Function References feature and use the ↵Alon Zakai2020-11-231-8/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | types (#3388) This adds the new feature and starts to use the new types where relevant. We use them even without the feature being enabled, as we don't know the features during wasm loading - but the hope is that given the type is a subtype, it should all work out. In practice, if you print out the internal type you may see a typed function reference-specific type for a ref.func for example, instead of a generic funcref, but it should not affect anything else. This PR does not support non-nullable types, that is, everything is nullable for now. As suggested by @tlively this is simpler for now and leaves nullability for later work (which will apparently require let or something else, and many passes may need to be changed). To allow this PR to work, we need to provide a type on creating a RefFunc. The wasm-builder.h internal API is updated for this, as are the C and JS APIs, which are breaking changes. cc @dcodeIO We must also write and read function types properly. This PR improves collectSignatures to find all the types, and also to sort them by the dependencies between them (as we can't emit X in the binary if it depends on Y, and Y has not been emitted - we need to give Y's index). This sorting ends up changing a few test outputs. InstrumentLocals support for printing function types that are not funcref is disabled for now, until we figure out how to make that work and/or decide if it's important enough to work on. The fuzzer has various fixes to emit valid types for things (mostly whitespace there). Also two drive-by fixes to call makeTrivial where it should be (when we fail to create a specific node, we can't just try to make another node, in theory it could infinitely recurse). Binary writing changes here to replace calls to a standalone function to write out a type with one that is called on the binary writer object itself, which maintains a mapping of type indexes (getFunctionSignatureByIndex).
* Remove dead code and unused includes. NFC. (#3328)Sam Clegg2020-11-081-0/+2
| | | Specifically try to cleanup use of asm_v_wasm.h and asmjs constants.
* Prototype new SIMD multiplications (#3291)Thomas Lively2020-10-281-0/+52
| | | | | | | Including saturating, rounding Q15 multiplication as proposed in https://github.com/WebAssembly/simd/pull/365 and extending multiplications as proposed in https://github.com/WebAssembly/simd/pull/376. Since these are just prototypes, skips adding them to the C or JS APIs and the fuzzer, as well as implementing them in the interpreter.
* DWARF: Fix handling of the end of control flow instructions (#3288)Alon Zakai2020-10-271-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously when we processed a block for example, we'd do this: ;; start is here (block (result type) ;; end is here .. contents .. ) ;; end delimiter is here Not how this represents the block's start and end as the "header", and uses an extra delimiter to mark the end. I think this is wrong, and was an attempt to handle some offsets from LLVM that otherwise made no sense, ones at the end of the "header". But it turns out that this makes us completely incorrect on some things where there is a low/high pc pair, and we need to understand that the end of a block is at the end opcode at the very end, and not the end of the header. This PR changes us to do that, i.e. ;; start is here (block (result type) .. contents .. ) ;; end is here This fixes a testcase already in the test suite, test/passes/fib_nonzero-low-pc_dwarf.bin.txt where you can see that lexical block now has a valid value for the end, and not a 0 (the proper scope extends all the way to the end of the big block in that function, and is now the same in the DWARF before and after we process it). test/passes/fannkuch3_dwarf.bin.txt is also improved by this. To implement this, this removes the BinaryLocations::End delimeter. After this we just need one type of delimiter actually, but I didn't refactor that any more to keep this PR small (see TODO). This removes an assertion in writeDebugLocationEnd() that is no longer valid: the assert ensures that we wrote an end only if there was a 0 for the end, but for a control flow structure, we write the end of the "header" automatically like for any expression, and then overwrite it later when we finish writing the children and the end marker. We could in theory special-case control flow structures to avoid the first write, but it would add more complexity. This uncovered what appears to be a possible bug in our debug_line handling, see test/passes/fannkuch3_manyopts_dwarf.bin.txt. That needs to be looked into more, but I suspect that was invalid info from when we looked at the end of the "header" of control flow structures. Note that there was one definite bug uncovered here, fixed by the extra } else if (locationUpdater.hasOldExprEnd(oldAddr)) { that is added here, which was definitely a bug.
* Implement i8x16.popcnt (#3286)Thomas Lively2020-10-271-0/+4
| | | | | | As proposed in https://github.com/WebAssembly/simd/pull/379. Since this instruction is still being evaluated for inclusion in the SIMD proposal, this PR does not add support for it to the C/JS APIs or to the fuzzer. This PR also performs a drive-by fix for unrelated instructions in c-api-kitchen-sink.c
* [NFC] `using namespace Abstract` to make matchers more compact (#3284)Thomas Lively2020-10-261-1/+1
| | | | | | | | | This change makes matchers in OptimizeInstructions more compact and readable by removing the explicit `Abstract::` namespace from individual operations. In some cases, this makes multi-line matcher expressions fit on a single line. This change is only possible because it also adds an explicit "RMW" prefix to each element of the `AtomicRMWOp` enumeration. Without that, their names conflicted with the names of Abstract ops.