| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
| |
This change makes matchers in OptimizeInstructions more compact and readable by
removing the explicit `Abstract::` namespace from individual operations. In some
cases, this makes multi-line matcher expressions fit on a single line.
This change is only possible because it also adds an explicit "RMW" prefix to
each element of the `AtomicRMWOp` enumeration. Without that, their names
conflicted with the names of Abstract ops.
|
|
|
|
| |
Fixes: #3226
|
|
|
| |
Adds `BinaryenGetFastMath` and `BinaryenSetFastMath` to the C API, respectively `binaryen.getFastMath` and `binaryen.setFastMath` to the JS API.
|
|
|
| |
NFC, except adding most of the boilerplate for the remaining GC instructions. Each implementation site is marked with a respective `TODO (gc): theInstruction` in between the typical boilerplate code.
|
|
|
| |
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.
|
| |
|
|
|
| |
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.
|
|
|
| |
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.
|
|
|
| |
Also includes a lot of new spec tests that eventually need to go into the spec repo
|
|
|
| |
Aligns the internal representations of `memory.size` and `memory.grow` with other more recent memory instructions by removing the legacy `Host` expression class and adding separate expression classes for `MemorySize` and `MemoryGrow`. Simplifies related APIs, but is also a breaking API change.
|
|
|
| |
Adds the `--enable-gc` feature flag, so far enabling the `anyref` type incl. subtyping, and removes the temporary `--enable-anyref` feature flag that it replaces.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Adds support for the module and local subsections of the name section plus the respective C and JS APIs to populate and obtain local names.
C API:
* BinaryenFunctionGetNumLocals(func)
* BinaryenFunctionHasLocalName(func, index)
* BinaryenFunctionGetLocalName(func, index)
* BinaryenFunctionSetLocalName(func, index, name)
JS API:
* Function.getNumLocals(func)
* Function.hasLocalName(func, index)
* Function.getLocalName(func, index)
* Function.setLocalName(func, index, name)
|
|
|
| |
Adds `anyref` type, which is enabled by a new feature `--enable-anyref`. This type is primarily used for testing that passes correctly handle subtype relationships so that the codebase will continue to be prepared for future subtyping. Since `--enable-anyref` is meaningless without also using `--enable-reference-types`, this PR also makes it a validation error to pass only the former (and similarly makes it a validation error to enable exception handling without enabling reference types).
|
|
|
|
|
| |
Adds an IR profile to each function so the validator can determine
which validation rules to apply and adds a flag to have the wast
parser set the profile to Poppy for testing purposes.
|
|
|
|
|
|
|
| |
Align with the current state of the reference types proposal:
* Remove `nullref`
* Remove `externref` and `funcref` subtyping
* A `Literal` of a nullable reference type can now represent `null` (previously was type `nullref`)
* Update the tests and temporarily comment out those tests relying on subtyping
|
|
|
| |
Fixes the `Relooper` leaking `Branch`es in `Optimizer::SkipEmptyBlocks`, by refactoring the API so a `std::unique_ptr` is ensured for each `Block`, `Branch` and `Shape` upon adding to the relooper.
|
|
|
|
|
|
|
|
|
| |
Split that mode into an option to check for loops (which indicate a function
is "heavy") and a constant check for having calls. The case of calls is
different as we would need more logic to avoid infinite recursion if we are
willing to inling functions with calls.
Practically, this renames allowHeavyweight to allowFunctionsWithLoops.
|
|
|
| |
These declarations were previously missing causing the respective APIs to be not exposed. Also makes sure that a Boolean is returned by the JS API and adds a test to verify that it is working now.
|
|
|
|
|
| |
As discussed in #2921, this allows inlining of functions not identified
as "lightweight" (that include a loop, for example).
|
|
|
| |
Since they make the code clearer and more self-documenting.
|
|
|
| |
This leads to simpler code and is a prerequisite for #3012, which makes it so that not all `Type`s are backed by vectors that `expand` could return.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
As a follow-up to https://github.com/WebAssembly/binaryen/pull/3012#pullrequestreview-459686171 this PR prepares for the new compound Signature, Struct and Array types that are single but not basic.
This includes:
* Renames `Type::getSingle` to `Type::getBasic` (NFC). Previously, its name was not representing its implementation (`isSingle` excluded `none` and `unreachable` while `getSingle` didn't, i.e. `getSingle` really was `getBasic`). Note that a hypothetical `Type::getSingle` cannot return `ValueType` anyway (new compound types are single but don't map to `ValueType`), so I figured it's best to skip implementing it until we actually need it.
* Marks locations where we are (still) assuming that all single types are basic types, as suggested in https://github.com/WebAssembly/binaryen/pull/3012#discussion_r465356708, but using a macro, so we get useful errors once we start implementing the new types and can quickly traverse the affected locations.
The macro is added where
* there used to be a `switch (type.getSingle())` or similar that handled any basic type (NFC), but in the future will also have to handle single types that are not basic types.
* we are not dealing with `Unary`, `Binary`, `Load`, `Store` or `AtomicXY` instructions, since these don't deal with compound types anyway.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Renames the following C-API functions
BinaryenBlockGetChild to BinaryenBlockGetChildAt
BinaryenSwitchGetName to BinaryenSwitchGetNameAt
BinaryenCallGetOperand to BinaryenCallGetOperandAt
BinaryenCallIndirectGetOperand to BinaryenCallIndirectGetOperandAt
BinaryenHostGetOperand to BinaryenHostGetOperandAt
BinaryenThrowGetOperand to BinaryenThrowGetOperandAt
BinaryenTupleMakeGetOperand to BinaryenTupleMakeGetOperandAt
Adds the following C-API functions
BinaryenExpressionSetType
BinaryenExpressionFinalize
BinaryenBlockSetName
BinaryenBlockSetChildAt
BinaryenBlockAppendChild
BinaryenBlockInsertChildAt
BinaryenBlockRemoveChildAt
BinaryenIfSetCondition
BinaryenIfSetIfTrue
BinaryenIfSetIfFalse
BinaryenLoopSetName
BinaryenLoopSetBody
BinaryenBreakSetName
BinaryenBreakSetCondition
BinaryenBreakSetValue
BinaryenSwitchSetNameAt
BinaryenSwitchAppendName
BinaryenSwitchInsertNameAt
BinaryenSwitchRemoveNameAt
BinaryenSwitchSetDefaultName
BinaryenSwitchSetCondition
BinaryenSwitchSetValue
BinaryenCallSetTarget
BinaryenCallSetOperandAt
BinaryenCallAppendOperand
BinaryenCallInsertOperandAt
BinaryenCallRemoveOperandAt
BinaryenCallSetReturn
BinaryenCallIndirectSetTarget
BinaryenCallIndirectSetOperandAt
BinaryenCallIndirectAppendOperand
BinaryenCallIndirectInsertOperandAt
BinaryenCallIndirectRemoveOperandAt
BinaryenCallIndirectSetReturn
BinaryenCallIndirectGetParams
BinaryenCallIndirectSetParams
BinaryenCallIndirectGetResults
BinaryenCallIndirectSetResults
BinaryenLocalGetSetIndex
BinaryenLocalSetSetIndex
BinaryenLocalSetSetValue
BinaryenGlobalGetSetName
BinaryenGlobalSetSetName
BinaryenGlobalSetSetValue
BinaryenHostSetOp
BinaryenHostSetNameOperand
BinaryenHostSetOperandAt
BinaryenHostAppendOperand
BinaryenHostInsertOperandAt
BinaryenHostRemoveOperandAt
BinaryenLoadSetAtomic
BinaryenLoadSetSigned
BinaryenLoadSetOffset
BinaryenLoadSetBytes
BinaryenLoadSetAlign
BinaryenLoadSetPtr
BinaryenStoreSetAtomic
BinaryenStoreSetBytes
BinaryenStoreSetOffset
BinaryenStoreSetAlign
BinaryenStoreSetPtr
BinaryenStoreSetValue
BinaryenStoreGetValueType
BinaryenStoreSetValueType
BinaryenConstSetValueI32
BinaryenConstSetValueI64
BinaryenConstSetValueI64Low
BinaryenConstSetValueI64High
BinaryenConstSetValueF32
BinaryenConstSetValueF64
BinaryenConstSetValueV128
BinaryenUnarySetOp
BinaryenUnarySetValue
BinaryenBinarySetOp
BinaryenBinarySetLeft
BinaryenBinarySetRight
BinaryenSelectSetIfTrue
BinaryenSelectSetIfFalse
BinaryenSelectSetCondition
BinaryenDropSetValue
BinaryenReturnSetValue
BinaryenAtomicRMWSetOp
BinaryenAtomicRMWSetBytes
BinaryenAtomicRMWSetOffset
BinaryenAtomicRMWSetPtr
BinaryenAtomicRMWSetValue
BinaryenAtomicCmpxchgSetBytes
BinaryenAtomicCmpxchgSetOffset
BinaryenAtomicCmpxchgSetPtr
BinaryenAtomicCmpxchgSetExpected
BinaryenAtomicCmpxchgSetReplacement
BinaryenAtomicWaitSetPtr
BinaryenAtomicWaitSetExpected
BinaryenAtomicWaitSetTimeout
BinaryenAtomicWaitSetExpectedType
BinaryenAtomicNotifySetPtr
BinaryenAtomicNotifySetNotifyCount
BinaryenAtomicFenceSetOrder
BinaryenSIMDExtractSetOp
BinaryenSIMDExtractSetVec
BinaryenSIMDExtractSetIndex
BinaryenSIMDReplaceSetOp
BinaryenSIMDReplaceSetVec
BinaryenSIMDReplaceSetIndex
BinaryenSIMDReplaceSetValue
BinaryenSIMDShuffleSetLeft
BinaryenSIMDShuffleSetRight
BinaryenSIMDShuffleSetMask
BinaryenSIMDTernarySetOp
BinaryenSIMDTernarySetA
BinaryenSIMDTernarySetB
BinaryenSIMDTernarySetC
BinaryenSIMDShiftSetOp
BinaryenSIMDShiftSetVec
BinaryenSIMDShiftSetShift
BinaryenSIMDLoadSetOp
BinaryenSIMDLoadSetOffset
BinaryenSIMDLoadSetAlign
BinaryenSIMDLoadSetPtr
BinaryenMemoryInitSetSegment
BinaryenMemoryInitSetDest
BinaryenMemoryInitSetOffset
BinaryenMemoryInitSetSize
BinaryenDataDropSetSegment
BinaryenMemoryCopySetDest
BinaryenMemoryCopySetSource
BinaryenMemoryCopySetSize
BinaryenMemoryFillSetDest
BinaryenMemoryFillSetValue
BinaryenMemoryFillSetSize
BinaryenRefIsNullSetValue
BinaryenRefFuncSetFunc
BinaryenTrySetBody
BinaryenTrySetCatchBody
BinaryenThrowSetEvent
BinaryenThrowSetOperandAt
BinaryenThrowAppendOperand
BinaryenThrowInsertOperandAt
BinaryenThrowRemoveOperandAt
BinaryenRethrowSetExnref
BinaryenBrOnExnSetEvent
BinaryenBrOnExnSetName
BinaryenBrOnExnSetExnref
BinaryenTupleMakeSetOperandAt
BinaryenTupleMakeAppendOperand
BinaryenTupleMakeInsertOperandAt
BinaryenTupleMakeRemoveOperandAt
BinaryenTupleExtractSetTuple
BinaryenTupleExtractSetIndex
BinaryenFunctionSetBody
Also introduces wrappers to the JS-API resembling the classes in C++
to perform the above operations on an expression. For example:
var unary = binaryen.Unary(module.i32.eqz(1));
unary.getOp(...) / .op
unary.setOp(...) / .op = ...
unary.getValue(...) / .value
unary.setValue(...) / .value = ...
unary.getType(...) / .type
unary.finalize()
...
Usage of wrappers is optional, and one can also use plain functions:
var unary = module.i32.eqz(1);
binaryen.Unary.getOp(unary, ...)
...
Also adds comments to all affected functions in case we'd like to generate
API documentation at some point.
|
|
|
|
|
|
|
| |
anyref future semantics were changed to only represent opaque host values, and thus renamed to externref.
[Chromium](https://bugs.chromium.org/p/v8/issues/detail?id=7748#c360) was just updated to today (not yet released). I couldn't find a Mozilla bugzilla ticket mentioning externref so I don't immediately know if they've updated yet.
https://github.com/WebAssembly/reference-types/pull/87
|
|
|
| |
As specified in https://github.com/WebAssembly/simd/pull/232.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This prevents `exnref.pop`s from being sinked and separated from
`catch`. For example,
```wast
(try
(do)
(catch
(local.set $0 (exnref.pop))
(call $foo
(i32.const 3)
(local.get $0)
)
)
)
```
Here, if we sink `exnref.pop` to remove `local.set $0` and
`local.get $0`, it becomes this:
```wast
(try
(do)
(catch
(nop)
(call $foo
(i32.const 3)
(exnref.pop)
)
)
)
```
This move was possible because `i32.const 3` does not have any side
effects. But this is incorrect because now `exnref.pop` does not follow
right after `catch`.
To prevent this, this patch checks this case in `canSink` in
SimplifyLocals. When we encountered a similar case in CodeFolding, we
prevented every expression that contains `Pop` anywhere in it from being
moved, which was too conservative. This adds `danglingPop` property in
`EffectAnalyzer`, so that only pops that are not enclosed within a
`catch` count as 'dangling pops` and we only prevent those pops from
being moved or sinked.
|
|
|
|
|
|
| |
Push and Pop have been superseded by tuples for their original
intended purpose of supporting multivalue. Pop is still used to
represent block arguments for exception handling, but there are no
plans to use Push for anything now or in the future.
|
|
|
|
| |
This is the only instruction in the current spec proposal that had not
yet been implemnented in the tools.
|
|
|
| |
As specified in https://github.com/WebAssembly/simd/pull/122.
|
|
|
|
|
|
| |
This API enables use cases where we want to keep the original expression, yet utilize passes like `vacuum` or `precompute` to evaluate it without implicitly modifying the original.
C-API: **BinaryenExpressionCopy**(expr, module)
JS-API: **Module#copyExpression**(expr)
|
|
|
|
|
|
| |
This feature was very useful in the early days of the C API,
but has not shown usefuless for quite a while, and has a
significant maintenance burden, so it it's makes sense to
remove it now.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Tackles the concerns raised in https://github.com/WebAssembly/binaryen/issues/2797 directly related to https://github.com/WebAssembly/binaryen/pull/2702 by reverting merging all of `PrecomputeExpressionRunner` into the base `ExpressionRunner`, instead adding a common base for both the precompute pass and the new C-API to inherit. No functional changes.
---
### Current hierarchy after https://github.com/WebAssembly/binaryen/pull/2702 is
```
ExpressionRunner
├ [PrecomputeExpressionRunner]
├ [CExpressionRunner]
├ ConstantExpressionRunner
└ RuntimeExpressionRunner
```
where `ExpressionRunner` contains functionality not utilized by `ConstantExpressionRunner` and `RuntimeExpressionRunner`.
### New hierarchy will be:
```
ExpressionRunner
├ ConstantExpressionRunner
│ ├ [PrecomputeExpressionRunner]
│ └ [CExpressionRunner]
├ InitializerExpressionRunner
└ RuntimeExpressionRunner
```
with the precompute pass's and the C-API's shared functionality now moved out of `ExpressionRunner` into a new `ConstantExpressionRunner`. Also renames the previous `ConstantExpressionRunner` to `InitializerExpressionRunner` to [better represent its uses](https://webassembly.org/docs/modules/#initializer-expression) and to make its previous name usable for the new intermediate template, where it fits perfectly. Also adds a few comments answering some of the questions that came up recently.
### Old hierarchy before https://github.com/WebAssembly/binaryen/pull/2702 for comparison:
```
ExpressionRunner
├ [PrecomputeExpressionRunner]
├ ConstantExpressionRunner
└ RuntimeExpressionRunner
```
|
| |
|
|
|
|
|
|
|
| |
Refactors most of the precompute pass's expression runner into its
base class so it can also be used via the C and JS APIs. Also adds
the option to populate the runner with known constant local and global
values upfront, and remembers assigned intermediate values as well
as traversing into functions if requested.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Instead of using indices into the global interned type table. This
means that a lock is *never* needed to access an expanded Type. The
Type lock is now only acquired when a complex Type is created. On a
real-world wasm2js workload this improves wall clock time by 23% on my
machine with 72 cores and makes traffic on the Type lock entirely
insignificant.
**Before**
72 cores
real 0m6.914s
user 184.014s
sys 0m3.995s
1 core
real 0m25.903s
user 0m25.658s
sys 0m0.253s
**After**
72 cores
real 5.349s
user 70.309s
sys 9.691s
1 core
real 25.859s
user 25.615s
sys 0.253s
|
|
|
|
| |
Adds functions for creating and inspecting tuple.make and
tuple.extract expressions in the C and JS APIs.
|
|
|
|
|
|
| |
Adds full support for the {i8x16,i16x8,i32x4}.abs instructions merged
to the SIMD proposal in https://github.com/WebAssembly/simd/pull/128
as well as the {i8x16,i16x8,i32x4}.bitmask instructions proposed in
https://github.com/WebAssembly/simd/pull/201.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Allows a user to modify the inlining limits using the C- and JS-APIs.
* binaryen.**getAlwaysInlineMaxSize**(): `number`
* binaryen.**setAlwaysInlineMaxSize**(size: `number`): `void`
* binaryen.**getFlexibleInlineMaxSize**(): `number`
* binaryen.**setFlexibleInlineMaxSize**(size: `number`): `void`
* binaryen.**getOneCallerInlineMaxSize**(): `number`
* binaryen.**setOneCallerInlineMaxSize**(size: `number`): `void`
|
|
|
|
|
|
|
|
|
| |
Allows a user to enable/disable the `lowMemoryUnused` option and to get/set/clear arbitrary pass arguments when using the C- or JS-APIs.
* binaryen.**getLowMemoryUnused**(): `boolean`
* binaryen.**setLowMemoryUnused**(on: `boolean`): `void`
* binaryen.**getPassArgument**(key: `string`): `string | null`
* binaryen.**setPassArgument**(key: `string`, value: `string | null`): `void`
* binaryen.**clearPassArguments**(): `void`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This adds EH support to `EffectAnalyzer`. Before `throw` and `rethrow`
conservatively set property. Now `EffectAnalyzer` has a new property
`throws` to represent an expression that can throw, and expression that
can throw sets `throws` correctly.
When EH is enabled, any calls can throw too, so we cannot reorder them
with another expression with any side effects, meaning all calls should
be treated in the same way as branches when evaluating `invalidate`.
This prevents many reorderings, so this patch sets `throws` for calls
only when the exception handling features is enabled. This is also why I
passed `--disable-exception-handling` to `wasm2js` tests. Most of code
changes outside of `EffectAnalyzer` class was made in order to pass
`FeatureSet` to it.
`throws` isn't always set whenever an expression contains a throwable
instruction. When an throwable instruction is within an inner try, it
will be caught by the corresponding inner catch, so it does not set
`throws`.
|
|
|
|
|
|
|
|
|
|
| |
Binaryen.js now uses offset instead of byteOffset when inspecting
a memory segment, matching the arguments on memory segment
creation. Also adds inspection of the passive property.
Previously, one would specify { offset, data, passive } on creation
and get back { byteOffset, data } upon inspection. This PR unifies
both to the keys on creation while also adding the respective C-API
to retrieve passive status, which was missing.
|
|
|
|
|
|
|
| |
Instead of reinventing the wheel on our side, this adds ExpressionAnalyzer
bindings to the C- and JS-APIs, which can be useful for generators. For
example, a generator may decide to simplify a compilation step if a
subexpression doesn't have any side effects, or simply skip emitting
something that is likely to compile to a drop or an empty block right away.
|
|
|
|
|
|
|
|
|
|
| |
* Remove implicit conversion operators from Type
Now types must be explicitly converted to uint32_t with Type::getID or
to ValueType with Type::getVT. This fixes #2572 for switches that use
Type::getVT.
* getVT => getSingle
|
| |
|
|
|
|
|
| |
This uses `FeatureSet` in place of `FeatureSet::Feature` when possible,
making it possible for functions take a set of multiple features as one
argument.
|
|
|
|
|
|
|
|
|
|
|
|
| |
This adds support for the reference type proposal. This includes support
for all reference types (`anyref`, `funcref`(=`anyfunc`), and `nullref`)
and four new instructions: `ref.null`, `ref.is_null`, `ref.func`, and
new typed `select`. This also adds subtype relationship support between
reference types.
This does not include table instructions yet. This also does not include
wasm2js support.
Fixes #2444 and fixes #2447.
|
|
|
| |
As specified in https://github.com/WebAssembly/simd/pull/126.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
According to the current spec, `local.tee`'s return type should be the
same as its local's type. (Discussions on whether we should change this
rule is going on in WebAssembly/reference-types#55, but here I will
assume this spec does not change. If this changes, we should change many
parts of Binaryen transformation anyway...)
But currently in Binaryen `local.tee`'s type is computed from its
value's type. This didn't make any difference in the MVP, but after we
have subtype relationship in #2451, this can become a problem. For
example:
```
(func $test (result funcref) (local $0 anyref)
(local.tee $0
(ref.func $test)
)
)
```
This shouldn't validate in the spec, but this will pass Binaryen
validation with the current `local.tee` implementation.
This makes `local.tee`'s type computed from the local's type, and makes
`LocalSet::makeTee` get a type parameter, to which we should pass the
its corresponding local's type. We don't embed the local type in the
class `LocalSet` because it may increase memory size.
This also fixes the type of `local.get` to be the local type where
`local.get` and `local.set` pair is created from `local.tee`.
|