diff options
author | Alon Zakai <azakai@google.com> | 2020-06-20 14:24:50 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-20 14:24:50 -0700 |
commit | 711f8cb0ccc0de434a86c6c704acd5a13848f4db (patch) | |
tree | 43e93ffb18c37a2e11ad46368f920992a38c239e /src | |
parent | dd4c07c77ee11a6f89651990ad66fd96776b58db (diff) | |
download | binaryen-711f8cb0ccc0de434a86c6c704acd5a13848f4db.tar.gz binaryen-711f8cb0ccc0de434a86c6c704acd5a13848f4db.tar.bz2 binaryen-711f8cb0ccc0de434a86c6c704acd5a13848f4db.zip |
wasm2js testing improvements before bulk-memory (#2918)
Necessary preparations for a later PR that adds bulk memory
support to wasm2js (splitting this out so the next PR is less big):
* Fix logging of print functions in wasm2js spec tests, there
was an extra space in the output (which console.log adds
automatically between items).
* Don't assume the output is always empty, as some tests
(like bulk memory) do have expected output.
* Rename test/bulk-memory.wast as it "conflicts" with
test/spec/bulk-memory.wast - the problem is that we scan
both places, and emit files in test/wasm2js/*, so those
would collide if the names overlap.
* Extend the parsing and emitting of JS for (assert.. ) lines such as
(assert_return (invoke "foo" (i32.const 1)) (i32.const 2))
to also handle
(invoke "foo" (i32.const 1)) (i32.const 2))
Without this, we skip (invoke ..) lines in spec tests, which normally is
fine, but in bulk memory at least they have side effects we need - we
must run them before the later assertions.
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/wasm2js.cpp | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/src/tools/wasm2js.cpp b/src/tools/wasm2js.cpp index 34ceaf357..b1fc45146 100644 --- a/src/tools/wasm2js.cpp +++ b/src/tools/wasm2js.cpp @@ -563,6 +563,11 @@ private: Element& e, Name testFuncName, Name asmModule); + Ref emitInvokeFunc(Builder& wasmBuilder, + Element& e, + Name testFuncName, + Name asmModule); + bool isInvokeHandled(Element& e); bool isAssertHandled(Element& e); void fixCalls(Ref asmjs, Name asmModule); @@ -690,6 +695,28 @@ Ref AssertionEmitter::emitAssertTrapFunc(Builder& wasmBuilder, return outerFunc; } +Ref AssertionEmitter::emitInvokeFunc(Builder& wasmBuilder, + Element& e, + Name testFuncName, + Name asmModule) { + Expression* body = sexpBuilder.parseExpression(e); + std::unique_ptr<Function> testFunc( + wasmBuilder.makeFunction(testFuncName, + std::vector<NameType>{}, + body->type, + std::vector<NameType>{}, + body)); + Ref jsFunc = processFunction(testFunc.get()); + fixCalls(jsFunc, asmModule); + emitFunction(jsFunc); + return jsFunc; +} + +bool AssertionEmitter::isInvokeHandled(Element& e) { + return e.isList() && e.size() >= 2 && e[0]->isStr() && + e[0]->str() == Name("invoke"); +} + bool AssertionEmitter::isAssertHandled(Element& e) { return e.isList() && e.size() >= 2 && e[0]->isStr() && (e[0]->str() == Name("assert_return") || @@ -796,19 +823,31 @@ void AssertionEmitter::emit() { emitWasm(wasm, out, flags, options.passOptions, funcName); continue; } - if (!isAssertHandled(e)) { + if (!isInvokeHandled(e) && !isAssertHandled(e)) { std::cerr << "skipping " << e << std::endl; continue; } Name testFuncName(IString(("check" + std::to_string(i)).c_str(), false)); + bool isInvoke = (e[0]->str() == Name("invoke")); bool isReturn = (e[0]->str() == Name("assert_return")); bool isReturnNan = (e[0]->str() == Name("assert_return_nan")); - Element& testOp = *e[1]; + Element* assertOp; + // An assertion of an invoke has the invoke inside the assert. + if (isAssertHandled(e)) { + assertOp = e[1]; + } else { + assertOp = &e; + } // Replace "invoke" with "call" - testOp[0]->setString(IString("call"), false, false); + (*assertOp)[0]->setString(IString("call"), false, false); // Need to claim dollared to get string as function target - testOp[1]->setString(testOp[1]->str(), /*dollared=*/true, false); - + (*assertOp)[1]->setString((*assertOp)[1]->str(), /*dollared=*/true, false); + if (isInvoke) { + emitInvokeFunc(wasmBuilder, e, testFuncName, asmModule); + out << testFuncName.str << "();\n"; + continue; + } + // Otherwise, this is some form of assertion. if (isReturn) { emitAssertReturnFunc(wasmBuilder, e, testFuncName, asmModule); } else if (isReturnNan) { |