summaryrefslogtreecommitdiff
path: root/src/wasm
Commit message (Collapse)AuthorAgeFilesLines
* DWARF support for multiple line tables (#2557)Alon Zakai2020-01-091-23/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Multiple tables appear to be emitted when linking files together. This fixes our support for that, which did not update their size properly. This required patching the YAML emitting code from LLVM in order to measure the size and then emit it, as that code is apparently not designed to handle changes in line table contents. Other minor fixes: * Set the flags for our dwarfdump command to emit the same as llvm-dwarfdump does with -v -all. * Add support for a few more opcodes, set_discriminator, set_basic_block, fixed_advance_pc, set_isa. * Handle a compile unit without abbreviations in the YAML code (again, apparently not something this LLVM code was intended to do). * Handle a compile unit with zero entries in the YAML code (ditto). * Properly set the AddressSize - we use the DWARFContext in a different way than LLVM expects, apparently. With this the emscripten test suite passes with -gforce_dwarf without crashing. My overall impression so from the the YAML code is that it probably isn't a long-term solution for us. Perhaps it may end up being scaffolding, that is, we can replace it with our own code eventually that is based on it, and remove most of the LLVM code. Before deciding that we should get everything working first, and this seems like the quickest path there.
* Remove implicit conversion operators from Type (#2577)Thomas Lively2020-01-084-107/+108
| | | | | | | | | | * Remove implicit conversion operators from Type Now types must be explicitly converted to uint32_t with Type::getID or to ValueType with Type::getVT. This fixes #2572 for switches that use Type::getVT. * getVT => getSingle
* Revert "Reland "Fix renaming in FixInvokeFunctionNamesWalker (#2513)" ↵Sam Clegg2020-01-071-26/+15
| | | | | (#2542)" (#2576) This reverts commit f62e171c38bea14302f9b79f7941a248ea704425.
* [NFC] Enforce use of `Type::` on type names (#2434)Thomas Lively2020-01-076-588/+681
|
* Allow subtype in throw instruction (#2568)Heejin Ahn2020-01-061-47/+52
| | | | | This allows subtype for arguments of `throw`. This also renames `shouldBeSubTypeOrUnreachable` to `shouldBeSubTypeOrFirstIsUnreachable`, to be consistent with `shouldBeEqualOrFirstIsUnreachable`.
* Add line and col info to wast parser exceptions (#2570)Heejin Ahn2020-01-061-63/+80
| | | | | | This adds line and column info to wast parser exception messages to be more readable when they are encoutered. In other cases this makes existing line and column number more fine grained, or adds some helpful strings (if line and column info is not available).
* Parse memarg in atomic.wait and atomic.notify (#2569)Heejin Ahn2020-01-032-21/+39
| | | | | | - Allow `atomic.notify` and `atomic.wait` instructions to parse memory arguments (`align` and `offset`) and print the offset in these instruction when writing binary, rather than assuming it to be 0 - Change arguments of `parseMemAttributes` to be references
* Generate push/pop in stack IR (#2566)Heejin Ahn2020-01-031-1/+2
| | | | | | | | | | | We have not been generating push and pop instructions in the stack IR. Even though they are not written in binary, they have to be in the stack IR to match the number of inputs and outputs of instructions. Currently `BinaryenIRWriter` is used both for stack IR generation and binary generation, so we should emit those instructions in `BinaryenIRWriter`. `BinaryenIRToBinaryWriter`, which inherits `BinaryenIRWriter`, does not do anything for push and pop instructions, so they are still not emitted in binary.
* Add support for reference types proposal (#2451)Heejin Ahn2019-12-307-223/+473
| | | | | | | | | | | | 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-294-100/+104
| | | | | | | | | | | 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`.
* Refactor module element related functions (NFC) (#2550)Heejin Ahn2019-12-231-81/+67
| | | | This does something similar to #2489 for more functions, removing boilerplate code for each module element using template functions.
* DWARF debug line updating (#2545)Alon Zakai2019-12-202-26/+370
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* Reland "Fix renaming in FixInvokeFunctionNamesWalker (#2513)" (#2542)Sam Clegg2019-12-201-15/+26
| | | | | | | | | | | | | | | | * Reland "Fix renaming in FixInvokeFunctionNamesWalker (#2513)" In the previous iteration of this change we were not calling `renameFunctions` for each of the functions we removed. The problem manifested itself when we rename the imported function to `emscripten_longjmp_jmpbuf` to `emscripten_longjmp`. In this case the import of `emscripten_longjmp` already exists so we remove the import of `emscripten_longjmp_jmpbuf` but we were not correclty calling renameFunctions to handle the rename of all the uses. Add an additional test case to cover the failures that we saw on the emscripten tree.
* Binary format code section offset tracking (#2515)Alon Zakai2019-12-193-6/+53
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* Revert "Fix renaming in FixInvokeFunctionNamesWalker (#2513)" (#2541)Sam Clegg2019-12-191-13/+8
| | | This reverts commit f0a2e2c75c7bb3008f10b6edbb8dc4cfd27b7d28.
* DWARF parsing and writing support using LLVM (#2520)Alon Zakai2019-12-192-0/+152
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This imports LLVM code for DWARF handling. That code has the Apache 2 license like us. It's also the same code used to emit DWARF in the common toolchain, so it seems like a safe choice. This adds two passes: --dwarfdump which runs the same code LLVM runs for llvm-dwarfdump. This shows we can parse it ok, and will be useful for debugging. And --dwarfupdate writes out the DWARF sections (unchanged from what we read, so it just roundtrips - for updating we need #2515). This puts LLVM in thirdparty which is added here. All the LLVM code is behind USE_LLVM_DWARF, which is on by default, but off in JS for now, as it increases code size by 20%. This current approach imports the LLVM files directly. This is not how they are intended to be used, so it required a bunch of local changes - more than I expected actually, for the platform-specific stuff. For now this seems to work, so it may be good enough, but in the long term we may want to switch to linking against libllvm. A downside to doing that is that binaryen users would need to have an LLVM build, and even in the waterfall builds we'd have a problem - while we ship LLVM there anyhow, we constantly update it, which means that binaryen would need to be on latest llvm all the time too (which otherwise, given DWARF is quite stable, we might not need to constantly update). An even larger issue is that as I did this work I learned about how DWARF works in LLVM, and while the reading code is easy to reuse, the writing code is trickier. The main code path is heavily integrated with the MC layer, which we don't have - we might want to create a "fake MC layer" for that, but it sounds hard. Instead, there is the YAML path which is used mostly for testing, and which can convert DWARF to and from YAML and from binary. Using the non-YAML parts there, we can convert binary DWARF to the YAML layer's nice Info data, then convert that to binary. This works, however, this is not the path LLVM uses normally, and it supports only some basic DWARF sections - I had to add ranges support, in fact. So if we need more complex things, we may end up needing to use the MC layer approach, or consider some other DWARF library. However, hopefully that should not affect the core binaryen code which just calls a library for DWARF stuff. Helps #2400
* SIMD {i8x16,i16x8}.avgr_u instructions (#2539)Thomas Lively2019-12-184-0/+26
| | | As specified in https://github.com/WebAssembly/simd/pull/126.
* Fix renaming in FixInvokeFunctionNamesWalker (#2513)Sam Clegg2019-12-171-8/+13
| | | | | | | | | | | | | This fixes https://github.com/emscripten-core/emscripten/issues/9950. The issue only shows up when debug names are not present so most of the changes in CL come from disabling debug names in the lld tests. We want to make sure that wasm-emscripten-finalize runs fine without debug names so I think it makes most sense to test in this mode. The actual bugfix is in wasm-emscripten.cpp as part of the FixInvokeFunctionNamesWalker. The problem was the name of the function rather than is import name was being added to importRenames. This means that when debug names were present (and the two names were the same) we didn't see the bug.
* Support stack overflow checks in standalone mode (#2525)Alon Zakai2019-12-121-5/+17
| | | | | | | | | In normal mode we call a JS import, but we can't import from JS in standalone mode. Instead, just trap in that case with an unreachable. (The error reporting is not as good in this case, but at least it catches all errors and halts, and the emitted wasm is valid for standalone mode.) Helps emscripten-core/emscripten#10019
* Make local.tee's type its local's type (#2511)Heejin Ahn2019-12-125-24/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-117-478/+285
| | | | | | | | | | | | | | | | | 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.
* Fix comparison of none and unreachable types (#2514)Heejin Ahn2019-12-091-2/+2
| | | | | | | | | | | | | | | | | | | Currently `none` and `unreachable` types are stored as the same empty `{}` in src/wasm/wasm-type.cpp. This makes `Type::operator<` incorrectly when given `none` and `unreachable`, because it expands both given types and lexicographically compare them, when both of the expanded vector will be empty. This was found by the fuzzer. This line in `Modder::visitExpression` tries to retrieve candidates of the same type. Because we can't really compare these two types, if you give `unreachable` as the key, candidates of `none` type can be returned. This generates incorrect code that ends up failing in validation in a very weird way. It was hard to generate a small testcase to trigger this part because it was found by generating fuzzed code from a random data file. But I guess this fix is pretty straightforward. Fixes #2512.
* Add some tracing to wasm-emscripten-finalize (#2505)Sam Clegg2019-12-051-0/+16
| | | | | Also fix, but in splitting the names of the trace channels. Obviously I can't write string.split correctly in C first time around.
* Add string parameter to WASM_UNREACHABLE (#2499)Sam Clegg2019-12-057-117/+118
| | | | | This works more like llvm's unreachable handler in that is preserves information even in release builds.
* Remove 'none' type as a branch target in ReFinalize (#2492)Alon Zakai2019-12-042-3/+3
| | | | | | | | | | | | | | | | | That was needed for super-old wasm type system, where we allowed (block $x (br_if $x (unreachable) (nop) ) ) That is, we differentiated "taken" branches from "named" ones (just referred to by name, but not actually taken as it's in unreachable code). We don't need to differentiate those any more. Remove the ReFinalize code that considered it, and also remove the named/taken distinction in other places.
* cmake: Convert to using lowercase for and functions/macros (#2495)Sam Clegg2019-12-041-2/+2
| | | This is line with modern cmake conventions is much less SHOUTY!
* Convert to using DEBUG macros (#2497)Sam Clegg2019-12-043-455/+174
| | | | | | This means that debugging/tracing can now be enabled and controlled centrally without managing and passing state around the codebase.
* Refactor removing module elements (#2489)Heejin Ahn2019-12-021-35/+42
| | | | | | | | | | | This creates utility functions for removing module elements: removing one element by name, and removing multiple elements using a predicate function. And makes other parts of code use it. I think this is a light-handed approach than calling `Module::updateMaps` after removing only a part of module elements. This also fixes a bug in the inlining pass: it didn't call `Module::updateMaps` after removing functions. After this patch callers don't need to additionally call it anyway.
* Collect all object files from the object libraries in a CMake variable (#2477)Immanuel Haffner2019-11-261-1/+1
| | | | | | | | | using the `$<TARGET_OBJECTS:objlib>` syntax. Use this variable when adding `libbinaryen` as static or shared library. Additionally, use the variable with the object files to simplify the `TARGET_LINK_LIBRARIES` commands: add the object libraries to the sources of executables and drop the use of our libraries in `TARGET_LINK_LIBRARIES`. (Object libraries cannot be linked but must be used as sources. See https://cmake.org/pipermail/cmake/2018-June/067721.html)
* Refactor and optimize binary writing type collection (#2478)Alon Zakai2019-11-262-45/+33
| | | | | | | | | | 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.
* Update type information for em_asm functions (#2480)Thomas Lively2019-11-261-1/+3
| | | | | | | | | We were only updating the imported Function's type name field and failing to update its params and results. This caused the binary writer to start using the wrong types after #2466. This PR fixes the code to update both type representations on the imported function. This double bookkeeping will be removed entirely in an upcoming PR.
* Print only literal values when printing literals (#2469)Heejin Ahn2019-11-261-1/+1
| | | | | | | | | | | | | | | Current `<<` operator on `Literal` prints `[type].const` with it. But `[type].const` is rather an instruction than a literal itself, and printing it with the literals makes less sense when we later have literals whose type don't have `const` instructions (such as reference types). This patch - Makes `<<` operator on `Literal` print only its value - Makes wasm-shell's shell interface comply with the spec interpreter's printing format (`value : type`). - Prints wasm-shell's `[trap]` message to stderr These make all `fix_` routines for spec tests in check.py unnecessary.
* Revert "Build libbinaryen as a monolithic statically/shared library (#2463)" ↵Alon Zakai2019-11-251-1/+1
| | | | | (#2474) This reverts commit bf8f36c31c0b8e6213bce840be66937dd6d0f6af.
* Remove FunctionType from Event (#2466)Thomas Lively2019-11-256-91/+162
| | | | | | | | | 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.
* Build libbinaryen as a monolithic statically/shared library (#2463)Immanuel Haffner2019-11-221-1/+1
| | | | | | | | | | | | * Transform libraries created in subdirectories from statically linked libraries to CMake object libraries. * Link object libraries as `PRIVATE` to `libbinaryen`. According to CMake documentation: "Libraries and targets following PRIVATE are linked to, but are not made part of the link interface." This is exactly what we want, as we only want the C API to be part of the interface.
* Multivalue type creation and inspection (#2459)Thomas Lively2019-11-225-83/+201
| | | | | | | | | | | | | 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.
* [NFC] Make Type a class instead of enum (#2433)Thomas Lively2019-11-131-1/+2
| | | | | | | | | The plan is to extend `Type` to represent arbitrary multivalue types, and as a prerequisite for that it is necessary to make it a class instead of an enum. This PR bends over backwards to add all the automatic conversions and constants necessary to allow the rest of the code to compile unmodified, but in the future it should be possible to standardize usage across the code base and remove some of these utilities.
* Fix catch parsing (#2428)Heejin Ahn2019-11-111-5/+8
| | | | | | | - When a catch body is a block, call its `finalize` function with the correct type - Don't create a block when there's one instruction in a catch body - Remove `makeCatch` from gen-s-parser.py; it's not necessary - Fix a test case that has a `catch` without `try`
* Don't attempt to de-duplicate asm consts (#2422)Sam Clegg2019-11-041-13/+11
| | | | | | | | | | | | Since we switched the using memory addresses for asm const indexes and stopping trying to modify the code we can no loner de-duplicate the asm const strings here. If we want to de-duplicate in the strings in emscripten we could do that but it seems like a marginal benefit. This fixes the test_html5_gamepad failures which is currently showing up on the emscripten waterfall.
* Add i32x4.dot_i16x8_s (#2420)Thomas Lively2019-11-044-0/+20
| | | | | 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-014-0/+145
| | | As proposed in https://github.com/WebAssembly/simd/pull/27.
* Use absolute memory addresses for emasm string indexes. (#2408)Sam Clegg2019-10-311-25/+36
| | | | | | | | | | Before we used 0-based indexes which meant that we needed to modify the code calling the emasm function to replace the first argument. Now we use the string address itself as the index/code for the emasm constant. This allows use code to go unmodifed as the emscripten side will accept the memory address as the index/code. See: https://github.com/emscripten-core/emscripten/issues/9013
* When renaming functions ensure the corresponding GOT.func entry is also ↵Sam Clegg2019-10-251-0/+7
| | | | | | renamed (#2382) Fixes https://github.com/WebAssembly/binaryen/issues/2180
* Make try body with multiple instructions roundtrip (#2374)Heejin Ahn2019-10-091-1/+1
| | | | | | | | | Previously we didn't print an additional block when there are multiple instructions within a `try` body, so those wast files cannot be parsed correctly, because the wast parser assumes there are two bodies within a `try` scope: a try body and a catch body. We don't need to print an additional block for a `catch` body because `(catch ...)` itself serves as a scope.
* MAIN_THREAD_EM_ASM support (#2367)Jacob Gravelle2019-10-071-71/+113
| | | | | | | | | | | | * Support for sync and async main-thread EM_ASM * Fix up import names as well * update test * fix whitespace * clang-format
* v8x16.swizzle (#2368)Thomas Lively2019-10-034-1/+22
| | | | As specified at https://github.com/WebAssembly/simd/blob/master/proposals/simd/SIMD.md#swizzling-using-variable-indices.
* Only create `_start` if it doesn't already exist (#2363)Sam Clegg2019-09-271-0/+3
|
* SIMD load and extend instructions (#2353)Thomas Lively2019-09-245-2/+72
| | | | | | 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-243-1/+8
| | | | | 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-235-20/+128
| | | | | | | 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.