| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
| |
This pull request implements EHv4. Binary is mostly untested until
interp is working.
|
|
|
|
| |
This adds support in the binary/text parsers and writers,
the validator and interpreter, and objdump (but not wasm2c).
|
|
|
|
|
| |
The memory64 `table.wast` test has started to depend on
function-references and gc (which WABT doesn't support yet), so vendor
an older version of the test.
|
|
|
|
|
| |
See https://github.com/WebAssembly/memory64/issues/51
Includes workaround for #2422
|
|
|
|
| |
Reflects change in the multi-memory proposal:
https://github.com/WebAssembly/multi-memory/pull/29
|
|
|
|
|
|
| |
This continues the work from #1783 and reduces special handling of elem
exprs, by treating them the same as other const expressions (init
expressions).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* memory64: when enabled, offset range check is at validation-time
Before memory64, the "offset" in a load/store expression was
a u32, and we enforced this in the WastParser and BinaryReader.
After memory64, the "offset" becomes a u64 syntactically, and the
validator checks that it's <= UINT32_MAX for i32 memories.
We hadn't been correctly allowing these very large offsets
in the text format (even when memory64 was enabled and the memory
was i64).
(This change also eliminates the "memories" member in the
BinaryReader. The BinaryReader no longer needs to keep track
of the memories and their types to check well-formedness.)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When both the multi-memory and memory64 features are enabled it's
possible for memory.copy to copy between two memories of different
types. In this case, the memory64 proposal specifies that the src and
dst arguments should correspond to the types of the memory they are
accessing, and the size argument should correspond to the "minimum" of
the two memory types [1]. That is, the size should be an i32 if either
of the memories has type i32 and it should be i64 if both of the
memories have type i64.
The existing code just expects all three arguments to match the type of
the source memory which works whenever the source and destination
memories have the same type. This change adjusts that logic to agree
with the memory64 proposal in the cases where the two memories have
differing types.
[1]
https://github.com/WebAssembly/memory64/blob/5bfb70d9888b96a2f3d6412ed3599b91364da610/proposals/memory64/Overview.md?plain=1#L211
|
|
|
| |
This makes things easier for users and packagers of libwabt.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
The validation was overly strict for ref.func index uses. In the spec,
the ref index just needs to appear in
"the set of function indices occurring in the module, except in its
functions or start function."
which includes uses in the global and export sections.
Fixes issue #1893
|
|
|
|
|
|
|
|
|
|
| |
For text validation, this means the error is always correctly reported on
the final expression in the function.
For binary validation, this means that we report the byte after the last
instruction in the function as the failure location. This is in line
with other binary validation reports. For example, for `type mismatch
in i32.add` we report the validation error at the byte *after* the add
instruction.
|
|
|
|
|
|
|
|
|
|
| |
The primary changes here are to the interpreter and how it handles
initializer expressions. With this change we model these are normal
function that we run during module initialization.
I imagine we could optimize this further by creating one long function
and encoding the `global.set`/`memory.init`/`table.init` into the
function itself, but this change seems like a good first step to make
the current tests pass.
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
In #1768, I renamed the parameter to `OnFuncRefExpr` without realizing
that there are two distinct methods in the codebase with this name. On
is the `BinaryReader` callback which takes a function index and one is
the `TypeChecker` callback which takes a function *type* (a type index).
|
|
|
|
|
|
|
|
|
|
|
|
| |
(#1783)
Previously we has special cases for initializer expressions (constant
expressions). This change paves the way for adding support for
extended constant expressions that support a wider range of
instructions.
This change removes twice as many lines as it adds which shows that
this simplification is probably worthwhile even without the pending
extensions.
|
|
|
|
|
|
|
|
|
|
| |
The SharedValidator was assuming it could keep a pointer to the incoming
location of each expression longer than the scope of the function.
This assumption holds true for one of the users of SharedValidator
(src/validator.cc) but I'm working on change that adds better location
tracking to the other one in (src/interp/binary-reader-interp.cc) and in
that case its easier to pass temporary locations into the
SharedValidator that don't outlive the call.
|
| |
|
|
|
|
| |
blocks. (#1695)
|
|
|
|
| |
supported call_ref (#1691)
|
|
|
| |
`unwind` was removed. See WebAssembly/exception-handling#156.
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
The reference-types proposal adds a select instruction with a type
vector, but any number greater than 1 is invalid.
Fixes #1577.
|
|
|
|
| |
Fixes: #1249
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
| |
See https://github.com/WebAssembly/reference-types/issues/99.
This change also updates the testsuite, so the spec tests pass too.
In addition, the behavior of `br_table` is no longer different from MVP,
and has a text to confirm this. That is now fixed in `type-checker.cc`
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.
|
|
|
|
|
|
|
|
|
|
| |
The following formats are supported:
* (type (array i32))
* (type (array (field i32)))
* (type (array (field (mut i32))))
This PR adds support for reading/writing binary and text, but no
interpreter support yet.
|
|
|
|
|
|
|
|
|
|
|
| |
This allows the following field formats:
* `(struct (field $name i32))`
* `(struct (field $name (mut i32)))`
* `(struct (field i32))`
* `(struct (field (mut i32)))`
* `(struct (mut i32))`
* `(struct i32)`
|
|
|
|
|
|
|
| |
Validation should only happen in ValidateModule, BinaryReader should
only check whether the binary is malformed.
This change also fixes a few places in BinaryReaderIR where an index is
assumed to be valid.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 major change to the error output is showing the max value instead of
max value - 1. It's a bit weird to see "out of range: 0 (max 0)" but
seeing 4294967295 is strictly worse.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is similar to the way Opcode is structured, which allows us to hang
member functions off of the enumeration.
The primary motivator for this change is the GC proposal (and the
function-references proposal) where a Type can be parameterized:
(type $T (struct ...))
(func
(local (ref $T)
...
)
In this case the type is ref, with a parameter of the type index. Making
Type a class will make it easier to store this additional information.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
| |
Since the validator tries to print as many errors as possible, it
shouldn't stop when the index is invalid (since this may produce future
errors). Instead it uses a default value.
This is encoded in a new function called CheckIndexWithValue, which
either accesses the vector, or uses a default value.
|
|
The TypeChecker was already shared, but the rest of the other validation
logic was duplicated. This change creates a SharedValidator which is
used by both the Validator and the BinaryReaderInterp classes.
The validator is structured similarly to TypeChecker as a collection of
functions. It's assumed that the functions will be called in the same
order as sections occur in the binary format. The IR valiator does this
too, even though it's possible to validate components out-of-order in
that case.
This change also splits Module validation and Script validation into two
different classes. It should have been written this way in the first
place, and it's nice to do as part of this change since the module
validator logic is mostly moved into the SharedValidator anyway.
Next steps:
* Remove all validation from BinaryReader and move it into the
SharedValidator.
* Move the TypeChecker into the SharedValidator (maybe not necessary)
* Ensure that validation occurs before creating IR from binary (use
SharedValidator in BinaryReaderIR? or maybe create
BinaryReaderValidator passthru that both BinaryReaderIR and
BinaryReaderInterp use?)
* Rename Validator -> IRValidator, SharedValidator -> Validator
|