From 4a720eca42c463d53db1c81f9957a3e5d9011836 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 12 May 2016 17:50:44 -0700 Subject: move console tool sources into src/tools (#490) --- src/asm2wasm-main.cpp | 114 -------------------- src/binaryen-shell.cpp | 252 ------------------------------------------- src/s2wasm-main.cpp | 140 ------------------------ src/tools/asm2wasm.cpp | 114 ++++++++++++++++++++ src/tools/binaryen-shell.cpp | 252 +++++++++++++++++++++++++++++++++++++++++++ src/tools/s2wasm.cpp | 140 ++++++++++++++++++++++++ src/tools/wasm-as.cpp | 69 ++++++++++++ src/tools/wasm-dis.cpp | 62 +++++++++++ src/wasm-as.cpp | 69 ------------ src/wasm-dis.cpp | 62 ----------- 10 files changed, 637 insertions(+), 637 deletions(-) delete mode 100644 src/asm2wasm-main.cpp delete mode 100644 src/binaryen-shell.cpp delete mode 100644 src/s2wasm-main.cpp create mode 100644 src/tools/asm2wasm.cpp create mode 100644 src/tools/binaryen-shell.cpp create mode 100644 src/tools/s2wasm.cpp create mode 100644 src/tools/wasm-as.cpp create mode 100644 src/tools/wasm-dis.cpp delete mode 100644 src/wasm-as.cpp delete mode 100644 src/wasm-dis.cpp (limited to 'src') diff --git a/src/asm2wasm-main.cpp b/src/asm2wasm-main.cpp deleted file mode 100644 index e18f78de9..000000000 --- a/src/asm2wasm-main.cpp +++ /dev/null @@ -1,114 +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. - */ - -// -// asm2wasm console tool -// - -#include "support/colors.h" -#include "support/command-line.h" -#include "support/file.h" -#include "wasm-printing.h" - -#include "asm2wasm.h" - -using namespace cashew; -using namespace wasm; - -int main(int argc, const char *argv[]) { - bool opts = true; - bool imprecise = false; - - Options options("asm2wasm", "Translate asm.js files to .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("--mapped-globals", "-m", "Mapped globals", Options::Arguments::One, - [](Options *o, const std::string &argument) { - o->extra["mapped globals"] = argument; - }) - .add("--total-memory", "-m", "Total memory size", Options::Arguments::One, - [](Options *o, const std::string &argument) { - o->extra["total memory"] = argument; - }) - .add("--no-opts", "-n", "Disable optimization passes", Options::Arguments::Zero, - [&opts](Options *o, const std::string &) { - opts = false; - }) - .add("--imprecise", "-i", "Imprecise optimizations", Options::Arguments::Zero, - [&imprecise](Options *o, const std::string &) { - imprecise = true; - }) - .add_positional("INFILE", Options::Arguments::One, - [](Options *o, const std::string &argument) { - o->extra["infile"] = argument; - }); - options.parse(argc, argv); - - const auto &mg_it = options.extra.find("mapped globals"); - const char *mappedGlobals = - mg_it == options.extra.end() ? nullptr : mg_it->second.c_str(); - - const auto &tm_it = options.extra.find("total memory"); - size_t totalMemory = - tm_it == options.extra.end() ? 16 * 1024 * 1024 : atoi(tm_it->second.c_str()); - if (totalMemory & ~Memory::kPageMask) { - std::cerr << "Error: total memory size " << totalMemory << - " is not a multiple of the 64k wasm page size\n"; - exit(EXIT_FAILURE); - } - - Asm2WasmPreProcessor pre; - auto input( - read_file>(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release)); - char *start = pre.process(input.data()); - - if (options.debug) std::cerr << "parsing..." << std::endl; - cashew::Parser builder; - Ref asmjs = builder.parseToplevel(start); - if (options.debug) { - std::cerr << "parsed:" << std::endl; - asmjs->stringify(std::cerr, true); - std::cerr << std::endl; - } - - if (options.debug) std::cerr << "wasming..." << std::endl; - Module wasm; - wasm.memory.initial = wasm.memory.max = totalMemory / Memory::kPageSize; - Asm2WasmBuilder asm2wasm(wasm, pre.memoryGrowth, options.debug, imprecise); - asm2wasm.processAsm(asmjs); - - if (opts) { - if (options.debug) std::cerr << "optimizing..." << std::endl; - asm2wasm.optimize(); - } - - if (options.debug) std::cerr << "printing..." << std::endl; - Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release); - WasmPrinter::printModule(&wasm, output.getStream()); - - if (mappedGlobals) { - if (options.debug) - std::cerr << "serializing mapped globals..." << std::endl; - asm2wasm.serializeMappedGlobals(mappedGlobals); - } - - if (options.debug) std::cerr << "done." << std::endl; -} 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 - -#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()->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* builder, - Name entry) { - std::unique_ptr interface; - std::unique_ptr instance; - if (wasm) { - interface = make_unique(); - instance = make_unique(*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 builder; - try { - builder = std::unique_ptr( - 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() - ->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 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>(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 builder; - try { - builder = make_unique(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); - } -} diff --git a/src/s2wasm-main.cpp b/src/s2wasm-main.cpp deleted file mode 100644 index 9688f6696..000000000 --- a/src/s2wasm-main.cpp +++ /dev/null @@ -1,140 +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. - */ - -// -// wasm2asm console tool -// - -#include "support/colors.h" -#include "support/command-line.h" -#include "support/file.h" -#include "s2wasm.h" -#include "wasm-linker.h" -#include "wasm-printing.h" - -using namespace cashew; -using namespace wasm; - -int main(int argc, const char *argv[]) { - bool ignoreUnknownSymbols = false; - bool generateEmscriptenGlue = false; - std::string startFunction; - std::vector archiveLibraries; - Options options("s2wasm", "Link .s file into .wast"); - 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("--ignore-unknown", "", "Ignore unknown symbols", - Options::Arguments::Zero, - [&ignoreUnknownSymbols](Options *, const std::string &) { - ignoreUnknownSymbols = true; - }) - .add("--start", "", "Generate the start method (default: main)", - Options::Arguments::Optional, - [&startFunction](Options *, const std::string &argument) { - startFunction = argument.size() ? argument : "main"; - }) - .add("--global-base", "-g", "Where to start to place globals", - Options::Arguments::One, - [](Options *o, const std::string &argument) { - o->extra["global-base"] = argument; - }) - .add("--allocate-stack", "-s", "Size of the user stack in linear memory", - Options::Arguments::One, - [](Options *o, const std::string &argument) { - o->extra["stack-allocation"] = argument; - }) - .add("--initial-memory", "-i", "Initial size of the linear memory", - Options::Arguments::One, - [](Options *o, const std::string &argument) { - o->extra["initial-memory"] = argument; - }) - .add("--max-memory", "-m", "Maximum size of the linear memory", - Options::Arguments::One, - [](Options *o, const std::string &argument) { - o->extra["max-memory"] = argument; - }) - .add("--emscripten-glue", "-e", "Generate emscripten glue", - Options::Arguments::Zero, - [&generateEmscriptenGlue](Options *, const std::string &) { - generateEmscriptenGlue = true; - }) - .add("--library", "-l", "Add archive library", - Options::Arguments::N, - [&archiveLibraries](Options *o, const std::string &argument) { - archiveLibraries.push_back(argument); - }) - .add_positional("INFILE", Options::Arguments::One, - [](Options *o, const std::string &argument) { - o->extra["infile"] = argument; - }); - options.parse(argc, argv); - - auto debugFlag = options.debug ? Flags::Debug : Flags::Release; - auto input(read_file(options.extra["infile"], Flags::Text, debugFlag)); - - if (options.debug) std::cerr << "Parsing and wasming..." << std::endl; - uint64_t globalBase = options.extra.find("global-base") != options.extra.end() - ? std::stoull(options.extra["global-base"]) - : 0; - uint64_t stackAllocation = - options.extra.find("stack-allocation") != options.extra.end() - ? std::stoull(options.extra["stack-allocation"]) - : 0; - uint64_t initialMem = - options.extra.find("initial-memory") != options.extra.end() - ? std::stoull(options.extra["initial-memory"]) - : 0; - uint64_t maxMem = - options.extra.find("max-memory") != options.extra.end() - ? std::stoull(options.extra["max-memory"]) - : 0; - if (options.debug) std::cerr << "Global base " << globalBase << '\n'; - - Linker linker(globalBase, stackAllocation, initialMem, maxMem, - ignoreUnknownSymbols, startFunction, options.debug); - - S2WasmBuilder mainbuilder(input.c_str(), options.debug); - linker.linkObject(mainbuilder); - - for (const auto& m : archiveLibraries) { - auto archiveFile(read_file>(m, Flags::Binary, debugFlag)); - bool error; - Archive lib(archiveFile, error); - if (error) Fatal() << "Error opening archive " << m << "\n"; - linker.linkArchive(lib); - } - - linker.layout(); - - std::stringstream meta; - if (generateEmscriptenGlue) { - if (options.debug) std::cerr << "Emscripten gluing..." << std::endl; - // dyncall thunks - linker.emscriptenGlue(meta); - } - - if (options.debug) std::cerr << "Printing..." << std::endl; - Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release); - WasmPrinter::printModule(&linker.getOutput().wasm, output.getStream()); - output << meta.str() << std::endl; - - if (options.debug) std::cerr << "Done." << std::endl; -} diff --git a/src/tools/asm2wasm.cpp b/src/tools/asm2wasm.cpp new file mode 100644 index 000000000..e18f78de9 --- /dev/null +++ b/src/tools/asm2wasm.cpp @@ -0,0 +1,114 @@ +/* + * 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. + */ + +// +// asm2wasm console tool +// + +#include "support/colors.h" +#include "support/command-line.h" +#include "support/file.h" +#include "wasm-printing.h" + +#include "asm2wasm.h" + +using namespace cashew; +using namespace wasm; + +int main(int argc, const char *argv[]) { + bool opts = true; + bool imprecise = false; + + Options options("asm2wasm", "Translate asm.js files to .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("--mapped-globals", "-m", "Mapped globals", Options::Arguments::One, + [](Options *o, const std::string &argument) { + o->extra["mapped globals"] = argument; + }) + .add("--total-memory", "-m", "Total memory size", Options::Arguments::One, + [](Options *o, const std::string &argument) { + o->extra["total memory"] = argument; + }) + .add("--no-opts", "-n", "Disable optimization passes", Options::Arguments::Zero, + [&opts](Options *o, const std::string &) { + opts = false; + }) + .add("--imprecise", "-i", "Imprecise optimizations", Options::Arguments::Zero, + [&imprecise](Options *o, const std::string &) { + imprecise = true; + }) + .add_positional("INFILE", Options::Arguments::One, + [](Options *o, const std::string &argument) { + o->extra["infile"] = argument; + }); + options.parse(argc, argv); + + const auto &mg_it = options.extra.find("mapped globals"); + const char *mappedGlobals = + mg_it == options.extra.end() ? nullptr : mg_it->second.c_str(); + + const auto &tm_it = options.extra.find("total memory"); + size_t totalMemory = + tm_it == options.extra.end() ? 16 * 1024 * 1024 : atoi(tm_it->second.c_str()); + if (totalMemory & ~Memory::kPageMask) { + std::cerr << "Error: total memory size " << totalMemory << + " is not a multiple of the 64k wasm page size\n"; + exit(EXIT_FAILURE); + } + + Asm2WasmPreProcessor pre; + auto input( + read_file>(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release)); + char *start = pre.process(input.data()); + + if (options.debug) std::cerr << "parsing..." << std::endl; + cashew::Parser builder; + Ref asmjs = builder.parseToplevel(start); + if (options.debug) { + std::cerr << "parsed:" << std::endl; + asmjs->stringify(std::cerr, true); + std::cerr << std::endl; + } + + if (options.debug) std::cerr << "wasming..." << std::endl; + Module wasm; + wasm.memory.initial = wasm.memory.max = totalMemory / Memory::kPageSize; + Asm2WasmBuilder asm2wasm(wasm, pre.memoryGrowth, options.debug, imprecise); + asm2wasm.processAsm(asmjs); + + if (opts) { + if (options.debug) std::cerr << "optimizing..." << std::endl; + asm2wasm.optimize(); + } + + if (options.debug) std::cerr << "printing..." << std::endl; + Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release); + WasmPrinter::printModule(&wasm, output.getStream()); + + if (mappedGlobals) { + if (options.debug) + std::cerr << "serializing mapped globals..." << std::endl; + asm2wasm.serializeMappedGlobals(mappedGlobals); + } + + if (options.debug) std::cerr << "done." << std::endl; +} diff --git a/src/tools/binaryen-shell.cpp b/src/tools/binaryen-shell.cpp new file mode 100644 index 000000000..360b576c8 --- /dev/null +++ b/src/tools/binaryen-shell.cpp @@ -0,0 +1,252 @@ +/* + * 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 + +#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()->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* builder, + Name entry) { + std::unique_ptr interface; + std::unique_ptr instance; + if (wasm) { + interface = make_unique(); + instance = make_unique(*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 builder; + try { + builder = std::unique_ptr( + 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() + ->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 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>(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 builder; + try { + builder = make_unique(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); + } +} diff --git a/src/tools/s2wasm.cpp b/src/tools/s2wasm.cpp new file mode 100644 index 000000000..9688f6696 --- /dev/null +++ b/src/tools/s2wasm.cpp @@ -0,0 +1,140 @@ +/* + * 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. + */ + +// +// wasm2asm console tool +// + +#include "support/colors.h" +#include "support/command-line.h" +#include "support/file.h" +#include "s2wasm.h" +#include "wasm-linker.h" +#include "wasm-printing.h" + +using namespace cashew; +using namespace wasm; + +int main(int argc, const char *argv[]) { + bool ignoreUnknownSymbols = false; + bool generateEmscriptenGlue = false; + std::string startFunction; + std::vector archiveLibraries; + Options options("s2wasm", "Link .s file into .wast"); + 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("--ignore-unknown", "", "Ignore unknown symbols", + Options::Arguments::Zero, + [&ignoreUnknownSymbols](Options *, const std::string &) { + ignoreUnknownSymbols = true; + }) + .add("--start", "", "Generate the start method (default: main)", + Options::Arguments::Optional, + [&startFunction](Options *, const std::string &argument) { + startFunction = argument.size() ? argument : "main"; + }) + .add("--global-base", "-g", "Where to start to place globals", + Options::Arguments::One, + [](Options *o, const std::string &argument) { + o->extra["global-base"] = argument; + }) + .add("--allocate-stack", "-s", "Size of the user stack in linear memory", + Options::Arguments::One, + [](Options *o, const std::string &argument) { + o->extra["stack-allocation"] = argument; + }) + .add("--initial-memory", "-i", "Initial size of the linear memory", + Options::Arguments::One, + [](Options *o, const std::string &argument) { + o->extra["initial-memory"] = argument; + }) + .add("--max-memory", "-m", "Maximum size of the linear memory", + Options::Arguments::One, + [](Options *o, const std::string &argument) { + o->extra["max-memory"] = argument; + }) + .add("--emscripten-glue", "-e", "Generate emscripten glue", + Options::Arguments::Zero, + [&generateEmscriptenGlue](Options *, const std::string &) { + generateEmscriptenGlue = true; + }) + .add("--library", "-l", "Add archive library", + Options::Arguments::N, + [&archiveLibraries](Options *o, const std::string &argument) { + archiveLibraries.push_back(argument); + }) + .add_positional("INFILE", Options::Arguments::One, + [](Options *o, const std::string &argument) { + o->extra["infile"] = argument; + }); + options.parse(argc, argv); + + auto debugFlag = options.debug ? Flags::Debug : Flags::Release; + auto input(read_file(options.extra["infile"], Flags::Text, debugFlag)); + + if (options.debug) std::cerr << "Parsing and wasming..." << std::endl; + uint64_t globalBase = options.extra.find("global-base") != options.extra.end() + ? std::stoull(options.extra["global-base"]) + : 0; + uint64_t stackAllocation = + options.extra.find("stack-allocation") != options.extra.end() + ? std::stoull(options.extra["stack-allocation"]) + : 0; + uint64_t initialMem = + options.extra.find("initial-memory") != options.extra.end() + ? std::stoull(options.extra["initial-memory"]) + : 0; + uint64_t maxMem = + options.extra.find("max-memory") != options.extra.end() + ? std::stoull(options.extra["max-memory"]) + : 0; + if (options.debug) std::cerr << "Global base " << globalBase << '\n'; + + Linker linker(globalBase, stackAllocation, initialMem, maxMem, + ignoreUnknownSymbols, startFunction, options.debug); + + S2WasmBuilder mainbuilder(input.c_str(), options.debug); + linker.linkObject(mainbuilder); + + for (const auto& m : archiveLibraries) { + auto archiveFile(read_file>(m, Flags::Binary, debugFlag)); + bool error; + Archive lib(archiveFile, error); + if (error) Fatal() << "Error opening archive " << m << "\n"; + linker.linkArchive(lib); + } + + linker.layout(); + + std::stringstream meta; + if (generateEmscriptenGlue) { + if (options.debug) std::cerr << "Emscripten gluing..." << std::endl; + // dyncall thunks + linker.emscriptenGlue(meta); + } + + if (options.debug) std::cerr << "Printing..." << std::endl; + Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release); + WasmPrinter::printModule(&linker.getOutput().wasm, output.getStream()); + output << meta.str() << std::endl; + + if (options.debug) std::cerr << "Done." << std::endl; +} diff --git a/src/tools/wasm-as.cpp b/src/tools/wasm-as.cpp new file mode 100644 index 000000000..40839ea55 --- /dev/null +++ b/src/tools/wasm-as.cpp @@ -0,0 +1,69 @@ +/* + * Copyright 2016 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. + */ + +// +// wasm2asm console tool +// + +#include "support/colors.h" +#include "support/command-line.h" +#include "support/file.h" +#include "wasm-binary.h" +#include "wasm-s-parser.h" + +using namespace cashew; +using namespace wasm; + +int main(int argc, const char *argv[]) { + Options options("wasm-as", "Assemble a .wast (WebAssembly text format) into a .wasm (WebAssembly binary format)"); + 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_positional("INFILE", Options::Arguments::One, + [](Options *o, const std::string &argument) { + o->extra["infile"] = argument; + }); + options.parse(argc, argv); + + auto input(read_file(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release)); + + Module wasm; + + try{ + if (options.debug) std::cerr << "s-parsing..." << std::endl; + SExpressionParser parser(const_cast(input.c_str())); + Element& root = *parser.root; + if (options.debug) std::cerr << "w-parsing..." << std::endl; + SExpressionWasmBuilder builder(wasm, *root[0]); + } catch (ParseException& p) { + p.dump(std::cerr); + Fatal() << "error in parsing wasm binary"; + } + + if (options.debug) std::cerr << "binarification..." << std::endl; + BufferWithRandomAccess buffer(options.debug); + WasmBinaryWriter writer(&wasm, buffer, options.debug); + writer.write(); + + if (options.debug) std::cerr << "writing to output..." << std::endl; + Output output(options.extra["output"], Flags::Binary, options.debug ? Flags::Debug : Flags::Release); + buffer.writeTo(output); + + if (options.debug) std::cerr << "Done." << std::endl; +} diff --git a/src/tools/wasm-dis.cpp b/src/tools/wasm-dis.cpp new file mode 100644 index 000000000..93c286913 --- /dev/null +++ b/src/tools/wasm-dis.cpp @@ -0,0 +1,62 @@ +/* + * Copyright 2016 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. + */ + +// +// wasm2asm console tool +// + +#include "support/colors.h" +#include "support/command-line.h" +#include "support/file.h" +#include "wasm-binary.h" +#include "wasm-printing.h" + +using namespace cashew; +using namespace wasm; + +int main(int argc, const char *argv[]) { + Options options("wasm-dis", "Un-assemble a .wasm (WebAssembly binary format) into a .wast (WebAssembly text format)"); + 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_positional("INFILE", Options::Arguments::One, + [](Options *o, const std::string &argument) { + o->extra["infile"] = argument; + }); + options.parse(argc, argv); + + auto input(read_file>(options.extra["infile"], Flags::Binary, options.debug ? Flags::Debug : Flags::Release)); + + if (options.debug) std::cerr << "parsing binary..." << std::endl; + Module wasm; + try { + WasmBinaryBuilder parser(wasm, input, options.debug); + parser.read(); + } catch (ParseException& p) { + p.dump(std::cerr); + Fatal() << "error in parsing wasm binary"; + } + + if (options.debug) std::cerr << "Printing..." << std::endl; + Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release); + WasmPrinter::printModule(&wasm, output.getStream()); + output << '\n'; + + if (options.debug) std::cerr << "Done." << std::endl; +} diff --git a/src/wasm-as.cpp b/src/wasm-as.cpp deleted file mode 100644 index 40839ea55..000000000 --- a/src/wasm-as.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2016 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. - */ - -// -// wasm2asm console tool -// - -#include "support/colors.h" -#include "support/command-line.h" -#include "support/file.h" -#include "wasm-binary.h" -#include "wasm-s-parser.h" - -using namespace cashew; -using namespace wasm; - -int main(int argc, const char *argv[]) { - Options options("wasm-as", "Assemble a .wast (WebAssembly text format) into a .wasm (WebAssembly binary format)"); - 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_positional("INFILE", Options::Arguments::One, - [](Options *o, const std::string &argument) { - o->extra["infile"] = argument; - }); - options.parse(argc, argv); - - auto input(read_file(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release)); - - Module wasm; - - try{ - if (options.debug) std::cerr << "s-parsing..." << std::endl; - SExpressionParser parser(const_cast(input.c_str())); - Element& root = *parser.root; - if (options.debug) std::cerr << "w-parsing..." << std::endl; - SExpressionWasmBuilder builder(wasm, *root[0]); - } catch (ParseException& p) { - p.dump(std::cerr); - Fatal() << "error in parsing wasm binary"; - } - - if (options.debug) std::cerr << "binarification..." << std::endl; - BufferWithRandomAccess buffer(options.debug); - WasmBinaryWriter writer(&wasm, buffer, options.debug); - writer.write(); - - if (options.debug) std::cerr << "writing to output..." << std::endl; - Output output(options.extra["output"], Flags::Binary, options.debug ? Flags::Debug : Flags::Release); - buffer.writeTo(output); - - if (options.debug) std::cerr << "Done." << std::endl; -} diff --git a/src/wasm-dis.cpp b/src/wasm-dis.cpp deleted file mode 100644 index 93c286913..000000000 --- a/src/wasm-dis.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2016 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. - */ - -// -// wasm2asm console tool -// - -#include "support/colors.h" -#include "support/command-line.h" -#include "support/file.h" -#include "wasm-binary.h" -#include "wasm-printing.h" - -using namespace cashew; -using namespace wasm; - -int main(int argc, const char *argv[]) { - Options options("wasm-dis", "Un-assemble a .wasm (WebAssembly binary format) into a .wast (WebAssembly text format)"); - 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_positional("INFILE", Options::Arguments::One, - [](Options *o, const std::string &argument) { - o->extra["infile"] = argument; - }); - options.parse(argc, argv); - - auto input(read_file>(options.extra["infile"], Flags::Binary, options.debug ? Flags::Debug : Flags::Release)); - - if (options.debug) std::cerr << "parsing binary..." << std::endl; - Module wasm; - try { - WasmBinaryBuilder parser(wasm, input, options.debug); - parser.read(); - } catch (ParseException& p) { - p.dump(std::cerr); - Fatal() << "error in parsing wasm binary"; - } - - if (options.debug) std::cerr << "Printing..." << std::endl; - Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release); - WasmPrinter::printModule(&wasm, output.getStream()); - output << '\n'; - - if (options.debug) std::cerr << "Done." << std::endl; -} -- cgit v1.2.3