summaryrefslogtreecommitdiff
path: root/test/example
Commit message (Collapse)AuthorAgeFilesLines
...
* Use stdbool boolean instead of int to represent boolean values in C API (#3670)Paulo Matos2021-03-173-6/+6
| | | Fixes #3664
* [Wasm GC] Optimize struct stores like stores to memory, ignore unneeded bits ↵Alon Zakai2021-03-121-0/+13
| | | | | | | (#3680) When storing to an i8, we can ignore any higher bits, etc. Adds a getByteSize utility to Field to make this convenient.
* Remove LUB calculation (#3669)Thomas Lively2021-03-112-114/+0
| | | | | | | | Since correct LUB calculation for recursive types is complicated, stop depending on LUBs throughout the code base. This also fixes a validation bug in which the validator required blocks to be typed with the LUB of all the branch types, when in fact any upper bound should have been valid. In addition to fixing that bug, this PR simplifies the code for break handling by not storing redundant information about the arity of types.
* [reference-types] Support passive elem segments (#3572)Abbas Mashayekh2021-03-054-30/+58
| | | | | | | | | | | Passive element segments do not belong to any table, so the link between Table and elem needs to be weaker; i.e. an elem may have a table in case of active segments, or simply be a collection of function references in case of passive/declarative segments. This PR takes Table::Segment out and turns it into a first class module element just like tables and functions. It also implements early support for parsing, printing, encoding and decoding passive/declarative elem segments.
* [Wasm GC] Allow subtyping in arguments to struct.get etc. Fixes #3636 (#3644)Alon Zakai2021-03-021-7/+21
| | | | | | | | | Note that Binaryen "canonicalizes" the type, so in the test output here we end up with $grandchild twice. This is a consequence of us not storing the heap type as an extra field. I can't think of a downside to this canonicalization, aside from losing perfect roundtripping, but I think that's a worthwhile tradeoff for efficiency as we've been thinking so far. Fixes #3636
* Add C and JS API bindings for ref.as_* (#3628)Daniel Wirtz2021-03-012-0/+42
|
* Use enum instead of bool for StackSignature kind (#3625)Thomas Lively2021-02-261-148/+187
| | | | | As a readability improvement, use an enum with `Polymorphic` and `Fixed` variants to represent the polymorphic behavior of StackSignatures rather than a `bool uneachable`.
* Support printing recursive types (#3624)Thomas Lively2021-02-262-0/+32
| | | | | Also fixes a few locations in Print.cpp where types were being printed directly rather than going through the s-expression type printer and removes vestigial wrapper types that were no longer used.
* [Wasm GC] Add array.wast and validator fixes for it (#3622)Alon Zakai2021-02-261-1/+2
|
* Slightly improve table C API (#3604)Daniel Wirtz2021-02-262-2/+8
| | | Uses BinaryenIndex instead of int to mirror parameter types in table construction, and adds setters for name, initial and max.
* Add TypedFunctionReferences feature to C and JS API (#3603)Daniel Wirtz2021-02-262-0/+2
|
* Support building recursive types (#3602)Thomas Lively2021-02-241-22/+71
| | | | | | | | | | | | | | | | | | | Updates TypeBuilder to support recursive types. Recursive types are particularly problematic because under the current scheme it is necessary to canonicalize the uses of a type's immediate children before canonicalizing the type itself to avoid leaking non-canonical, temporary types out of the TypeBuilder and into the global type stores. In the case of recursive types, it is not possible to do this because of their cyclic nature. In principle this could be overcome by hashing recursive types based on their structure rather than their contents, but that would be complicated. Instead, this PR takes the shortcut of not canonicalizing self-referential HeapTypes at all, but rather moving them out of the TypeBuilder and into the global type store without changing their addresses or needing to update any of their use sites. This breaks all cycles and makes it possible to canonicalize the other types correctly. Note that this PR only adds support for building recursive types. Doing almost anything with the types, such as printing, comparing, or emitting them will certainly lead to infinite recursions. A follow up PR will update all these operations to work correctly with recursive types.
* Fix hashing of a use of a name without the context/target for it (#3601)Alon Zakai2021-02-241-0/+10
| | | | | | | | | | Before this we would assert on hashing e.g. (br $x) by itself, without the context so we recognized the name $x. Somehow that was not an issue until delegate, we just happened to not hash such things. I believe I remember that @aheejin noticed this issue before, but given we didn't have a testcase, we deferred fixing it - now is the time, I guess, as with delegate it is easy to get e.g. CodeFolding to hash a Try with a delegate. Issue found by emscripten-core/emscripten#13485
* Fix TypeBuilder canonicalization (#3578)Thomas Lively2021-02-181-4/+7
| | | | | | | | | | | | | | | | | | | | | | When types or heap types were used multiple times in a TypeBuilder instance, it was possible for the canonicalization algorithm to canonicalize a parent type before canonicalizing all of its component child types, leaking the temporary types into globally interned types. This bug led to incorrect canonicalization results and use-after free bugs. The cause of the bug was that types were canonicalized in the reverse of the order that they were visited in, but children were visited after the first occurrence of their parents, not necessarily after the last occurrence of their parents. One fix could have been to remove the logic that prevented types from being visited multiple times so that children would always be visited after their parents. That simple fix, however, would not scale gracefully to handle recursive types because it would require some way to detect recursions without accidentally reintroducing these bugs. This PR implements a more robust solution: topologically sorting the traversed types to ensure that children are canonicalized before their parents. This solution will be trivial to adapt for recursive types because recursive types are trivial to detect from the reachability graph used to perform the topological sort.
* [EH] Update C and binaryen.js API for delegate (#3565)Heejin Ahn2021-02-132-2/+46
| | | | | | | | | | This updates C and binaryen.js API to match the new `Try` structure to support `delegate`, added in #3561. Now `try` can take a name (which can be null) like a block, and also has an additional `delegateTarget` field argument which should only be used for try-delegate and otherwise null. This also adds several more variant of `makeTry` methods in wasm-builder. Some are for making try-delegate and some are for try-catch(_all).
* Print the features section in a comment (#3563)Alon Zakai2021-02-121-1/+1
|
* StackSignature subtypes and LUBs (#3543)Thomas Lively2021-02-112-48/+180
| | | | | | | | Add a utility for calculating the least upper bounds of two StackSignatures, taking into account polymorphic unreachable behavior. This will important in the finalization and validation of Poppy IR blocks, where a block is allowed to directly produce fewer values than the branches that target it carry if the difference can be made up for by polymorphism due to an unreachable instruction in the block.
* [reference-types] remove single table restriction in IR (#3517)Abbas Mashayekh2021-02-095-11/+126
| | | Adds support for modules with multiple tables. Adds a field for the table name to `CallIndirect` and updates the C/JS APIs accordingly.
* [GC] RefIsNull => RefIs. (#3516)Alon Zakai2021-01-261-2/+2
| | | | | | | | This internal refactoring prepares us for ref.is_func/data/i31, by renaming the node and adding an "op" field. For now that field must always be "Null" which means it is a ref.is_null. This adjusts the C API to match the new IR shape. The high-level JS API is unchanged.
* Reorder i31ref and dataref (#3509)Heejin Ahn2021-01-232-1/+8
| | | | | | | | | | The binary spec (https://docs.google.com/document/d/1yAWU3dbs8kUa_wcnnirDxUu9nEBsNfq0Xo90OWx6yuo/edit#) lists `dataref` after `i31ref`, and `dataref` also comes after `i31ref` in its binary code in the value-increasing order. This reorders these two in wasm-type.h and other places, although in most of those places the order is irrelevant. This also adds C and JS API for `dataref`.
* Remove exnref and br_on_exn (#3505)Heejin Ahn2021-01-224-41/+5
| | | This removes `exnref` type and `br_on_exn` instruction.
* [GC] Add dataref type (#3500)Alon Zakai2021-01-211-1/+1
| | | | | This is not 100% of everything, but is enough to get tests passing, which includes full binary and text format support, getting all switches to compile without error, and some additions to InstrumentLocals.
* Basic EH instrucion support for the new spec (#3487)Heejin Ahn2021-01-152-42/+14
| | | | | | | | | | | | | | | | | | | | This updates `try`-`catch`-`catch_all` and `rethrow` instructions to match the new spec. `delegate` is not included. Now `Try` contains not a single `catchBody` expression but a vector of catch bodies and events. This updates most existing routines, optimizations, and tests modulo the interpreter and the CFG traversal. Because the interpreter has not been updated yet, the EH spec test is temporarily disabled in check.py. Also, because the CFG traversal for EH is not yet updated, several EH tests in `rse_all-features.wast`, which uses CFG traversal, are temporarily commented out. Also added a few more tests in existing EH test functions in test/passes. In the previous spec, `catch` was catching all exceptions so it was assumed that anything `try` body throws is caught by its `catch`, but now we can assume the same only if there is a `catch_all`. Newly added tests test cases when there is a `catch_all` and cases there are only `catch`es separately.
* [GC] More HeapType instead of Type (#3475)Alon Zakai2021-01-112-0/+16
| | | | | | | | To handle both nullable and non-nullable i31s and other heap types, we cannot just look at the isBasic case (which is just one of the two). This may fix this issue on the release builder: https://github.com/WebAssembly/binaryen/runs/1669944081?check_suite_focus=true but the issue does not reproduce locally, so I worry it is something else...
* Remove c-api-kitchen-sink.txt.txt (#3465)Heejin Ahn2021-01-071-2236/+0
| | | | This seems to be a file that used to contain results of tracing, but now that tracing is gone, this file is not updated or used from anywhere.
* Prototype SIMD extending pairwise add instructions (#3466)Thomas Lively2021-01-052-12/+0
| | | | | | As proposed in https://github.com/WebAssembly/simd/pull/380, using the opcodes used in LLVM and V8. Since these opcodes overlap with the opcodes of i64x2.all_true and i64x2.any_true, which have long since been removed from the SIMD proposal, this PR also removes those instructions.
* [module-splitting] Fix a crash when a function is exported twice (#3455)Thomas Lively2020-12-172-0/+44
| | | | | | | | | `ModuleSplitter::thunkExportedSecondaryFunctions` creates a thunk for each secondary function that needs to be exported from the main module. Previously, if a secondary function was exported twice, this code would try to create two thunks for it rather than just making one thunk and exporting it twice. This caused a fatal error because the second thunk had the same name as the first thunk and therefore could not be added to the module. This PR fixes the issue by creating no more than one thunk per function.
* Refactor printing code so that printing Expressions always works (#3450)Alon Zakai2020-12-172-9/+5
| | | | | | | | This avoids needing to add include wasm-printing if a file doesn't already have it. To achieve that, add the std::ostream hooks in wasm.h, and also use them when possible, removing the need for the special WasmPrinter object. Also stop printing in "full" (print types on each line) in error messages by default. The user can still get that, as always, using BINARYEN_PRINT_FULL=1 in the env.
* Use enums for mutability and nullability (#3443)Thomas Lively2020-12-142-151/+169
| | | | | Previously we were using bools for both of these concepts, but using enums makes the code clearer. In particular, the PR removes many instances of `/*nullability=*/ true`.
* TypeBuilder (#3418)Thomas Lively2020-12-102-0/+166
| | | | | | | | | | | | | | | | | Introduce TypeBuilder, a utility for constructing heap types in terms of other heap types that may have not yet been defined. Internally, it works by creating HeapTypes backed by mutable HeapTypeInfos owned by the TypeBuilder. That lets the TypeBuilder create temporary Types that can refer to the TypeBuilder-managed HeapTypes. Those temporary Types can in turn be used to initialize the very HeapTypes they refer to. Since the TypeBuilder-managed HeapTypes are only valid for the lifetime of their TypeBuilder, there is a canonicalization step that converts them into globally interned canonical HeapTypes. This PR allows HeapTypes to be built in terms of as of yet undefined HeapTypes, but it currently errors out in the presence of recursive types. Supporting recursive types will require further work to canonicalize them into finite, acyclic representations. Currently any attempt to compare, print, or otherwise manipulate recursive types would infinitely recurse.
* Intern HeapTypes and clean up types code (#3428)Thomas Lively2020-12-071-46/+46
| | | | | | | | | Interns HeapTypes using the same patterns and utilities already used to intern Types. This allows HeapTypes to efficiently be compared for equality and hashed, which may be important for very large struct types in the future. This change also has the benefit of increasing symmetry between the APIs of Type and HeapType, which will make the developer experience more consistent. Finally, this change will make TypeBuilder (#3418) much simpler because it will no longer have to introduce TypeInfo variants to refer to HeapTypes indirectly.
* [module-splitting] Allow splitting with non-const table offsets (#3408)Thomas Lively2020-12-012-0/+405
| | | | | | | | | | Extend the splitting logic to handle splitting modules with a single table segment with a non-const offset. In this situation the placeholder function names are interpreted as offsets from the table base global rather than absolute indices into the table. Since addition is not allowed in segment offset expressions, the secondary module's segment must start at the same place as the first table's segment. That means that some primary functions must be duplicated in the secondary segment to fill any gaps. They are exported and imported as necessary.
* [TypedFunctionReferences] Add Typed Function References feature and use the ↵Alon Zakai2020-11-232-9/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | types (#3388) This adds the new feature and starts to use the new types where relevant. We use them even without the feature being enabled, as we don't know the features during wasm loading - but the hope is that given the type is a subtype, it should all work out. In practice, if you print out the internal type you may see a typed function reference-specific type for a ref.func for example, instead of a generic funcref, but it should not affect anything else. This PR does not support non-nullable types, that is, everything is nullable for now. As suggested by @tlively this is simpler for now and leaves nullability for later work (which will apparently require let or something else, and many passes may need to be changed). To allow this PR to work, we need to provide a type on creating a RefFunc. The wasm-builder.h internal API is updated for this, as are the C and JS APIs, which are breaking changes. cc @dcodeIO We must also write and read function types properly. This PR improves collectSignatures to find all the types, and also to sort them by the dependencies between them (as we can't emit X in the binary if it depends on Y, and Y has not been emitted - we need to give Y's index). This sorting ends up changing a few test outputs. InstrumentLocals support for printing function types that are not funcref is disabled for now, until we figure out how to make that work and/or decide if it's important enough to work on. The fuzzer has various fixes to emit valid types for things (mostly whitespace there). Also two drive-by fixes to call makeTrivial where it should be (when we fail to create a specific node, we can't just try to make another node, in theory it could infinitely recurse). Binary writing changes here to replace calls to a standalone function to write out a type with one that is called on the binary writer object itself, which maintains a mapping of type indexes (getFunctionSignatureByIndex).
* [effects.h] Add a trap effect for unreachable (#3387)Alon Zakai2020-11-181-0/+14
| | | | | | | | | | | We did not really model the effects of unreachable properly before. It always traps, so it's not an implicit trap, but we didn't do anything but mark it as "branches out", which is not really enough, as while yes it does branch inside the current function, it also traps which is noticeable outside. To fix that, add a trap effect to track this. implicitTrap will set trap as well, automatically, if we do not ignore implicit traps, so it is enough to check just that (unless one cares about the difference between implicit and explicit ones).
* Rename atomic.notify and *.atomic.wait (#3353)Heejin Ahn2020-11-132-4/+4
| | | | | | | | | | | | | | - atomic.notify -> memory.atomic.notify - i32.atomic.wait -> memory.atomic.wait32 - i64.atomic.wait -> memory.atomic.wait64 See WebAssembly/threads#149. This renames instruction name printing but not the internal data structure names, such as `AtomicNotify`, which are not always the same as printed instruction names anyway. This also does not modify C API. But this fixes interface functions in binaryen.js because it seems binaryen.js's interface functions all follow the corresponding instruction names.
* Module splitting (#3317)Thomas Lively2020-11-122-0/+930
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Adds the capability to programatically split a module into a primary and secondary module such that the primary module can be compiled and run before the secondary module has been instantiated. All calls to secondary functions (i.e. functions that have been split out into the secondary module) in the primary module are rewritten to be indirect calls through the table. Initially, the table slots of all secondary functions contain references to imported placeholder functions. When the secondary module is instantiated, it will automatically patch the table to insert references to the original functions. The process of module splitting involves these steps: 1. Create the new secondary module. 2. Export globals, events, tables, and memories from the primary module and import them in the secondary module. 3. Move the deferred functions from the primary to the secondary module. 4. For any secondary function exported from the primary module, export in its place a trampoline function that makes an indirect call to its placeholder function (and eventually to the original secondary function), allocating a new table slot for the placeholder if necessary. 5. Rewrite direct calls from primary functions to secondary functions to be indirect calls to their placeholder functions (and eventually to their original secondary functions), allocating new table slots for the placeholders if necessary. 6. For each primary function directly called from a secondary function, export the primary function if it is not already exported and import it into the secondary module. 7. Replace all references to secondary functions in the primary module's table segments with references to imported placeholder functions. 8. Create new active table segments in the secondary module that will replace all the placeholder function references in the table with references to their corresponding secondary functions upon instantiation. Functions can be used or referenced three ways in a WebAssembly module: they can be exported, called, or placed in a table. The above procedure introduces a layer of indirection to each of those mechanisms that removes all references to secondary functions from the primary module but restores the original program's semantics once the secondary module is instantiated. As more mechanisms that reference functions are added in the future, such as ref.func instructions, they will have to be modified to use a similar layer of indirection. The code as currently written makes a few assumptions about the module that is being split: 1. It assumes that mutable-globals is allowed. This could be worked around by introducing wrapper functions for globals and rewriting secondary code that accesses them, but now that mutable-globals is shipped on all browsers, hopefully that extra complexity won't be necessary. 2. It assumes that all table segment offsets are constants. This simplifies the generation of segments to actively patch in the secondary functions without overwriting any other table slots. This assumption could be relaxed by 1) having secondary segments re-write primary function slots as well, 2) allowing addition in segment offsets, or 3) synthesizing a start function to modify the table instead of using segments. 3. It assumes that each function appears in the table at most once. This isn't necessarily true in general or even for LLVM output after function deduplication. Relaxing this assumption would just require slightly more complex code, so it is a good candidate for a follow up PR. Future Binaryen work for this feature includes providing a command line tool exposing this functionality as well as C API, JS API, and fuzzer support. We will also want to provide a simple instrumentation pass for finding dead or late-executing functions that would be good candidates for splitting out. It would also be good to integrate that instrumentation with future function outlining work so that dead or exceptional basic blocks could be split out into a separate module.
* Fix BinaryenFunctionOptimize. (#3339)Alon Zakai2020-11-112-0/+43
| | | | | | We mistakenly tried to run all passes there, but should run only the function ones. Fixes #3333
* Avoid boilerplate in ExpressionAnalyzer comparing & hashing (#3332)Alon Zakai2020-11-112-0/+143
| | | | | | | | | | | | | | | | | | | | Expands on #3294: * Scope names must be distinguished as either defs or uses. * Error when a core #define is missing, which is less error-prone, as suggested by @tlively * Add DELEGATE_GET_FIELD which lets one define "get the field" once and then all the loops can use it. This helps avoid boilerplate for loops at least in some cases (when there is a single object on which to get the field). With those, it is possible to replace boilerplate in comparisons and hashing logic. This also fixes a bug where BrOnExn::sent was not scanned there. Add some unit tests for hashing. We didn't have any, and hashing can be subtly wrong without observable external effects (just more collisions).
* Implement i8x16.popcnt (#3286)Thomas Lively2020-10-272-24/+16
| | | | | | As proposed in https://github.com/WebAssembly/simd/pull/379. Since this instruction is still being evaluated for inclusion in the SIMD proposal, this PR does not add support for it to the C/JS APIs or to the fuzzer. This PR also performs a drive-by fix for unrelated instructions in c-api-kitchen-sink.c
* Only write explicit names to name section (#3241)Sam Clegg2020-10-151-1/+1
| | | | Fixes: #3226
* Fuzz fix for MemoryPacking on trampled data (#3222)Alon Zakai2020-10-152-0/+116
| | | | | | | | | | | | | I believe originally wasm did not allow overlapping segments, that is, where one memory segment tramples the data from a previous one. But then the spec changed its mind and we allowed it. Binaryen seems to have assumed the original case, and not checked for trampling. If there is a chance of trampling, we cannot optimize out zeros - the zero may have an effect if it tramples data from a previous segment. This does not occur in practice in LLVM output, which is why this wasn't a problem so far, I think. An existing testcase hit this issue, so I split it up.
* Prototype extended-name-section proposal (#3162)Daniel Wirtz2020-09-291-1/+1
| | | Implements the parts of the Extended Name Section Proposal that are trivially applicable to Binaryen, in particular table, memory and global names. Does not yet implement label, type, elem and data names.
* Add new unary and binary matchers (#3168)Thomas Lively2020-09-242-13/+66
| | | | | Adds new matchers that allow for matching any unary or binary operation and optionally extracting it. The previous matchers only allowed matching specific unary and binary operations. This should help simplify #3132.
* GC: Add i31 instructions (#3154)Daniel Wirtz2020-09-242-0/+24
| | | Adds the `i31.new` and `i31.get_s/u` instructions for creating and working with `i31ref` typed values. Does not include fuzzer integration just yet because the fuzzer expects that trivial values it creates are suitable in global initializers, which is not the case for trivial `i31ref` expressions.
* Add Memory64 feature flag to the C and JS APIs (#3148)Daniel Wirtz2020-09-212-0/+2
|
* GC: Add ref.eq instruction (#3145)Daniel Wirtz2020-09-212-0/+10
| | | With `eqref` now integrated, the `ref.eq` instruction can be implemented. The only valid LHS and RHS value is `(ref.null eq)` for now, but implementation and fuzzer integration is otherwise complete.
* GC: Integrate eqref and i31ref types (#3141)Daniel Wirtz2020-09-193-2/+16
| | | Adds the `eqref` and `i31ref` types to their respective code locations. Implements what can be implemented trivially and otherwise traps with a TODO for now. Integration of `eqref` is mostly complete due to it being nullable, just like `anyref`, but `i31ref` needs to remain disabled in the fuzzer because we are lacking the functionality to create trivial `i31ref` values, i.e. `(i31.new (i32.const 0))`, which is left for follow-ups to implement.
* Expression matching API (#3134)Thomas Lively2020-09-182-0/+457
| | | | | | | | | | | Provides an easily extensible layered API for matching expression patterns and extracting their components. The low-level API provides modular building blocks for creating matchers for any data type and the high-level API provides a succinct and flexible interface for matching expressions and extracting useful information from them. Matchers are currently provided for Const, Unary, Binary, and Select instructions. Adding a matcher for a new type of expression is straightforward enough that I expect to add them as they become useful as part of other changes.
* Initial implementation of "Memory64" proposal (#3130)Wouter van Oortmerssen2020-09-182-3/+3
| | | Also includes a lot of new spec tests that eventually need to go into the spec repo
* Implement more cases for getMaxBits (#2879)Max Graey2020-09-172-16/+530
| | | | | | | | | | | | | | | - Complete 64-bit cases in range `AddInt64` ... `ShrSInt64` - `ExtendSInt32` and `ExtendUInt32` for unary cases - For binary cases - `AddInt32` / `AddInt64` - `MulInt32` / `MulInt64` - `RemUInt32` / `RemUInt64` - `RemSInt32` / `RemSInt64` - `DivUInt32` / `DivUInt64` - `DivSInt32` / `DivSInt64` - and more Also more fast paths for some getMaxBits calculations