diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-05-12 17:50:44 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-05-12 17:50:44 -0700 |
commit | 4a720eca42c463d53db1c81f9957a3e5d9011836 (patch) | |
tree | b6810b5161b7a6835a468f63403080e26799cfad /src/binaryen-shell.cpp | |
parent | f518f097c80c0659fbacf11fe12f89955093282b (diff) | |
download | binaryen-4a720eca42c463d53db1c81f9957a3e5d9011836.tar.gz binaryen-4a720eca42c463d53db1c81f9957a3e5d9011836.tar.bz2 binaryen-4a720eca42c463d53db1c81f9957a3e5d9011836.zip |
move console tool sources into src/tools (#490)
Diffstat (limited to 'src/binaryen-shell.cpp')
-rw-r--r-- | src/binaryen-shell.cpp | 252 |
1 files changed, 0 insertions, 252 deletions
diff --git a/src/binaryen-shell.cpp b/src/binaryen-shell.cpp deleted file mode 100644 index 360b576c8..000000000 --- a/src/binaryen-shell.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright 2015 WebAssembly Community Group participants - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// -// A WebAssembly shell, loads a .wast file (WebAssembly in S-Expression format) -// and executes it. This provides similar functionality as the reference -// interpreter, like assert_* calls, so it can run the spec test suite. -// - -#include <memory> - -#include "pass.h" -#include "shell-interface.h" -#include "support/command-line.h" -#include "support/file.h" -#include "wasm-interpreter.h" -#include "wasm-printing.h" -#include "wasm-s-parser.h" -#include "wasm-validator.h" - -using namespace cashew; -using namespace wasm; - -// -// An invocation into a module -// - -struct Invocation { - ModuleInstance* instance; - IString name; - ModuleInstance::LiteralList arguments; - - Invocation(Element& invoke, ModuleInstance* instance, SExpressionWasmBuilder& builder) : instance(instance) { - assert(invoke[0]->str() == INVOKE); - name = invoke[1]->str(); - for (size_t j = 2; j < invoke.size(); j++) { - Expression* argument = builder.parseExpression(*invoke[j]); - arguments.push_back(argument->dynCast<Const>()->value); - } - } - - Literal invoke() { - return instance->callExport(name, arguments); - } -}; - -static void verify_result(Literal a, Literal b) { - if (a == b) return; - // accept equal nans if equal in all bits - assert(a.type == b.type); - if (a.type == f32) { - assert(a.reinterpreti32() == b.reinterpreti32()); - } else if (a.type == f64) { - assert(a.reinterpreti64() == b.reinterpreti64()); - } else { - abort(); - } -} - -static void run_asserts(size_t* i, bool* checked, Module* wasm, - Element* root, - std::unique_ptr<SExpressionWasmBuilder>* builder, - Name entry) { - std::unique_ptr<ShellExternalInterface> interface; - std::unique_ptr<ModuleInstance> instance; - if (wasm) { - interface = make_unique<ShellExternalInterface>(); - instance = make_unique<ModuleInstance>(*wasm, interface.get()); - if (entry.is()) { - Function* function = wasm->getFunction(entry); - if (!function) { - std::cerr << "Unknown entry " << entry << std::endl; - } else { - ModuleInstance::LiteralList arguments; - for (WasmType param : function->params) { - arguments.push_back(Literal(param)); - } - try { - instance->callExport(entry, arguments); - } catch (ExitException&) { - } - } - } - } - while (*i < root->size()) { - Element& curr = *(*root)[*i]; - IString id = curr[0]->str(); - if (id == MODULE) break; - *checked = true; - Colors::red(std::cerr); - std::cerr << *i << '/' << (root->size() - 1); - Colors::green(std::cerr); - std::cerr << " CHECKING: "; - Colors::normal(std::cerr); - std::cerr << curr << '\n'; - if (id == ASSERT_INVALID) { - // a module invalidity test - Module wasm; - bool invalid = false; - std::unique_ptr<SExpressionWasmBuilder> builder; - try { - builder = std::unique_ptr<SExpressionWasmBuilder>( - new SExpressionWasmBuilder(wasm, *curr[1]) - ); - } catch (const ParseException&) { - invalid = true; - } - if (!invalid) { - // maybe parsed ok, but otherwise incorrect - invalid = !WasmValidator().validate(wasm); - } - assert(invalid); - } else if (id == INVOKE) { - assert(wasm); - Invocation invocation(curr, instance.get(), *builder->get()); - invocation.invoke(); - } else { - // an invoke test - assert(wasm); - bool trapped = false; - Literal result; - try { - Invocation invocation(*curr[1], instance.get(), *builder->get()); - result = invocation.invoke(); - } catch (const TrapException&) { - trapped = true; - } - if (id == ASSERT_RETURN) { - assert(!trapped); - if (curr.size() >= 3) { - Literal expected = builder->get() - ->parseExpression(*curr[2]) - ->dynCast<Const>() - ->value; - std::cerr << "seen " << result << ", expected " << expected << '\n'; - verify_result(expected, result); - } else { - Literal expected; - std::cerr << "seen " << result << ", expected " << expected << '\n'; - verify_result(expected, result); - } - } - if (id == ASSERT_TRAP) assert(trapped); - } - *i += 1; - } -} - -// -// main -// - -int main(int argc, const char* argv[]) { - Name entry; - std::vector<std::string> passes; - - Options options("binaryen-shell", "Execute .wast files"); - options - .add("--output", "-o", "Output file (stdout if not specified)", - Options::Arguments::One, - [](Options* o, const std::string& argument) { - o->extra["output"] = argument; - Colors::disable(); - }) - .add( - "--entry", "-e", "call the entry point after parsing the module", - Options::Arguments::One, - [&entry](Options*, const std::string& argument) { entry = argument; }) - .add("", "-O", "execute default optimization passes", - Options::Arguments::Zero, - [&passes](Options*, const std::string&) { - passes.push_back("O"); - }) - .add_positional("INFILE", Options::Arguments::One, - [](Options* o, const std::string& argument) { - o->extra["infile"] = argument; - }); - for (const auto& p : PassRegistry::get()->getRegisteredNames()) { - options.add( - std::string("--") + p, "", PassRegistry::get()->getPassDescription(p), - Options::Arguments::Zero, - [&passes, p](Options*, const std::string&) { passes.push_back(p); }); - } - options.parse(argc, argv); - - auto input(read_file<std::vector<char>>(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release)); - - if (options.debug) std::cerr << "parsing text to s-expressions...\n"; - SExpressionParser parser(input.data()); - Element& root = *parser.root; - - // A .wast may have multiple modules, with some asserts after them - bool checked = false; - size_t i = 0; - while (i < root.size()) { - Element& curr = *root[i]; - IString id = curr[0]->str(); - if (id == MODULE) { - if (options.debug) std::cerr << "parsing s-expressions to wasm...\n"; - Module wasm; - std::unique_ptr<SExpressionWasmBuilder> builder; - try { - builder = make_unique<SExpressionWasmBuilder>(wasm, *root[i]); - } catch (ParseException& p) { - p.dump(std::cerr); - abort(); - } - i++; - assert(WasmValidator().validate(wasm)); - - MixedArena moreModuleAllocations; - - if (passes.size() > 0) { - if (options.debug) std::cerr << "running passes...\n"; - PassRunner passRunner(&wasm); - if (options.debug) passRunner.setDebug(true); - for (auto& passName : passes) { - if (passName == "O") { - passRunner.addDefaultOptimizationPasses(); - } else { - passRunner.add(passName); - } - } - passRunner.run(); - } - - run_asserts(&i, &checked, &wasm, &root, &builder, entry); - } else { - run_asserts(&i, &checked, nullptr, &root, nullptr, entry); - } - } - - if (checked) { - Colors::green(std::cerr); - Colors::bold(std::cerr); - std::cerr << "all checks passed.\n"; - Colors::normal(std::cerr); - } -} |