| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
| |
This pull request implements EHv4. Binary is mostly untested until
interp is working.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
| |
This makes things easier for users and packagers of libwabt.
|
|
|
|
| |
- Rebase test output to match new location tracking on Vars
- Eliminate single-argument Var() constructor.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
See https://github.com/WebAssembly/tool-conventions/blob/main/CodeMetadata.md for the specification.
In particular this pr implements the following:
- Parsing code metadata sections in BinaryReader, providing appropriate callbacks that a BinaryReaderDelegate can implement:
- BinaryReaderObjdump: show the sections in a human-readable form
- BinaryReaderIr: add code metadata in the IR as expressions
- Parsing code metadata annotations in text format, adding them in the IR like the BinaryReaderIR does
- Writing the code metadata present in the IR in the proper sections when converting IR to binary
- Support in wasm-decompiler for showing code metadata as comments in the pseudo-code
All the features have corresponding tests.
Support for code metadata is gated through the --enable-code-metadata feature. For reading/writing in the text format, --enable-annotations is also required.
Missing features:
Support for function-level code metadata (offset 0)
Extensive validation in validator.cc (like making sure that all metadata instances are at the same code offset of an instruction)
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Doing validation at parse time means we cannot run tests which
included invalid instruction in the elem init expressions.
For example. the updated test suite repo contains tests such as this:
```
(assert_invalid
(module
(table 1 funcref)
(elem (i32.const 0) funcref (item (i32.add (i32.const 0) (i32.const 1))))
)
"constant expression required"
)
```
There we have an illegal instruction sequence in the init expresssion.
However, in order to run this test we need to be able to process it with
wast2json first which means it at least has to parse correctly.
This change removes the `ElemExpr` and `ElemExprKind` types from the IR
and instead just stores elem init expressions as `ExprList` like we do
for global init expressions. This expression list can then be validated
but crucially can also be invalid.
This technique matches the existing `OnDataSegmentInitExpr_Other` and
`OnGlobalInitExpr_Other` and indeed it seem that it was indented to
work this way since the `OnElemSegmentElemExpr_Other` already existed
(unused) in the codebase.
|
|
|
|
| |
supported call_ref (#1691)
|
|
|
|
|
|
|
|
|
|
|
| |
We recently decided to change 'event' to 'tag', and 'event section' to
'tag section', out of the rationale that the section contains a
generalized tag that references a type, which may be used for something
other than exceptions, and the name 'event' can be confusing in the web
context.
See
- https://github.com/WebAssembly/exception-handling/issues/159#issuecomment-857910130
- https://github.com/WebAssembly/exception-handling/pull/161
|
| |
|
|
|
|
|
|
|
|
|
| |
This is a new kind of ir/ast node/instruction. It has 3 immediates:
memarg align, memarg offset, and lane index. This required new visitor
functions in all the places.
Drive-by cleanup to share the simd lane parsing logic between shuffle,
lane op and this new load lane instructions. This requires rebasing some
tests because the error messages are slightly different now.
|
|
|
|
| |
This requires a new ir type, and the relevant implementation of virtual
mthods in the various visitors.
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
Function types and struct types share an index space, but a function can
only be defined using a function type.
Since `Module::GetFuncType` already returns `nullptr` for an OOB index,
it makes sense to return `nullptr` for an invalid type too.
|
|
|
|
|
|
|
|
| |
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`
|
|
|
|
|
| |
See https://github.com/WebAssembly/threads/pull/141 for the binary
encoding. This patch does add a field to AtomicFenceExpr for the
consistency model, though without a type for the time being.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Const previously stored each value as a union of bit patterns (uint32_t,
uint64_t, v128, etc). It was then extended to support cases where NaN
value (either arithmetic or canonical) was expected.
bool is_expected_nan;
union {
uint32_t u32;
uint32_t f32_bits;
...
ExpectedNan expected;
}
With the SIMD proposal, it's possible for each lane of a f32x4 or f64x2
to be a float or an expected NaN, so this doesn't work anymore. It's
possible to move ExpectedNan out of the union, but it's a bit clumsy to
use properly:
bool is_expected_nan[4];
ExpectedNan expected[4];
union { ... }
Instead, I took this as an opportunity to clean up the class a bit.
First, ExpectedNan is extended to handle the case where it is not a NaN
(i.e. not a not a number), which allows us to remove the bool. Then I
store the rest of the data as an array of `uint32_t`, and provide
accessor functions instead.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This parses just the format `(struct)` as a new type. I added a test for
this using `wat2wasm`, but that requires a rudimentary binary format.
The test runner automatically attempts to rountrip all wat2wasm tests,
so this required implementing the wat writing and binary reading too.
Here's a summary of the changes:
* binary-reader:h: Rename `BinaryReader::OnType` callbacks to `OnFuncType`
* binary-reader.h: Add `BinaryReader::OnStructType`
* binary-reader.cc: Use a switch after reading the type form to
determine whether we're reading a function or struct.
* tokens.def: Add new `TokenType::Struct`
* lexer-keywords.txt: Add new `struct` keyword
* type.h: Add `Type::Struct` type form
* wast-parser.cc: Parse `(struct)` in text format
* wat-writer.cc: Write Func or Struct type forms
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The new table-sub test, checks whether the subtyping is handled
properly w/ table.init and table.copy instructions.
The BeginElemSegment callback can't pass the element type anymore, since
it's not known yet. The callback also can't be deferred, since the
BeginElemSegmentInitExpr callback has to happen after the
BeginElemSegment callback, but the reference type is not always known
until after the initializer expression is read. To work around this, I
added a new OnElemSegmentElemType callback.
Other element segment changes:
* The element type must be tracked in the SharedValidator
* A subtle fix: when writing out the segment flags, we need to take into
account whether the element type of the segment is not funcref, even
if there are no element expressions. In that case, we have to use flag
bit 0x4 (SegUseElemExprs).
In addition, the TableCopy and TableInit instructions weren't handling
table indexes fully.
* TableCopy variables are read in the parser (both optional)
* TableCopy names are now resolved + applied
* TableCopy indexes are now validated
* TableInit table variables are read in the parser; this is subtle,
since the text format has order $table $segment, but the $table is
optional.
|
|
|
|
|
|
|
|
|
|
|
| |
The type section currently only has one form: functions. With the GC
proposal, at least two more forms are added: struct and array. To
facilitate this:
* Rename FuncTypeModuleField -> TypeModuleField
* Rename Module::func_types -> Module::types
* Rename func_type_bindings -> type_bindings
* TypeEntry is added as a base class of FuncType
* TypeModuleField stores a unique_ptr to a TypeEntry
|
|
|
|
| |
This should fix #1280, #1268, #1269.
|
| |
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
- Implement ref.func everywhere.
- Implement table.get and table.set in the interpreter.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Add support for v8x16.shuffle1 and v8x16.shuffle2_imm.
v8x16.shuffle2_imm is a rename of the previous v8x16.shuffle, but I add a copy of the code as if it were a new instruction in case the spec proposal makes further changes. The tests for old v8x16.shuffle remain in place and while there are new tests for the new v8x16.shuffle1, there are not for v8x16.shuffle2_imm. The behaviour and implementation are the same as for v8x16.shuffle, so we should simply search and replace the existing tests at some point, leaving one of them untested, probably the deprecated v8x16.shuffle.
I did test v8x16.shuffle1 against the SIMD spec test from WAVM and it passes. The WAVM spec tests for v8x16.shuffle2_imm parse but it has no invocations of the instruction.
* Rename v8x16.shuffle1 and x8v16.shuffle2_imm to v8x16.swizzle and v8x16.shuffle_imm.
* Update SIMD operands.
* Swizzle is just a binary operator.
* Shuffle is named "v8x16.shuffle".
* Add 4 new opcodes for load_splat.
* Remove legacy 0xfd 0x03 opcode for shuffle.
* Test all four load splats.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
| |
It takes two u32 immediates: the branch depth and an exception index. The
stack signature is `[expect_ref] -> [except_ref]`, so the `except_ref`
can be tested easily against multiple exception types.
|
| |
|
|
|
|
| |
It is no longer part of the exception proposal.
|
|
|
| |
Carrying over renames from WebAssembly/bulk-memory-operations#46
|
|
|
|
|
|
|
|
| |
This huge PR does all the renaming as described in issue #933. It also
updates to the latest testsuite so the new names are used.
The old names of the MVP instructions are still supported for
convenience (though we should remove those too at some point), but the
old simd and atomic instruction names are no longer supported.
|
|
|
|
|
|
| |
The `BindingHash` object is used to map from a name to an Index, and to
detect multiply-defined names. Since the locals and params use the same
Index space and namespace, they should always have been using the same
`BindingHash`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Allow for names in data/elem segments:
```
(data $foo (i32.const 0) "abcdef")
```
* These names can be referenced by the memory/table instructions that
operate on segments:
```
memory.drop $foo
```
* Fix running wasm-objdump with bulk-memory instructions
* Check for valid data/elem segments in validation
* Check that bulk-memory is enabled when parsing text
Partial fix for #928; still needs interpreter checks too.
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit starts to add support in wabt's various tools for the
upcoming [bulk memory proposal][1]. This is based off the current
proposal's overview, although these may get tweaked over time!
This is also the first time I've significantly contributed to wabt, and
what I thought would be a relatively simple addition ended up being much
larger than I imagined! I didn't add many negative tests yet but if more
tests are desired please let me know!
[1]: https://github.com/webassembly/bulk-memory-operations
|
|
|
|
|
|
|
|
|
|
|
|
| |
This doesn't do any of the real work yet, it just adds the
ReturnCall/ReturnCallIndirect Expr and Opcode types, and the
"--enable-tail-call" flag.
Still TODO:
* Parse the opcodes in binary-reader.cc
* Validate the opcodes in validator.cc and type-checker.cc
* Implement the opcodes in interp.cc
* Write standard wabt tests, and enable the spec proposal tests too
|
|
|
|
|
|
| |
Also clean up `LocalTypes` a bit, so we can ensure that `decls_` never
has a count of 0.
Fixes issue #826. Thanks for finding @opticaliqlusion!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since the binary format stores locals as Type+Count pairs, it is easy to
generate a function with a huge number of locals. The text format has
no way to compress this, so the resulting file will be huge.
However, if the binary file has an error, it would be useful to be able
to catch it without allocating a huge number of locals.
To do so, we store all locals as Type+Count pairs in the IR as well, and
provide accessor functions for getting the number of local types, the
type of a particular local index, etc.
This fixes issue #819.
|
|
|
|
| |
I also fixed some for/if to use braces if I noticed it. This is a
non-functional change.
|
| |
|
|
|
|
|
| |
Including:
1. All necessary code for SIMD lanes accessing.
2. i8x16.extract_lane_s implementation.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Implemented:
* Parsing `try`, `if_except`, `throw`, `rethrow`
* Validation
* Binary and text output
Still missing:
* `except_ref` for locals
* Interpreter implementation
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add `wasm2c`, a new tool that reads a `.wasm` file and generates a C
source file and its accompanying header file. The C output currently
only supports gcc/clang compilers, since it uses builtins for some
functionality.
The resulting C code is not standalone; there are runtime functions that
must be provided, as well as pointers to all imports.
The C runtime symbols that must be provided are as follows:
* `void wasm_rt_trap(wasm_rt_trap_t code)`:
Called when the WebAssembly code traps. This function must not return.
* `u32 wasm_rt_register_func_type(u32 param_count, u32 result_count, ...)`:
Register a function type with the given signature. This function must
check whether this signature has already been registered and return
the original index.
* `void wasm_rt_allocate_memory(wasm_rt_memory_t*, u32 initial, u32 max)`:
Allocate the memory buffer for the given memory object, given the
number of pages. The memory must be zeroed before returning.
* `u32 wasm_rt_grow_memory(wasm_rt_memory_t*, u32 delta)`:
Grow memory by the given number of pages. If allocation fails, or the
new pages size is larger than the maximum, return -1. Otherwise return
the previous number of pages. The newly allocated memory must be
zeroed.
* `void wasm_rt_allocate_table(wasm_rt_table_t*, u32 initial, u32 max)`:
Allocate the buffer for the given table object. The buffer must be
zeroed before returning.
* `u32 wasm_rt_call_stack_depth`:
A symbol that tracks the current call stack depth. If this value
exceeds `WASM_RT_MAX_CALL_STACK_DEPTH` then a trap occurs. This value
defaults to 500, but can redefined.
An example implementation can be found in `spec-wasm2c-prefix.c`.
All functionality from the WebAssembly MVP is supported, and the
generated code passes all of the core spec tests. There is a new test
tool called `run-spec-wasm2c.py` which runs the following:
* `wast2json` to convert the spec test to json and wasm files
* `wasm2c` to convert the wasm to C source and headers
* a C compiler (default `cc`) to compile and link all C source files,
including a C test runner (`spec-wasm2c-prefix.c`)
* Finally, the resulting executable to produce output
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The `(import...` syntax doesn't allow for inline exports, but the wat
writer assumed that all exports would be written inline, so the exports
would be omitted.
This CL fixes it by writing the exports normally:
```
(module
(import "foo" "bar" (func))
(export "baz" (func 0))
)
```
It is also possible to fix this by writing the imports inline, but this
is not currently supported by the .wat writer:
```
(module
(func (export "baz") (import "foo" "bar"))
)
```
|
|
|
|
|
| |
This is a sequential PR of Wabt simd v128.const instruction initial PR (096f7ab84749b5725a5780671111434c34cc17ea)
The PR implement wasm interp, objdump and validate functions for v128.const.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is an initial PR for Wabt simd support.
This PR only implement the v128.const instruction.
It will construct a simd 128-bits const.
The expected wat format is:
v128.const i32 0x00000000 0x11111111 0x22222222 0x33333333
For simplify, this PR only implement the wat2wasm and wasm2wat functions.
The following PRs will implement the full functions in Wabt.
such as: Interp, objdump, logging, etc....
|
| |
|