summaryrefslogtreecommitdiff
path: root/test/unit
Commit message (Collapse)AuthorAgeFilesLines
* [NFC] Improve ClusterFuzz testing (#7157)Alon Zakai2024-12-181-11/+14
| | | | | | | 1. Error on retrying due to a wasm-opt issue, locally (in production, we don't want to error on ClusterFuzz). 2. Move some asserts from test_run_py to the helper generate_testcases (so that the asserts happen in all callers).
* Fuzz JSPI (#7148)Alon Zakai2024-12-161-1/+21
| | | | | | | | | | * Add a new "sleep" fuzzer import, that does a sleep for some ms. * Add JSPI support in fuzz_shell.js. This is in the form of commented-out async/await keywords - commented out so that normal fuzzing is not impacted. When we want to fuzz JSPI, we uncomment them. We also apply the JSPI operations of marking imports and exports as suspending/promising. JSPI fuzzing is added to both fuzz_opt.py and ClusterFuzz's run.py.
* Add bulk-memory-opt feature and ignore call-indirect-overlong (#7139)Derek Schuff2024-12-062-3/+27
| | | | | | | | | | LLVM recently split the bulk-memory-opt feature out from bulk-memory, containing just memory.copy and memory.fill. This change follows that, making bulk-memory-opt also enabled when all of bulk-memory is enabled. It also introduces call-indirect-overlong following LLVM, but ignores it, since Binaryen has always allowed the encoding (i.e. command line flags enabling or disabling the feature are accepted but ignored).
* [Fuzzing] Emit secondary wasm files in ClusterFuzz testcases (#7122)Alon Zakai2024-11-261-17/+56
| | | | | | | | | The two files are then linked and run by fuzz_shell.js (we had this functionality already in order to fuzz wasm-split). By adding multiple build and run commands of both the primary and secondary wasm files, we can end up with multiple instances of two different wasm files that call between themselves. To help testing, add a script that extracts the wasm files from the testcase. This may also be useful in the future for testcase reduction.
* [NFC] Refactor ClusterFuzz run.py (#7101)Alon Zakai2024-11-211-8/+8
| | | | | This just moves code around. It will allow more code reuse in a later PR. Also add a bit of test logging.
* Fuzzing: Append more JS operations in run.py (#7098)Alon Zakai2024-11-211-0/+37
| | | | | | | | | | | | | | | The main fuzz_shell.js code builds and runs the given wasm. After the refactoring in #7096, it is simple to append to that file and add more build and run operations, adding more variety to the code, including cross-module interactions. Add logic to run.py to do that for ClusterFuzz. To test this, add a node test that builds a module with internal state that can actually show which module is being executed. The test appends a build+run operation, whose output prove that we are calling from the first module to the second and vice versa. Also add a ClusterFuzz test for run.py that verifies that we add a variety of build/run operations.
* Fuzzer: Legalize and prune the JS interface in pickPasses (#7092)Alon Zakai2024-11-201-0/+12
| | | | Also add a test that the ClusterFuzz run.py does not warn, which was helpful when debugging this.
* Fuzzing: ClusterFuzz integration (#7079)Alon Zakai2024-11-191-0/+259
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The main addition here is a bundle_clusterfuzz.py script which will package up the exact files that should be uploaded to ClusterFuzz. It also documents the process and bundling and testing. You can do bundle.py OUTPUT_FILE.tgz That bundles wasm-opt from ./bin., which is enough for local testing. For actually uploading to ClusterFuzz, we need a portable build, and @dschuff had the idea to reuse the emsdk build, which works nicely. Doing bundle.py OUTPUT_FILE.tgz --build-dir=/path/to/emsdk/upstream/ will bundle wasm-opt (+libs) from the emsdk. I verified that those builds work on ClusterFuzz. I added several forms of testing here. First, our main fuzzer fuzz_opt.py now has a ClusterFuzz testcase handler, which simulates a ClusterFuzz environment. Second, there are smoke tests that run in the unit test suite, and can also be run separately: python -m unittest test/unit/test_cluster_fuzz.py Those unit tests can also run on a given bundle, e.g. one created from an emsdk build, for testing right before upload: BINARYEN_CLUSTER_FUZZ_BUNDLE=/path/to/bundle.tgz python -m unittest test/unit/test_cluster_fuzz.py A third piece of testing is to add a --fuzz-passes test. That is a mode for -ttf (translate random data into a valid wasm fuzz testcase) that uses random data to pick and run a set of passes, to further shape the wasm. (--fuzz-passes had no previous testing, and this PR fixes it and tidies it up a little, adding some newer passes too). Otherwise this PR includes the key run.py script that is bundled and then executed by ClusterFuzz, basically a python script that runs wasm-opt -ttf [..] to generate testcases, sets up their JS, and emits them. fuzz_shell.js, which is the JS to execute testcases, will now check if it is provided binary data of a wasm file. If so, it does not read a wasm file from argv[1]. (This is needed because ClusterFuzz expects a single file for the testcase, so we make a JS file with bundled wasm inside it.)
* Binary parser: Lift the limit on the number of locals (#6973)Jérôme Vouillon2024-09-301-0/+16
| | | | | | | This raises the number of locals accepted by the binary parser to the absolute limit in the spec. A warning is now printed when writing a binary file if the Web limit of 50,000 locals is exceeded. Fixes #6968.
* [NFC] Eagerly create segments when parsing datacount (#6958)Thomas Lively2024-09-192-15/+0
| | | | | | | | | The purpose of the datacount section is to pre-declare how many data segments there will be so that engines can allocate space for them and not have to back patch subsequent instructions in the code section that refer to them. Once we use IRBuilder in the binary parser, we will have to have the data segments available by the time we parse instructions that use them, so eagerly construct the data segments when parsing the datacount section.
* [FP16] Add a feature flag for FP16. (#6864)Brendan Dahl2024-08-221-0/+1
| | | Ensure the "fp16" feature is enabled for FP16 instructions.
* [threads] Add a "shared-everything" feature (#6658)Thomas Lively2024-06-141-0/+1
| | | | | Add the feature and flags to enable and disable it. Require the new feature to be enabled for shared heap types to validate. To make the test work, update the validator to actually check features for global types.
* [StackIR] Run StackIR during binary writing and not as a pass (#6568)Alon Zakai2024-05-091-7/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | Previously we had passes --generate-stack-ir, --optimize-stack-ir, --print-stack-ir that could be run like any other passes. After generating StackIR it was stashed on the function and invalidated if we modified BinaryenIR. If it wasn't invalidated then it was used during binary writing. This PR switches things so that we optionally generate, optimize, and print StackIR only during binary writing. It also removes all traces of StackIR from wasm.h - after this, StackIR is a feature of binary writing (and printing) logic only. This is almost NFC, but there are some minor noticeable differences: 1. We no longer print has StackIR in the text format when we see it is there. It will not be there during normal printing, as it is only present during binary writing. (but --print-stack-ir still works as before; as mentioned above it runs during writing). 2. --generate/optimize/print-stack-ir change from being passes to being flags that control that behavior instead. As passes, their order on the commandline mattered, while now it does not, and they only "globally" affect things during writing. 3. The C API changes slightly, as there is no need to pass it an option "optimize" to the StackIR APIs. Whether we optimize is handled by --optimize-stack-ir which is set like other optimization flags on the PassOptions object, so we don't need the old option to those C APIs. The main benefit here is simplifying the code, so we don't need to think about StackIR in more places than just binary writing. That may also allow future improvements to our usage of StackIR.
* [Parser] Enable the new text parser by default (#6371)Thomas Lively2024-04-251-203/+0
| | | | | | | | | | | | | | The new text parser is faster and more standards compliant than the old text parser. Enable it by default in wasm-opt and update the tests to reflect the slightly different results it produces. Besides following the spec, the new parser differs from the old parser in that it: - Does not synthesize `loop` and `try` labels unnecessarily - Synthesizes different block names in some cases - Parses exports in a different order - Parses `nop`s instead of empty blocks for empty control flow arms - Does not support parsing Poppy IR - Produces different error messages - Cannot parse `pop` except as the first instruction inside a `catch`
* Fixes regarding explicit names (#6466)Jérôme Vouillon2024-04-111-0/+0
| | | | | | | - Only write explicit function names. - When merging modules, the name of types, globals and tags in all modules but the first were lost. - Set name as explicit when copying a function with a new name.
* Add an Asyncify option to propagate the addList (#5935)かめのこにょこにょこ2024-04-011-0/+9
| | | | | The new asyncify flag --pass-arg=asyncify-propagate-addlist changes the behavior of --pass-arg=asyncify-addlist : with it, callers of functions in the asyncify-addlist will be also instrumented.
* Add package.json for unit tests (#6245)Alon Zakai2024-02-082-0/+4
| | | | | | | | | The JS there is not an ES6 module, so declare it so (otherwise a package.json in a parent, perhaps in folders outside of our own project that we are pasted in, can cause an error, as require does not work in ES6 modules and we might be forced to be seen as one). Fixes #6240
* Get more tests working with the new text parser (#6284)Thomas Lively2024-02-075-7/+6
| | | | | | | | The new parser enforces the rule that imports must come before declarations (except for type declarations). The old parser does not enforce this rule, so many of our tests did not follow it. Fix them to follow that rule and fix other invalid syntax. Also add missing finalization of Load expressions in wasm-builder.h that was causing a test to fail under the new parser and guard against an error case in wasm-ir-builder.cpp that used to cause a segfault.
* Update the text syntax for tuple types (#6246)Thomas Lively2024-01-261-1/+1
| | | | Instead of e.g. `(i32 i32)`, use `(tuple i32 i32)`. Having a keyword to introduce the s-expression is more consistent with the rest of the language.
* Require `then` and `else` with `if` (#6201)Thomas Lively2024-01-043-33/+57
| | | | | | | | | | | | We previously supported (and primarily used) a non-standard text format for conditionals in which the condition, if-true expression, and if-false expression were all simply s-expression children of the `if` expression. The standard text format, however, requires the use of `then` and `else` forms to introduce the if-true and if-false arms of the conditional. Update the legacy text parser to require the standard format and update all tests to match. Update the printer to print the standard format as well. The .wast and .wat test inputs were mechanically updated with this script: https://gist.github.com/tlively/85ae7f01f92f772241ec994c840ccbb1
* Drop support for non-standard quoted function names (#6188)Thomas Lively2023-12-204-20/+16
| | | | | | | | | | | | | | | | | | We previously supported a non-standard `(func "name" ...` syntax for declaring functions exported with the quoted name. Since that is not part of the standard text format, drop support for it, replacing it with the standard `(func $name (export "name") ...` syntax instead. Also replace our other usage of the quoted form in our text output, which was where we quoted names containing characters that are not allowed to appear in standard names. To handle that case, adjust our output from `"$name"` to `$"name"`, which is the standards-track way of supporting such names. Also fix how we detect non-standard name characters to match the spec. Update the lit test output generation script to account for these changes, including by making the `$` prefix on names mandatory. This causes the script to stop interpreting declarative element segments with the `(elem declare ...` syntax as being named "declare", so prevent our generated output from regressing by counting "declare" as a name in the script.
* Add a `tuple.drop` text pseudoinstruction (#6170)Thomas Lively2023-12-121-1/+1
| | | | | | | | | | | | | | | | | We previously overloaded `drop` to mean both normal drops of single values and also drops of tuple values. That works fine in the legacy text parser since it can infer parent-child relationships directly from the s-expression structure of the input, so it knows that a drop should drop an entire tuple if the tuple-producing instruction is a child of the drop. The new text parser, however, is much more like the binary parser in that it uses instruction types to create parent-child instructions. The new parser always assumes that `drop` is meant to drop just a single value because that's what it does in WebAssembly. Since we want to continue to let `Drop` IR expressions consume tuples, and since we will need a way to write tests for that IR pattern that work with the new parser, introduce a new pseudoinstruction, `tuple.drop`, to represent drops of tuples. This pseudoinstruction only exists in the text format and it parses to normal `Drop` expressions. `tuple.drop` takes the arity of its operand as an immediate, which will let the new parser parse it correctly in the future.
* Update `tuple.make` text format to include arity (#6169)Thomas Lively2023-12-121-2/+2
| | | | | | | | | | Previously, the number of tuple elements was inferred from the number of s-expression children of the `tuple.make` expression, but that scheme would not work in the new wat parser, where s-expressions are optional and cannot be semantically meaningful. Update the text format to take the number of tuple elements (i.e. the tuple arity) as an immediate. This new format will be able to be implemented in the new parser as follow-on work.
* [wasm-emscripten-finalize] Remove --separate-data-segments (#6091)Sam Clegg2023-11-271-1/+1
| | | See #6088
* Remove various testing spam (#6109)Alon Zakai2023-11-142-2/+1
| | | | | Avoid some common warnings and stop printing various stdout/stderr stuff. Helps #6104
* Typed Continuations: Add cont type (#5998)Frank Emrich2023-10-241-0/+12
| | | | | | | | | This PR is part of a series that adds basic support for the [typed continuations proposal](https://github.com/wasmfx/specfx). This PR adds continuation types, of the form `(cont $foo)` for some function type `$foo`. The only notable changes affecting existing code are the following: - This is the first `HeapType` which has another `HeapType` (rather than, say, a `Type`) as its immediate child. This required fixes to certain traversals that have a flag for being at the toplevel of a type. - Some shared logic for parsing `HeapType`s has been factored out.
* [typed-cont] Allow result types on tags (#5997)Frank Emrich2023-10-051-0/+16
| | | | | | | | | | | This PR is part of a series that adds basic support for the typed continuations proposal. This PR relaxes the restriction that tags must not have results , only params. Tags with results must not be used for exception handling and are only allowed if the typed continuations feature is enabled. As a minor point, this PR also changes the printing of tags without params: To make the presentation consistent, (param) is omitted when printing a tag.
* [typed-cont] Add feature flag (#5996)Frank Emrich2023-10-051-0/+1
| | | | | | | This PR is part of a series that adds basic support for the [typed continuations proposal](https://github.com/wasmfx/specfx). This particular PR simply extends `FeatureSet` with a corresponding entry for this proposal.
* Use standard GC encodings by default (#5873)Thomas Lively2023-09-121-0/+0
| | | | The legacy encodings remain available for now by defining USE_LEGACY_GC_ENCODINGS at build time.
* Rename multimemory flag (#5890)Ashley Nelson2023-08-211-1/+1
| | | Renaming the multimemory flag in Binaryen to match its naming in LLVM.
* Remove the --hybrid and --nominal command line options (#5669)Thomas Lively2023-04-141-24/+21
| | | | | 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.
* [Fuzzer] Simplify the hang limit mechanism (#5513)Alon Zakai2023-02-231-21/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Fix opt/shrink levels when running the optimizer multiple times (#5333)Alon Zakai2022-12-141-0/+18
| | | | | | | | | | Previously -O3 -O1 would run -O1 twice since the last flag set the global opt level to 1, and then all invocations of the optimizer pipeline read that. This makes each pipeline define its own opt level. This has been a long-standing annoyance, which wasn't much noticed except that with wasm GC there is more of a need to run the optimization pipeline more than once. And sometimes it is nice to run different levels.
* [Wasm GC] Implement closed-world flag (#5303)Alon Zakai2022-11-301-0/+49
| | | | | | | | | | | | | With this change we default to an open world, that is, we do the safe thing by default: we no longer assume a closed world. Users that want a closed world must pass --closed-world. Atm we just do not run passes that assume a closed world. (We might later refine them to find which types don't escape and only optimize those.) The RemoveUnusedModuleElements is an exception in that the closed-world flag influences one part of its operation, but not the rest. Fixes #5292
* Update default features to match new llvm defaults (#5212)Sam Clegg2022-11-031-7/+5
| | | See: https://reviews.llvm.org/D125728
* [NFC] Mention relevant flags in validator errors (#5203)Alon Zakai2022-11-011-12/+9
| | | | | | | | | | E.g. Atomic operation (atomics are disabled) => Atomic operations require threads [--enable-threads]
* Binary format: Don't emit empty Memory sections (#5145)Alon Zakai2022-10-173-2/+12
| | | | If the only memories are imported, we don't need the section. We were already doing that for tables, functions, etc.
* Implement bottom heap types (#5115)Thomas Lively2022-10-071-0/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | These types, `none`, `nofunc`, and `noextern` are uninhabited, so references to them can only possibly be null. To simplify the IR and increase type precision, introduce new invariants that all `ref.null` instructions must be typed with one of these new bottom types and that `Literals` have a bottom type iff they represent null values. These new invariants requires several additional changes. First, it is now possible that the `ref` or `target` child of a `StructGet`, `StructSet`, `ArrayGet`, `ArraySet`, or `CallRef` instruction has a bottom reference type, so it is not possible to determine what heap type annotation to emit in the binary or text formats. (The bottom types are not valid type annotations since they do not have indices in the type section.) To fix that problem, update the printer and binary emitter to emit unreachables instead of the instruction with undetermined type annotation. This is a valid transformation because the only possible value that could flow into those instructions in that case is null, and all of those instructions trap on nulls. That fix uncovered a latent bug in the binary parser in which new unreachables within unreachable code were handled incorrectly. This bug was not previously found by the fuzzer because we generally stop emitting code once we encounter an instruction with type `unreachable`. Now, however, it is possible to emit an `unreachable` for instructions that do not have type `unreachable` (but are known to trap at runtime), so we will continue emitting code. See the new test/lit/parse-double-unreachable.wast for details. Update other miscellaneous code that creates `RefNull` expressions and null `Literals` to maintain the new invariants as well.
* Warn on too many parameters for Web VMs (#5119)Alon Zakai2022-10-061-0/+22
| | | Fixes emscripten-core/emscripten#17988
* Remove typed-function-references feature (#5030)Thomas Lively2022-09-091-1/+0
| | | | | | | | | | | | | | | | In practice typed function references will not ship before GC and is not independently useful, so it's not necessary to have a separate feature for it. Roll the functionality previously enabled by --enable-typed-function-references into --enable-gc instead. This also avoids a problem with the ongoing implementation of the new GC bottom heap types. That change will make all ref.null instructions in Binaryen IR refer to one of the bottom heap types. But since those bottom types are introduced in GC, it's not valid to emit them in binaries unless unless GC is enabled. The fix if only reference types is enabled is to emit (ref.null func) instead of (ref.null nofunc), but that doesn't always work if typed function references are enabled because a function type more specific than func may be required. Getting rid of typed function references as a separate feature makes this a nonissue.
* Adding Multi-Memories Wasm Feature (#4968)Ashley Nelson2022-08-251-0/+1
| | | Adding multi-memories to the the list of wasm-features.
* Restore the `extern` heap type (#4898)Thomas Lively2022-08-171-1/+1
| | | | | | | The GC proposal has split `any` and `extern` back into two separate types, so reintroduce `HeapType::ext` to represent `extern`. Before it was originally removed in #4633, externref was a subtype of anyref, but now it is not. Now that we have separate heaptype type hierarchies, make `HeapType::getLeastUpperBound` fallible as well.
* Remove metadata generation from wasm-emscripten-finalize (#4863)Sam Clegg2022-08-071-5/+1
| | | | This is no longer needed by emscripten as of: https://github.com/emscripten-core/emscripten/pull/16529
* [Strings] Add feature flag for Strings proposal (#4766)Alon Zakai2022-06-301-0/+1
|
* Remove externref (#4633)Thomas Lively2022-05-042-5/+5
| | | | | | Remove `Type::externref` and `HeapType::ext` and replace them with uses of anyref and any, respectively, now that we have unified these types in the GC proposal. For backwards compatibility, continue to parse `extern` and `externref` and maintain their relevant C API functions.
* Add support for extended-const proposal (#4529)Sam Clegg2022-03-191-0/+1
| | | See https://github.com/WebAssembly/extended-const
* [Fuzzer] Allow empty data in --translate-to-fuzz (#4406)Heejin Ahn2021-12-281-0/+14
| | | | | | | When a parameter and a member variable have the same name within a constructor, to access (and change) the member variable, we need to either use `this->` or change the name of the parameter. The current code ended up changing the parameter and didn't affect the status of the member variable, which remained empty.
* Add feature flag for relaxed-simd (#4183)Ng Zhi An2021-09-231-0/+1
|
* Add a test for too many locals in Asyncify (#4110)Alon Zakai2021-08-271-0/+15
| | | Followup to #4108
* Apply features from the commandline first (#3960)Alon Zakai2021-07-021-17/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | As suggested in https://github.com/WebAssembly/binaryen/pull/3955#issuecomment-871016647 This applies commandline features first. If the features section is present, and disallows some of them, then we warn. Otherwise, the features can combine (for example, a wasm may enable feature X because it has to use it, and a user can simply add the flag for feature Y if they want the optimizer to try to use it; both flags will then be enabled). This is important because in some cases we need to know the features before parsing the wasm, in the case that the wasm does not use the features section. In particular, non-nullable GC locals have an effect during parsing. (Typed function references also does, but we found a way to apply its effect all the time, that is, always use the refined type, and that happened to not break the case where the feature is disabled - but such a workaround is not possible with non-nullable locals.) To make this less error-prone, add a FeatureSet input as a parameter to WasmBinaryBuilder. That is, when building a module, we must give it the features to use while doing so. This will unblock #3955 . That PR will also add a test for the actual usage of a feature during loading (the test can only be added there, after that PR unbreaks things).