summaryrefslogtreecommitdiff
path: root/src/wasm
Commit message (Collapse)AuthorAgeFilesLines
* [NFC] Refactor LocalGraph's core getSets API (#6877)Alon Zakai2024-08-281-1/+1
| | | | | | | | | | | | | | Before we just had a map that people would access with localGraph.getSetses[get], while now it is a call localGraph.getSets(get), which more nicely hides the internal implementation details. Also rename getSetses => getSetsMap. This will allow a later PR to optimize the internals of this API. This is performance-neutral as far as I can measure. (We do replace a direct read from a data structure with a call, but the call is in a header and should always get inlined.)
* Rename relaxed SIMD fma instructions to match spec. (#6876)Brendan Dahl2024-08-273-30/+34
| | | | | | | The instructions relaxed_fma and relaxed_fnma have been renamed to relaxed_madd and relaxed_nmadd. https://github.com/WebAssembly/relaxed-simd/blob/main/proposals/relaxed-simd/Overview.md#binary-format
* [FP16] Implement unary operations. (#6867)Brendan Dahl2024-08-275-7/+97
| | | | Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md
* Fix null dereference in FunctionValidator (#6849)mtb2024-08-261-2/+11
| | | | | | | | | | visitBlock() and validateCallParamsAndResult() both assumed they were running inside a function, but might be called on global code too. Calls and blocks are invalid in global positions, so we should error there, but must do so properly without a null deref. Fixes #6847 Fixes #6848
* Support more reference constants in wast scripts (#6865)Thomas Lively2024-08-261-18/+0
| | | | | | | | | | | | | | Spec tests use constants like `ref.array` and `ref.eq` to assert that exported function return references of the correct types. Support more such constants in the wast parser. Also fix a bug where the interpretation of `array.new_data` for arrays of packed fields was not properly truncating the packed data. Move the function for reading fields from memory from literal.cpp to wasm-interpreter.h, where the function for truncating packed data lives. Other bugs prevent us from enabling any more spec tests as a result of this change, but we can get farther through several of them before failing. Update the comments about the failures accordingly.
* [FP16] Add a feature flag for FP16. (#6864)Brendan Dahl2024-08-223-14/+33
| | | Ensure the "fp16" feature is enabled for FP16 instructions.
* [NFC] Avoid quadratic time in StackIROptimizer::removeUnneededBlocks() (#6859)Alon Zakai2024-08-211-5/+15
| | | | | | | | | | | | | | | This is in quite ancient code, so it's a long-standing issue, but it got worse when we enabled StackIR in more situations (#6568), which made it more noticeable, I think. For example, testing on test_biggerswitch in Emscripten, the LLVM part is pretty slow too so the Binaryen slowdown didn't stand out hugely, but just doing wasm-opt --optimize-level=2 input.wasm -o output.wasm (that is, do no work, but set the optimize level to 2 so that StackIR opts are run) used to take 28 seconds (!). With this PR that goes down to less than 1.
* [FP16] Implement arithmetic operations. (#6855)Brendan Dahl2024-08-214-5/+110
| | | | Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md
* Support `ref.extern n` in spec tests (#6858)Thomas Lively2024-08-211-0/+3
| | | | | | | | | | | | | | | | | Spec tests pass the value `ref.extern n`, where `n` is some integer, into exported functions that expect to receive externrefs and receive such values back out as return values. The payload serves to distinguish externrefs so the test can assert that the correct one was returned. Parse these values in wast scripts and represent them as externalized i31refs carrying the payload. We will need a different representation eventually, since some tests explicitly expect these externrefs to not be i31refs, but this suffices to get several new tests passing. To get the memory64 version of table_grow.wast passing, additionally fix the interpreter to handle growing 64-bit tables correctly. Delete the local versions of the upstream tests that can now be run successfully.
* Fix encoding of heap type definitions (#6856)Thomas Lively2024-08-201-13/+13
| | | | | | | | The leading bytes that indicate what kind of heap type is being defined are bytes, but we were previously treating them as SLEB128-encoded values. Since we emit the smallest LEB encodings possible, we were writing the correct bytes in output files, but we were also improperly accepting binaries that used more than one byte to encode these values. This was caught by an upstream spec test.
* [Exceptions] Finish interpreter + optimizer support for try_table. (#6814)Sébastien Doeraene2024-08-203-2/+21
| | | | | | * Add interpreter support for exnref values. * Fix optimization passes to support try_table. * Enable the interpreter (but not in V8, see code) on exceptions.
* Validate array.init_elem segment in IRBuilder (#6852)Thomas Lively2024-08-191-0/+10
| | | | | | | | | IRBuilder is responsible for validation involving type annotations on GC instructions because those type annotations may not be preserved in the built IR to be used by the main validator. For `array.init_elem`, we were not using the type annotation to validate the element segment, which allowed us to parse invalid modules when the reference operand was a nullref. Add the missing validation in IRBuilder and fix a relevant spec test.
* [NFC] Use HeapType::getKind more broadly (#6846)Thomas Lively2024-08-192-96/+116
| | | | | | | | Replace code that checked `isStruct()`, `isArray()`, etc. in sequence with uses of `HeapType::getKind()` and switch statements. This will make it easier to find the code that needs updating if/when we add new heap type kinds in the future. It also makes it much easier to find code that already needs updating to handle continuation types by grepping for "TODO: cont".
* Add a pass for minimizing recursion groups (#6832)Thomas Lively2024-08-171-0/+1
| | | | | | | | | | | | Most of our type optimization passes emit all non-public types as a single large rec group, which trivially ensures that different types remain different, even if they are optimized to have the same structure. Usually emitting a single large rec group is fine, but it also means that if the module is split, all of the types will need to be repeated in all of the split modules. To better support this use case, add a pass that can split the large rec group back into minimal rec groups, taking care to preserve separate type identities by emitting different permutations of the same group where possible or by inserting unused brand types to differentiate them.
* Fix direct comparisons with unshared basic heap types (#6845)Thomas Lively2024-08-162-2/+2
| | | | | Audit the remaining ocurrences of `== HeapType::` and fix those that did not handle shared types correctly. Add tests for some of the fixes; others are NFC but clarify the code.
* Implement table.init (#6827)Alon Zakai2024-08-165-3/+75
| | | | | Also use TableInit in the interpreter to initialize module's table state, which will now handle traps properly, fixing #6431
* Simplify validation of stale types (#6842)Thomas Lively2024-08-151-24/+9
| | | | | | | | | | | | | | | | | | | The previous rules for stale types were complicated and hard to remember: in general it was ok for result types to be further refinable as long as they were not refinable all the way to `unreachable`, but control flow structures had a carve-out and it was ok for them to be refinable all the way to unreachable. Simplify the rules so that further refinable result types are always ok, no matter what they can be refined to and no matter what kind of instruction is being validated. This will be much easier to remember and reason about. This relaxation of the rules strictly increases the set of valid IR, so no passes or tests need to be updated. It does make it possible for us to miss type refinement opportunities that previously would have been validation errors, but only in cases where non-control-flow instructions could have been refined all the way to unreachable, so the risk seems small.
* [NFC] Clean up Literal copy constructor (#6841)Alon Zakai2024-08-151-30/+27
| | | | | | | | Diff without whitespace is smaller. * HeapType::ext was handled in two places. The second place was wrong, but not reached. * Near the end all we have left are refs, so no need to check isRef etc. * Simplify the code to get the heap type once.
* Save build ID in a source map (#6799)Marcin Kolny2024-08-152-1/+27
| | | | | | | This is based on these two proposals: * https://github.com/WebAssembly/tool-conventions/blob/main/BuildId.md * https://github.com/tc39/source-map/blob/main/proposals/debug-id.md
* Heap type `none` requires GC (#6840)Thomas Lively2024-08-141-1/+1
| | | | | | Since reference types only introduced function and extern references, all of the types in the `any` hierarchy require GC, including `none`. Fixes #6839.
* Add a TypeBuilder API for copying a heap type (#6828)Thomas Lively2024-08-121-2/+2
| | | | | | | | | | Given a function that maps the old child heap types to new child heap types, the new API takes care of copying the rest of the structure of a given heap type into a TypeBuilder slot. Use the new API in GlobalTypeRewriter::rebuildTypes. It will also be used in an upcoming type optimization. This refactoring also required adding the ability to clear the supertype of a TypeBuilder slot, which was previously not possible.
* [FP16] Implement relation operations. (#6825)Brendan Dahl2024-08-094-0/+66
| | | | Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md
* [FP16] Implement lane access instructions. (#6821)Brendan Dahl2024-08-085-0/+53
| | | | Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md
* Add a utility for comparing and hashing rec group shapes (#6808)Thomas Lively2024-08-072-0/+349
| | | | | | | | | | | This is very similar to the internal utilities for canonicalizing rec groups in the type system implementation, except that the new utility also supports ordered comparison of rec groups, and of course the new utility only uses the public type API. A follow-up PR will replace the internal implementation of rec group comparison and hashing in the type system with this one. Another follow-up PR will use this new utility in a type optimization.
* [FP16] Implement load and store instructions. (#6796)Brendan Dahl2024-08-063-22/+78
| | | | Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md
* Restore isString type methods (#6815)Thomas Lively2024-08-062-1/+3
| | | | | | | | | PR ##6803 proposed removing Type::isString and HeapType::isString in favor of more explicit, verbose callsites. There was no consensus to make this change, but it was accidentally committed as part of #6804. Revert the accidental change, except for the useful, noncontroversial parts, such as fixing the `isString` implementation and a few other locations to correctly handle shared types.
* [Source maps] Handle single-segment entries in source map header decoder (#6794)Ömer Sinan Ağacan2024-08-061-6/+13
| | | | | Single-segment mappings were already handled in readNextDebugLocation, but not in readSourceMapHeader.
* [NFC] Add HeapType::getKind returning a new HeapTypeKind enum (#6804)Thomas Lively2024-08-062-104/+75
| | | | | | | | | | | | | | | | | The HeapType API has functions like `isBasic()`, `isStruct()`, `isSignature()`, etc. to test the classification of a heap type. Many users have to call these functions in sequence and handle all or most of the possible classifications. When we add a new kind of heap type, finding and updating all these sites is a manual and error-prone process. To make adding new heap type kinds easier, introduce a new API that returns an enum classifying the heap type. The enum can be used in switch statements and the compiler's exhaustiveness checker will flag use sites that need to be updated when we add a new kind of heap type. This commit uses the new enum internally in the type system, but follow-on commits will add new uses and convert uses of the existing APIs to use `getKind` instead.
* WasmBinaryReader: Use helper function to create names for items. NFC (#6810)Sam Clegg2024-08-051-14/+15
| | | | | As a followup we could probably make these more consistent. For example, we could use a single char prefix for defined functions/tables/globals (e.g. f0/t0/g0)
* [NFC] Remove unused `isException` type methods (#6802)Thomas Lively2024-08-051-6/+0
|
* [NFC] Avoid a temp local (#6800)Alon Zakai2024-08-011-3/+3
| | | | | The local was only used once, so it didn't really add much. And, it was causing some compilers to error on "unused variable" (when building without assertions, the use was removed).
* Use Names::getValidNameGivenExisting in binary reading (#6793)Alon Zakai2024-07-311-8/+3
| | | | | | We had a TODO to use it once Names was optimized, which it has been. The Names version is also far faster. When building https://github.com/JetBrains/kotlinconf-app it saves 70 seconds(!).
* Fix shareability of externalized nulls (#6791)Alon Zakai2024-07-301-2/+3
|
* Fix shareability of internalized nulls (#6789)Alon Zakai2024-07-291-2/+3
|
* Generalize Literal::externalize/internalize for strings and shareability (#6784)Alon Zakai2024-07-291-18/+12
|
* Validate RefAsNonNull (#6785)Alon Zakai2024-07-242-3/+18
| | | Fixes #6781
* Properly validate ref.cast when lacking a common supertype (#6741)Alon Zakai2024-07-231-0/+15
| | | | | | | When lacking a common supertype the GLB operation makes the type of the cast unreachable, which errors on getHeapType in the later code. Fixes #6738
* [NFC] Add HeapType::isMaybeShared(BasicHeapType) utility (#6773)Thomas Lively2024-07-184-6/+4
| | | | | | | | | This abbreviates a common pattern where we first had to check whether a heap type was basic, then if it was, get its unshared version and compare it to some expected BasicHeapType. Suggested in https://github.com/WebAssembly/binaryen/pull/6771#discussion_r1683005495.
* Validate features for types used in element segments (#6769)Thomas Lively2024-07-181-0/+8
|
* Validate features for types used in tables (#6768)Thomas Lively2024-07-181-13/+8
| | | | We previously special-cased things like GC types, but switch to a more general solution of detecting what features a table's type requires.
* [threads] ref.i31_shared requires shared-everything in validation (#6767)Thomas Lively2024-07-181-0/+6
|
* [threads] Simplify and generalize reftype writing without GC (#6766)Thomas Lively2024-07-181-16/+8
| | | | | | Similar to #6765, but for types instead of heap types. Generalize the logic for transforming written reference types to types that are supported without GC so that it will automatically handle shared types and other new types correctly.
* [threads] Simplify and generalize heap type writing without GC (#6765)Thomas Lively2024-07-171-14/+1
| | | | | | | | | | We represent `ref.null`s as having bottom heap types, even when GC is not enabled. Bottom heap types are a feature of the GC proposal, so in that case the binary writer needs to write the corresponding top type instead. We previously had separate logic for this for each type hierarchy in the binary writer, but that did not handle shared types and would not have automatically handled other new types, either. Simplify and generalize the implementation and test that we can write `ref.null`s of shared types without GC enabled.
* [threads] Fix shared ref.eq and disallow mixed-shareability (#6763)Thomas Lively2024-07-172-1/+8
| | | | | | | Update the validator to reject mixed-shareability ref.eq, although this is still under discussion in https://github.com/WebAssembly/shared-everything-threads/issues/76. Fix the implementation of `Literal::operator==` to work properly with shared i31ref.
* Revert "[threads] Allow i31refs of mixed shareability to compare equal ↵Thomas Lively2024-07-171-9/+3
| | | | | | | | | | | | | | (#6752)" (#6761) Allowing Literals with different types to compare equal causes problems for passes that want equality to mean real equality, e.g. because they are using literals as map keys or because they otherwise need to use them interchangeably. At a minimum, we would need to differentiate a `refEq` operation where mixed-shareability i31refs can compare equal from physical equality on Literals, but there is also appetite to disallow mixed-shareability ref.eq at the spec level. See https://github.com/WebAssembly/shared-everything-threads/issues/76.
* Error more clearly on wasm components (#6751)Alon Zakai2024-07-171-1/+9
| | | | | | Component binary format: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Binary.md#component-definitions Context: https://github.com/WebAssembly/binaryen/issues/6728#issuecomment-2231288924
* [threads] Validate all features required by ref.null (#6757)Thomas Lively2024-07-161-15/+25
| | | | | | | `ref.null` of shared types should only be allowed when shared-everything is enabled, but we were previously checking only that reference types were enabled when validating `ref.null`. Update the code to check all features required by the null type and factor out shared logic for printing lists of missing feature options in error messages.
* [threads] Fix feature detection for shared basic heap types (#6756)Thomas Lively2024-07-161-4/+4
| | | | The logic for adding the shared-everything feature was not previously executed for shared basic heap types.
* [threads] Allow i31refs of mixed shareability to compare equal (#6752)Thomas Lively2024-07-161-3/+9
| | | | | | | Normally, values of different types can never compare equal to each other, but since i31refs are not actually allocations, `ref.eq` has no way to differentiate a shared i31ref and an unshared i31ref with the same value, so it will report them as equal. Update the implementation of value equality to reflect this correctly.
* Remove extra space printed in empty structs (#6750)Thomas Lively2024-07-161-4/+0
| | | | | | When we switched to the new type printing machinery, we inserted this extra space to minimize the diff in the test output compared with the previous type printer. Improve the quality of the printed output by removing it.