| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
| |
If we don't enable features in assertion failure tests, new feature
tests fail not because they are malformed but because they have
unsupported features. It's hard to add tests because existing
`assert_invalid` tests were already failing because they have
unsupported features.
|
|
|
|
|
|
|
| |
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.
|
| |
|
| |
|
| |
|
|
|
|
|
| |
This prints events in color like other module elements such as globals.
This also splits `visitEvent` into two functions to be consistent with
`visitGlobals` or `visitFunctions`.
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previously `StackWriter` and its subclasses had routines for all three
modes (`Binaryen2Binary`, `Binaryen2Stack`, and `Stack2Binary`) within a
single class. This splits routines for each in a separate class and
also factors out binary writing into a separate class
(`BinaryInstWriter`) so other classes can make use of it.
The new classes are:
- `BinaryInstWriter`:
Binary instruction writer. Only responsible for emitting binary
contents and no other logic
- `BinaryenIRWriter`: Converts binaryen IR into something else
- `BinaryenIRToBinaryWriter`: Writes binaryen IR to binary
- `StackIRGenerator`: Converts binaryen IR to stack IR
- `StackIRToBinaryWriter`: Writes stack IR to binary
|
|
|
|
|
|
|
| |
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`.
|
|
|
|
|
| |
(#2244)
This reverts commit 72c52ea7d4eb61b95cf8a5164947cb760fe42e9c, which was causing test failures after it merged.
|
|
|
|
| |
This prevents those instructions from becoming invalid due to memory
packing optimizations and is also a code size win. Fixes #2227.
|
|
|
|
|
|
|
|
|
| |
(#2242)
Main change here is in pass.h, everything else is changes to work with the new API.
The add("name") remains as before, while the weird variadic add(..) which constructed the pass now just gets a std::unique_ptr of a pass. This also makes the memory management internally fully automatic. And it makes it trivial to parallelize WalkerPass::run on parallel passes.
As a benefit, this allows removing a lot of code since in many cases there is no need to create a new pass runner, and running a pass can be just a single line.
|
| |
|
|
|
|
|
| |
The key thing is that there is a single constant, which may or may not be saved/loaded from a local, and may or may not get an added global if in relocatable code.
Fixes emscripten-core/emscripten#8993
|
|
|
|
|
| |
* Clarify the difference between old and new Asyncify.
* Remove the old --bysyncify pass option.
|
| |
|
|
|
|
|
|
|
| |
After some discussion this seems like a less confusing name: what the pass does is "asyncify" code, after all.
The one downside is the name overlaps with the old emscripten "Asyncify" utility, which we'll need to clarify in the docs there.
This keeps the old --bysyncify flag around for now, which is helpful for avoiding temporary breakage on CI as we move the emscripten side as well.
|
|
|
|
| |
In WebAssembly/exception-handling#79 we agreed to rename `except_ref`
type to `exnref`.
|
|
|
| |
We don't ever emit "use asm" anymore, so this similar annotation is not really useful, it just increases size.
|
| |
|
|
|
| |
This became noticeable after #2216 which led to some eqz eqz pairs in the test suite.
|
|
|
| |
This can't use the normal wasm-opt mechanism because we modify the discard the wasm as part of running wasm2js, so we need to emit it in the proper place in the middle.
|
|
|
|
|
|
|
| |
An if whose body is a br_if can be turned into a br_if of a combined condition (if side effects allow it).
The naive size in bytes is identical between the patterns, but the select may avoid a hardware branch, and also the select may be further optimized. On the benchmark suite this helps every single benchmark, but by quite small amounts (e.g. 100 bytes on sqlite, which is 1MB).
This was noticed in emscripten-core/emscripten#8941
|
|
|
| |
This is core import like __memory_base and __table_base.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
I'm working on a change to lld that will cause `-pie` binaries to
import __stack_pointer, just like -shared do already. Because we
don't yet support mutable globals everywhere this change will
internalize the import and create a new immutable import that is used
to initialize the internal one.
This change is part of the fix for:
https://github.com/emscripten-core/emscripten/issues/8915
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We were passing bad value in --initial-stack-pointer which did not
include the STATIC_BUMP (since STATIC_BUMP is determinted by the output
of finalize).
If emscripten wants to set the stack pointer position it can do
so by calling the stackRestore() function at startup.
This argument will be removed completely once we stop passing it on the
emscripten side.
See https://github.com/emscripten-core/emscripten/issues/8905
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
struct FooPass : public wasm::Pass {
FooPass(int a, int b);
};
PassRunner runner {module};
runner.add<FooPass>(1, 2); // To allow this
This change avoids unnecessary copying and allows us to pass the reference without reference_wrapper.
struct BarPass : public wasm::Pass {
BarPass(std::ostream& s);
};
runner.add<BarPass>(std::cout); // Error (cout is uncopyable)
runner.add<BarPass>(std::ref(std::cout)); // OK
↓
runner.add<BarPass>(std::cout); // OK (passed by reference)
runner.add<BarPass>(std::ref(std::cout)); // OK
|
| |
|
|
|
|
| |
instructions (#2199)
|
|
|
|
|
|
|
|
|
|
|
| |
Including parsing, printing, assembling, disassembling.
TODO:
- interpreting
- effects
- finalization and typing
- fuzzing
- JS/C API
|
|
|
|
| |
Allow MemoryPacking to run when there are no passive segments, even if
bulk memory is enabled.
|
|
|
|
|
| |
Fix and test mutable globals support, replace string literals with
constants, and add a pass to emit the target features section.
|
|
|
|
|
|
|
| |
This is the first stage of adding support for stacky/multivaluey things. It adds new push/pop instructions, and so far just shows that they can be read and written, and that the optimizer doesn't do anything immediately wrong on them.
No fuzzer support, since there isn't a "correct" way to use these yet. The current test shows some "incorrect" usages of them, which is nice to see that we can parse/emit them, but we should replace them with proper usages of push/pop once we actually have those (see comments in the tests).
This should be enough to unblock exceptions (which needs a pop in try-catches). It is also a step towards multivalue (I added some docs about that), but most of multivalue is left to be done.
|
|
|
| |
Previously we tried to export it if the memory was exported, even if growth was not on, which caused an error.
|
|
|
|
|
|
| |
The event section should be between the global section and the export
section, if present. Here tests are missing, but we don't have a very
good way of testing validity of binary anyway. We are planning to add d8
tests in a separate PR.
|
|
|
|
|
| |
Add assertions on stack overflow in all 4 Bysyncify API calls (previously only 2 did it).
Also add a check that those assertions are hit.
|
|
|
|
|
|
|
| |
(#2191)
Keep limiting in precompute as before: that is useful since that pass is run as part of normal compilation, and we want to avoid native stack limits on all platforms. Also that pass is not likely to find any pattern of size 50 of higher that it can't precompute as a sum of smaller pieces.
Restore the 250 limit from before for interpreting entire modules, as without that the fuzzer will sometimes hit the limit and cause a false positive.
|
|
|
|
|
|
|
|
| |
Gets fuzzing support for Bysyncify working.
* Add the python to run the fuzzing on bysyncify.
* Add a JS script to load and run a testcase with bysyncify support. The code has all the runtime support for sleep/resume etc., which it does on calls to imports at random in a deterministic manner.
* Export memory from fuzzer so JS can access it.
* Fix tiny builder bug with makeExport.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Workaround for wasm2js output minification issue with emscripten
When using emscripten with -O2 and --memory-init-file 0, the
JS minification breaks on this function for memory initialization
setup, causing an exception to be thrown during module setup.
Moving from two 'var' declarations for the same variable to one
should avoid hitting this with no change in functionality (the
var gets hoisted anyway).
https://github.com/emscripten-core/emscripten/issues/8886
|