| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previously we used "Top" for both exports and the top level
(which has functions and globals). The warning about name
collisions there was meant only for exports (where if a name
collides and so it must be renamed, means that there will
be an externally-visible oddness for the user). But it applied
to functions too, which could be annoying, and was not
dangerous (at worst, it might be confusing when reading the
emitted JS and seeing NAME_1, NAME_2, but there is no
effect on execution or on exports).
To fix this, add a new Export name scope. This separates
function names from export names. However, it runs into
another issue which is that when checking for a name conflict
we had a big set of all the names in all the scopes. That is,
FOO would only ever be used in one scope, period, and
other appearances of that Name in wasm would get a
suffix. As a result, if an exported function FOO has the name
foo, we'd export it as FOO but name the function FOO_1
which is annoying. To fix that, keep sets of all names in each
scope. When mangling a name we can then only care about
the relevant scope, EXCEPT for local names, which must
also not conflict with function names. That is, this would be
bad:
function foo(bar) {
var bar = 0;
}
function bar() { ..
It's not ok to call a parameter "bar" if there is a function by
that name (well, it could be if it isn't called in that scope).
So when mangling the Local scope, also check the Top one
as well.
The test output changes are due to non-overlapping scopes,
specifically Local and Label. It's fine to have
foo : while(1) {
var foo = 5;
}
Those "foo"s do not conflict.
Fixes emscripten-core/emscripten#11743
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We emit FUNCTION_TABLE[ptr], where FUNCTION_TABLE is a JS
array. That is a rare case where true is handled differently than 1
(a typed array or an add would cast, etc.), so we must explicitly cast
there.
Fixes an issue that existed before, but became a problem due to
#2869 which optimized some selects into a form that emitted a true
or a false, and if that was a function pointer, it could be bad, see
https://app.circleci.com/pipelines/github/emscripten-core/emscripten/6699/workflows/0c4da49c-75d0-4b0a-8fac-686a8330a3fe/jobs/336520
The new test/wasm2js/indirect-select.2asm.js.opt output shows
what happened there.
Verified as passing emscripten's wasm2js1 wasm2js2 test suites.
|
|
|
|
|
|
|
|
|
|
|
| |
i64 reinterprets were lowered in the i64 pass, and i32s at the very end, in
wasm2js itself. This could break since in between the i64 pass and wasm2js
we run optimizations, and the optimizer was not aware of what we lower
the i32 reinterprets to - calls to use scratch memory. Those calls have a
side effect of altering scratch memory. The optimizer just saw an i32
reinterpret, and moved it across the i64 reinterpret's scratch memory calls.
This makes 32-bit reinterprets use separate scratch memory from 64-bit ones,
which means they can never interfere with each other.
|
|
|
|
|
|
| |
The usual "trick" to extend: shift left so the sign bit in the small
integer is now the sign bit in a 32-bit integer, then shift right to
spread that sign bit out and return the lower bits to their
proper place, (x << 24) >> 24.
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
|
|
|
|
| |
* Micro-optimize base64Decode
* Update test expectations
|
|
|
|
|
| |
Reland of #2864
Also ensure a relative install rpath by adding setup to each tool config.
The CMake code is cribbed from LLVM's implementation.
|
|
|
| |
This reverts commit f6b7f0018ca5ce604e94cc6cf50ee712bb7e9b27.
|
|
|
| |
When building the libbinaryen dynamic library, also link the binaryen tools against it. This reduces combined tool size on mac from 76M to 2.8M
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In wasm2js we ignore things that trap in wasm that we can't
really handle, like a load from memory out of bounds would
trap in wasm, but in JS we don't want to emit a bounds check
on each load. So wasm2js focuses on programs that don't
trap.
However, this is annoying in the fuzzer as it turns out that
our behavior for places where wasm would trap was not
deterministic. That is, wasm would trap, wasm2js would not
trap and do behavior X, and wasm2js with optimizations
would also not trap but do behavior Y != X. This produced
false positives in the fuzzer (and might be annoying in
manual debugging too).
As a workaround, this adds a --deterministic flag to wasm2js,
which tries to be deterministic about what it does for cases
where wasm would trap. This handles the case of an int
division by 0 which traps in wasm but without this flag could
have different behavior in wasm2js with or without opts
(see details in the patch).
|
|
|
|
|
|
|
|
|
| |
These seem to be accidentally introduced in when we enforced use of
`Type::` on type names in #2434.
By the way TIL this actually compiles, and don't know why:
```
Type::Type::Type::Type::Type::Type::Type::Type::none
```
|
|
|
|
|
|
|
|
|
|
|
| |
coalesce-locals is nonlinear in the number of locals, so it is
greatly beneficial to reorder the locals (which then drops the
unused ones at the end automatically). The default passes
do this already, but wasm2js does some custom work, and
this was missing.
With this change that pass takes 10x less time on poppler
with --flatten --flatten --simplify-locals-notee-nostructure
which approximates what wasm2js does.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Depends on emscripten-core/emscripten#10741
which ensures that table indexes are unique. With that guarantee,
a main module can just add its function pointers into the table, and
use them based on that index. The loader will then see them in the
table and then give other modules the identical function pointer for
a function, ensuring function pointer equality.
This avoids calling fp$ functions during startup for the main
module's own functions (which are slow). We do still call fp$s
of things we import from outside, as we don't have anything to
put in the table for them, we depend on the loader for that.
I suspect this can also be done with SIDE_MODULES, but did not
want to try too much at once.
|
|
|
|
|
|
|
|
|
| |
Implements parsing and emitting of tuple creation and extraction and tuple-typed control flow for both the text and binary formats.
TODO:
- Extend Precompute/interpreter to handle tuple values
- C and JS API support/testing
- Figure out how to lower in stack IR
- Fuzzing
|
|
|
|
|
|
|
|
|
|
| |
EMSCRIPTEN_END_FUNCS markers. (#2626)
* Fix missing newline after // EMSCRIPTEN_START_FUNCS and // EMSCRIPTEN_END_FUNCS markers.
* Flake
* Update tests
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Optimize base64 decoding (about 7x-10x faster and temporary garbage-free compared to the original version)
* new Uint8Array
* Reuse Uint8Array view
* Fix end handling
* Code format
* Update tests
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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`.
|
|
|
|
|
|
|
|
|
|
| |
* 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
|
| |
|
| |
|
|
|
|
|
|
| |
By doing so we ensure that our calls to convert wasm
types to JS types never try to convert an unreachable.
Fixes #2558
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Function signatures were previously redundantly stored on Function
objects as well as on FunctionType objects. These two signature
representations had to always be kept in sync, which was error-prone
and needlessly complex. This PR takes advantage of the new ability of
Type to represent multiple value types by consolidating function
signatures as a pair of Types (params and results) stored on the
Function object.
Since there are no longer module-global named function types,
significant changes had to be made to the printing and emitting of
function types, as well as their parsing and manipulation in various
passes.
The C and JS APIs and their tests also had to be updated to remove
named function types.
|
|
|
|
|
| |
This works more like llvm's unreachable handler in that is preserves
information even in release builds.
|
|
|
|
|
|
| |
This means that debugging/tracing can now be enabled and controlled
centrally without managing and passing state around the codebase.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Adds the ability to create multivalue types from vectors of concrete value
types. All types are transparently interned, so their representation is still a
single uint32_t. Types can be extracted into vectors of their component parts,
and all the single value types expand into vectors containing themselves.
Multivalue types are not yet used in the IR, but their creation and inspection
functionality is exposed and tested in the C and JS APIs.
Also makes common type predicates methods of Type and improves the ergonomics of
type printing.
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
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...).
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 `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.
|
|
|
|
|
| |
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 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
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
| |
(#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.
|
|
|
| |
We don't ever emit "use asm" anymore, so this similar annotation is not really useful, it just increases size.
|
|
|
| |
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.
|
| |
|
|
|
|
| |
instructions (#2199)
|
|
|
| |
Previously we tried to export it if the memory was exported, even if growth was not on, which caused an error.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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
|
|
|
|
|
|
|
|
|
| |
This adds a new pass, Bysyncify, which transforms code to allow unwind and rewinding the call stack and local state. This allows things like coroutines, turning synchronous code asynchronous, etc.
The new pass file itself has a large comment on top with docs.
So far the tests here seem to show this works, but this hasn't been tested heavily yet. My next step is to hook this up to emscripten as a replacement for asyncify/emterpreter, see emscripten-core/emscripten#8561
Note that this is completely usable by itself, so it could be useful for any language that needs coroutines etc., and not just ones using LLVM and/or emscripten. See docs on the ABI in the pass source.
|
|
|
|
|
| |
This pattern-matches towers of blocks + a br_table into a JS switch. This is much smaller in code size and also avoids heavy nesting that can exceed the recursion limits of JS parsers.
This is not enough yet, because it pattern-matches very specifically. In reality, switches can look slightly different. Followup PRs will extend this. For now, this passes the test suite (what passed before - not including the massive-switch tests) + fuzzing so it's a good start.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Reflected new renamed instruction names in code and tests:
- `get_local` -> `local.get`
- `set_local` -> `local.set`
- `tee_local` -> `local.tee`
- `get_global` -> `global.get`
- `set_global` -> `global.set`
- `current_memory` -> `memory.size`
- `grow_memory` -> `memory.grow`
- Removed APIs related to old instruction names in Binaryen.js and added
APIs with new names if they are missing.
- Renamed `typedef SortedVector LocalSet` to `SetsOfLocals` to prevent
name clashes.
- Resolved several TODO renaming items in wasm-binary.h:
- `TableSwitch` -> `BrTable`
- `I32ConvertI64` -> `I32WrapI64`
- `I64STruncI32` -> `I64SExtendI32`
- `I64UTruncI32` -> `I64UExtendI32`
- `F32ConvertF64` -> `F32DemoteI64`
- `F64ConvertF32` -> `F64PromoteF32`
- Renamed `BinaryenGetFeatures` and `BinaryenSetFeatures` to
`BinaryenModuleGetFeatures` and `BinaryenModuleSetFeatures` for
consistency.
|
| |
|