summaryrefslogtreecommitdiff
path: root/src/ir.cc
Commit message (Collapse)AuthorAgeFilesLines
* binary/wat: Implement EHv4 (#2470)Soni L.2024-11-201-0/+2
| | | | This pull request implements EHv4. Binary is mostly untested until interp is working.
* Update testsuite (#2054)Sam Clegg2022-11-131-5/+4
| | | | | | | | | | | | | | | 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
* Move headers to include/wabt/ (#1998)Alex Reinking2022-09-281-2/+2
| | | This makes things easier for users and packagers of libwabt.
* Track locations of Vars in BinaryReaderIR and BinaryReaderInterp (#1963)Keith Winstein2022-08-151-2/+4
| | | | - Rebase test output to match new location tracking on Vars - Eliminate single-argument Var() constructor.
* wast2json: write binary modules verbatim (#1932)Ben Smith2022-06-031-2/+7
| | | | | | | | | | | | | | 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.
* Add initial support for code metadata (#1840)Yuri Iozzelli2022-02-251-0/+1
| | | | | | | | | | | | | | | | | | | | | 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)
* Use C++17 string_view (#1826)Sam Clegg2022-02-111-4/+4
| | | | | Now that we have C++17 we don't need our own string_view class anymore. Depends on #1825
* Use C++17 pair destructuring for loops (#1827)Sam Clegg2022-02-111-4/+3
|
* Clang-format codebase (#1684)Heejin Ahn2021-12-201-64/+63
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Delay validation of elem init expressions until validation time (#1730)Sam Clegg2021-10-141-5/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Begin support for typed function references proposal: added the flag and ↵Dmitry Bezhetskov2021-07-251-0/+1
| | | | supported call_ref (#1691)
* [EH] Replace event with tag (#1678)Heejin Ahn2021-06-221-22/+22
| | | | | | | | | | | 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
* [simd] Implement store lane (#1647)Ng Zhi An2021-03-221-0/+1
|
* [simd] Implement load lane (#1646)Ng Zhi An2021-03-221-0/+1
| | | | | | | | | 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.
* [simd] Implement v128.load{32,64}_zero (#1644)Ng Zhi An2021-03-171-0/+1
| | | | This requires a new ir type, and the relevant implementation of virtual mthods in the various visitors.
* Update exception handling support to current proposal (#1596)Asumu Takikawa2021-02-101-1/+0
| | | | | | | | | | 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.
* Fix assert when function has struct type (#1498)Ben Smith2020-07-251-1/+1
| | | | | | | 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.
* Reference types changes to remove subtyping (#1407)Ben Smith2020-05-281-1/+1
| | | | | | | | 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`
* Add support for atomic.fence from the threads proposal (#1231)Andy Wingo2020-04-201-0/+1
| | | | | 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.
* Refactor Const struct's internal storage (#1356)Ben Smith2020-03-161-15/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Initial pass parsing/reading struct (#1352)Ben Smith2020-03-091-2/+4
| | | | | | | | | | | | | | | | | | 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
* Update testsuite (w/ reference-types changes) (#1351)Ben Smith2020-02-281-4/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Add TypeEntry, base class for type section entries (#1349)Ben Smith2020-02-281-14/+13
| | | | | | | | | | | 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
* Segment flags should be MVP-compat when possible (#1286)Ben Smith2020-01-081-0/+48
| | | | This should fix #1280, #1268, #1269.
* reference-types: add table.fill instruction (#1252)Sam Clegg2019-11-251-0/+1
|
* Rename v128_bits to simply vec128 since this is stored natively (#1207)Sam Clegg2019-11-111-1/+1
| | | | | | | 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.
* Initial implementation of reftype proposal in the interpreter. (#1206)Sam Clegg2019-11-071-0/+1
| | | | - Implement ref.func everywhere. - Implement table.get and table.set in the interpreter.
* Add support for v8x16.swizzle and the load_splats. (#1116)nlewycky2019-07-191-0/+1
| | | | | | | | | | | | | | | | | | | * 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 (#938)Alex Crichton2019-02-141-0/+6
| | | | | | | | | | | | | | | | | | | | * 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.
* Add br_on_exn instruction (#1016)Ben Smith2019-02-131-0/+1
| | | | | | 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.
* Rename exception -> event (#1013)Ben Smith2019-02-111-22/+22
|
* Remove the `if_except` instruction (#1009)Ben Smith2019-02-101-1/+0
| | | | It is no longer part of the exception proposal.
* Rename {memory,table}.drop to {data,elem}.drop (#1000)Alex Crichton2019-01-301-2/+2
| | | Carrying over renames from WebAssembly/bulk-memory-operations#46
* The great renaming (#985)Ben Smith2018-12-191-7/+7
| | | | | | | | 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.
* Combine param_binding and local_binding in IR (#969)Ben Smith2018-12-041-13/+1
| | | | | | 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`.
* Add more bulk memory tests; use vars for segments (#930)Ben Smith2018-10-151-2/+44
| | | | | | | | | | | | | | | | | | | | * 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.
* Add bulk memory opcode definitions (#927)Alex Crichton2018-10-121-2/+9
| | | | | | | | | | | | 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
* Tailcall (#918)Ben Smith2018-10-011-0/+2
| | | | | | | | | | | | 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
* Don't allow a local decl count of 0 (#827)Ben Smith2018-04-101-5/+5
| | | | | | 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!
* Store local types as Type+Count pairs (#820)Ben Smith2018-03-281-2/+41
| | | | | | | | | | | | | | 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.
* Run clang-format over all the files (#814)Ben Smith2018-03-161-11/+5
| | | | I also fixed some for/if to use braces if I noticed it. This is a non-functional change.
* SIMD v8x16.shuffle implementation. (#811)lizhengxing2018-03-151-0/+1
|
* Simd i8x16.extract_lane_s instruction implementation. (#802)lizhengxing2018-03-131-0/+1
| | | | | Including: 1. All necessary code for SIMD lanes accessing. 2. i8x16.extract_lane_s implementation.
* WIP on support for level1 exception spec (#773)Ben Smith2018-03-021-2/+3
| | | | | | | | | | | | Implemented: * Parsing `try`, `if_except`, `throw`, `rethrow` * Validation * Binary and text output Still missing: * `except_ref` for locals * Interpreter implementation
* SIMD v128.bitselect instruction implementation. (#759)lizhengxing2018-02-191-0/+1
|
* Add wasm2c tool (#710)Ben Smith2018-01-081-0/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* Fix bug when writing inline exports for import (#700)Ben Smith2017-12-191-0/+22
| | | | | | | | | | | | | | | | | | | | | | | 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")) ) ```
* Wabt simd v128.const instruction PR (Part 2): (#702)lizhengxing2017-12-191-2/+1
| | | | | 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.
* Wabt simd v128.const instruction initial PR: (#677)lizhengxing2017-12-151-0/+5
| | | | | | | | | | | | | 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....
* [cleanup] Always use braces with if (#691)Ben Smith2017-12-091-21/+42
|