summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* getHeapTypeCounts() must note select types for references (#5540)Alon Zakai2023-03-031-0/+3
| | | | Without this we hit an assertion on trying to write the binary, on a missing heap type.
* Fuzzer: Be careful with ArrayNew sizes (#5537)Alon Zakai2023-03-011-1/+11
| | | | Only very rarely ask to create a huge array, as that can easily hit a host size limit and cause a run to be ignored.
* Fuzzer: Ignore host limits (#5536)Alon Zakai2023-03-011-4/+10
| | | | | We can't just skip host limits (#5534) but must also ignore execution at that point, as optimizations can change the results if they change whether we reach a host limit.
* Validation: Function types with multiple results require multivalue (#5535)Alon Zakai2023-03-011-2/+7
| | | | | | This was not noticed before because normally if there is a function type with multiple results then there is also a function with that property. But it is possible to make small testcases without such a function, and one might be imported etc., so we do need to validate this.
* JSPI - Replace function table references with JSPI'ed wrapper. (#5519)Brendan Dahl2023-03-011-0/+18
| | | | This makes it possible to get the JSPI'ed version of the function from the function table.
* Fuzzer: Handle HostLimitException during instance creation (#5534)Alon Zakai2023-03-011-0/+5
| | | | We handle this like the existing handling of TrapException: we skip running this module (since we can't even instantiate it, so there is nothing to run).
* Fuzzer: Only use RefAs in a function context (#5533)Alon Zakai2023-03-011-1/+4
| | | It is not a constant instruction and cannot be used in globals.
* Fuzzer: Create struct/array initial values when fields are nondefaultable ↵Alon Zakai2023-03-011-4/+18
| | | | (#5529)
* Fuzzer: Avoid local.get when not in a function (#5528)Alon Zakai2023-03-011-1/+1
|
* Parse and print `array.new_fixed` (#5527)Thomas Lively2023-02-288-10/+20
| | | | | | | | | 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-2830-99/+106
| | | | | | | | 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.
* Emit source map information for control flow structures (#5524)Alon Zakai2023-02-281-1/+1
| | | | | With this, the sourcemap testcase outputs the exact same thing as the input. Followup to #5504
* [wasm2js] Fix atomic notify to take an unsigned count (#5525)Thomas Lively2023-02-271-2/+3
| | | | | Without this fix, the common idiom of using `INT_MAX` in C source to mean an unlimited number of waiters should be woken up actually compiled down to an argument of -1 in JS, causing zero waiters to be woken.
* [wasm-ctor-eval] Properly handle multiple ctors with GC (#5522)Alon Zakai2023-02-241-8/+22
| | | | | | | | | | Before, a single ctor with GC worked, but any subsequent ones simply dropped the globals from the previous ones, because we were missing an addGlobal in an important place. Also, we can get confused about which global names are in use in the module, so fix that as well by storing them directly (we keep removing and re-adding globals, so we can't use the normal module mechanism to find which names are in use).
* Memory flattening cannot be done in the presence of DataDrop (#5521)Alon Zakai2023-02-241-7/+9
| | | | Like MemoryInit, this instruction cares about segment identity, so merging segments into one big one for flattening is disallowed.
* Fix sourcemap nesting in reading and writing (#5504)JesseCodeBones2023-02-243-14/+31
| | | | The stack logic was incorrect, and led to source locations being emitted on parents instead of children.
* Fix validation of DataDrop (#5517)Alon Zakai2023-02-231-3/+6
| | | Fixes #5511
* [Fuzzer] Simplify the hang limit mechanism (#5513)Alon Zakai2023-02-236-37/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously the idea was that we started with HANG_LIMIT = 10 or so, and we'd decrement it by one in each potentially-recursive call and loop entry. When we reached 0 we'd start to unwind the stack. Then, after we unwound it all the way, we'd reset HANG_LIMIT before calling the next export. That approach adds complexity that each "execution wrapper", like for JS or for --fuzz-exec, had to manually reset HANG_LIMIT. That was done by calling an export. Calls to those exports had to appear in various places, which is sort of a hack. The new approach here does the following when the hang limit reaches zero: It resets HANG_LIMIT, and it traps. The trap unwinds the call stack all the way out. When the next export is called, it will have a fresh hang limit since we reset it before the trap. This does have downsides. Before, we did not always trap when we hit the hang limit but rather we'd emit something unreachable, like a return. The idea was that we'd leave the current function scope at least, so we don't hang forever. That let us still execute a small amount of code "on the way out" as we unwind the stack. I'm not sure it's worth the complexity for that. The advantages of this PR are to simplify the code, and also it makes more fuzzing approaches easy to implement. I'd like to add a wasm-ctor-eval fuzzer, and having to add hacks to call the hang limit init export in it would be tricky. With this PR, the execution model is simple in the fuzzer: The exports are called one by one, in order, and that's it - no extra magic execution needs to be done. Also bump the hang limit from 10 to 100, just to give some more chance for code to run.
* [wasm-ctor-eval] Stop evalling at table.set for now (#5516)Alon Zakai2023-02-231-0/+7
| | | | Until we get full support for serializing table changes, stop evalling so we do not break things.
* [wasm-ctor-eval] Add v128 load/store support (#5512)Alon Zakai2023-02-231-0/+8
|
* [wasm-ctor-eval] Add support for multivalue serialization and a quiet mode ↵Alon Zakai2023-02-231-18/+56
| | | | | | | | | | (#5510) Simply loop over the values and use tuple.make. This also adds a lit test for ctor-eval. I found that the problem blocking us before was the logging, which confuses the update script. As this test at least does not require that logging, this PR adds a --quiet flag that disables the logging, and then a lit test just works.
* [Strings] Add hashing and equality support for strings (#5507)Alon Zakai2023-02-212-0/+11
| | | This is enough to test RSE.
* [Strings] Interpret string.eq and string.compare (#5501)Alon Zakai2023-02-171-1/+66
|
* [Strings] Add support for strings in getLiteral and Literal() (#5500)Alon Zakai2023-02-174-6/+14
| | | This is enough for DAE and other opts to run on string consts.
* [Strings] Start some basic fuzzing support for strings (#5499)Alon Zakai2023-02-171-0/+2
| | | | | This is necessary to avoid fuzzer breakage after #5497 as it added a test with strings. We could also ignore that file, like we do for other string files, but this was not much work so just implement it.
* Fuzzer: Be more careful with unreachable code (#5498)Alon Zakai2023-02-162-3/+14
| | | | Half the time, never add any unreachable code. This ensures we run the most code we possibly can half the time, at least.
* [Strings] string.compare does not return a bool (#5497)Alon Zakai2023-02-161-1/+3
| | | | string.eq does, and when we added string.compare I forgot to adjust the boolean property for that new opcode.
* Fuzzer: Replace with unreachable sometimes (#5496)Alon Zakai2023-02-162-15/+21
| | | | | | | | | | | | | This makes the fuzzer replace things with an unreachable instruction in rare situations. The hope was to find bugs like #5487, but instead it's mostly found bugs in the inliner actually (#5492, #5493). This also fixes an uncovered bug in the fuzzer, where we refinalized in more than one place. It is unsafe to do so before labels are fixed up (as duplicate labels can confuse us as to which types are needed; this is actually the same issue as in #5492). To fix that, remove the extra refinalize that was too early, and also rename the fixup function since it does a general fixup for all the things.
* Never flip a call from unreachable to reachable during inlining (#5493)Alon Zakai2023-02-161-8/+33
| | | | | | | | | | | | See example in the new comment. In general, we never want to go from unreachable to reachable (refinalize doesn't even try), as it misses out on DCE opportunities. Also it may have validation issues, which is how the fuzzer found this. Remove code in the same place that was redundant after the refinalize was added in #5492. That simplifies some existing testcases slightly, by removing an unneeded br we added, and now we add a new unreachable at the end in other cases that need it.
* [Strings] Initial string execution support (#5491)Alon Zakai2023-02-159-15/+104
| | | | | | | | | | Store string data as GC data. Inefficient (one Const per char), but ok for now. Implement string.new_wtf16 and string.const, enough for basic testing. Create strings in makeConstantExpression, which enables ctor-eval support. Print strings in fuzz-exec which makes testing easier.
* Unreachability fixes for inlining (#5492)Alon Zakai2023-02-151-5/+10
| | | | | | | | | | | | We must refinalize as inlining unreachable code can lead to more things becoming unreachable. We also must uniquify label names before refinalizing, as the IR must be valid at that time, so that code is moved. This causes some minor changes to existing test code (some label changes, and refinalization makes more things unreachable), but only the two new tests show actual problems that needed to be fixed.
* [wasm2js] Support nonzero offsets in memory.atomic.wait32 (#5489)Thomas Lively2023-02-143-6/+8
| | | | | The assertion that the offset is zero does not necessarily hold for code that uses this instruction via the clang builtin. Add support so that Emscripten wasm2js tests pass in the presence of such code.
* [Wasm GC] Fix array.new order of operand execution (#5487)Alon Zakai2023-02-141-4/+7
|
* Vacuum unneeded instructions even if children have effects (#5488)Alon Zakai2023-02-141-3/+12
| | | | | | | | | | | | | | | | | | | This can handle e.g. (drop (i32.add (call ..) (call ..) ) ) We can remove the add and just leave two dropped calls: (drop (call ..) ) (drop (call ..) )
* [Wasm GC] Optimize casts to bottom types (#5484)Alon Zakai2023-02-082-12/+34
| | | | | | | | | A cast to a non-nullable null (an impossible type) must trap. In traps-never-happen mode, a cast that either returns a null or traps will definitely return a null. Followup to #5461 which emits casts to bottom types.
* [C API] Add relaxed SIMD operations (#5482)dcode2023-02-073-0/+76
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Exposes the constants **Unary** * BinaryenRelaxedTruncSVecF32x4ToVecI32x4 * BinaryenRelaxedTruncSVecF32x4ToVecI32x4 * BinaryenRelaxedTruncZeroSVecF64x2ToVecI32x4 * BinaryenRelaxedTruncZeroUVecF64x2ToVecI32x4 **Binary** * BinaryenRelaxedSwizzleVecI8x16 * BinaryenRelaxedMinVecF32x4 * BinaryenRelaxedMaxVecF32x4 * BinaryenRelaxedMinVecF64x2 * BinaryenRelaxedMaxVecF64x2 * BinaryenRelaxedQ15MulrSVecI16x8 * BinaryenDotI8x16I7x16SToVecI16x8 **SIMDTernary** * BinaryenRelaxedFmaVecF32x4 * BinaryenRelaxedFmsVecF32x4 * BinaryenRelaxedFmaVecF64x2 * BinaryenRelaxedFmsVecF64x2 * BinaryenLaneselectI8x16 * BinaryenLaneselectI16x8 * BinaryenLaneselectI32x4 * BinaryenLaneselectI64x2 * BinaryenDotI8x16I7x16AddSToVecI32x4 so the respective instructions can be produced and inspected with the C API.
* [Strings] Add experimental string.hash instruction (#5480)Alon Zakai2023-02-036-0/+20
| | | See WebAssembly/stringref#60
* [Wasm GC] Add AbstractTypeRefining pass (#5461)Alon Zakai2023-02-038-82/+395
| | | | | | | | | | | | | | If a type hierarchy has abstract classes in the middle, that is, types that are never instantiated, then we can optimize casts and other operations to them. Say in Java that we have `AbstractList`, and it only has one subclass `IntList` that is ever created, then any place we have an `AbstractList` we must actually have an `IntList`, or a null. (Or, if no subtype is instantiated, then the value must definitely be a null.) The actual implementation does a type mapping, that is, it finds all places using an abstract type and makes them refer to the single instantiated subtype (or null). After that change, no references to the abstract type remain in the program, so this both refines types and also cleans up the type section.
* Fix issues with ref.cast_nop (#5473)Alon Zakai2023-02-033-3/+3
| | | | It did not have proper annotation for the safety field, and also it could not handle basic heap types.
* Optimize ref.as_non_null removal effect computation (#5479)Alon Zakai2023-02-031-8/+14
| | | Followup to #5474
* [Wasm GC] Fix struct.set / ref.as_non_null ordering issue (#5474)Alon Zakai2023-02-021-10/+51
| | | | | | | | | | | If traps can happen, then we can't always remove a trap on null on the ref input to struct.set, since it has two children, (struct.set (ref.as_non_null X) (call $foo)) Removing the ref.as would not prevent a trap, as the struct.set will trap, but it does move the trap to after the call which is bad.
* [Wasm GC] Fix RemoveUnusedModuleEffects struct field reads with ↵Alon Zakai2023-02-021-5/+31
| | | | | | | | | | | | | | | | | | call.without.effects (#5477) If we see (struct.new $A (call $call.without.effects ;; intrinsic (ref.func $getter) ) ) then we can ignore side effects in that call, as the intrinsic tells us to. However, that function is still called (it will be called normally, after intrinsics are lowered away), and we should not remove it. That is, such an intrinsic call can be removed, but it cannot be left as it is and also ignored as if it does not exist.
* Fix racing merge breakage (#5472)Alon Zakai2023-02-011-3/+1
|
* [C API] Add experimental StringNew and StringEq variants (#5471)dcode2023-02-013-7/+45
| | | | Adds APIs for string.from_code_point, string.new_utf8_try, string.new_utf8_array_try (#5459) and string.compare (#5453).
* RemoveUnusedModuleElements: Support function subtyping (#5470)Alon Zakai2023-02-011-18/+32
| | | | When we see a call_ref or call_indirect of a heap type, we might be calling a subtype of that type.
* RemoveUnusedModuleElements: Optimize unread struct.new fields (#5445)Alon Zakai2023-02-012-3/+166
| | | | | | | | | | | | | | | | | | | | | | | | | | | | This is similar to the existing optimization for function references: a RefFunc is just a reference, and we do not consider the function actually used unless some CallRef can actually call it. Here we optimize StructNew fields by tracking if they are read. Consider this object: (struct.new $object (global.get $vtable) ) Before this PR, when we saw that StructNew we'd make that global used, and process all of its contents, which look like this: (global $vtable (struct.new $object (ref.func $foo) ) ) With this PR we track which fields on the struct types are even read. If they are not then we do not add uses of the things they refer to. In this example, the global vtable would be referenced, but not used, and likewise the RefFunc inside it. The technical way we handle this is to walk StructNews carefully: when we see a field that has been read, we can just read it normally, but if it has not been read then we note it on the side, and only process it later if we see a read.
* RemoveUnusedModuleElements: Handle changes to tables (#5469)Alon Zakai2023-01-311-0/+5
| | | | | This is a long-standing bug - we ignored the possibility of table.set in this pass. We have few tests for this so it took a while for the fuzzer to notice it I suppose.
* OptimizeInstructions: Handle signed overflow properly in canOverflow() (#5467)Alon Zakai2023-01-311-13/+23
| | | | | We only checked for an unsigned overflow, which was wrong. Fixes #5464
* [NFC] Refactor RemoveUsedModuleElements to clarify references and uses (#5444)Alon Zakai2023-01-311-196/+309
| | | | | | | | | | | | | | | | | | | This pass talked about reachability and uses and such, but it wasn't very clear on those things. This refactors it to clarify that we look for references and uses, and what that means. Specifically, a reference to something makes us keep it alive, as we need to refer to it; a use makes us also keep it identical in its contents so that when it is used no behavior changes. A function reference without a call_ref that can call it is an example of a reference without a use, which this pass already optimized. To make that more clear in the code, this refactors out the reference-finding logic into a new struct, ReferenceFinder. This also replaces the normal walking logic with a more manual traversal using ChildIterator. This is necessary to properly differentiate references from uses, but is not immediately useful in this PR except for clarity. It will be necessary in the next PR, which this prepares for, in which we'll optimize more reference-but-not-use things.
* [NFC] Improve debug printing for type canonicalization (#5465)Thomas Lively2023-01-301-2/+3
| | | | | | Use an `IndexedTypeNameGenerator` to give types stable names for the entire `dump` method rather than generating fresh type names every time a single type is printed. This makes it possible to understand the relationships between the types in the debug output.