| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
| |
Adds support for the new load and extend instructions. Also updates
from C++11 to C++17 in order to use generic lambdas in the interpreter
implementation.
|
|
|
|
|
| |
As specified at https://github.com/WebAssembly/simd/pull/102.
Also fixes bugs in the JS API for other SIMD bitwise operators.
|
|
|
|
|
|
|
| |
Introduces a new instruction class, `SIMDLoad`. Implements encoding,
decoding, parsing, printing, and interpretation of the load and splat
instructions, including in the C and JS APIs. `v128.load` remains in
the `Load` instruction class for now because the interpreter code
expects a `Load` to be able to load any memory value type.
|
|
|
| |
See emscripten-core/emscripten#9381 for rationale.
|
|
|
| |
The flag indicates that we want to run the wasm by itself, without JS support. In that case we don't emit JS dynCalls etc., and we also emit a wasi _start if there is a main, i.e., we try to use the current conventions in the wasm-only space.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This optimizes stuff like
(global.set $x (i32.const 123))
(global.get $x)
into
(global.set $x (i32.const 123))
(i32.const 123)
This doesn't help much with LLVM output as it's rare to use globals (except for the stack pointer, and that's already well optimized), but it may help on general wasm. It can also help with Asyncify that does use globals extensively.
|
|
|
|
|
| |
With the optional asserts, we throw if we see an unwind begin in code that we thought could never unwind (say, because the user incorrectly blacklisted it).
Helps with emscripten-core/emscripten#9389
|
|
|
|
|
| |
Properly handle fastcomp wasm safe heap: emscripten_get_sbrk_ptr is an asm.js library function, which means it is inside the wasm after asm2wasm, and exported. Find it via the export.
|
|
|
| |
This helps with debugging human-readable sections like sourceMappingURL.
|
|
|
|
|
|
|
| |
Currently emscripten links the wasm, then links the JS, then computes the final static allocations and in particular the location of the sbrk ptr (i.e. the location in memory of the brk location). Emscripten then imports that into the asm.js or wasm as env.DYNAMICTOP_PTR. However, this didn't work in the wasm backend where we didn't have support for importing globals from JS, so we implement sbrk in JS.
I am proposing that we change this model to allow us to write sbrk in C and compile it to wasm. To do so, that C code can import an extern C function, emscripten_get_sbrk_ptr(), which basically just returns that location. The PostEmscripten pass can even apply that value at compile time, so we avoid the function call, and end up in the optimal place, see #2325 and emscripten PRs will be opened once other stuff lands.
However, the SafeHeap pass must be updated to handle this, or our CI will break in the middle. This PR fixes that, basically making it check if env.DYNAMICTOP_PTR exists, or if not then looking for env.emscripten_get_sbrk_ptr, so that it can handle both.
|
|
|
|
|
|
|
| |
We emitted the __wasm_memory_size function only when memory growth was enabled, but it can be used without that too.
In theory we could only emit it if either memory growth or memory.size is used, but I think we can expect JS minifiers to do that later.
Also fix a test suite bug - the check/auto_update script didn't run all the wasm2js tests when you run it with argument wasm2js (it used that as the list of tests, instead of the list of files, which confused me here for a while...).
|
|
|
|
|
|
|
| |
(which is called DYNAMICTOP_PTR in emscripten) (#2325)
The assumption is that an import env.emscripten_get_sbrk_ptr exists, and we replace the value returned from there with a constant. (We can't do all this in wasm-emscripten-finalize, as it happens before the JS compiler runs, which can add more static allocations; we only know where the sbrk ptr is later in compilation.) This just replaces the import with a function returning the constant; inlining etc. can help more later.
By setting this at compile time we can reduce code size and avoid importing it at runtime, which makes us more compatible with wasi (less special imports).
|
|
|
|
|
|
|
|
|
| |
Renames the SIMDBitselect class to SIMDTernary and adds the new
{f32x4,f64x2}.qfm{a,s} ternary instructions. Because the SIMDBitselect
class is no more, this is a backwards-incompatible change to the C
interface. The new instructions are not yet used in the fuzzer because
they are not yet implemented in V8.
The corresponding LLVM commit is https://reviews.llvm.org/rL370556.
|
| |
|
|
|
| |
This makes the minification pass aware of "wasi_unstable" and "wasi" as well.
|
|
|
| |
See emscripten-core/emscripten#9206, the asyncify names can need complex escaping, so this provides an escape hatch.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Emscripten's minifier mis-minifies a couple bits in the memory
init function that's used with wasm2js when not using an external
memory init file:
https://github.com/emscripten-core/emscripten/issues/8886
Previous fix worked around the bug in one place but failed to
account for another. Have now confirmed that it works with this
change in place.
Updated test cases to match.
|
| |
|
|
|
|
|
|
| |
This adds `-all` argument to wasm2js testing and fixes wasm2js to
actually take that argument (currently it doesn't, when it takes a wast
file). This also adds a wasm2js test for `atomic.fence` instruction that
was added in #2307.
|
|
|
|
|
|
|
| |
This adds `atomic.fence` instruction:
https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md#fence-operator
This also fix bugs in `atomic.wait` and `atomic.notify` instructions in
binaryen.js and adds tests for them.
|
|
|
|
|
|
| |
It is not valid to defer the truncation of divisions because
accumulated non-integral results can produce different values when
they are combined before truncation. This was causing a test failure
in the Rust test suite.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Another round of trying to push upstream things from my fork.
This PR only adds support for anyref itself as an opaque type. It does NOT implement the full [reference types proposal](https://github.com/WebAssembly/reference-types/blob/master/proposals/reference-types/Overview.md)--so no table.get/set/grow/etc or ref.null, ref.func, etc.
Figured it was easier to review and merge as we go, especially if I did something fundamentally wrong.
***
I did put it under the `--enable-reference-types` flag as I imagine that even though this PR doesn't complete the full feature set, it probably is the right home. Lmk if not.
I'll also be adding a few github comments to places I want to point out/question.
|
| |
|
|
|
|
|
|
|
|
|
| |
This reverts commit 12add6f17c377de7ac334e8fa7885b61b98f3db4 (#2283).
This is done due to the complexity of supporting EM_ASM and
setjmp/longjmp, especially with dynamic linking thrown into the mix.
In https://reviews.llvm.org/D66356, using EM_ASM and setjmp/longjmp in
the same function is now an error.
|
|
|
|
|
|
|
|
| |
pep8 specifies 4 space indentation. The use of 2 spaces is, I believe
a historical anomaly where certain large organizations such as google
chose 2 over 4 and have yet to make the switch.
Since there isn't too much code in binaryen today it seems reasonable to
make the switch.
|
|
|
|
|
| |
The switch lowering will "hoist" blocks of code into the JS switch when it can. If it can hoist some but not others, it must not fall through into those others (while it can fall through the hoisted ones - they began as nested blocks with falling-through between them). To fix this, after the hoisted ones issue a break out of the switch (which now contains all the hoisted code, so breaking out of it gets to the code right after the hoisted ones).
fixes #2300
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This adds basic support for exception handling instructions, according
to the spec:
https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md
This PR includes support for:
- Binary reading/writing
- Wast reading/writing
- Stack IR
- Validation
- binaryen.js + C API
- Few IR routines: branch-utils, type-updating, etc
- Few passes: just enough to make `wasm-opt -O` pass
- Tests
This PR does not include support for many optimization passes, fuzzer,
or interpreter. They will be follow-up PRs.
Try-catch construct is modeled in Binaryen IR in a similar manner to
that of if-else: each of try body and catch body will contain a block,
which can be omitted if there is only a single instruction. This block
will not be emitted in wast or binary, as in if-else. As in if-else,
`class Try` contains two expressions each for try body and catch body,
and `catch` is not modeled as an instruction. `exnref` value pushed by
`catch` is get by `pop` instruction.
`br_on_exn` is special: it returns different types of values when taken
and not taken. We make `exnref`, the type `br_on_exn` pushes if not
taken, as `br_on_exn`'s type.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is both an optimization and a workaround for the problem that emscripten-core/emscripten#7641 uncovered and had to be reverted because of.
What's going on there is that wasm-emscripten-finalize turns emscripten_longjmp_jmpbuf into emscripten_longjmp (for some LLVM internal reason - there's a long comment in the source that I didn't fully follow). There are two such imports already, one for each name, and before that PR, we ended up with just one. After that PR, we end up with two. And with two, the minification of import names gets confused - we have two imports with the same name, and the code there ends up ignoring one of them.
I'm not sure why that PR changed things - I guess the wasm-emscripten-finalize code looks at the name, and that PR changed what name appears? @sbc100 maybe #2285 is related?
Anyhow, it's not trivial to make import minification code support two identical imports, but I don't think we should - we should avoid having such duplication anyhow. And we should add an assert that they don't exist (I'll open a PR for that later when it's possible).
This fixes the duplication by adding a useful pass to remove duplicate imports (just functions, for now). Pretty simple, but we didn't do it yet. Even if there is a wasm-emscripten-finalize bug we need to fix with those duplicate imports, I think this pass is still a good thing to add.
I confirmed that this fixes the issue caused by that PR.
|
| |
|
| |
|
| |
|
|
|
|
|
| |
This reverts commit 692f4666fd116fb7827b53348978f29bba253d47.
See details in the reverted PR.
|
|
|
|
|
| |
The lists are comma separated, but the names can have internal commas since they are human-readable. This adds awareness of bracketing things, so void foo(int, double) is parsed as a single function name, properly.
Helps emscripten-core/emscripten#9128
|
|
|
|
|
| |
I fixed flatten.bin.txt which seems to have just had some corrupted data, and I removed some fancy unicode from the spec comments tests, which I'm not sure it's important enough to figure out how to fix.
Fixes #1691
|
|
|
|
|
| |
This fix does not handle dynamic linking, which requires additional work.
Refs https://github.com/emscripten-core/emscripten/issues/8894.
|
|
|
|
|
|
| |
Without `assert`, even if a test does not validate, the errors will only
show up in its corresponding `.txt` file while the test will succeed.
This makes sure it errors out when a test fails to validate. This also
adds validation checks if there is none.
|
|
|
|
|
|
|
|
| |
* Fix stack pointer identification for wasm::ABI::getStackSpace().
Recent stack pointer simplification in Emscripten broke the --spill-pointers
pass. This fix for #2229 restores this functionality by recognizing an
alternative coding idiom in Emscripten-generated WASM code.
|
|
|
|
|
|
|
| |
This fixes names that would be invalid in JS, like a.b. Turns out the Go compiler emits wasm with such imports.
Also add some docs on how to use wasm2js.
Fixes #2263
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Currently various expressions handle this differently, and now we
consistently follow this rules:
---
For all non-control-flow value-returning instructions, if a type of an
expression is unreachable, we emit an unreachable and don't emit the
instruction itself. If we don't emit an unreachable, instructions that
follow can have validation failure in wasm binary format. For example:
```
[unreachable] (f32.add
[unreachable] (i32.eqz
[unreachable] (unreachable)
)
...
)
```
This is a valid prgram in binaryen IR, because the unreachable type
propagates out of an expression, making both i32.eqz and f32.add
unreachable. But in binary format, this becomes:
```
unreachable
i32.eqz
f32.add ;; validation failure; it expects f32 but takes an i32!
```
And here f32.add causes validation failure in wasm validation. So in this
case we add an unreachable to prevent following instructions to consume
the current value (here i32.eqz).
In actual tests, I used `global.get` to an f32 global, which does not
return a value, instead of `f32.add`, because `f32.add` itself will not
be emitted if one of argument is unreachable.
---
So the changes are:
- For instructions that don't return a value, removes unreachable
emitting code if it exists.
- Add the unreachable emitting code for value-returning instructions if
there isn't one.
- Check for unreachability only once after emitting all children for
atomic instructions. Currently only atomic instructions check
unreachability after visiting each children and bail out right after,
which is valid, but not consistent with others.
- Don't emit an extra unreachable after a return (and return_call). I
guess it is unnecessary.
|
|
|
|
|
|
|
|
|
| |
When a memory instruction's type is unreachable, i.e., one of its
child expressions is unreachable, the instruction will be printed like
`unreachable.load`, which is invalid text format.
This prints unreachable prefix instruction types as `i32` to just make
them pass the parser. It is OK because they are not reachable anyway.
Also this removes printing of `?` in atomic.rmw instruction printing.
|
|
|
|
|
|
|
|
|
| |
The blacklist means "functions here are to be ignored and not instrumented, we can assume they never unwind." The whitelist means "only these functions, and no others, can unwind." I had hoped such lists would not be necessary, since Asyncify's overhead is much smaller than the old Asyncify and Emterpreter, but as projects have noticed, the overhead to size and speed is still significant. The lists give power users a way to reduce any unnecessary overhead.
A slightly tricky thing is escaping of names: we escape names from the names section (see #2261 #1646). The lists arrive in human-readable format, so we escape them before comparing to the internal escaped names. To enable that I refactored wasm-binary a little bit to provide the escaping logic, cc @yurydelendik
If both lists are specified, an error is shown (since that is meaningless). If a name appears in a list that is not in the module, we show a warning, which will hopefully help people debug typos etc. I had hoped to make this an error, but the problem is that due to inlining etc. a single list will not always work for both unoptimized and optimized builds (a function may vanish when optimizing, due to duplicate function elimination or inlining).
Fixes #2218.
|
|
|
|
|
|
|
| |
This adds
- `push`/`pop` support for other types: v128 and exnref
- `push`/`pop` support for binaryen.js
Because binaryen.js follows Binaryen's AST structure, without `pop` in
binaryen.js, EH instructions cannot be represented in binaryen.js.
|
|
|
|
| |
Before I disallowed events with no values, but spec does not say
anything about it, so I think that restriction is not necessary.
|
|
|
|
| |
Adds tail call support to fuzzer and makes small changes to handle return calls in multiple utilities and passes. Makes larger changes to DAE and inlining passes to properly handle tail calls.
|
|
|
|
|
|
|
| |
The new flag indicates whether main reads the argc/argv parameters. If it does not, we can avoid emitting code to generate those arguments in the JS, which is not trivial in small programs - it requires some string conversion code.
Nicely the existing test inputs were enough for testing this (see outputs).
This depends on an emscripten change to land first, as emscripten.py asserts on metadata fields it doesn't recognize.
|
|
|
|
|
|
|
|
|
|
|
| |
(global $g1 (mut i32) (i32.const 42))
(global $g2 i32 (global.get $g1))
can be optimized to
(global $g1 (mut i32) (i32.const 42))
(global $g2 i32 (i32.const 42))
even though $g1 is mutable - because it can't be mutated during module instantiation.
|
|
|
|
| |
#2242 had exposed the bug that the `Trapper` pass was defining `walkFunction` when it should have been defining `doWalkFunction`.
|