summaryrefslogtreecommitdiff
path: root/src/tools/fuzzing/fuzzing.cpp
Commit message (Collapse)AuthorAgeFilesLines
* [threads] Update the fuzzer for shared types (#6771)Thomas Lively2024-07-181-53/+88
| | | | | | | | Update the fuzzer to both handle shared types in initial contents and create and use new shared types without crashing or producing invalid modules. Since V8 does not have a complete implementation of shared-everything-threads yet, disable fuzzing V8 when shared-everything is enabled. To avoid losing too much coverage of V8, disable shared-everything in the fuzzer more frequently than other features.
* Simplify fuzzer generation of function references (#6745)Thomas Lively2024-07-151-17/+11
| | | | | | | | | | | | When creating a reference to `func`, fix the probability of choosing to continue on to choose some function other than the last one rather than making it depend on the number of functions. Then, do not eagerly pick from the rest of the candidate functions. Instead, fall through to the more general logic that will already pick a random candidate function. Also move the logic for coming up with a concrete signature down to where it is needed. These simplifications will make it easier to update the code to handle shared types.
* [threads] Fuzz shared types in type fuzzer (#6704)Thomas Lively2024-06-261-1/+4
| | | | | | | | | | | | | | Give the type fuzzer the ability to generate shared heap types when the shared-everything feature is enabled. It correctly ensures that shared structs and arrays cannot reference unshared heap types, but that unshared heap types can reference any heap type. Update the main fuzzer so that for the time being it never uses the shared-everything feature when generating additional heap types, so it never generates shared types. We can lift this restriction once the main fuzzer has been updated to properly handle shared types. As a drive-by, fix some logic for subtracting feature sets from each other that is used in this commit.
* [threads] Shared basic heap types (#6667)Thomas Lively2024-06-191-2/+4
| | | | | | | | | | | Implement binary and text parsing and printing of shared basic heap types and incorporate them into the type hierarchy. To avoid the massive amount of code duplication that would be necessary if we were to add separate enum variants for each of the shared basic heap types, use bit 0 to indicate whether the type is shared and replace `getBasic()` with `getBasic(Unshared)`, which clears that bit. Update all the use sites to record whether the original type was shared and produce shared or unshared output without code duplication.
* Fix fuzzer generation of a DataSegment + add validation that would have ↵Alon Zakai2024-05-231-3/+4
| | | | | | | | | | caught it (#6626) The DataSegment was manually added to .dataSegments, but we need to add it using addDataSegment so the maps are updated and getDataSegment(name) works. Also add validation that would have caught this earlier: check that each item in the item lists can be fetched by name.
* Fuzzer: Better fuzzing of globals (#6611)Alon Zakai2024-05-211-32/+52
| | | | | | | | | | | | | With this PR we generate global.gets in globals, which we did not do before. We do that by replacing makeConst (the only thing we did before, for the contents of globals) with makeTrivial, and add code to makeTrivial to sometimes make a global.get. When no suitable global exists, makeGlobalGet will emit a constant, so there is no danger in trying. Also raise the number of globals a little. Also explicitly note the current limitation of requiring all tuple globals to contain tuple.make and nothing else, including not global.get, and avoid adding such invalid global.gets in tuple globals in the fuzzer.
* [Strings] Remove operations not included in imported strings (#6589)Thomas Lively2024-05-151-3/+2
| | | | | | The stringref proposal has been superseded by the imported JS strings proposal, but the former has many more operations than the latter. To reduce complexity, remove all operations that are part of stringref but not part of imported strings.
* [Strings] Remove stringview types and instructions (#6579)Thomas Lively2024-05-151-31/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The stringview types from the stringref proposal have three irregularities that break common invariants and require pervasive special casing to handle properly: they are supertypes of `none` but not subtypes of `any`, they cannot be the targets of casts, and they cannot be used to construct nullable references. At the same time, the stringref proposal has been superseded by the imported strings proposal, which does not have these irregularities. The cost of maintaing and improving our support for stringview types is no longer worth the benefit of supporting them. Simplify the code base by entirely removing the stringview types and related instructions that do not have analogues in the imported strings proposal and do not make sense in the absense of stringviews. Three remaining instructions, `stringview_wtf16.get_codeunit`, `stringview_wtf16.slice`, and `stringview_wtf16.length` take stringview operands in the stringref proposal but cannot be removed because they lower to operations from the imported strings proposal. These instructions are changed to take stringref operands in Binaryen IR, and to allow a graceful upgrade path for users of these instructions, the text and binary parsers still accept but ignore `string.as_wtf16`, which is the instruction used to convert stringrefs to stringviews. The binary writer emits code sequences that use scratch locals and `string.as_wtf16` to keep the output valid. Future PRs will further align binaryen with the imported strings proposal instead of the stringref proposal, for example by making `string` a subtype of `extern` instead of a subtype of `any` and by removing additional instructions that do not have analogues in the imported strings proposal.
* Fuzzer: Stop emitting nullable stringviews (#6574)Alon Zakai2024-05-081-5/+17
| | | | | | | | | | | | | As of https://chromium-review.googlesource.com/c/v8/v8/+/5471674 V8 requires stringviews to be non-nullable. It might be possible to make that change in our IR, or to remove views entirely, but for now this PR makes the fuzzer stop emitting nullable stringviews as a workaround to allow us to fuzz current V8. There are still rare corner cases where this pattern is emitted, that we have not tracked down, and so this also makes the fuzzer ignore the error for now.
* [Strings] Work around ref.cast not working on string views, and add fuzzing ↵Alon Zakai2024-04-291-4/+31
| | | | | | | | | | | | | (#6549) As suggested in #6434 (comment) , lower ref.cast of string views to ref.as_non_null in binary writing. It is a simple hack that avoids the problem of V8 not allowing them to be cast. Add fuzzing support for the last three core string operations, after which that problem becomes very frequent. Also add yet another makeTrappingRefUse that was missing in that fuzzer code.
* [Strings] Fix effects of string.compare and add fuzzing (#6547)Alon Zakai2024-04-251-10/+24
| | | | | | | | We added string.compare late in the spec process, and forgot to add effects for it. Unlike string.eq, it can trap. Also use makeTrappingRefUse in recent fuzzer string generation places that I forgot, which should reduce the amount of traps in fuzzer output.
* [Strings] Fuzz string.encode (#6539)Alon Zakai2024-04-251-14/+50
| | | | | | | A little trickier than the others due to the risk of trapping, which this handles like the other array operations. Also stop using immutable i16 arrays for string operations - only mutable ones work atm.
* Fuzzer: Update the typeLocals data structure before mutation (#6537)Alon Zakai2024-04-241-2/+12
| | | | | Rather than compute the map of type to locals of that type once, at the start, also update it when relevant, as we can add more locals in some cases. This allows us to local.get from those late-added locals too.
* [Strings] Fuzzer: Emit StringConcat (#6532)Alon Zakai2024-04-241-66/+86
| | | Also refactor the code a little to make it easier to add this (mostly whitespace).
* [Strings] Add the string heaptype to core fuzzer places (#6527)Alon Zakai2024-04-231-20/+23
| | | | | | | With this we emit strings spontaneously (as opposed to just getting them from initial contents). The relevant -ttf test has been tweaked slightly to show the impact of this change: now there are some string.new/const in the output.
* [Strings] Fuzz and interpret all relevant StringNew methods (#6526)Alon Zakai2024-04-231-41/+80
| | | | This adds fuzzing for string.new_wtf16_array and string.from_code_point. The latter was also missing interpreter support, which this adds.
* Fuzzer: Randomly pick which functions to use in RefFunc (#6503)Alon Zakai2024-04-151-10/+12
| | | | | | | Previously we chose the first with a proper type, and now we start to scan from a random index, giving later functions a chance too, so we should be emitting a greater variety of ref.func targets. Also remove some obsolete fuzzer TODOs.
* Fuzzer: Emit signed Struct/ArrayGet operations (#6486)Alon Zakai2024-04-111-5/+12
|
* Typed continuations: nocont and cont basic heap types (#6468)Frank Emrich2024-04-041-0/+7
| | | | | | | | This PR is part of a series that adds basic support for the typed continuations/wasmfx proposal. This particular PR adds cont and nocont as top and bottom types for continuation types, completely analogous to func and nofunc for function types (also: exn and noexn).
* Fuzzer: Work around the lack of wtf8/iter support (#6445)Alon Zakai2024-03-271-5/+6
| | | | We only have interpreter support for wtf16, so we should not emit operations on the other types, as the interpreter will error.
* Add "interposition" to the fuzzer's mutate() method (#6427)Alon Zakai2024-03-261-15/+145
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Before this PR we only mutated by replacing an expression with another, which replaced all the children. With this PR we also do these two patterns: (A (B) (C) ) => ;; keep children, replace A (block (drop (B)) (drop (C)) (NEW) ) , (D (A (B) (C) ) ) => ;; keep A, replace it in the parent (D (block (drop (A (B) (C) ) ) (NEW) ) ) We also try to replace onto the new D (either A itself, or A's children).
* Fuzzer: Implement a few more String TODOs (#6439)Alon Zakai2024-03-251-1/+3
|
* Generate interesting strings in fuzzer (#6430)Thomas Lively2024-03-231-2/+38
| | | | Instead of generating exclusively ascii strings, generate empty strings and strings containing various unicode characters and unpaired surrogates as well.
* [Strings] Represent string values as WTF-16 internally (#6418)Thomas Lively2024-03-221-2/+8
| | | | | | | | | | | | | | | | WTF-16, i.e. arbitrary sequences of 16-bit values, is the encoding of Java and JavaScript strings, and using the same encoding makes the interpretation of string operations trivial, even when accounting for non-ascii characters. Specifically, use little-endian WTF-16. Re-encode string constants from WTF-8 to WTF-16 in the parsers, then back to WTF-8 in the writers. Update the constructor for string `Literal`s to interpret the string as WTF-16 and store a sequence of WTF-16 code units, i.e. 16-bit integers. Update `Builder::makeConstantExpression` accordingly to convert from the new `Literal` string representation back to a WTF-16 string. Update the interpreter to remove the logic for detecting non-ascii characters and bailing out. The naive implementations of all the string operations are correct now that our string encoding matches the JS string encoding.
* [Strings] Implement TODOs in the fuzzer (#6416)Alon Zakai2024-03-211-1/+6
|
* Fix a build error when assertions are disabled (#6397)Thomas Lively2024-03-131-2/+4
| | | | | Add `[[maybe_unused]]` to variables that are only used in assertions. In builds without assertions enabled, these were causing compiler errors about unused variables.
* Handle extended const segment offsets in the fuzzer (#6382)Thomas Lively2024-03-071-13/+13
| | | | | | The fuzzer already had logic to remove all references to non-imported globals from global initializers and data segment offsets, but it was missing for element segment offsets. Add it, and also add a missing check line for the new test that uncovered this bug as initial fuzzer input.
* Fix EH fuzz bugs (#6381)Thomas Lively2024-03-071-1/+1
| | | | | Due to a typo, the fuzzer was making externrefs when it should have been making exnrefs. Fix that and also let eh-utils.cpp know that TryTable exists to avoid an assertion failure.
* Fuzzer: Allow using initial content with V8 (#6327)Alon Zakai2024-02-221-0/+9
| | | | | | | | | | | | | | | One problem was that spec testcases had exports with names that are not valid to write as JS exports.name. For example an export with a - in the name would end up as exports.foo-bar etc. Since #6310 that is fixed as we do not emit such JS (we use the generic fuzz_shell.js script which iterates over the keys in exports with exports[name]). Also fix a few trivial fuzzer issues that initial content uncovered: - Ignore a wat file with invalid utf-8. - Print string literals in the same way from JS as from C++. - Enable the stringref flag in V8. - Remove tag imports (the same as we do for global and function and other imports).
* Fuzzer: Do not emit huge and possibly non-validating tables (#6288)Alon Zakai2024-02-121-0/+17
|
* [EH] Add exnref type back (#6149)Heejin Ahn2023-12-081-1/+13
| | | | | | | | | | | | | At the Oct hybrid CG meeting, we decided to add back `exnref`, which was removed in 2020: https://github.com/WebAssembly/meetings/blob/main/main/2023/CG-10.md The new version of the proposal reflected in the explainer: https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md While adding support for `exnref` in the current codebase which has all GC subtype hierarchies, I noticed we might need `noexn` heap type for the bottom type of `exn`. We don't have it now so I just set it to 0xff for the moment.
* Fuzzer: Better handling of globals from initial content (#6072)Alon Zakai2023-11-011-19/+43
| | | | | | | | | | | | | | | Previously the fuzzer never added gets or sets of globals from initial content. That was an oversight, I'm pretty sure - it's just that the code that sets up the lists from which we pick globals for gets and sets was in another place. That is, any globals in the initial content file were never used in new random code the fuzzer generates (only new globals the fuzzer generated were used there). This PR allows us to use those globals, but also ignores them with some probability, to avoid breaking patterns like "once" globals (that we want to only be used from initial content, at least much of the time). Also simplify the code here: we don't need isInvalidGlobal just to handle the hang limit global, which is already handled by not being added to the lists we pick names from anyhow.
* Fuzzer: Allow non-nullable locals (#6019)Alon Zakai2023-10-181-9/+30
| | | | | | | Remove the code that avoided such locals. To avoid much new trapping, add logic to set a value to such locals if they have accesses that are not dominated by a set already. Also in makeTrivial only rarely emit a local.get of a non-nullable local (prefer a constant).
* Add getGeneralSuperType() that includes basic supers, and use in fuzzer (#6005)Alon Zakai2023-10-171-2/+1
| | | | With this, the fuzzer can replace e.g. an eq expression with a specific struct type, because now it is away that struct types have eq as their ancestor.
* Fuzzer: Move logic for adding a new local on demand to local.get (#6008)Alon Zakai2023-10-171-15/+36
| | | | | | | Previously makeTrappingRefUse would add a local on demand if one was missing for the type, and add a tee for it. This PR moves that logic to makeLocalGet so that we get those benefits any time we want to emit a local.get of a local type that does not exist (including from makeTrappingRefUse which calls makeLocalGet).
* [NFC] Rename getSuperType to getDeclaredSuperType (#6015)Alon Zakai2023-10-171-2/+2
| | | | A later PR will add getSuperType which will mean "get the general super type - either declared, or not".
* Replace i31.new with ref.i31 everywhere (#5931)Thomas Lively2023-09-131-1/+1
| | | | | Replace i31.new with ref.i31 in the printer, tests, and source code. Continue parsing i31.new for the time being to allow a graceful transition. Also update the JS API to reflect the new instruction name.
* Replace I31New with RefI31 everywhere (#5930)Thomas Lively2023-09-131-1/+1
| | | | | | | | Globally replace the source string "I31New" with "RefI31" in preparation for renaming the instruction from "i31.new" to "ref.i31", as implemented in the spec in https://github.com/WebAssembly/gc/pull/422. This would be NFC, except that it also changes the string in the external-facing C APIs. A follow-up PR will make the corresponding behavioral change.
* Remove legacy WasmGC instructions (#5861)Thomas Lively2023-08-091-2/+1
| | | | | Remove old, experimental instructions and type encodings that will not be shipped as part of WasmGC. Updating the encodings and text format to match the final spec is left as future work.
* Fuzzer: Emit more variations of If (#5806)Alon Zakai2023-07-101-2/+24
| | | | | | Before we always created if-elses. Now we also create an If with one arm some of the time, when we can. Also, sometimes make one if arm unreachable, if we have two arms.
* [NFC] Fix the use of "strict" in subtypes.h (#5804)Thomas Lively2023-07-061-1/+1
| | | | | | | | Previously we incorrectly used "strict" to mean the immediate subtypes of a type, when in fact a strict subtype of a type is any subtype excluding the type itself. Rename the incorrect `getStrictSubTypes` to `getImmediateSubTypes`, rename the redundant `getAllStrictSubTypes` to `getStrictSubTypes`, and rename the redundant `getAllSubTypes` to `getSubTypes`. Fixing the capitalization of "SubType" to "Subtype" is left as future work.
* Fuzzing for Try and Throw (#5776)Alon Zakai2023-06-211-3/+71
|
* Fuzzer: Limit ArrayNew sizes most of the time (#5738)Alon Zakai2023-05-221-2/+11
|
* Fuzzer: Use subtype consistently in make() (#5674)Alon Zakai2023-04-191-4/+4
|
* [Wasm GC] Fuzz array.copy and array.fill (#5663)Alon Zakai2023-04-171-4/+84
|
* [Wasm GC] Improve GC operation coverage by using locals more (#5661)Alon Zakai2023-04-171-19/+54
| | | | | | | | | | | | When we emit e.g. a struct.get's reference, this PR makes us prefer a non-nullable value, and even to reuse an existing local if possible. By doing that we reduce the risk of a trap, and also by using locals we end up testing operations on the same data, like this: x = new A(); x.a = .. foo(x.a) In contrast, without this PR each of those x. uses might be new A().
* Remove the --hybrid and --nominal command line options (#5669)Thomas Lively2023-04-141-4/+2
| | | | | After this change, the only type system usable from the tools will be the standard isorecursive type system. The nominal type system is still usable via the API, but it will be removed entirely in a follow-on PR.
* [Wasm GC] Casts of a non-nullable bottom type to non-null fail (#5645)Alon Zakai2023-04-121-6/+4
| | | | | | | | | | | Casting (ref nofunc) to (ref func) seems like it can succeed based on the rule of "if it's a subtype, it can cast ok." But the fuzzer found a corner case where that leads to a validation error (see testcase). Refactor the cast evaluation logic to handle uninhabitable refs directly, and return Unreachable for them (since the cast cannot even be reached). Also reorder the rule checks there to always check for a non-nullable cast of a bottom type (which always fails).
* [NFC] Refactor some old fuzzer code (#5658)Alon Zakai2023-04-121-13/+8
| | | | A return value was unused, and we have BranchUtils::operateOnScopeNameDefs now which can replace old manual code.
* [NFC] Refactor fuzzer array check logic (#5659)Alon Zakai2023-04-121-20/+30
|