summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
...
* Fuzzer: Emit nulls with low probability in makeConstCompoundRef (#5559)Alon Zakai2023-03-102-18/+28
| | | | In particular, the removed code path here that did a RefAsNonNull of a null was causing a lot of code to just trap.
* Emit the fuzzer hashMemory function after modifications (#5558)Alon Zakai2023-03-092-47/+54
| | | | | | | | | | Previously we emitted it early, and would then modify it in random ways like other initial content. But this function is called frequently during execution, so if we were unlucky and modded that function to trap then basically all other functions would trap as well. After fixing this, some places assert on not having any functions or types to pick a random one from, so fix those places too.
* Integrate the heap type fuzzer into the main fuzzer (#5555)Alon Zakai2023-03-093-4/+36
| | | | | | | | | | | | | With this we generate random GC types that may be used in creating instructions later. We don't create many instructions yet, which will be the next step after this. Also add some trivial assertions in some places, that have helped debugging in the past. Stop fuzzing TypeMerging for now due to #5556 , which this PR uncovers.
* Fuzzer: Pick from existing heap types in the module (#5539)Alon Zakai2023-03-082-5/+46
|
* Refactor type fuzzer to expose `getInhabitable` API (#5552)Thomas Lively2023-03-083-76/+88
| | | | | The main fuzzer needs to be able to filter out uninhabitable types and the type fuzzer has code for finding uninhabitable types. Move and refactor the code to expose a `getInhabitable` function that can be used for both purposes.
* CodePushing: Pushing into an if may require non-nullable fixups (#5551)Alon Zakai2023-03-071-5/+0
| | | | | | | | | | | | | | | This became an issue because the timeline was this: * We added non-nullable locals support. At the time, obviously CodePushing did not require any fixups for that, since it just moved code forward in a single block (and not past any uses). So we marked the pass as not needing such fixups. * We added pushing of code into ifs. But moving code into an if can affect non-nullable validation since it is based on block scoping. So we need to remove the mark on the pass, which will make it check and apply fixups as necessary. See the testcase for an example.
* SignatureRefining: Skip types with supertypes for now (#5548)Alon Zakai2023-03-061-0/+6
| | | We'd need to handle contravariance to optimize them.
* Skip function references when detecting uninhabitable types (#5545)Thomas Lively2023-03-032-25/+28
| | | | | | Function references are always inhabitable because functions can be created with any function type, even types that refer to uninhabitable types. Take advantage of this by skipping function references when finding non-nullable reference cycles that cause uninhabitability.
* [Wasm GC] Skip types with subtypes in SignatureRefining (#5544)Alon Zakai2023-03-031-0/+11
| | | | | | | For now just skip them, to avoid problems. In the future we should look into modifying their children, when possible. Fixes #5463
* Note function signature param/result features for validation (#5542)Alon Zakai2023-03-031-42/+69
| | | | | | | | As with #5535, this was not noticed because it can only happen on very small modules where the param/result type appears nowhere else but in a function signature. Use generic heap type scanning, which also scans into struct and array types etc.
* Fix type printing in the type fuzzer (#5543)Thomas Lively2023-03-031-4/+3
| | | | | | In #5437 we updated type printing so that printing a heap type would print its name in addition to its contents. We had already been separately printing type names in the type fuzzer, so after that change we were printing each type name twice. Remove the redundant printing in the fuzzer to fix the error.
* Add a fuzzer utility for ensuring types are inhabitable (#5541)Thomas Lively2023-03-035-3/+511
| | | | | | | | | | | | | | Some valid GC types, such as non-nullable references to bottom heap types and types that contain non-nullable references to themselves, are uninhabitable, meaning it is not possible to construct values of those types. This can cause problems for the fuzzer, which generally needs to be able to construct values of arbitrary types. To simplify things for the fuzzer, introduce a utility for transforming type graphs such that all their types are inhabitable. The utility performs a DFS to find cycles of non-nullable references and breaks those cycles by introducing nullability. The new utility is itself fuzzed in the type fuzzer.
* 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.