summaryrefslogtreecommitdiff
path: root/src/binaryen-shell.cpp
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-05-12 17:50:44 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-05-12 17:50:44 -0700
commit4a720eca42c463d53db1c81f9957a3e5d9011836 (patch)
treeb6810b5161b7a6835a468f63403080e26799cfad /src/binaryen-shell.cpp
parentf518f097c80c0659fbacf11fe12f89955093282b (diff)
downloadbinaryen-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.cpp252
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);
- }
-}