| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
| |
We must emit those, even if otherwise it looks like a line we can
omit, as the ends of sequences have important meaning and
dwarfdump will warn without them.
Looks like fannkuch0 in the test suite already had an example
of an incorrectly-omitted sequence_end, so no need for a new
testcase.
Verified that without this e.g. wasm2.test_exceptions with -g
added will lead to a wasm that warns, but with this PR the debug_line
section is reported as valid by dwarfdump.
|
|
|
|
|
| |
Atomic loads, stores, RMW, cmpXchg, wait, and notify. This is enough
to get the asm.js atomics tests in the emscripten test suite to pass, at least
(but they are a subset of the entire pthreads suite).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
That code originally used memory location 1024 to save 64 bits of
data (as that is what rust does apparently). We refactored it
manually to instead use a scratch memory helper, which is safer.
However, that 64-bit function ends up legalized, which actually
changes the interface between the module and the outside,
which is confusing and causes problems with optimizations
that can remove the getTempRet0 imports, see
emscripten-core/emscripten#11456
Instead, just use a global i64 to stash those bits. This requires
adding support for copying globals from the intrinsics module,
but otherwise seems simpler overall.
|
| |
|
|
|
|
|
|
|
|
|
| |
This finds out which locals are live at call sites that might pause/resume,
which is the set of locals we need to actually save/load. That is, if a local
is not alive at any call site in the function, then it's value doesn't need to
stay alive while sleeping.
This saves about 10% of locals that are saved/loaded, and about 1.5%
in final code size.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Adds a special helper functions for data.drop etc., as unlike most
wasm instructions these are too big to emit inline.
Track passive segments at runtime in var memorySegments
whose indexes are the segment indexes.
Emit var bufferView even if the memory exists even without
memory segments, as we do still need the view in order to
operate on it.
Also adds a few constants for atomics that will be useful in future
PRs (as this PR updates the constant lists anyhow).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Necessary preparations for a later PR that adds bulk memory
support to wasm2js (splitting this out so the next PR is less big):
* Fix logging of print functions in wasm2js spec tests, there
was an extra space in the output (which console.log adds
automatically between items).
* Don't assume the output is always empty, as some tests
(like bulk memory) do have expected output.
* Rename test/bulk-memory.wast as it "conflicts" with
test/spec/bulk-memory.wast - the problem is that we scan
both places, and emit files in test/wasm2js/*, so those
would collide if the names overlap.
* Extend the parsing and emitting of JS for (assert.. ) lines such as
(assert_return (invoke "foo" (i32.const 1)) (i32.const 2))
to also handle
(invoke "foo" (i32.const 1)) (i32.const 2))
Without this, we skip (invoke ..) lines in spec tests, which normally is
fine, but in bulk memory at least they have side effects we need - we
must run them before the later assertions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(#2913)
When doing manual tuning of calls using asyncify lists, we want it to
be possible to write out all the functions that can be on the stack when
pausing, and for that to work. This did not quite work right with the
ignore-indirect option: that would ignore all indirect calls all the
time, so that if foo() calls bar() indirectly, that indirect call was
not instrumented (we didn't check for a pause around it), even if
both foo() and bar() were listed. There was no way to make that
work (except for not ignoring indirect calls at all).
This PR makes the add-list and only-lists fully instrument the functions
mentioned in them: both themselves, and indirect calls from them.
(Note that direct calls need no special handling - we can just add
the direct call target to the add-list or only-list.)
This may add some overhead to existing users, but only in a function
that is instrumented anyhow, and also indirect calls are slow anyhow,
so it's probably fine. And it is simpler to do it this way instead of
adding another list for indirect call handling.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Asyncify does a whole-program analysis to figure out the list of functions
to instrument. In
emscripten-core/emscripten#10746 (comment)
we realized that we need another type of list there, an "add list" which is a
list of functions to add to the instrumented functions list, that is, that we
should definitely instrument.
The use case in that link is that we disable indirect calls, but there is
one special indirect call that we do need to instrument. Being able to add
just that one can be much more efficient than assuming all indirect calls in
a big codebase need instrumentation. Similar issues can come up if we
add a profile-guided option to asyncify, which we've discussed.
The existing lists were not good enough to allow that, so a new option
is needed. I took the opportunity to rename the old ones to something
better and more consistent, so after this PR we have 3 lists as follows:
* The old "remove list" (previously "blacklist") which removes functions
from the list of functions to be instrumented.
* The new "add list" which adds to that list (note how add/remove are
clearly parallel).
* The old "only list" (previously "whitelist") which simply replaces the
entire list, and so only those functions are instrumented and no other.
This PR temporarily still supports the old names in the commandline
arguments, to avoid immediate breakage for our CI.
|
|
|
|
| |
To avoid the conditional trailing comma.
|
|
|
|
|
|
|
| |
The process of DCE'ing the argument handling is already handled in
a different way in standalone more. In standalone mode the entry
point is `_start` which takes no args, and argv code is included
on-demand via the presence or absence the wasi syscalls for argument
processing (__wasi_args_get/__wasi_args_sizes_get).
|
|
|
|
|
|
|
| |
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
|
|
|
|
| |
Expressions that may throw cannot be sinked into 'try'. At the start of
'try', we drop all sinkables that may throw.
|
|
|
|
|
| |
* Micro-optimize base64Decode
* Update test expectations
|
|
|
| |
As specified in https://github.com/WebAssembly/simd/pull/232.
|
|
|
|
|
|
|
|
|
| |
Instead of instrumenting every local.get, instrument parameters
on arrival at a function once on entry. After that, every local will
always contain a de-naned value (since we would denan on a
local.set). This is more efficient and also less confusing I think.
Also avoid doing anything to values that fall through as they
have already been fixed up.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
After #2783 `SideEffects::Branches` includes possibly throwing
expressions, which can be calls (when EH is enabled). This changes
`SideEffects::Branches` back to only include branches, returns, and
infinite loops as it was before #2783.
|
|
|
|
| |
In CodeFolding, we should not take an expression that may throw out of a
`try` scope. This patch adds this restriction in `canMove`.
|
|
|
|
|
|
| |
This moves the fuzzer de-NaN logic out into a separate pass. This is
cleaner and also better since the old way would de-NaN once, but then
the reducer could generate code with nans. The new way lets us de-NaN
while reducing.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(#2862)
In the .debug_loc section the Start/End address offsets in a location list are
relative to the address of the compilation unit that refers that location list.
There is a problem in function wasm::Debug:: updateLoc(), which compares these
offsets with the actual module addresses of expressions and functions, causing
the generation of invalid location lists.
The fix is not trivial, because the DWARF debug_loc section does not specify
which is the compilation unit associated to each location list entry.
A simple workaround is to store, in LocationUpdater, a map of location list
offsets to the base address of the compilation units referencing them, and that
can be easily calculated in updateDIE().
|
|
|
|
|
|
|
|
|
| |
The special-casing of unreachable there could lead to bad
behavior, where we did nothing to the unreachable and ended
up moving something with side effects before it, see testcase
in test/passes/flatten_all-features.wast.
This emits less efficient code, but only if --dce was not run
earlier, so probably not worth optimizing.
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
| |
These are now implemented in assembly as part of emscripten's
compiler-rt.
See: https://github.com/emscripten-core/emscripten/pull/11166
|
|
|
|
|
|
|
| |
- `br_on_exn`'s target block cannot be optimized to have a separate
return value. This handles that in `SimplifyLocals`.
- `br_on_exn` and `rethrow` can trap (when the arg is null). This
handles that in `EffectAnalyzer`.
- Fix a few nits
|
|
|
|
| |
This is the only instruction in the current spec proposal that had not
yet been implemnented in the tools.
|
|
|
|
| |
Turns out we had a testcase for this already, but were doing the
wrong thing on it.
|
|
|
|
|
|
|
|
|
|
| |
This change was generated by running:
$ ./scripts/test/generate_lld_tests.py --binaryen-bin=$PWD/../binaryen-out/bin/ $PWD/../llvm-build/bin/ $PWD/../emscripten
Then:
$ ./auto_update_tests.py --binaryen-bin=../binaryen-out/bin/ lld
|
|
|
|
|
| |
This test verifies that functions in the llvm input source that
do stack pointer manipulation get correctly handled by
`wasm-emscripten-finalize --check-stack-overflow` (StackLimitEnforcer)
|
|
|
|
|
|
|
|
|
|
|
|
| |
In `ReFinalize`'s branch handling, `updateBreakValueType` is supposed to
be executed only when the branch itself is not replaced with its
argument (because it is guaranteed not to be taken).
Also this moves `visitBrOnExn` from `RuntimeExpressionRunner` to its
base class `ExpressionRunner`, because it does not depend on anything on
the runtime instance to work. This is effectively NFC for now because
`visitTry` is still only implemented only in `RuntimeExpressionRunner`
because it relies on multivalue handling of it, and without it we cannot
create a valid exception `Literal`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previously we were able to omit the new syntax `do` when `try` body is
empty. This makes `do` clause mandatory, so when a `try` body is empty,
the folded text format will be
```
(try
(do)
(catch
...
)
```
Suggested in
https://github.com/WebAssembly/exception-handling/issues/52#issuecomment-626696720.
|
|
|
|
|
|
|
| |
This adds support for `throw`, `rethrow`, and `br_on_exn` in
MergeBlocks. While unrelated instructions within blocks can be hoisted
as in other instructions, `br_on_exn` requires a special handling in
`ProblemFinder`, because unlike `br_if`, its `exnref` argument itself
cannot be moved out of `br_on_exn`.
|
|
|
| |
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)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In WebAssembly/exception-handling#52, We decided to put `try` bodies in
a `do` clause to be more consistent with `catch`.
- Before
```wast
(try
...
(catch
...
)
)
```
- After
```wast
(try
(do
...
)
(catch
...
)
)
```
Another upside of this change is when there are multiple instructions
within a `try` body, we no longer need to wrap them in a `block`.
|
|
|
|
| |
This adds missing handlings for `throw` and `rethrow` in DCE. They
should set `reachable` variable to `false`, like other branches.
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
| |
This adds interpreter support for EH instructions. This adds
`ExceptionPackage` struct, which contains info of a thrown exception (an
event tag and thrown values), and the union in `Literal` can take a
`unique_ptr` to `ExceptionPackage`. We need a destructor, a copy
constructor, and an assignment operator for `Literal`, because the union
in `Literal` now has a member that cannot be trivially copied or
deleted.
|
|
|
| |
As described in https://github.com/WebAssembly/simd/pull/209.
|
|
|
|
|
|
|
| |
This allows emscripten to statically set the initial value of the
stack pointer.
Should allow use to avoid doing it dynamically at startup:
https://github.com/emscripten-core/emscripten/pull/11031
|
|
|
|
| |
This list is identical to the export list no there is no need to
output this twice.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We had some ad-hoc tuning of which nodes to emit more
frequently in the fuzzer, but it wasn't very good. Things like
loads and stores for example were far too rare. Also it wasn't
easy to adjust the frequencies.
This adds a simple way to adjust them, by passing a size_t
which is the "weight" of that node. Then it just makes that
number of copies of it, making it more likely to be picked.
Example output comparison:
node before after
================================
binary 281 365
block 898 649
break 278 144
call 182 290
call_indirect 9 42
const 808 854
drop 43 92
global.get 440 398
global.set 223 171
if 335 254
load 22 84
local.get 429 301
local.set 434 211
loop 176 99
nop 117 54
return 264 197
select 8 33
store 1 39
unary 405 304
unreachable 1 2
Lots of noise here obviously, but there are large increases
for loads and stores compared to before.
Also add a testcase of random data of the typical size the
fuzzer runs, and print metrics on it. This might help us get
a feel for how future tuning changes affect frequencies.
|
|
|
| |
Since the --roundtrip pass is more general than --fuzz-binary anyways. Also reimplements `ModuleUtils::clearModule` to use the module destructor and placement new to ensure that no members are missed.
|
|
|
|
| |
type. fixes #2807 (#2808)
|
| |
|
| |
|
|
|
|
|
|
| |
Without this change only the import gets renamed not the internal
name. Since the internal name is the one that ends up in the name
section this means that rename wasn't effecting the name section.
|