| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
| |
This will allow for the completely removal of
`__growWasmMemory` as a followup. We currently
unconditionally generate this function
in `generateMemoryGrowthFunction`.
See #3180
|
|
|
| |
It's not an actual constructor, just a JS function that returns the object.
|
|
|
|
|
| |
Also, format the asmFunc call to make it more readable in the ES6
modules case.
|
|
|
|
|
|
|
|
|
|
|
|
| |
These test output files are ignored and so contain stale output
that is neither checked during `check.py` not updated during
`auto_update_tests.py`.
There are three clases to tests here:
1. Spec tests that end in 64.wast are ignored by scripts/test/wasm2js.py
2. Spec tests that are globallyi ignoed by shared.py:SPEC_TESTS_TO_SKIP
3. hello_world.2asm.js.. I cant tell where this came remove it seems
like an anomaly.
|
| |
|
|
|
| |
Add floating point Eq and Ne operators to Properties::isSymmetric. Also treat additional float ops as symmetric specifically in OptimizeInstructions when their operands are known to be non-NaN.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It was hardcoded as "env.memory", which is usually correct. But if we minify
import names, as in -O3 in emscripten, we need to use the minified name.
Note how in the test it now emits
var memory = env.a;
for the import.
Fixes emscripten-core/emscripten#12123
This was not noticed earlier since that import is only used in memory
growth. The tests that would catch it are wasm2js3.test*memory_growth*
but we only run wasm2js1 on CI. I'll add testing after this lands.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
| |
optimizeBoolean does not receive a boolean, it is done when the
output flows into a boolean context.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It is usually fine to do if (x | 0) => if (x) since it just cares if the
value is 0 or not. However, if the cast turns it into 0, then that is
incorrect, which the fuzzer found as
-2147483648 + -2147483648 | 0
(the sum is 2^32, which | 0 is 0).
We can maybe look into doing this in a safe way, but for now
just remove it. It doesn't have a big impact on code size as this
is pretty rare (e.g. the minimal runtime code size test is not
broken by this).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
x ? 1 : 0 => !!x
and so forth.
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
|
|
|
|
| |
Since the global is never read, we know that any write operation
will be unobservable.
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
| |
When memory is packed and there are passive segments, bulk memory
operations that reference those segments by index need to be updated to
reflect the new indices and possibly split into multiple instructions
that reference multiple split segments. For some bulk-memory operations,
it is necessary to introduce new globals to explicitly track the drop
state of the original segments, but this PR is careful to only add
globals where necessary.
|
|
|
|
|
|
|
|
|
|
|
|
| |
isBinary was used where we should only accept
a signed binary, as removing the | 0 from an unsigned
value may be incorrect.
This does regress a few small things (as can be seen
in the diff). If it's important we can add more sophisticated
optimizations here, perhaps like an assumption that the
signedness of a local never matters.
Fixes emscripten-core/emscripten#10173
|
|
|
|
|
|
| |
By doing so we ensure that our calls to convert wasm
types to JS types never try to convert an unreachable.
Fixes #2558
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This updates spec test suite to that of the current up-to-date version
of https://github.com/WebAssembly/spec repo.
- All failing tests are added in `BLACKLIST` in shared.py with reasons.
- For tests that already existed and was passing and started failing
after the update, we add the new test to the blacklist and preserve
the old file by renaming it to 'old_[FILENAME].wast' not to lose test
coverage. When the cause of the error is fixed or the unsupported
construct gets support so the new test passes, we can delete the
corresponding 'old_[FILENAME].wast' file.
- Adds support for `spectest.print_[type] style imports.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
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...).
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
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
|
| |
|
|
|
|
|
| |
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 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
|
|
|
| |
We don't ever emit "use asm" anymore, so this similar annotation is not really useful, it just increases size.
|
|
|
| |
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 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.
|
|
|
|
|
| |
gets (#2118)
In unreachable code, a get may have a single set that assigns to it, and that set may be assigned to by that very get.
|
| |
|
| |
|
| |
|
|
|
| |
Set it to a local in the asmFunc scope, so that minifiers can easily see it's a simple local value (instead of using it as an upvar from the parameters higher up, which was how the emscripten glue was emitting it).
|
|
|
| |
This happens on e.g. an i32 load of a constant offset, then we have constant >> 2.
|
|
|
| |
This helps quite a lot on wasm2js.
|