| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Optionally track the binary format code section offsets,
that is, when loading a binary, remember where each IR
node was read from. This is necessary for DWARF
debug info, as these are the offsets DWARF refers to.
(Note that eventually we may want to do something
else, like first read the DWARF and only then add
debug info annotations into the IR in a more LLVM-like
manner, but this is more straightforward and should be
enough to update debug lines and ranges).
This tracking adds noticeable overhead - every single
IR node adds an entry in a map - so avoid it unless
actually necessary. Specifically, if the user passes in
-g and there are actually DWARF sections in the
binary, and we are not about to remove those sections,
then we need it.
Print binary format code section offsets in text, when
printing with -g. This will help debug and test dwarf
support. It looks like
;; code offset: 0x7
as an annotation right before each node.
Also add support for -g in wasm-opt tests (unlike
a pass, it has just one - as a prefix).
Helps #2400
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This PR enables compiling Binaryen to WebAssembly when building binaryen.js. Since WebAssembly is best compiled and instantiated asynchronously in browsers, it also adds a new mechanism to tell if respectively when the module is ready by means of one of the following:
// Using a promise
const binaryen = require("binaryen");
binaryen.ready.then(() => {
... use normally ...
});
// Using await
const binaryen = require("binaryen");
(async () => {
await binaryen.ready;
... use normally ...
})();
// Where top-level await is available
const binaryen = await require("binaryen").ready;
... use normally ...
One can also tell if Binaryen is already ready (for example when assuming it in follow-up code) by:
if (/* we already know that */ binaryen.isReady) {
... use normally ...
} else {
throw Error("Binaryen is supposed to be ready here but isn't");
}
The JS test cases have been updated accordingly by wrapping everything in a test function and invoking it once ready. Documentation will have to be updated as well to cover this of course. New file size is about 2.5mb, even though the Wasm becomes inlined into the JS file which makes distribution across different environments a lot easier.
Also makes building binaryen (to either js or wasm) emit binaryen.js, and not binaryen_js.js etc.
Supersedes and thus fixes #1381
With .ready it also fixes #2452
|
|
|
| |
This reverts commit f0a2e2c75c7bb3008f10b6edbb8dc4cfd27b7d28.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This imports LLVM code for DWARF handling. That code has the
Apache 2 license like us. It's also the same code used to
emit DWARF in the common toolchain, so it seems like a safe choice.
This adds two passes: --dwarfdump which runs the same code LLVM
runs for llvm-dwarfdump. This shows we can parse it ok, and will
be useful for debugging. And --dwarfupdate writes out the DWARF
sections (unchanged from what we read, so it just roundtrips - for
updating we need #2515).
This puts LLVM in thirdparty which is added here.
All the LLVM code is behind USE_LLVM_DWARF, which is on
by default, but off in JS for now, as it increases code size by 20%.
This current approach imports the LLVM files directly. This is not
how they are intended to be used, so it required a bunch of
local changes - more than I expected actually, for the platform-specific
stuff. For now this seems to work, so it may be good enough, but
in the long term we may want to switch to linking against libllvm.
A downside to doing that is that binaryen users would need to
have an LLVM build, and even in the waterfall builds we'd have a
problem - while we ship LLVM there anyhow, we constantly update
it, which means that binaryen would need to be on latest llvm all
the time too (which otherwise, given DWARF is quite stable, we
might not need to constantly update).
An even larger issue is that as I did this work I learned about how
DWARF works in LLVM, and while the reading code is easy to
reuse, the writing code is trickier. The main code path is heavily
integrated with the MC layer, which we don't have - we might want
to create a "fake MC layer" for that, but it sounds hard. Instead,
there is the YAML path which is used mostly for testing, and which
can convert DWARF to and from YAML and from binary. Using
the non-YAML parts there, we can convert binary DWARF to
the YAML layer's nice Info data, then convert that to binary. This
works, however, this is not the path LLVM uses normally, and it
supports only some basic DWARF sections - I had to add ranges
support, in fact. So if we need more complex things, we may end
up needing to use the MC layer approach, or consider some other
DWARF library. However, hopefully that should not affect the core
binaryen code which just calls a library for DWARF stuff.
Helps #2400
|
|
|
|
|
|
|
|
|
|
|
| |
This does two things:
- Restore `visitDataDrop` handler deleted in #2529, but now we convert
invalid `data.drop`s to not `unreachable` but `nop`. This conforms to
the revised spec that `data.drop` on the active segment can be treated
as a nop.
- Make `visitMemoryInit` trap if offset or size are not equal to 0 or if
the dest address is out of bounds. Otherwise drop all its argument.
Fixes #2535.
|
|
|
| |
As specified in https://github.com/WebAssembly/simd/pull/126.
|
|
|
|
|
|
| |
Currently `ModuleUtils::clearModule` does not clear `exists` flags in
the memory and table, and running RoundTrip pass on any module that has
a memory or a table fails as a result. This creates `clear` function in
`Memory` and `Table` and makes `clearModule` call them.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This fixes https://github.com/emscripten-core/emscripten/issues/9950.
The issue only shows up when debug names are not present so most of
the changes in CL come from disabling debug names in the lld tests.
We want to make sure that wasm-emscripten-finalize runs fine without
debug names so I think it makes most sense to test in this mode.
The actual bugfix is in wasm-emscripten.cpp as part of the
FixInvokeFunctionNamesWalker. The problem was the name of the function
rather than is import name was being added to importRenames. This means
that when debug names were present (and the two names were the same)
we didn't see the bug.
|
|
|
|
|
|
|
| |
- Remove a function from memory-packing_all-features.wast, because it
does not test anything meaningful after #2529.
- Rename a test file to use `--all-features`; it started failing I guess
because `exnref` requires also reference type features, but not sure
why it was OK so far.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This implements recent bulk memory spec changes
(WebAssembly/bulk-memory-operations#126) in Binaryen. Now `data.drop` is
equivalent to shrinking a segment size to 0, and dropping already
dropped segments or active segments (which are thought to be dropped in
the beginning) is treated as a no-op. And all bounds checking is
performed in advance, so partial copying/filling/initializing does not
occur.
I tried to implement `visitDataDrop` in the interpreter as
`segment.data.clear();`, which is exactly what the revised spec says. I
didn't end up doing that because this also deletes all contents from
active segments, and there are cases we shouldn't do that:
- `wasm-ctor-eval` shouldn't delete active segments, because it will
store the changed contents back into segments
- When `--fuzz-exec` is given to `wasm-opt`, it runs the module and
compare the execution call results before and after transformations.
But if running a module will nullify all active segments, applying
any transformation to the module or re-running it does not make any
sense.
|
|
|
|
|
|
| |
contains the passes (#2532)
We already supported this, but required that the filename be a number.
This lets the name be anything, and we check if *.passes exists for it.
|
| |
|
|
|
|
|
| |
Currently `BINARYEN_PASS_DEBUG=3` prints `.wasm` files but they are
actually text wast files. This makes `BINARYEN_PASS_DEBUG=3` prints both
wasm/wast files, where wasm contains a binary file and wast a text file.
|
| |
|
|
|
|
|
|
|
| |
When the expression type is none, it does not seem to be necessary to
make it a prelude and insert a nop. This also results in unnecessary
blocks that contains an expression with a nop, which can be reduced to
just the expression. This also adds some newlines to improve
readability.
|
|
|
|
|
|
|
|
|
| |
In normal mode we call a JS import, but we can't import from JS
in standalone mode. Instead, just trap in that case with an
unreachable. (The error reporting is not as good in this case, but
at least it catches all errors and halts, and the emitted wasm is
valid for standalone mode.)
Helps emscripten-core/emscripten#10019
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
According to the current spec, `local.tee`'s return type should be the
same as its local's type. (Discussions on whether we should change this
rule is going on in WebAssembly/reference-types#55, but here I will
assume this spec does not change. If this changes, we should change many
parts of Binaryen transformation anyway...)
But currently in Binaryen `local.tee`'s type is computed from its
value's type. This didn't make any difference in the MVP, but after we
have subtype relationship in #2451, this can become a problem. For
example:
```
(func $test (result funcref) (local $0 anyref)
(local.tee $0
(ref.func $test)
)
)
```
This shouldn't validate in the spec, but this will pass Binaryen
validation with the current `local.tee` implementation.
This makes `local.tee`'s type computed from the local's type, and makes
`LocalSet::makeTee` get a type parameter, to which we should pass the
its corresponding local's type. We don't embed the local type in the
class `LocalSet` because it may increase memory size.
This also fixes the type of `local.get` to be the local type where
`local.get` and `local.set` pair is created from `local.tee`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 fixes the parent-child relationship computation in `DataFlow.Graph`
when there is a loop. This wasn't discovered until now because this is
used in Souperify and Souperify only runs after Flatten pass, which
produces redundant blocks between inside and outside of a loop.
|
| |
|
|
|
|
| |
(#2508)
|
|
|
|
|
|
| |
This pass writes and reads the module. This shows the effects
of converting to and back from the binary format, and will be
useful in testing dwarf debug support (where we'll need to see
that writing and reading a module preserves debug info properly).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Currently `none` and `unreachable` types are stored as the same empty
`{}` in src/wasm/wasm-type.cpp. This makes `Type::operator<` incorrectly
when given `none` and `unreachable`, because it expands both given types
and lexicographically compare them, when both of the expanded vector
will be empty.
This was found by the fuzzer. This line in `Modder::visitExpression`
tries to retrieve candidates of the same type. Because we can't really
compare these two types, if you give `unreachable` as the key,
candidates of `none` type can be returned. This generates incorrect code
that ends up failing in validation in a very weird way.
It was hard to generate a small testcase to trigger this part because it
was found by generating fuzzed code from a random data file. But I guess
this fix is pretty straightforward.
Fixes #2512.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
The `$` is not actually part of the name, its the marker that starts
a name in the wat format. It can be confusing to see it show up when
doing `cerr << name`, for example.
This change has Print.cpp add the `$` which seem like the right place
to do this. Plus it revealed a bunch of places where were not calling
printName to escape all the names we were printing.
|
|
|
|
| |
debug builds. (#2507)
|
|
|
|
|
|
| |
This allows us to support not just wasi_unstable but also the new
wasi_snapshot_preview1 and beyond.
See https://github.com/emscripten-core/emscripten/pull/9956
|
|
|
|
|
| |
Also fix, but in splitting the names of the trace channels. Obviously
I can't write string.split correctly in C first time around.
|
| |
|
|
|
|
|
| |
This works more like llvm's unreachable handler in that is preserves
information even in release builds.
|
|
|
|
|
|
|
|
| |
We always enable assertions by default, but this options allows for
a build without them.
Fix all errors in the ASSERTIONS=OFF build, even though we don't
normally build this its good to keep it building.
|
|
|
| |
This like was mistakenly removed as part of the BYN_TRACE conversion.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
That was needed for super-old wasm type system, where we allowed
(block $x
(br_if $x
(unreachable)
(nop)
)
)
That is, we differentiated "taken" branches from "named" ones (just
referred to by name, but not actually taken as it's in unreachable code).
We don't need to differentiate those any more. Remove the ReFinalize
code that considered it, and also remove the named/taken distinction in
other places.
|
|
|
| |
This is line with modern cmake conventions is much less SHOUTY!
|
|
|
|
|
|
| |
This means that debugging/tracing can now be enabled and controlled
centrally without managing and passing state around the codebase.
|
|
|
|
|
|
|
|
|
| |
This allows for debug trace message to be split my channel. So you
can pass `--debug` to simply debug everything, or `--debug=opt`
to only debug wasm-opt.
This change is the initial introduction but as a followup I hope to
convert all tracing over to this new system so we can more easily
control the debug output.
|
|
|
|
|
|
|
|
| |
With #2483 merged, emcc hits the following warning when attempting to compile wasm-opt to JS with Emsdk:latest-fastcomp:
shared:WARNING: for wasm there is no need to set ELIMINATE_DUPLICATE_FUNCTIONS, the binaryen optimizer does it automatically
shared:ERROR: treating warnings as errors (-Werror)
Appears this happens because ELIMINATE_DUPLICATE_FUNCTIONS is set for all targets when using fastcomp, even though only binaryen_js uses WASM=0. So this PR moves it into the binaryen_js target.
|
|
|
|
|
|
|
|
|
|
|
|
| |
We already have exports for _malloc and _free in the Emscripten build, but there
is no way yet to initialize the data without resorting to JS. Hence this PR
adds a few additional memory helpers to the Emscripten build so it becomes
possible to manipulate Binaryen memory without the need for extra glue code, for
example when Binaryen is a WebAssembly import, and one is allocating strings to
be used by / reading strings returned by Binaryen.
I expect this to be a bit controversial because the use case is relatively
specific, but it makes sense for us because we are consuming the C-API directly
(from JS and eventually Wasm) and don't rely on binaryen.js-post.js.
|
|
|
| |
And use LTO in upstream opt builds, which improves code size by >20%.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
This creates utility functions for removing module elements: removing
one element by name, and removing multiple elements using a predicate
function. And makes other parts of code use it. I think this is a
light-handed approach than calling `Module::updateMaps` after removing
only a part of module elements.
This also fixes a bug in the inlining pass: it didn't call
`Module::updateMaps` after removing functions. After this patch callers
don't need to additionally call it anyway.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
| |
Fixes #2453
As a bonus this also provides a port of wasm-opt etc. with NODERAWFS
and everything seems to work, that is, you can run stuff like
nodejs wasm-opt.js input.wasm --metrics
|
|
|
|
|
|
|
|
| |
This makes auto_update_tests.py update spec test outputs (ones that are
printed with `spectest.print` import) and extracts spec tests blacklist
into shared.py with comments for reasons why each of them fails.
Also deletes if-label-scope.fail.wast.log because it does not seem to
match with any of existing tests.
|
|
|
| |
These have not been used in years and seem outdated.
|
|
|
|
|
|
|
|
|
| |
using the `$<TARGET_OBJECTS:objlib>` syntax. Use this variable when
adding `libbinaryen` as static or shared library. Additionally, use the
variable with the object files to simplify the `TARGET_LINK_LIBRARIES`
commands: add the object libraries to the sources of executables and
drop the use of our libraries in `TARGET_LINK_LIBRARIES`. (Object
libraries cannot be linked but must be used as sources. See
https://cmake.org/pipermail/cmake/2018-June/067721.html)
|
|
|
|
|
|
|
|
|
|
| |
Create a new ParallelFunctionAnalysis helper, which lets us
run in parallel on all functions and collect info from them,
without manually handling locks etc.
Use that in the binary writing code's type collection logic,
avoiding a lock for each type increment.
Also add Signature printing which was useful to debug this.
|
|
|
|
|
|
|
|
|
| |
We were only updating the imported Function's type name
field and failing to update its params and results. This caused the
binary writer to start using the wrong types after #2466.
This PR fixes the code to update both type representations on the
imported function. This double bookkeeping will be removed entirely in
an upcoming PR.
|