| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
| |
This adds support in the binary/text parsers and writers,
the validator and interpreter, and objdump (but not wasm2c).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The interpreter could overflow the stack without trapping properly in
`call_indirect` situations. While it would set the `out_trap` to the
trap reason, it would return `RunResult::Ok` and the interpreter code
would only check `RunResult::Ok` to decide whether or not to keep
running. In other words, while the stack overflow meant the interpreter
wouldn't push a frame onto the call stack, the interpreter loop would
continue advancing instructions, resulting in instructions after the
runaway `call_indirect` running.
If the offending `call_indirect` didn't have return values, it would be
as if the call returned normally. If it did have return values, nothing
would be pushed onto the value stack, yet the return types would be
pushed onto the type stack. With careful manipulation of the following
instructions, this could be used to cause all sorts of memory
corruption.
As it turns out, the function exit code, as well as a handful of other
instructions, do check the state of the value and type stacks and can
safely reproduce the bug without the memory corruption, so that's what
we made the test do.
The obvious fix was to make `call_indirect` propagate `RunResult::Trap`
properly. Additionally, we made it so `assert_exhaustion` checks both
the `RunResult` *and* the `out_trap`, and asserts if they don't match.
This should help catch similar bugs in the future.
Closes #2462
Fixes #2398
|
|
|
|
|
| |
See https://github.com/WebAssembly/memory64/issues/51
Includes workaround for #2422
|
|
|
|
|
|
|
| |
The main change here is because `comments.wast` was updated to include
a "quoted" module at the top level.
Previously quoted modules had only been used as part of invalid or
malformed assertion expressions.
|
|
|
|
|
|
| |
Previously assert_malformed was treated the same as assert_invalid
Also fixes a bug where spectest-interp wasn't trying to validate
text modules (e.g. `(assert_invalid (module quote "...") "")`).
|
|
|
|
| |
Fixes one issue where Validator was incorrectly accepting some
malformed modules from the spec tests.
|
|
|
| |
Fixes #2020
|
| |
|
|
|
|
|
|
|
|
| |
This adds support for the new opcodes from the Relaxed SIMD proposal
(https://github.com/WebAssembly/relaxed-simd) behind the
"--enable-relaxed-simd" flag.
The exception is the f32x4.relaxed_dot_bf16x8_add_f32x4 instruction
which is not yet implemented.
|
|
|
|
| |
This is more modern and (IMHO) easier to read than that old C typedef
syntax.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
As well as the testsuite update there are two notable changes that
come with it here. These can both be split out an landed first if
it makes sense.
1. wasm2c now supports element sections containing externref. Currently
only the null reference is supported.
2. element segments no longer use funcref as the default element type
but instead, unless explicitly included in the binary, the
element type defaults to the type of the table in which the segment
is active.
Fixes: #1612 #2022
|
|
|
|
|
| |
* Log all lexing errors in WastLexer (rather than via parser)
* Update docs/demo/libwabt.js
|
|
|
| |
This makes things easier for users and packagers of libwabt.
|
|
|
|
|
|
|
| |
The GetLane methods were looping over a "lane" variable, masking the
parameter of the same name. This led to the last lane being returned
in all cases, so tests would ignore the other lanes.
Signed-off-by: Marcus Better <marcus@better.se>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previously any top-level module defined in a .wast file would be parsed
and converted to a `Module` and stored in a `ModuleCommand`, since it
may be used later by the script (e.g. via an `invoke` command). This
means that when it was written out later it may have been changed, which
is undesirable for binary and quoted modules.
This change adds a new `ScriptModuleCommand`, which stores both a
`Module` and a `ScriptModule`. The `Module` contains the parsed
information, and the `ScriptModule` contains the original contents of
the binary or quoted data.
This fixes issue #1927.
|
|
|
|
| |
(#1895)
|
|
|
|
|
| |
Now that we have C++17 we don't need our own string_view class anymore.
Depends on #1825
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This applies clang-format to the whole codebase.
I noticed we have .clang-format in wabt but the codebase is not very
well formatted. This kind of mass-formatting PR has fans and skeptics
because it can mess with `git blame`, but we did a similar thing in
Binaryen a few years ago (WebAssembly/binaryen#2048, which was merged in
WebAssembly/binaryen#2059) and it was not very confusing after all.
If we are ever going to format the codebase, I think it is easier to do
it in a single big PR than dozens of smaller PRs.
This is using the existing .clang-format file in this repo, which
follows the style of Chromium. If we think this does not suit the
current formatting style, we can potentially tweak .clang-format too.
For example, I noticed the current codebase puts many `case` statements
within a single line when they are short, but the current .clang-format
does not allow that.
This does not include files in src/prebuilt, because they are generated.
This also manually fixes some comment lines, because mechanically
applying clang-format to long inline comments can look weird.
I also added a clang-format check hook in the Github CI in #1683, which
I think can be less controversial, given that it only checks the diff.
---
After discussions, we ended up reverting many changes, especially
one-liner functions and switch-cases, which are too many to wrap in
`// clang-format off` and `// clang-format on`. I also considered fixing
`.clang-format` to allow those one-liners but it caused a larger churn
in other parts. So currently the codebase does not conform to
`.clang-format` 100%, but we decided it's fine.
|
|
|
|
|
|
|
|
| |
This requires `Type::GetName` to return to be dynamicllay created and
return `std::string` rather then a `const char*`
As this diff shows this type name is only used in textual output and
error messages so should this change should not have a effect of binary
parse time or the interpreter.
|
|
|
|
| |
I think it was always intended to work this way but was
left as a TODO.
|
|
|
|
|
|
|
|
| |
This PR imports the spec tests from the Wasm testsuite repo and adds infrastructure to run them correctly.
* Adds test expectations for exception handling proposal spec tests.
* Adds missing tag signature matching code for import tests.
* Adds support for the `assert_exception` command used in new tests.
* Fix filename normalization for the spec test runner.
|
|
|
|
|
|
|
|
|
|
| |
This PR updates the support of exception handling to the latest proposal (that is compatible with future 2-phase exception handling) described in https://github.com/WebAssembly/exception-handling/pull/137 and https://github.com/WebAssembly/exception-handling/pull/143.
* Adds back tagged `catch $e`, `catch_all`, and `rethrow N` from a previous version of wabt, but with updates to match the current spec (e.g., `catch_all` shares an opcode with `else`, `rethrow`'s depth indexes only catch blocks, etc).
* Adds `unwind` and `delegate` instructions.
* Removes `exnref` and `br_on_exn`.
* Updates relevant tests.
There are some details that could still change (e.g., maybe how `delegate`'s depth is validated), but I'd be happy to submit further PRs if the spec details change.
|
|
|
|
| |
I'm not sure why we were using stdout but the convention is normally to
write all logging and error message to stderr.
|
|
|
|
|
| |
Adds a type field to `Value` to verify the right union member is being read.
A Wasm module that has been validated shouldn't need this, but any code reading the wrong value would trigger UB, but still often work (like a uint32_t read from a uint64_t on little endian machine), and mask bugs.
Turning this on found bugs in the PR I just landed (as I suspected) but also in older code.
|
|
|
|
|
|
|
|
| |
Main changes:
* Rename `anyref` -> `externref`
* Remove `nullref`
* Rename `hostref` -> `externref`
* `ref.null` and `ref.is_null` now have "ref kind" parameter
* Add ref kind keywords: `func`, `extern`, `exn`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The for experimental WASI implementation I'm working on the WASI
callbacks (implemented as HostFuncs) need to know which module a call is
coming from. This is because the implicitly operate on the memory of
the calling instance.
This approach seems the match the current convention of passing in the
Thread in `Func::DoCall`.
The purpose here is to allow the HostCall callback to determine from
which instance it is being called. An alternative approach that I
considered was created different set of WASI HostCall object for
each instance so that instance and its memory we bound to the WASI
functions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Lots of changes necessary to make this work, as well as some bug fixes.
The main change is allowing `nan:canonical` and `nan:arithmetic` as a
possible value for each lane of a `v128`. This needs to propogate
through the parser, IR, the JSON format, and the spec interpreter.
This also changes the format of the spec JSON file, where a SIMD value
is now stored as a list of values instead of a single u128:
```
{"type": "v128", "lane_type": "i32", "value": ["0", "0", "0", "0"]}
```
Since the lane type can be `i8` and `i16`, these types can now be used
in more places (not just the decompiler). They'll be used for the GC
proposal too (for packed values), so I've updated them to use the binary
value specified for that proposal.
Here are the actual SIMD fixes:
* SIMD lanes are malformed if they don't match the binary format, but
invalid if they are smaller than the lane width. For example,
`i8x16.extract_lane_s` is malformed if the lane is >= 256, because the
lane is stored as a byte. But it is invalid if the lane is >= 16.
* The `i8x16.narrow_i16x8_u`, `i16x8.narrow_i32x4_u` and
`i64x2.load_32x2_u` instructions were not handling sign-extension
propoerly.
TODO: This code is pretty clumsy now; it would be better to have a
universal `Value` and `ExpectedValue` that can be used everywhere, so
the logic doesn't need to be duplicated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It's modeled closely on the wasm-c-api. All runtime objects are
garbage-collected. The GC'd objects are subclasses of `Object` and all
stored in the `Store`. GC roots can be created using a RefPtr<T> struct.
The `Module` stores no runtime objects, only description structs (named
`*Desc`, e.g. `FuncDesc`). Instantiation takes these descriptors and
turns them into runtime objects (e.g. `FuncDesc` is used to create a
`Func`). Only import-matching occurs during instantiation; all other
validation is assumed to have occurred during Module compilation.
As with the previous interpreter, the wasm instructions are not executed
directly, and instead compiled to an instruction stream that is easier
to interpret (e.g. all branches become gotos). It's still a stack
machine, though.
The previous interpreter would always compile and instantiate in one
step, which means that it was always known whether an imported function
is a host function or wasm function. As a result, calls between modules
that stayed in wasm could be very cheap (just update PC). Now that the
module is compiled before instantiation, an imported function call
always has to check first, which may be a slight performance hit.
One major difference to the structure of the interpreter is that
floating-point values are passed directly, instead of using their
equivalent bit pattern. This is more convenient in general, but requires
annotating all functions with WABT_VECTORCALL so Visual Studio x86 works
properly (otherwise floats are passed in the x87 FP stack).
Instruction stream decoding/tracing/disassembling is now all handled in
the `Istream` class. This reduces a lot of duplication between the
three, which makes the logging-all-opcodes and tracing-all-opcodes less
valuable, so I've removed them.
Here are the changes to files:
binary-reader-metadata.{h,cc} -> [removed]
interp-{disassemble.trace}.cc -> istream.{h,cc}
There are new helper files:
interp-util.{h,cc}: Primarily print debugging functions
interp-math.h: Templates used for handling wasm math
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Validating function signatures (i.e. making sure a named function type
matches its explicit signature) really should be parse of text parsing.
Example:
(type $F (func (param i32) (result i32)))
...
(call_indirect (type $F) (param f32) (result i32) ;; ERROR!
This change doesn't quite get us there, but it's closer. The next step
will be to remove `ValidateFuncSignatures` entirely and perform those
checks in the parser itself.
|
|
|
|
|
|
|
|
|
| |
Resolving names (i.e. remapping variable names to indexes) is meant to
be part of the parsing process. The spec even considers an unmapped
variable name to be "malformed" text.
This PR moves in that direction, by always running ResolveNames after
parsing text. The next step would be to integrate this more closely with
the parser itself.
|
|
|
|
|
|
|
|
|
|
| |
* Remove `assert_return_func`. This is now handled by using
`assert_return` with `(ref.func)`.
* The reference types proposal depends on the bulk memory proposal, so
using `--enable-reference-types` automatically includes
`--enable-bulk-memory`.
* `table.fill` no longer clamps to the valid range, and instead checks
before writing anything. This matches the other bulk instructions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The two primary changes involved are:
1. Removal of `assert_return_canonical_nan`/`arithetic nan` in favor of
special `nan:canonical`/`nan:arithmetic` constants that can only be
used in test expectations.
See: https://github.com/WebAssembly/spec/pull/1104
2. New trapping behaviour for bulk memory operations. Range checks are
now performed up front for opterations such as memory.fill and
memory.copy.
See: https://github.com/webassembly/bulk-memory-operations/issues/111
And: https://github.com/webassembly/bulk-memory-operations/pull/123
The old behaviour is still kept around to support table.fill which
is defined in reference-types proposal and has yet to be updated.
|
|
|
|
| |
These were being silently ignored previously.
|
|
|
|
|
|
|
| |
- Allow `ref.func` for global initialization expressions
- Allow `nullref` as a full-fledged type, after
WebAssembly/reference-types#66
- Enable reference types when exnref is used (The reference types
proposal is a prerequisite of the EH proposal)
|
|
|
|
|
|
|
| |
The only major change to the interpreter is to move segment
initialization out `ReadBinaryInterp` (in the binary reader) and into
interp.cc. This is because the test suite now expects out of bound
semgments to be reported during initialization rather than reported
as validation errors.
|
|
|
|
|
|
|
|
|
|
|
| |
This means we can give more precise/useful errors for runtime failures.
Change interp::Result from an enum to struct so it can hold the
result enum plus an optional detailed error message.
Add TRAP_MSG and TRAP_IF_MSG macros that work just like TRAP and
TRAP_IF but contain a format string and printf-like arguments which
are formatted to produce the error message.
|
|
|
|
| |
NFC (#1235)
|
|
|
|
|
| |
This is needed for running the reference-types tests.
See: #1223
|
|
|
|
|
|
|
| |
The _bits suffix is used the floating point types where we use types
that differ from the native C types. For v128 we have a native struct
type that we store and manipulate directly.
Also remove the unneeded bitcast operations.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Closes: #1106
Ported versioning system from [Binaryen CMakeLists.txt](https://github.com/WebAssembly/binaryen/blob/dc31b460fef47dfb3415b4ae6276fff4919a03e2/CMakeLists.txt#L10-L23)
```
bin/wasm2c --version
1.0.11-44-g71f883ad
```
Applied to (all) tools in `src/tools/`.
|
|
|
|
|
| |
* Never allow a null options pointer to `ParseWatModule` or
`ParseWastScript`
* Allow a token of type Int or Nat when parsing a simd float const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Add spec test support for V128.
* This algorithm, however simple, produces the digits in reverse order. Remember to reverse them again before printing.
* Correct order of the quads of the v128.
Given (v128.const i32x4 0x01020304 0x05060708 0x090a0b0c 0x0d0e0f00), the wabt v128 struct will contain 0x01020304 in v128_bits.v[0]. If a wasm program uses v128.store to store this constant then loads each byte with i32.load8_u, the wabt interpreter produces the order 04 03 02 01, 08 07 06 05, 0c 0b 0a 09, 00 0f 0e 0d.
* Add a parser for v128 and implement support in spectest-interp.
* Move WriteUint128 to literal.cc, add tests.
Rewrite so as to not use string streams. Roll repeated code into a loop.
Rename functions to comply with style guide, use anonymous namespace.
* Now that v128 has operator==, we can use it here.
* In a spectest with a binary module, use the same features for that module as for the outer spectest.
|
|
|
|
|
|
|
|
|
|
|
| |
The wast file definition for assert_exhaustion looks like:
```wasm
(assert_exhaustion
(invoke "function" (i32.const 132))
"error message")
```
This commit adds the "error message" part to the output.
|
|
|
|
|
|
|
|
|
| |
* Implement bulk memory in interpreter
* Read/Write elem_type in element segments
* Binary format
* Text format (`(elem passive funcref...)`)
* Add DataSegment runtime objects
* Only initialize active data segments when instantiating
|
|
|
|
|
|
|
|
|
|
| |
When a module is instantiated, and the start function traps, the
contents of the memory and the table may have been modified. This case
is handled by the `assert_uninstantiable` check in a wast test.
In spectest-interp, assert_uninstantiable would instantiate the module,
but was incorrectly resetting the environment. In run-spec-wasm2c, the
`assert_uninstantiable` tests weren't being run at all. Now the module's
`init` function is run, and it is expected to trap.
|
|
|
|
|
|
| |
The only benefit to LexerSourceFile is to read files that are larger
than can be loaded into memory. That probably is only a valuable feature
when loading GB-sized files on a 32-bit machine. I'm not certain that
it's worth the extra complexity.
|
|
|
|
|
|
|
|
|
| |
Also:
* Add feature limits on using v128 and anyref types (requires
--enable-simd and --enable-reference-types respectively).
* Separate out ParseValueType (used for params, locals, global types)
from ParseRefType (used for table types).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Add support for the reference types proposal
This commit adds support for the reference types proposal to wabt.
Namely it adds new opcodes like `table.{get,set,grow}` as well as adds a
new `anyref` type. These are plumbed throughout for various operations
in relatively simple fashions, no support was added for a subtyping
relationship between `anyref` and `anyfunc` just yet.
This also raises the restriction that multiple tables are disallowed,
allowing multiple tables to exist when `--enable-reference-types` is
passed.
* Allow nonzero table indices in `call_indirect`
Plumb support throughout for the `call_indirect` instruction (and
`return_call_indirect`) to work with multi-table modules according to
the reference types proposal.
|
|
|
|
|
|
|
| |
`spectest-interp` used to return 0 (success) when tests failed, and
non-zero only if the source could not be parsed. It's more useful to
return non-zero if the tests fail too.
Fixes issue #1002.
|