summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-binary.cpp
Commit message (Collapse)AuthorAgeFilesLines
* [NFC] Enforce use of `Type::` on type names (#2434)Thomas Lively2020-01-071-75/+76
|
* Add support for reference types proposal (#2451)Heejin Ahn2019-12-301-15/+68
| | | | | | | | | | | | This adds support for the reference type proposal. This includes support for all reference types (`anyref`, `funcref`(=`anyfunc`), and `nullref`) and four new instructions: `ref.null`, `ref.is_null`, `ref.func`, and new typed `select`. This also adds subtype relationship support between reference types. This does not include table instructions yet. This also does not include wasm2js support. Fixes #2444 and fixes #2447.
* Move Type-related functions into Type class (NFC) (#2556)Heejin Ahn2019-12-291-2/+2
| | | | | | | | | | | Several type-related functions currently exist outside of `Type` class and thus in the `wasm`, effectively global, namespace. This moves these functions into `Type` class, making them either member functions or static functions. Also this renames `getSize` to `getByteSize` to make it not to be confused with `size`, which returns the number of types in multiple types. This also reorders the order of functions in `wasm-type.cpp` to match that of `wasm-type.h`.
* DWARF debug line updating (#2545)Alon Zakai2019-12-201-15/+65
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | With this, we can update DWARF debug line info properly as we write a new binary. To do that we track binary locations as we write. Each instruction is mapped to the location it is written to. We must also adjust them as we move code around because of LEB optimization (we emit a function or a section with a 5-byte LEB placeholder, the maximal size; later we shrink it which is almost always possible). writeDWARFSections() now takes a second param, the new locations of instructions. It then maps debug line info from the original offsets in the binary to the new offsets in the binary being written. The core logic for updating the debug line section is in wasm-debug.cpp. It basically tracks state machine logic both to read the existing debug lines and to emit the new ones. I couldn't find a way to reuse LLVM code for this, but reading LLVM's code was very useful here. A final tricky thing we need to do is to update the DWARF section's internal size annotation. The LLVM YAML writing code doesn't do that for us. Luckily it's pretty easy, in fixEmittedSection we just update the first 4 bytes in place to have the section size, after we've emitted it and know the size. This ignores debug lines with a 0 in the line, col, or addr, see WebAssembly/debugging#9 (comment) This ignores debug line offsets into the middle of instructions, which LLVM sometimes emits for some reason, see WebAssembly/debugging#9 (comment) Handling that would likely at least double our memory usage, which is unfortunate - we are run in an LTO manner, where the entire app's DWARF is present, and it may be massive. I think we should see if such odd offsets are a bug in LLVM, and if we can fix or prevent that. This does not emit "special" opcodes for debug lines. Those are purely an optimization, which I wanted to leave for later. (Even without them we decrease the size quite a lot, btw, as many lines have 0s in them...) This adds some testing that shows we can load and save fib2.c and fannkuch.cpp properly. The latter includes more than one function and has nontrivial code. To actually emit correct offsets a few minor fixes are done here: * Fix the code section location tracking during reading - the correct offset we care about is the body of the code section, not including the section declaration and size. * Fix wasm-stack debug line emitting. We need to update in BinaryInstWriter::visit(), that is, right before writing bytes for the instruction. That differs from * BinaryenIRWriter::visit which is a recursive function that also calls the children - so the offset there would be of the first child. For some reason that is correct with source maps, I don't understand why, but it's wrong for DWARF... * Print code section offsets in hex, to match other tools. Remove DWARFUpdate pass, which was useful for testing temporarily, but doesn't make sense now (it just updates without writing a binary). cc @yurydelendik
* Binary format code section offset tracking (#2515)Alon Zakai2019-12-191-3/+48
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* SIMD {i8x16,i16x8}.avgr_u instructions (#2539)Thomas Lively2019-12-181-0/+8
| | | As specified in https://github.com/WebAssembly/simd/pull/126.
* Make local.tee's type its local's type (#2511)Heejin Ahn2019-12-121-2/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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`.
* Remove FunctionType (#2510)Thomas Lively2019-12-111-108/+40
| | | | | | | | | | | | | | | | | 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.
* Add string parameter to WASM_UNREACHABLE (#2499)Sam Clegg2019-12-051-7/+8
| | | | | This works more like llvm's unreachable handler in that is preserves information even in release builds.
* Convert to using DEBUG macros (#2497)Sam Clegg2019-12-041-428/+152
| | | | | | This means that debugging/tracing can now be enabled and controlled centrally without managing and passing state around the codebase.
* Refactor and optimize binary writing type collection (#2478)Alon Zakai2019-11-261-45/+29
| | | | | | | | | | 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.
* Remove FunctionType from Event (#2466)Thomas Lively2019-11-251-51/+105
| | | | | | | | | This is the start of a larger refactoring to remove FunctionType entirely and store types and signatures directly on the entities that use them. This PR updates BrOnExn and Events to remove their use of FunctionType and makes the BinaryWriter traverse the module and collect types rather than using the global FunctionType list. While we are collecting types, we also sort them by frequency as an optimization. Remaining uses of FunctionType in Function, CallIndirect, and parsing will be removed in a future PR.
* Multivalue type creation and inspection (#2459)Thomas Lively2019-11-221-3/+3
| | | | | | | | | | | | | Adds the ability to create multivalue types from vectors of concrete value types. All types are transparently interned, so their representation is still a single uint32_t. Types can be extracted into vectors of their component parts, and all the single value types expand into vectors containing themselves. Multivalue types are not yet used in the IR, but their creation and inspection functionality is exposed and tested in the C and JS APIs. Also makes common type predicates methods of Type and improves the ergonomics of type printing.
* Add i32x4.dot_i16x8_s (#2420)Thomas Lively2019-11-041-0/+4
| | | | | This experimental instruction is specified in https://github.com/WebAssembly/simd/pull/127 and is being implemented to enable further investigation of its performance impact.
* Add SIMD integer min and max instructions (#2416)Thomas Lively2019-11-011-0/+48
| | | As proposed in https://github.com/WebAssembly/simd/pull/27.
* v8x16.swizzle (#2368)Thomas Lively2019-10-031-0/+4
| | | | As specified at https://github.com/WebAssembly/simd/blob/master/proposals/simd/SIMD.md#swizzling-using-variable-indices.
* SIMD load and extend instructions (#2353)Thomas Lively2019-09-241-0/+24
| | | | | | Adds support for the new load and extend instructions. Also updates from C++11 to C++17 in order to use generic lambdas in the interpreter implementation.
* v128.andnot instruction (#2355)Thomas Lively2019-09-241-0/+4
| | | | | As specified at https://github.com/WebAssembly/simd/pull/102. Also fixes bugs in the JS API for other SIMD bitwise operators.
* vNxM.load_splat instructions (#2350)Thomas Lively2019-09-231-18/+43
| | | | | | | Introduces a new instruction class, `SIMDLoad`. Implements encoding, decoding, parsing, printing, and interpretation of the load and splat instructions, including in the C and JS APIs. `v128.load` remains in the `Load` instruction class for now because the interpreter code expects a `Load` to be able to load any memory value type.
* SIMD narrowing and widening operations (#2341)Thomas Lively2019-09-141-0/+48
|
* QFMA/QFMS instructions (#2328)Thomas Lively2019-09-031-9/+29
| | | | | | | | | Renames the SIMDBitselect class to SIMDTernary and adds the new {f32x4,f64x2}.qfm{a,s} ternary instructions. Because the SIMDBitselect class is no more, this is a backwards-incompatible change to the C interface. The new instructions are not yet used in the fuzzer because they are not yet implemented in V8. The corresponding LLVM commit is https://reviews.llvm.org/rL370556.
* Add atomic.fence instruction (#2307)Heejin Ahn2019-08-271-0/+17
| | | | | | | This adds `atomic.fence` instruction: https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md#fence-operator This also fix bugs in `atomic.wait` and `atomic.notify` instructions in binaryen.js and adds tests for them.
* Add initial support for anyref as an opaque type (#2294)Jay Phelps2019-08-201-0/+6
| | | | | | | | | | | | | Another round of trying to push upstream things from my fork. This PR only adds support for anyref itself as an opaque type. It does NOT implement the full [reference types proposal](https://github.com/WebAssembly/reference-types/blob/master/proposals/reference-types/Overview.md)--so no table.get/set/grow/etc or ref.null, ref.func, etc. Figured it was easier to review and merge as we go, especially if I did something fundamentally wrong. *** I did put it under the `--enable-reference-types` flag as I imagine that even though this PR doesn't complete the full feature set, it probably is the right home. Lmk if not. I'll also be adding a few github comments to places I want to point out/question.
* Add basic exception handling support (#2282)Heejin Ahn2019-08-131-2/+96
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This adds basic support for exception handling instructions, according to the spec: https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md This PR includes support for: - Binary reading/writing - Wast reading/writing - Stack IR - Validation - binaryen.js + C API - Few IR routines: branch-utils, type-updating, etc - Few passes: just enough to make `wasm-opt -O` pass - Tests This PR does not include support for many optimization passes, fuzzer, or interpreter. They will be follow-up PRs. Try-catch construct is modeled in Binaryen IR in a similar manner to that of if-else: each of try body and catch body will contain a block, which can be omitted if there is only a single instruction. This block will not be emitted in wast or binary, as in if-else. As in if-else, `class Try` contains two expressions each for try body and catch body, and `catch` is not modeled as an instruction. `exnref` value pushed by `catch` is get by `pop` instruction. `br_on_exn` is special: it returns different types of values when taken and not taken. We make `exnref`, the type `br_on_exn` pushes if not taken, as `br_on_exn`'s type.
* Asyncify: whitelist and blacklist support (#2264)Alon Zakai2019-07-261-4/+4
| | | | | | | | | The blacklist means "functions here are to be ignored and not instrumented, we can assume they never unwind." The whitelist means "only these functions, and no others, can unwind." I had hoped such lists would not be necessary, since Asyncify's overhead is much smaller than the old Asyncify and Emterpreter, but as projects have noticed, the overhead to size and speed is still significant. The lists give power users a way to reduce any unnecessary overhead. A slightly tricky thing is escaping of names: we escape names from the names section (see #2261 #1646). The lists arrive in human-readable format, so we escape them before comparing to the internal escaped names. To enable that I refactored wasm-binary a little bit to provide the escaping logic, cc @yurydelendik If both lists are specified, an error is shown (since that is meaningless). If a name appears in a list that is not in the module, we show a warning, which will hopefully help people debug typos etc. I had hoped to make this an error, but the problem is that due to inlining etc. a single list will not always work for both unoptimized and optimized builds (a function may vanish when optimizing, due to duplicate function elimination or inlining). Fixes #2218.
* Refactor stack IR / binary writer (NFC) (#2250)Heejin Ahn2019-07-231-3/+3
| | | | | | | | | | | | | | | | Previously `StackWriter` and its subclasses had routines for all three modes (`Binaryen2Binary`, `Binaryen2Stack`, and `Stack2Binary`) within a single class. This splits routines for each in a separate class and also factors out binary writing into a separate class (`BinaryInstWriter`) so other classes can make use of it. The new classes are: - `BinaryInstWriter`: Binary instruction writer. Only responsible for emitting binary contents and no other logic - `BinaryenIRWriter`: Converts binaryen IR into something else - `BinaryenIRToBinaryWriter`: Writes binaryen IR to binary - `StackIRGenerator`: Converts binaryen IR to stack IR - `StackIRToBinaryWriter`: Writes stack IR to binary
* Rename except_ref type to exnref (#2224)Heejin Ahn2019-07-141-2/+2
| | | | In WebAssembly/exception-handling#79 we agreed to rename `except_ref` type to `exnref`.
* Initial tail call implementation (#2197)Thomas Lively2019-07-031-0/+18
| | | | | | | | | | | Including parsing, printing, assembling, disassembling. TODO: - interpreting - effects - finalization and typing - fuzzing - JS/C API
* Clean up loose ends in feature handling (#2203)Thomas Lively2019-07-031-7/+9
| | | | | Fix and test mutable globals support, replace string literals with constants, and add a pass to emit the target features section.
* Fix event section order (#2202)Heejin Ahn2019-07-021-1/+1
| | | | | | The event section should be between the global section and the export section, if present. Here tests are missing, but we don't have a very good way of testing validity of binary anyway. We are planning to add d8 tests in a separate PR.
* Make feature section errors into warnings (#2175)Alon Zakai2019-06-181-14/+18
| | | | Otherwise there is no way to view a wasm object file in binaryen.
* Use BinaryIndexes instead of copies in BinaryWriter (NFC) (#2161)Heejin Ahn2019-06-041-20/+10
|
* Add event section (#2151)Heejin Ahn2019-05-311-0/+95
| | | | | | | | | | | | | | | | | | This adds support for the event and the event section, as specified in https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md#changes-to-the-binary-model. Wasm events are features that suspend the current execution and transfer the control flow to a corresponding handler. Currently the only supported event kind is exceptions. For events, this includes support for - Binary file reading/writing - Wast file reading/writing - Binaryen.js API - Fuzzer - Validation - Metadce - Passes: metrics, minify-imports-and-exports, remove-unused-module-elements
* Reflect instruction renaming in code (#2128)Heejin Ahn2019-05-211-33/+33
| | | | | | | | | | | | | | | | | | | | | | | | | | | | - Reflected new renamed instruction names in code and tests: - `get_local` -> `local.get` - `set_local` -> `local.set` - `tee_local` -> `local.tee` - `get_global` -> `global.get` - `set_global` -> `global.set` - `current_memory` -> `memory.size` - `grow_memory` -> `memory.grow` - Removed APIs related to old instruction names in Binaryen.js and added APIs with new names if they are missing. - Renamed `typedef SortedVector LocalSet` to `SetsOfLocals` to prevent name clashes. - Resolved several TODO renaming items in wasm-binary.h: - `TableSwitch` -> `BrTable` - `I32ConvertI64` -> `I32WrapI64` - `I64STruncI32` -> `I64SExtendI32` - `I64UTruncI32` -> `I64UExtendI32` - `F32ConvertF64` -> `F32DemoteI64` - `F64ConvertF32` -> `F64PromoteF32` - Renamed `BinaryenGetFeatures` and `BinaryenSetFeatures` to `BinaryenModuleGetFeatures` and `BinaryenModuleSetFeatures` for consistency.
* Fix misc. things for globals (#2119)Heejin Ahn2019-05-171-2/+1
|
* Delete WasmBinaryBuilder::mappedGlobals (NFC) (#2098)Heejin Ahn2019-05-121-31/+14
| | | | | | It doesn't seem to be used anywhere and I don't know why the implementation for `WasmBinaryBuilder::getGlobalName` and `WasmBinaryBuilder::getFunctionIndexName` are different. Renamed `getFunctionIndexName` to `getFunctionName` for consistency.
* Add except_ref type (#2081)Heejin Ahn2019-05-071-0/+2
| | | | This adds except_ref type, which is a part of the exception handling proposal.
* Add exception handling feature (#2083)Heejin Ahn2019-05-031-1/+3
| | | This only adds the feature and its flag and not the instructions yet.
* clang-tidy braces changes (#2075)Alon Zakai2019-05-011-217/+434
| | | Applies the changes in #2065, and temprarily disables the hook since it's too slow to run on a change this large. We should re-enable it in a later commit.
* Apply format changes from #2048 (#2059)Alon Zakai2019-04-261-694/+1905
| | | Mass change to apply clang-format to everything. We are applying this in a PR by me so the (git) blame is all mine ;) but @aheejin did all the work to get clang-format set up and all the manual work to tidy up some things to make the output nicer in #2048
* Finish bulk memory support (#2030)Thomas Lively2019-04-221-1/+4
| | | | | | | Implement interpretation of remaining bulk memory ops, add bulk memory spec tests with light modifications, fix bugs preventing the fuzzer from running correctly with bulk memory, and fix bugs found by the fuzzer.
* Reland emitting of DataCount section (#2027)Thomas Lively2019-04-181-8/+3
| | | | | | This reverts commit cb2d63586c08a3dd194d2b733ceb3f5051c081f8. The issues with feature validation were mostly resolved in #1993, and this PR finishes the job by adding feature flags to wasm-as to avoid emitting the DataCount section when bulk-memory is not enabled.
* Do not emit the DataCount section (#2010)Thomas Lively2019-04-151-3/+8
| | | | | Its presence was causing validation errors in the Emscripten test suite. This should be reverted once the default feature set is no longer All.
* DataCount section (#2006)Thomas Lively2019-04-151-0/+24
| | | | | | | | * DataCount section Read the DataCount section and verify that it agrees with the data section. Also emit the DataCount section when bulk-memory is enabled and there are a nonzero number of segments. Factor out some shared unit test code.
* Move features from passOptions to Module (#2001)Thomas Lively2019-04-121-2/+84
| | | | | This allows us to emit a (potentially modified) target features section and conditionally emit other sections such as the DataCount section based on the presence of features.
* Better memory fuzzing (#1987)Alon Zakai2019-04-081-1/+1
| | | | | | | | Hash the contents of all of memory and log that out in random places in the fuzzer, so we are more sensitive there and can catch memory bugs. Fix UB that was uncovered by this in the binary writing code - if a segment is empty, we should not look at &vector[0], and instead use vector.data(). Add Builder::addExport convenience method.
* Move segment merging to fit web limits into its own pass (#1980)Thomas Lively2019-04-081-100/+8
| | | | | | It was previously part of writing a binary, but changing the number of segments at such a late stage would not work in the presence of bulk memory's datacount section. Also updates the memory packing pass to respect the web's limits on the number of data segments.
* Passive segments (#1976)Thomas Lively2019-04-051-19/+48
| | | | | Adds support for the bulk memory proposal's passive segments. Uses a new (data passive ...) s-expression syntax to mark sections as passive.
* Use target features section in wasm-opt (#1967)Thomas Lively2019-04-031-1/+1
| | | | | | | If the user does not supply features explicitly on the command line, read and use the features in the target features section for validation and passes. If the user does supply features explicitly, error if they are not a superset of the features marked as used in the target features section and the user does not explicitly handle this.
* Rename atomic wait/notify instructions (#1972)Heejin Ahn2019-03-301-7/+7
| | | | | | | | This renames the following: - `i32.wait` -> `i32.atomic.wait` - `i64.wait` -> `i64.atomic.wait` - `wake` -> `atomic.notify` to match the spec.