| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
| |
* Fix label fixup code to use delegates-fields. This makes it support BrOn etc.
* Add an isRtt() in places RTTs are not supported.
* Implement makeConst for arbitrary RTTs.
This is enough to get the fuzzer working for more than a few iterations at
a time, but no more.
|
| |
|
|
|
|
|
| |
This adds missing stack IR printing support for the new form of
try-catch-catch_all. Also uses `printMedium` when printing instructions
consistently.
|
|
|
|
|
|
|
| |
dataref was not noted as isRef, and we also did not handle the LUB for it,
which caused validation errors. After these two fixes, it is possible to add a
testcase that goes through the optimizer.
View without whitespace as the LUB change has a lot of that.
|
|
|
|
|
|
|
|
|
|
| |
As discussed in #3517, we need a way to maintain the ability to print
expressions in a backward-compatible way. This adds a FeatureSet
to PrintExpressionContents which defaults to FeatureSet::All in case
a feature set is not available.
This will be used for CallIndirect to decide whether to print the table
name arg.
|
|
|
|
|
|
|
|
| |
As proposed in https://github.com/WebAssembly/simd/pull/395. Note that the other
instructions in the proposal have not been implemented in LLVM or in V8, so
there is no need to implement them in Binaryen right now either. This PR
introduces a new expression class for the new instructions because they uniquely
take an immediate argument identifying which portion of the input vector to
widen.
|
|
|
|
|
|
|
|
|
| |
We added isGCData() before we had dataref. But now there is a clear
parallel of Function vs Data. This PR makes us more consistent there,
renaming isGCData to isData and using that throughout.
This also fixes a bug where the old isGCData just checked if the input
was an Array or a Struct, and ignored the data heap type itself. It is not
possible to test that, however, due to other bugs, so that is deferred.
|
|
|
|
|
|
|
|
|
|
|
| |
This is only partial support, as br_on_null also has an extra optional
value in the spec. Implementing that is cumbersome in binaryen, and
there is ongoing spec discussions about it (see
https://github.com/WebAssembly/function-references/issues/45 ), so
for now we only support the simple case without the default value.
Also fix prefixed opcodes to be LEBs in RefAs, which was noticed here
as the change here made it noticeable whether the values were int8 or
LEBs.
|
|
|
|
|
|
|
| |
That type is non-nullable, so we need to disable it until we fully support that.
Right now if we emit such locals we immediately get a validation error.
With this change the fuzzer can run at least a few thousand iterations with
no errors once more.
|
|
|
|
|
|
| |
This break stack is maintained to compute branch depths, but it seems we
don't need to push and pop for each of if and else block or every single
catch/catch_all block; it would be sufficient to have just one stack
entry for the whole try-catch or if-else.
|
|
|
|
|
|
|
| |
We used to error out in Flatten when EH is used because Flatten makes
all block types `none` by setting their return values to locals and
getting them later, but `br_on_exn` by definition pops value from the
value stack at the end of a block so it couldn't be flattened. Now that
we don't have `br_on_exn` we don't need these restriction.
|
|
|
|
|
|
| |
This is different than the other RefAs variants in that it is part of the
typed functions proposal, and not GC. But it is part of GC prototype 3.
Note: This is not useful to us yet as we don't support non-nullable types.
|
|
|
|
|
|
|
|
| |
This expands the existing BrOnCast into BrOn that can also handle the
func/data/i31 variants. This is not as elegant as RefIs / RefAs in that BrOnCast
has an extra rtt field, but I think it is still the best option. We already have optional
fields on Break (the value and condition), so making rtt optional is not odd. And
it allows us to share all the behavior of br_on_* which aside from the cast or the
check itself, is identical - returning the value if the branch is not taken, etc.
|
|
|
|
|
|
|
| |
As a result, we cannot handle a br_on_cast with an unreachable RTT. The
binary format solves the problem by ignoring unreachable code, and this makes
the text format do the same.
A nice benefit of this is that we can remove the castType extra field.
|
|
|
|
|
|
| |
wasm-finalize currently makes byte-wise copies of section data in the
user and data sections. If the section is large, that's extraordinarily
expensive. With a memcpy instead I see a speedup of 1.6 for a large
wasm binary with DWARF data.
|
|
|
|
|
|
|
|
|
|
| |
This used to return a simple name like "if" for an If, but it is redundant with
our proper printing logic. This PR turns it into a trivial helper that just prints
out the name of the class, so it now prints "If" with a capital. That is useful
for some logging, like in Metrics I think it is clearer than it was earlier (since
we are actually counting the classes, and our old emitting of text-format-like
names are just confusing, as we emitted "binary" there which is not valid).
Also replace some usages of that method with proper printing.
|
|
|
|
|
|
|
|
| |
These are similar to is, but instead of returning an i32 answer, they trap on
an invalid value, and return it otherwise.
These could in theory be in a single RefDoThing, with opcodes for both As
and Is, but as the return values are different, that would be a little odd, and
the name would be less clear.
|
| |
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previously the addDefault* methods would avoid adding opt passes that we
know are incompatible with DWARF. However, that didn't handle the case of
passes that are added in other ways. For example, when running Asyncify,
emcc will run --flatten before, and that pass is not compatible with DWARF.
This PR lets us warn on that by annotating the passes themselves. Then we
use those annotation to either not run a pass at all (matching the previous
behavior) or to show a warning when necessary.
Fixes emscripten-core/emscripten#13288 . That is, concretely
after this PR running asyncify + DWARF will show a warning to the user.
|
|
|
|
|
|
|
|
| |
We now have multiple catches in each try, and a possible catch-all.
This changes our "extra delimiter" storage to store either an "else"
(unchanged from before) or an arbitrary list of things - we use that
for catches.
|
|
|
|
|
|
|
|
|
|
| |
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`.
|
|
|
|
|
| |
Some fields were removed, see
https://docs.google.com/document/d/1yAWU3dbs8kUa_wcnnirDxUu9nEBsNfq0Xo90OWx6yuo/edit#
|
|
|
| |
This removes `exnref` type and `br_on_exn` instruction.
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This updates the interpreter for the EH instructions (modulo `delegate`)
to match the new spec. Before we had an `exnref` type so threw a
`Literal` of `exnref` type which contained `ExceptionPackage`. But now
that we don't have `exnref` anymore, so we add the contents of
`ExceptionPackage` to `WasmException`, which is used only for the
`ExpressionRunner` class hierarchy. `exnref` and `ExceptionPackage` will
be removed in a followup CL.
This allows nonzero depths for `rethrow` for now for testing; we
disallowed that for safety measure, but given that there are no passes
that modifies that field, I think the risk is low.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This updates CFG traversal to match the new spec. Previously there was
only a single `catch` block that caught all exceptions, so all throwing
instructions needed to have a link to its innermost catch BB. But now we
can have multiple catches per try, requiring all throwing instrutions to
have an edge to all of those innermost catch BBs. Furthermore, if there
are only `catch`es and not a `catch_all` in a try, throwing instructions
can further unwind to outer catches until they find a `catch_all`.
`unwindCatchStack` and `unwindExprStack` are necessary to track and make
correct links between throwing instructions and their unwind destination
BBs.
`processCatchStack` is used to remember the catch BBs currently being
processed, so that after processing all of them, we can make a link from
each of those catch's last block to the continuation block after the
try-catch.
RSE test cases are updated because they use the CFG traversal. The tests
there mainly test that if all possible CFG edge to a `local.set` sets
the same value to a local, the `local.set` is redundant and thus can be
removed.
|
|
|
|
|
| |
This uses existing `getAllNested` function in `ExpressionWrapper`
functions. Also adds `setAllNested` which works in the other direction
and uses it within `ExpressionWrapper` functions.
|
|
|
|
| |
As proposed in https://github.com/WebAssembly/simd/pull/383, with opcodes
coordinated with the WIP V8 prototype.
|
|
|
|
|
| |
We mistakenly did not set the flags to all, which meant that if the
features section was not present, we'd not have the proper features
set, leading to errors on writing.
|
|
|
|
|
|
|
|
|
| |
This goes back to the downsides of #2813, but that seems unavoidable
as without this, testcases without the features section but that use features
did not work.
This PR at least makes it easy to customize the flags send to the commands.
See also #3393 (comment)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
For now we don't support non-nullability, and can therefore lower a let into
simpler things. That is,
(let $x = ...
;;
)
=>
(block
$x = ...
;;
)
This lets us handle wasm binaries with let, so that we can optimize them
(with the current downside of losing non-nullability).
This is still not trivial to do, sadly, because the indexing of lets is somewhat
odd in the binary. A let modifies the indexes of other things declared before it,
which means that index "0" means different things at different times. And this
is trickier for us because we add more locals as needed for tuples and stacky
code. So this PR makes us track the absolute local indexes from which each
let started to allocate its locals.
The binary testcase was created from this wat using wasp:
(module
(type $vector (array (field (mut f64))))
(func $main
(local $x i32)
(local $y i32)
(drop (local.get $x)) ;; 0 is the index appearing in the binary
;; first let
(array.new_with_rtt $vector
(f64.const 3.14159)
(i32.const 1)
(rtt.canon $vector)
)
(let (local $v (ref $vector))
(drop (local.get $v)) ;; 0
(drop (local.get $x)) ;; 1
;; another one, nested
(array.new_with_rtt $vector
(f64.const 1234)
(i32.const 2)
(rtt.canon $vector)
)
(let (local $w (ref $vector))
(drop (local.get $v)) ;; 1
(drop (local.get $w)) ;; 0
(drop (local.get $x)) ;; 2
)
)
;; another one, later
(array.new_with_rtt $vector
(f64.const 2.1828)
(i32.const 3)
(rtt.canon $vector)
)
(let (local $v (ref $vector))
(drop (local.get $v)) ;; 0
(drop (local.get $x)) ;; 1
)
(drop (local.get $x)) ;; 0
)
)
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The risk the warning checks for is giving the reducer a script that ignores
the input. To do so it runs the command in the input, and runs it on a
garbage file, and checks if the result is different. However, if the script
does immediately fail on the input - because the input is a crash testcase
or such - then this does not work, as the result on a garbage input may be
the same error.
To avoid that, also check what happens on a trivial valid wasm as input.
Only show the warning if the result on the original input, on a garbage
wasm, and on a trivial wasm, are all the same - in that case, likely the
script really is ignoring the input.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
| |
Followup to #3486, I wonder if it isn't a little more clear this way,
which avoids the confusion of usedElements being changed
while we are using it.
In general I think it's best to only use usedElements in the most
internal methods, and to call size() otherwise.
|
|
|
| |
See WebAssembly/gc#175
|
|
|
|
|
|
|
|
| |
Because `resize()` sets `usedElements` to its argument, we were
accessing `data[usedElements]`, which can be outside of allocated memory
depending the internal state, i.e., `allocatedElements`'s value.
It is hard to come up with a test case for this because apparently the
failure condition depends on the vector's internal state.
|
|
|
|
|
| |
The code previously assumed it could always call getGCData, but
that assumes the input is an array or a struct. It could also be an
anyref etc. that contains something other than GC data.
|
| |
|
|
|
|
|
|
|
|
| |
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...
|
|
|
|
|
|
|
|
|
| |
Noticed by comparing to V8 and Wasp. After this things are almost identical,
but there is also at least https://bugs.chromium.org/p/v8/issues/detail?id=11300
Test updates are due to having an instruction with two operands of which one is
unreachable. The new order puts the non-unreachable first, so it is not removed by
round-tripping through the binary format like before (which removes all unreachable
code).
|
|
|
| |
See https://github.com/emscripten-core/emscripten/pull/13208
|
|
|
|
|
| |
builder for some inexplicable reason (#3477)
See #3459
|
|
|
|
| |
This required a few test fixes, to ensure we don't have invalid wasts with
writes to immutable fields.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
This lets us parse (ref null i31) and (ref i31) and not just i31ref.
It also fixes the parsing of i31ref, making it nullable for now, which we
need to do until we support non-nullability.
Fix some internal handling of i31 where we had just i31ref (which meant we
just handled the non-nullable type).
After fixing a bug in printing (where we didn't print out (ref null i31)
properly), I found some a simplification, to remove TypeName.
|
|
|
|
| |
As proposed in https://github.com/WebAssembly/simd/pull/352, using the opcodes
used in the LLVM and V8 implementations.
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
* BinaryenGetFunction, BinaryenGetGlobal, BinaryenGetEvent now return NULL if an element does not exist
* Adds BinaryenGetExport, BinaryenGetNumGlobals, BinaryenGetGlobalByIndex
* Corrects BinaryenGetNumFunctions return type
* Adds related descriptions of C API functions
|
|
|
|
|
| |
Also, avoid packing builtin llvm segments names so that
segments such as `__llvm_covfun` (use by llvm-cov) are
preserved in the final output.
|