summaryrefslogtreecommitdiff
path: root/test
Commit message (Collapse)AuthorAgeFilesLines
* Fix extra unreachable generation (#2266)Heejin Ahn2019-07-276-1/+357
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently various expressions handle this differently, and now we consistently follow this rules: --- For all non-control-flow value-returning instructions, if a type of an expression is unreachable, we emit an unreachable and don't emit the instruction itself. If we don't emit an unreachable, instructions that follow can have validation failure in wasm binary format. For example: ``` [unreachable] (f32.add [unreachable] (i32.eqz [unreachable] (unreachable) ) ... ) ``` This is a valid prgram in binaryen IR, because the unreachable type propagates out of an expression, making both i32.eqz and f32.add unreachable. But in binary format, this becomes: ``` unreachable i32.eqz f32.add ;; validation failure; it expects f32 but takes an i32! ``` And here f32.add causes validation failure in wasm validation. So in this case we add an unreachable to prevent following instructions to consume the current value (here i32.eqz). In actual tests, I used `global.get` to an f32 global, which does not return a value, instead of `f32.add`, because `f32.add` itself will not be emitted if one of argument is unreachable. --- So the changes are: - For instructions that don't return a value, removes unreachable emitting code if it exists. - Add the unreachable emitting code for value-returning instructions if there isn't one. - Check for unreachability only once after emitting all children for atomic instructions. Currently only atomic instructions check unreachability after visiting each children and bail out right after, which is valid, but not consistent with others. - Don't emit an extra unreachable after a return (and return_call). I guess it is unnecessary.
* Fix unreachable prefix in instruction printing (#2265)Heejin Ahn2019-07-267-4/+75
| | | | | | | | | When a memory instruction's type is unreachable, i.e., one of its child expressions is unreachable, the instruction will be printed like `unreachable.load`, which is invalid text format. This prints unreachable prefix instruction types as `i32` to just make them pass the parser. It is OK because they are not reachable anyway. Also this removes printing of `?` in atomic.rmw instruction printing.
* Asyncify: whitelist and blacklist support (#2264)Alon Zakai2019-07-265-0/+631
| | | | | | | | | 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.
* More push/pop support (#2260)Heejin Ahn2019-07-244-35/+166
| | | | | | | This adds - `push`/`pop` support for other types: v128 and exnref - `push`/`pop` support for binaryen.js Because binaryen.js follows Binaryen's AST structure, without `pop` in binaryen.js, EH instructions cannot be represented in binaryen.js.
* Allow 0-value events (#2256)Heejin Ahn2019-07-245-9/+11
| | | | Before I disallowed events with no values, but spec does not say anything about it, so I think that restriction is not necessary.
* Finalize tail call support (#2246)Thomas Lively2019-07-2312-82/+490
| | | | Adds tail call support to fuzzer and makes small changes to handle return calls in multiple utilities and passes. Makes larger changes to DAE and inlining passes to properly handle tail calls.
* wasm-emscripten-finalize: Add mainReadsParams metadata (#2247)Alon Zakai2019-07-2214-14/+28
| | | | | | | The new flag indicates whether main reads the argc/argv parameters. If it does not, we can avoid emitting code to generate those arguments in the JS, which is not trivial in small programs - it requires some string conversion code. Nicely the existing test inputs were enough for testing this (see outputs). This depends on an emscripten change to land first, as emscripten.py asserts on metadata fields it doesn't recognize.
* SimplifyGlobals: Propagate constants in global initializers (#2238)Alon Zakai2019-07-201-6/+6
| | | | | | | | | | | (global $g1 (mut i32) (i32.const 42)) (global $g2 i32 (global.get $g1)) can be optimized to (global $g1 (mut i32) (i32.const 42)) (global $g2 i32 (i32.const 42)) even though $g1 is mutable - because it can't be mutated during module instantiation.
* Re-land #2235 with fixes (#2245)Thomas Lively2019-07-202-1/+47
| | | | #2242 had exposed the bug that the `Trapper` pass was defining `walkFunction` when it should have been defining `doWalkFunction`.
* Revert "Remove bulk memory instructions refering to active segments (#2235)" ↵Thomas Lively2019-07-192-47/+1
| | | | | (#2244) This reverts commit 72c52ea7d4eb61b95cf8a5164947cb760fe42e9c, which was causing test failures after it merged.
* Remove bulk memory instructions refering to active segments (#2235)Thomas Lively2019-07-192-1/+47
| | | | This prevents those instructions from becoming invalid due to memory packing optimizations and is also a code size win. Fixes #2227.
* SimplifyGlobals: Constant-propagate constant values of immutable globals (#2234)Alon Zakai2019-07-188-12/+95
|
* Tail call C/JS API (#2223)Thomas Lively2019-07-155-55/+179
|
* Bysyncify => Asyncify (#2226)Alon Zakai2019-07-1518-1058/+1058
| | | | | | | After some discussion this seems like a less confusing name: what the pass does is "asyncify" code, after all. The one downside is the name overlaps with the old emscripten "Asyncify" utility, which we'll need to clarify in the docs there. This keeps the old --bysyncify flag around for now, which is helpful for avoiding temporary breakage on CI as we move the emscripten side as well.
* Rename except_ref type to exnref (#2224)Heejin Ahn2019-07-149-12/+12
| | | | In WebAssembly/exception-handling#79 we agreed to rename `except_ref` type to `exnref`.
* Stop emitting "almost asm" in wasm2js output (#2221)Alon Zakai2019-07-12101-123/+0
| | | We don't ever emit "use asm" anymore, so this similar annotation is not really useful, it just increases size.
* Handle passive segments in wasm-emscripten-finalize (#2217)Thomas Lively2019-07-112-0/+151
|
* Optimize select fallthrough values (#2220)Alon Zakai2019-07-115-21/+29
| | | This became noticeable after #2216 which led to some eqz eqz pairs in the test suite.
* Optimize if of br_if (#2216)Alon Zakai2019-07-1112-77/+195
| | | | | | | An if whose body is a br_if can be turned into a br_if of a combined condition (if side effects allow it). The naive size in bytes is identical between the patterns, but the select may avoid a hardware branch, and also the select may be further optimized. On the benchmark suite this helps every single benchmark, but by quite small amounts (e.g. 100 bytes on sqlite, which is 1MB). This was noticed in emscripten-core/emscripten#8941
* Ignore --initial-stack-pointer arg to wasm-emscripten-finalize (#2201)Sam Clegg2019-07-1011-11/+11
| | | | | | | | | | | | | We were passing bad value in --initial-stack-pointer which did not include the STATIC_BUMP (since STATIC_BUMP is determinted by the output of finalize). If emscripten wants to set the stack pointer position it can do so by calling the stackRestore() function at startup. This argument will be removed completely once we stop passing it on the emscripten side. See https://github.com/emscripten-core/emscripten/issues/8905
* Initial tail call implementation (#2197)Thomas Lively2019-07-038-6/+79
| | | | | | | | | | | Including parsing, printing, assembling, disassembling. TODO: - interpreting - effects - finalization and typing - fuzzing - JS/C API
* Use v8 to test wasm binaries are valid in test suite binary checks (#2206)Alon Zakai2019-07-032-344/+0
|
* Loosen conditions on MemoryPacking (#2205)Thomas Lively2019-07-032-0/+0
| | | | Allow MemoryPacking to run when there are no passive segments, even if bulk memory is enabled.
* Clean up loose ends in feature handling (#2203)Thomas Lively2019-07-032-0/+24
| | | | | Fix and test mutable globals support, replace string literals with constants, and add a pass to emit the target features section.
* Minimal Push/Pop support (#2207)Alon Zakai2019-07-036-0/+182
| | | | | | | This is the first stage of adding support for stacky/multivaluey things. It adds new push/pop instructions, and so far just shows that they can be read and written, and that the optimizer doesn't do anything immediately wrong on them. No fuzzer support, since there isn't a "correct" way to use these yet. The current test shows some "incorrect" usages of them, which is nice to see that we can parse/emit them, but we should replace them with proper usages of push/pop once we actually have those (see comments in the tests). This should be enough to unblock exceptions (which needs a pop in try-catches). It is also a step towards multivalue (I added some docs about that), but most of multivalue is left to be done.
* wasm2js: export memory growth function only if memory growth is enabled (#2194)Alon Zakai2019-07-036-0/+384
| | | Previously we tried to export it if the memory was exported, even if growth was not on, which caused an error.
* Bysyncify: Assertion improvements (#2193)Alon Zakai2019-07-018-96/+338
| | | | | Add assertions on stack overflow in all 4 Bysyncify API calls (previously only 2 did it). Also add a check that those assertions are hit.
* Bysyncify: Fuzzing (#2192)Alon Zakai2019-07-013-4/+6
| | | | | | | | Gets fuzzing support for Bysyncify working. * Add the python to run the fuzzing on bysyncify. * Add a JS script to load and run a testcase with bysyncify support. The code has all the runtime support for sleep/resume etc., which it does on calls to imports at random in a deterministic manner. * Export memory from fuzzer so JS can access it. * Fix tiny builder bug with makeExport.
* Workaround for wasm2js output minification issue with emscripten (#2185)Brion Vibber2019-07-015-10/+15
| | | | | | | | | | | | | | * Workaround for wasm2js output minification issue with emscripten When using emscripten with -O2 and --memory-init-file 0, the JS minification breaks on this function for memory initialization setup, causing an exception to be thrown during module setup. Moving from two 'var' declarations for the same variable to one should avoid hitting this with no change in functionality (the var gets hoisted anyway). https://github.com/emscripten-core/emscripten/issues/8886
* Relax bulk memory rules (#2186)Thomas Lively2019-06-301-26/+8
| | | As decided in the recent in-person CG meeting.
* Bysyncify: fix skipping of flattened if condition (#2187)Alon Zakai2019-06-303-49/+137
| | | | | We assigned it to a local, but didn't run maybeSkip on it. As a result, it was executed during rewinding, which broke restoring the saved value. Found by the fuzzer.
* Bysyncify: ensure memory exists (#2188)Alon Zakai2019-06-302-0/+60
| | | | | We need memory in order to read and write rewinding info, so add it if the module didn't have any memory at all. Found by the fuzzer.
* Bysyncify: optimize better by coalescing before instrumenting control flow ↵Alon Zakai2019-06-255-899/+1710
| | | | | | | | | (#2183) This results in better code sizes on many testcases, sometimes much better. For example, on SQLite the 150K function has only 27 locals instead of 3,874 which it had before (!). This also reduces total code size on SQLite by 15%. The key issue is that after instrumenting control flow we have a lot bigger live ranges. This must be done rather carefully, as we need to introduce some temp locals early on (for breaking up ifs, for call return values, etc.).
* Skip imports in table during RemoveImports (#2181)Thomas Lively2019-06-242-1/+11
| | | | This prevents RemoveImports from producing an invalid module that references functions that no longer exist.
* Bysyncify: Don't instrument functions that call bysyncify_* directly (#2179)Alon Zakai2019-06-217-683/+626
| | | | | Those functions are assumed to be part of the runtime. Instrumenting them would mean nothing can work. With this fix, bysyncify is useful with pure wasm, and not just through imports.
* Bysyncify: add ignore-imports and ignore-indirect options (#2178)Alon Zakai2019-06-212-0/+252
| | | ignore-imports makes it not assume that any import may unwind/rewind the stack. ignore-indirect makes it not assume any indirect call can reach an unwind/rewind (which means, it assumes there is not an indirect call on the stack while unwinding).
* Bysyncify: bysyncify_stop_unwind (#2173)Alon Zakai2019-06-169-152/+409
| | | Add a method to note the stopping of an unwind. This is enough to implement coroutines. Includes an example of coroutine usage in the test suite.
* Bysyncify: async transform for wasm (#2172)Alon Zakai2019-06-159-0/+7013
| | | | | | | | | This adds a new pass, Bysyncify, which transforms code to allow unwind and rewinding the call stack and local state. This allows things like coroutines, turning synchronous code asynchronous, etc. The new pass file itself has a large comment on top with docs. So far the tests here seem to show this works, but this hasn't been tested heavily yet. My next step is to hook this up to emscripten as a replacement for asyncify/emterpreter, see emscripten-core/emscripten#8561 Note that this is completely usable by itself, so it could be useful for any language that needs coroutines etc., and not just ones using LLVM and/or emscripten. See docs on the ABI in the pass source.
* Copy debug info when inlining (#2168)Alon Zakai2019-06-0714-7/+199
|
* Fix bug and leak in relooper merge consecutive blocks (#2159)hobby82019-06-072-0/+86
| | | | | | | | | | | | | | | | | | Fixes in Relooper merge consecutive blocks: Entry block getting removed when it is part of a loop: bb1->AddBranchTo(bb2, nullptr); bb1->AddBranchTo(bb3, ...); bb2->AddBranchTo(bb1, nullptr); bb3->AddBranchTo(bb4, nullptr); relooper.AddBlock(bb1); relooper.AddBlock(bb2); relooper.AddBlock(bb3); relooper.AddBlock(bb4); relooper.Calculate(bb1); Branches memory leak
* Use splatted zero vector in makeZero (#2164)Thomas Lively2019-06-052-1/+21
| | | | | This prevents the optimizer from producing v128.const instructions, which are not supported by V8 at this time.
* Reduce interpreter recursion limit (#2162)Alon Zakai2019-06-042-8/+8
| | | | | | | This should be small enough to work in a 512K stack on Linux, which may then be small enough to work on all common OSes. I had to update some spec tests which actually did more recursive calls, but I don't think the change reduces any relevant amount of test coverage. This may fix the Mac bot finally, as with this it passes for me on the stack size I think Macs have by default.
* Add event section (#2151)Heejin Ahn2019-05-3135-704/+1186
| | | | | | | | | | | | | | | | | | 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
* Add --print-function-map to print out a map of function index to name (#2155)Alon Zakai2019-05-312-0/+19
| | | | | | | | | | * work * fix * fix * format
* Add Features.MVP and Features.All to binaryen.js (#2148)Heejin Ahn2019-05-294-16/+15
| | | | This adds `Features.MVP` and `Features.All` to binaryen.js and make test cases use it.
* wasm2js: Switch optimizations (#2141)Alon Zakai2019-05-2810-37278/+37616
| | | | | This pattern-matches towers of blocks + a br_table into a JS switch. This is much smaller in code size and also avoids heavy nesting that can exceed the recursion limits of JS parsers. This is not enough yet, because it pattern-matches very specifically. In reality, switches can look slightly different. Followup PRs will extend this. For now, this passes the test suite (what passed before - not including the massive-switch tests) + fuzzing so it's a good start.
* Refactor type and function parsing (#2143)Heejin Ahn2019-05-24128-1450/+1487
| | | | | | | | | | | | | | | | | | | | | | | | | | | | - Refactored & fixed typeuse parsing rules so now the rules more closely follow the spec. There have been multiple parsing rules that were different in subtle ways, which are supposed to be the same according to the spec. - Duplicate types, i.e., types with the same signature, in the type section are allowed as long as they don't have the same given name. If a name is given, we use it; if type name is not given, we generate one in the form of `$FUNCSIG$` + signature string. If the same generated name already exists in the type section, we append `_` at the end. This causes most of the changes in the autogenerated type names in test outputs. - A typeuse has to be in the order of (type) -> (param) -> (result), if more than one of them exist. In case of function definitions, (local) has to be after all of these. Fixed some test cases that violate this rule. - When only (param)/(result) are given, its type will be the type with the smallest existing type index whose parameter and result are the same. If there's no such type, a new type will be created and inserted. - Added a test case `duplicate_types.wast` to test type namings for duplicate types. - Refactored `parseFunction` function. - Add more overrides to helper functions: `getSig` and `ensureFunctionType`.
* Add `getGlobal` to binaryen.js (#2142)Heejin Ahn2019-05-242-0/+3
| | | | | We have `getFunction`, but not `getGlobal` because its name clashed with APIs for the deprecated instruction `get_global`. Now we have reflected instruction renaming in code, we can add it for consistency.
* Show line/col for parsing exceptions in gen-s-parser (#2138)Heejin Ahn2019-05-241-0/+18
|
* Add BinaryenModuleWriteSExpr to write a module to a string in s-expr format ↵Siddharth2019-05-212-0/+35
| | | | | (#2106) Fixes #2103.