summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
...
* [NFC] Generalize and simplify wasm-delegations-fields.h (#6465)Alon Zakai2024-04-033-762/+601
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This removes the hard-coded generation of a switch and cases, and allows the user to define the boilerplate at the start and end of the main output, and of what is generated for each expression. By default we still emit a switch and cases. Also standardize the output by never emitting ; unnecessarily, which we were inconsistent about. This serves two goals: First, it will make using embind on Binaryen simpler as embind needs to generate C++ template logic for each expression, and not a switch (and we cannot have extra ; in embind notation). Second, this makes the format much simple to parse, which is a stepping stone for #6460, e.g. before we had case Expression::Id::LoopId: { DELEGATE_START(Loop); DELEGATE_FIELD_CHILD(Loop, body); DELEGATE_FIELD_SCOPE_NAME_DEF(Loop, name); DELEGATE_END(Loop); break; } and now we have DELEGATE_FIELD_CASE_START(Loop) DELEGATE_FIELD_CHILD(Loop, body) DELEGATE_FIELD_SCOPE_NAME_DEF(Loop, name) DELEGATE_FIELD_CASE_END(Loop) The main part of this diff was autogenerated by this python: for l in x.splitlines(): if l.startswith(' case'): id = l.split(':')[4][:-2] print(f'DELEGATE_FIELD_CASE_START({id})') if l.startswith(' DELEGATE_FIELD'): print(l) if l.startswith(' DELEGATE_END'): id = l[17:-2] print(f'DELEGATE_FIELD_CASE_END({id})') print()
* Fix writing of data segment names in name section (#6462)Jérôme Vouillon2024-04-023-2/+36
| | | | - Output segment names even when no memory is declared. - Only write explicit names.
* Fix merge error after #5935 (#6461)Alon Zakai2024-04-011-14/+29
|
* Add an Asyncify option to propagate the addList (#5935)かめのこにょこにょこ2024-04-013-12/+334
| | | | | 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.
* [Strings] string.new_wtf16_array should trap if the end index is less than ↵Alon Zakai2024-04-012-1/+71
| | | | the start (#6459)
* GUFA: Fix hashing of GlobalInfo's type (#6455)Alon Zakai2024-03-291-2/+6
| | | | | | | | | For a global we store the name and a type, and the type may be more precise than the global's type in the wasm. As a result, when hashing, it is not enough to hash only the name, so hash the type as well. Also add a random TODO as a comment.
* GUFA: Fix nondeterminism in roots (#6456)Alon Zakai2024-03-291-1/+4
| | | | | Found by the fuzzer. We already processed the work queue in a deterministic order, but the roots were unordered. The work queue's initial state is filled by the roots, so we must process the roots deterministically as well.
* Report timeout in interpretation of AtomicWait (#6452)Thomas Lively2024-03-292-2/+2
| | | | | | | To avoid slow-running fuzz cases, we report a host limit when interpreting atomic.wait with any non-zero timeout. However, in the allowed case where the timeout is zero, we were incorrectly interpreting the wait as returning 0, meaning that it was woken up, instead of 2, meaning that the timeout expired. Fix it to return 2.
* Remove the TRAVERSE_CALLS option in the ConstantExpressionRunner (#6449)Thomas Lively2024-03-297-79/+2
| | | | | | | | The implementation of calls with this option was incorrect because it cleared the locals before evaluating the call arguments. The likely explanation for why this was never noticed is that there are no users of this option, especially since it is exposed in the C and JS APIs but not used internally. Rather than try to fix the implementation, just remove the option.
* [Strings] Lower string.concat in StringLowering (#6453)Thomas Lively2024-03-293-33/+69
|
* wasm-merge: Check that the types of imports and exports match (#6437)Jérôme Vouillon2024-03-272-0/+192
|
* Fix parsing of table imports (#6446)Jérôme Vouillon2024-03-272-6/+24
| | | The types was ignored and funcref was always used instead.
* Fuzzer HeapType generator: Do not use string types if not allowed (#6447)Alon Zakai2024-03-271-1/+1
|
* 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.
* [NFC] Fix fuzzer counting of ignored runs due to many errors (#6444)Alon Zakai2024-03-271-4/+12
| | | | | | When the interpreter sees that most exports simply trap we mark the iteration as ignored. But we run the interpreter on the before wasm and also the after wasm, so we were incrementing that counter by 2 each time, which could be misleading.
* Fix stringview subtyping (#6440)Thomas Lively2024-03-263-36/+77
| | | | | | The stringview types (`stringview_wtf8`, `stringview_wtf16`, and `stringview_iter`) are not subtypes of `any` even though they are supertypes of `none`. This breaks the type system invariant that types share a bottom type iff they share a top type, but we can work around that.
* Add "interposition" to the fuzzer's mutate() method (#6427)Alon Zakai2024-03-263-72/+216
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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).
* [Strings] Escape strings printed by fuzz-exec (#6441)Thomas Lively2024-03-263-12/+92
| | | | | | | | | | | Previously we printed strings as WTF-8 in the output of fuzz-exec, but this could produce invalid unicode output and did not make unprintable characters visible. Fix both these problems by escaping the output, using the JSON string escape procedure since the string to be escaped is WTF-16. Reimplement the same escaping procedure in fuzz_shell.js so that the way we print strings when running on a real JS engine matches the way we print them in our own fuzz-exec interpreter. Fixes #6435.
* Fuzzer: Implement a few more String TODOs (#6439)Alon Zakai2024-03-251-1/+3
|
* StringNew: Trap on OOB start index (#6438)Alon Zakai2024-03-252-1/+54
|
* 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.
* Remove "minimal" JS import/export legalization (#6428)Sam Clegg2024-03-228-152/+8
| | | | | | | | | | | | This change removes the "minimal" mode from `LegalizeJSInterface` which was added in #1883. The idea behind this change was to avoid legalizing most function except those we know that JS will be calling. The idea was that for dynamic linking we always want the non-legalized version to be shared between wasm module. These days we solve this problem in a different way with the `legalize-js-interface-export-originals` which exports the original functions alongside the legalized ones. Emscripten then always prefers the `$orig` functions when doing dynamic linking.
* [Strings] Represent string values as WTF-16 internally (#6418)Thomas Lively2024-03-2220-207/+339
| | | | | | | | | | | | | | | | 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.
* Remove extra conversion in string test (#6426)Thomas Lively2024-03-221-6/+2
| | | | `string.encode_wtf16_array` operates on stringref, not on wtf16 string views, so this conversion was causing validation errors when passed to V8 by the fuzzer.
* Add missing conversions in string slice tests (#6424)Thomas Lively2024-03-221-3/+9
| | | | Our validator apparently does not catch this type issue yet. For now just fix the tests.
* Update file name in INITIAL_CONTENTS_IGNORE (#6425)Thomas Lively2024-03-221-1/+1
| | | | The test file was renamed, but the fuzzer still used the old name in INITIAL_CONTENTS_IGNORE.
* Precompute: Mark StringEncode as non-removable, just like ArrayCopy (#6423)Alon Zakai2024-03-222-7/+68
| | | | | | | | | | | | | | The only StringEncode we support is the one that writes into an array, so it has the same effects as ArrayCopy. Precompute needs to be made aware of such side effects in a manual manner (as we already do for ArrayCopy etc.): it simply tries to execute code in the interpreter, and if it succeeds it replaces; it does not check for side effects (checking for side effects would prevent optimizing cases where the side effects do not happen, as we check them statically, e.g. dividing by a non-zero constant does not trap but a division would be seen as having a potential trap effect). I verified no other string operation is hit by this: all the others emit or operate on immutable strings; it is just StringEncode that is basically an Array operation that appears in the Strings proposal.)
* [Strings] Handle overflow in string.encode_wtf16_array (#6422)Alon Zakai2024-03-222-2/+43
|
* CodeFolding: Fix up old EH when we fold away an If (#6420)Alon Zakai2024-03-222-1/+69
| | | | | | | | | | | | | | | | | | | | | The pass does (among other things) this: (if condition X X ) => (block (drop condition ) X ;; deduplicated ) After that the condition is now nested in a block, so we may need EH fixups if it contains a pop.
* Mark non-closed types as requiring GC (#6421)Thomas Lively2024-03-212-1/+14
| | | This omission was able to cause a problem with text round-tripping.
* [Strings] Implement TODOs in the fuzzer (#6416)Alon Zakai2024-03-211-1/+6
|
* [Strings] Add (partial) validation for StringNew (#6417)Alon Zakai2024-03-211-1/+34
|
* [Strings] Emit unreachable when a string instruction cannot be emitted ↵Alon Zakai2024-03-211-0/+13
| | | | | properly (#6415) See WebAssembly/stringref#66
* [Strings] Fix StringSlice end computation (#6414)Alon Zakai2024-03-212-3/+17
| | | | | Like JS string slicing, if the end index is out of bounds that is fine, we clamp to the end. This also matches the behavior in V8 and the spec.
* Revert "Strings: Disable precomputing for now (#6412)" (#6413)Alon Zakai2024-03-203-74/+13
| | | | | | | | This reverts commit 70ac213fce134840609190a5d3a18118a089ba8a. Reverts #6412 On second thought we found a way to make fixing this less urgent, and the code size downsides of this are worrying, so let's revert it.
* Strings: Disable precomputing for now (#6412)Alon Zakai2024-03-203-13/+74
| | | | Our UTF implementation is still not fully stable it seems as we have reports of issues. Disable it for now.
* [Strings] Avoid mishandling unicode in StringConcat (#6411)Roberto Lublinerman2024-03-192-1/+32
|
* Atomics: Handle timeouts in waits in the (single-threaded) interpreter (#6408)Alon Zakai2024-03-192-3/+30
| | | | | | | | | The interpreter does not run multiple threads, and it was returning 0 from atomic.wait, which means it was woken up. But it is more correct for it to return 2, which means it timed out - which is actually the case, as no other thread exists that can wake it up. However, even that is not good for fuzzing as the timeout may be infinite or large, so just emit a host limit error on any timeout for now, until we actually implement threads.
* [Strings] Implement stringview_wtf16.slice (#6404)Alon Zakai2024-03-194-5/+95
|
* Typed continuations: suspend instructions (#6393)Frank Emrich2024-03-1929-22/+281
| | | | | | | | | | | | | | | | | | | | | This PR is part of a series that adds basic support for the [typed continuations/wasmfx proposal](https://github.com/wasmfx/specfx). This particular PR adds support for the `suspend` instruction for suspending with a given tag, documented [here](https://github.com/wasmfx/specfx/blob/main/proposals/continuations/Overview.md#instructions). These instructions are of the form `(suspend $tag)`. Assuming that `$tag` is defined with _n_ `param` types `t_1` to `t_n`, the instruction consumes _n_ arguments of types `t_1` to `t_n`. Its result type is the same as the `result` type of the tag. Thus, the folded textual representation looks like `(suspend $tag arg1 ... argn)`. Support for the instruction is implemented in both the old and the new wat parser. Note that this PR does not implement validation of the new instruction. This PR also fixes finalization of `cont.new`, `cont.bind` and `resume` nodes in those cases where any of their children are unreachable.
* [Strings] Avoid mishandling unicode in interpreter (#6405)Thomas Lively2024-03-182-5/+135
| | | | | | | Our interpreter implementations of `stringview_wtf16.length`, `stringview_wtf16.get_codeunit`, and `string.encode_wtf16_array` are not unicode-aware, so they were previously incorrect in the face of multi-byte code units. As a fix, bail out of the interpretation if there is a non-ascii code point that would make our naive implementation incorrect.
* [NFC] Fix build error on RISC-V 64 (#6410)moui02024-03-181-1/+11
| | | | | | | | | | | | | | | | | | | | | | Similar issue as: #6330 FAILED: src/passes/CMakeFiles/passes.dir/Precompute.cpp.o /usr/bin/c++ -I/build/binaryen/src/binaryen-version_117/src -I/build/binaryen/src/binaryen-version_117/third_party/llvm-project/include -I/build/binaryen/src/binaryen-version_117/build -march=rv64gc -mabi=lp64d -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -Wp,-D_GLIBCXX_ASSERTIONS -g -ffile-prefix-map=/build/binaryen/src=/usr/src/debug/binaryen -DBUILD_LLVM_DWARF -Wall -Werror -Wextra -Wno-unused-parameter -Wno-dangling-pointer -fno-omit-frame-pointer -fno-rtti -Wno-implicit-int-float-conversion -Wno-unknown-warning-option -Wswitch -Wimplicit-fallthrough -Wnon-virtual-dtor -fPIC -fdiagnostics-color=always -O3 -DNDEBUG -UNDEBUG -std=c++17 -MD -MT src/passes/CMakeFiles/passes.dir/Precompute.cpp.o -MF src/passes/CMakeFiles/passes.dir/Precompute.cpp.o.d -o src/passes/CMakeFiles/passes.dir/Precompute.cpp.o -c /build/binaryen/src/binaryen-version_117/src/passes/Precompute.cpp In file included from /build/binaryen/src/binaryen-version_117/src/wasm-traversal.h:30, from /build/binaryen/src/binaryen-version_117/src/pass.h:24, from /build/binaryen/src/binaryen-version_117/src/ir/intrinsics.h:20, from /build/binaryen/src/binaryen-version_117/src/ir/effects.h:20, from /build/binaryen/src/binaryen-version_117/src/passes/Precompute.cpp:30: In copy constructor ‘wasm::SmallVector<wasm::Expression*, 10>::SmallVector(const wasm::SmallVector<wasm::Expression*, 10>&)’, inlined from ‘constexpr std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _U1 = wasm::Select* const; _U2 = wasm::SmallVector<wasm::Expression*, 10>; typename std::enable_if<(std::_PCC<true, _T1, _T2>::_ConstructiblePair<_U1, _U2>() && std::_PCC<true, _T1, _T2>::_ImplicitlyConvertiblePair<_U1, _U2>()), bool>::type <anonymous> = true; _T1 = wasm::Select* const; _T2 = wasm::SmallVector<wasm::Expression*, 10>]’ at /usr/include/c++/13.2.1/bits/stl_pair.h:559:21, inlined from ‘T& wasm::InsertOrderedMap<Key, T>::operator[](const Key&) [with Key = wasm::Select*; T = wasm::SmallVector<wasm::Expression*, 10>]’ at /build/binaryen/src/binaryen-version_117/src/support/insert_ordered.h:112:29: /build/binaryen/src/binaryen-version_117/src/support/small_vector.h:42:38: error: ‘<unnamed>.wasm::SmallVector<wasm::Expression*, 10>::fixed’ is used uninitialized [-Werror=uninitialized] 42 | template<typename T, size_t N> class SmallVector { | ^~~~~~~~~~~ In file included from /build/binaryen/src/binaryen-version_117/src/passes/Precompute.cpp:38: /build/binaryen/src/binaryen-version_117/src/support/insert_ordered.h: In function ‘T& wasm::InsertOrderedMap<Key, T>::operator[](const Key&) [with Key = wasm::Select*; T = wasm::SmallVector<wasm::Expression*, 10>]’: /build/binaryen/src/binaryen-version_117/src/support/insert_ordered.h:112:29: note: ‘<anonymous>’ declared here 112 | std::pair<const Key, T> kv = {k, {}}; | ^~
* DeadArgumentElimination/SignaturePruning: Prune params even if called with ↵Alon Zakai2024-03-187-125/+822
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | effects (#6395) Before this PR, when we saw a param was unused we sometimes could not remove it. For example, if there was one call like this: (call $target (call $other) ) That nested call has effects, so we can't just remove it from the outer call - we'd need to move it first. That motion was hard to integrate which was why it was left out, but it turns out that is sometimes very important. E.g. in Java it is common to have such calls that send the this parameter as the result of another call; not being able to remove such params meant we kept those nested calls alive, creating empty structs just to have something to send there. To fix this, this builds on top of #6394 which makes it easier to move all children out of a parent, leaving only nested things that can be easily moved around and removed. In more detail, DeadArgumentElimination/SignaturePruning track whether we run into effects that prevent removing a field. If we do, then we queue an operation to move the children out, which we do using a new utility ParamUtils::localizeCallsTo. The pass then does another iteration after that operation. Alternatively we could try to move things around immediately, but that is quite hard: those passes already track a lot of state. It is simpler to do the fixup in an entirely separate utility. That does come at the cost of the utility doing another pass on the module and the pass itself running another iteration, but this situation is not the most common.
* [Strings] Implement string.concat in the interpreter (#6403)Roberto Lublinerman2024-03-152-1/+40
|
* [Strings] Implement string.encode_wtf16_array (#6402)Alon Zakai2024-03-142-1/+105
|
* [Strings] Fix precomputing of StringEq (#6401)Alon Zakai2024-03-142-35/+46
| | | | | | | | We incorrectly overrode the string operations in the interpreter's subclasses. But string operations can be implemented in the topmost class there (as they depend on no module state), so just implement them there, once, in a proper way. This fixes StringEq by removing its override, and moves the others to the right place.
* Fix ASan/TSan errors by using LLVM 18 (#6396)Alon Zakai2024-03-141-8/+16
| | | | | Github actions CI started to fail for no obvious reason. It seems some VM change happened, and very recent LLVM/clang is needed to keep running sanitizers. LLVM 18 is the first version that works.
* [NFC] Refactor ChildLocalizer to handle unreachable code better (#6394)Alon Zakai2024-03-143-24/+133
| | | | | | | | | | | | | | | | This is NFC in the current users, but is necessary functionality for a later PR. ChildLocalizer moves children into locals as needed. It used to stop when it saw the first unreachable. After this change we move such unreachable children out of the parent as well, making this more uniform: all interacting effects are moved out, and all that is left nested in the parent can be moved around and removed as desired. Also add a getReplacement helper that makes using this easier. This cannot be tested comprehensively with the current user as that user will not call this code path on an unreachable parent at all, so this just adds what can be tested. The later PR will have tests for all corner cases.
* DCE: Fix old EH on a pop that gets moved in a catch body (#6400)Alon Zakai2024-03-142-9/+79
|
* 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.