summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/asm2wasm-main.cpp2
-rw-r--r--src/binaryen-js.cpp31
-rw-r--r--src/binaryen-shell.cpp169
-rw-r--r--src/js/binaryen.idl74
-rw-r--r--src/passes/Print.cpp3
-rw-r--r--src/s2wasm-main.cpp2
-rw-r--r--src/s2wasm.h2
-rw-r--r--src/shared-constants.h9
-rw-r--r--src/shell-interface.h180
-rw-r--r--src/wasm-as.cpp2
-rw-r--r--src/wasm-dis.cpp2
-rw-r--r--src/wasm-interpreter.h4
-rw-r--r--src/wasm-js.cpp2
-rw-r--r--src/wasm-printing.h30
-rw-r--r--src/wasm-s-parser.h7
-rw-r--r--src/wasm2asm-main.cpp2
16 files changed, 332 insertions, 189 deletions
diff --git a/src/asm2wasm-main.cpp b/src/asm2wasm-main.cpp
index 12a06d0de..a9b1197ff 100644
--- a/src/asm2wasm-main.cpp
+++ b/src/asm2wasm-main.cpp
@@ -102,7 +102,7 @@ int main(int argc, const char *argv[]) {
if (options.debug) std::cerr << "printing..." << std::endl;
Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release);
- printWasm(&wasm, output.getStream());
+ WasmPrinter::printModule(&wasm, output.getStream());
if (mappedGlobals) {
if (options.debug)
diff --git a/src/binaryen-js.cpp b/src/binaryen-js.cpp
new file mode 100644
index 000000000..d7d84706e
--- /dev/null
+++ b/src/binaryen-js.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+#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 wasm;
+
+#include "../glue.cpp"
+
diff --git a/src/binaryen-shell.cpp b/src/binaryen-shell.cpp
index 8fc067562..72fad992b 100644
--- a/src/binaryen-shell.cpp
+++ b/src/binaryen-shell.cpp
@@ -23,6 +23,7 @@
#include <memory>
#include "pass.h"
+#include "shell-interface.h"
#include "support/command-line.h"
#include "support/file.h"
#include "wasm-interpreter.h"
@@ -37,172 +38,6 @@ using namespace wasm;
MixedArena globalAllocator;
-IString ASSERT_RETURN("assert_return"),
- ASSERT_TRAP("assert_trap"),
- ASSERT_INVALID("assert_invalid"),
- SPECTEST("spectest"),
- PRINT("print"),
- INVOKE("invoke"),
- EXIT("exit");
-
-struct ExitException {};
-struct TrapException {};
-struct ParseException {};
-
-//
-// Implementation of the shell interpreter execution environment
-//
-
-struct ShellExternalInterface : ModuleInstance::ExternalInterface {
- // The underlying memory can be accessed through unaligned pointers which
- // isn't well-behaved in C++. WebAssembly nonetheless expects it to behave
- // properly. Avoid emitting unaligned load/store by checking for alignment
- // explicitly, and performing memcpy if unaligned.
- //
- // The allocated memory tries to have the same alignment as the memory being
- // simulated.
- class Memory {
- // Use char because it doesn't run afoul of aliasing rules.
- std::vector<char> memory;
- template <typename T>
- static bool aligned(const char* address) {
- static_assert(!(sizeof(T) & (sizeof(T) - 1)), "must be a power of 2");
- return 0 == (reinterpret_cast<uintptr_t>(address) & (sizeof(T) - 1));
- }
- Memory(Memory&) = delete;
- Memory& operator=(const Memory&) = delete;
-
- public:
- Memory() {}
- void resize(size_t newSize) {
- // Ensure the smallest allocation is large enough that most allocators
- // will provide page-aligned storage. This hopefully allows the
- // interpreter's memory to be as aligned as the memory being simulated,
- // ensuring that the performance doesn't needlessly degrade.
- //
- // The code is optimistic this will work until WG21's p0035r0 happens.
- const size_t minSize = 1 << 12;
- size_t oldSize = memory.size();
- memory.resize(std::max(minSize, newSize));
- if (newSize < oldSize && newSize < minSize) {
- std::memset(&memory[newSize], 0, minSize - newSize);
- }
- }
- template <typename T>
- void set(size_t address, T value) {
- if (aligned<T>(&memory[address])) {
- *reinterpret_cast<T*>(&memory[address]) = value;
- } else {
- std::memcpy(&memory[address], &value, sizeof(T));
- }
- }
- template <typename T>
- T get(size_t address) {
- if (aligned<T>(&memory[address])) {
- return *reinterpret_cast<T*>(&memory[address]);
- } else {
- T loaded;
- std::memcpy(&loaded, &memory[address], sizeof(T));
- return loaded;
- }
- }
- } memory;
-
- ShellExternalInterface() : memory() {}
-
- void init(Module& wasm) override {
- memory.resize(wasm.memory.initial * wasm::Memory::kPageSize);
- // apply memory segments
- for (auto segment : wasm.memory.segments) {
- assert(segment.offset + segment.size <= wasm.memory.initial * wasm::Memory::kPageSize);
- for (size_t i = 0; i != segment.size; ++i) {
- memory.set(segment.offset + i, segment.data[i]);
- }
- }
- }
-
- Literal callImport(Import *import, ModuleInstance::LiteralList& arguments) override {
- if (import->module == SPECTEST && import->base == PRINT) {
- for (auto argument : arguments) {
- std::cout << argument << '\n';
- }
- return Literal();
- } else if (import->module == ENV && import->base == EXIT) {
- // XXX hack for torture tests
- std::cout << "exit()\n";
- throw ExitException();
- }
- std::cout << "callImport " << import->name.str << "\n";
- abort();
- }
-
- Literal load(Load* load, size_t addr) override {
- // ignore align - assume we are on x86 etc. which does that
- switch (load->type) {
- case i32: {
- switch (load->bytes) {
- case 1: return load->signed_ ? Literal((int32_t)memory.get<int8_t>(addr)) : Literal((int32_t)memory.get<uint8_t>(addr));
- case 2: return load->signed_ ? Literal((int32_t)memory.get<int16_t>(addr)) : Literal((int32_t)memory.get<uint16_t>(addr));
- case 4: return load->signed_ ? Literal((int32_t)memory.get<int32_t>(addr)) : Literal((int32_t)memory.get<uint32_t>(addr));
- default: abort();
- }
- break;
- }
- case i64: {
- switch (load->bytes) {
- case 1: return load->signed_ ? Literal((int64_t)memory.get<int8_t>(addr)) : Literal((int64_t)memory.get<uint8_t>(addr));
- case 2: return load->signed_ ? Literal((int64_t)memory.get<int16_t>(addr)) : Literal((int64_t)memory.get<uint16_t>(addr));
- case 4: return load->signed_ ? Literal((int64_t)memory.get<int32_t>(addr)) : Literal((int64_t)memory.get<uint32_t>(addr));
- case 8: return load->signed_ ? Literal((int64_t)memory.get<int64_t>(addr)) : Literal((int64_t)memory.get<uint64_t>(addr));
- default: abort();
- }
- break;
- }
- case f32: return Literal(memory.get<float>(addr));
- case f64: return Literal(memory.get<double>(addr));
- default: abort();
- }
- }
-
- void store(Store* store, size_t addr, Literal value) override {
- // ignore align - assume we are on x86 etc. which does that
- switch (store->type) {
- case i32: {
- switch (store->bytes) {
- case 1: memory.set<int8_t>(addr, value.geti32()); break;
- case 2: memory.set<int16_t>(addr, value.geti32()); break;
- case 4: memory.set<int32_t>(addr, value.geti32()); break;
- default: abort();
- }
- break;
- }
- case i64: {
- switch (store->bytes) {
- case 1: memory.set<int8_t>(addr, (int8_t)value.geti64()); break;
- case 2: memory.set<int16_t>(addr, (int16_t)value.geti64()); break;
- case 4: memory.set<int32_t>(addr, (int32_t)value.geti64()); break;
- case 8: memory.set<int64_t>(addr, value.geti64()); break;
- default: abort();
- }
- break;
- }
- // write floats carefully, ensuring all bits reach memory
- case f32: memory.set<int32_t>(addr, value.reinterpreti32()); break;
- case f64: memory.set<int64_t>(addr, value.reinterpreti64()); break;
- default: abort();
- }
- }
-
- void growMemory(size_t /*oldSize*/, size_t newSize) override {
- memory.resize(newSize);
- }
-
- void trap(const char* why) override {
- std::cerr << "[trap " << why << "]\n";
- throw TrapException();
- }
-};
-
//
// An invocation into a module
//
@@ -285,7 +120,7 @@ static void run_asserts(size_t* i, bool* checked, AllocatingModule* wasm,
new SExpressionWasmBuilder(wasm, *curr[1], [&]() {
invalid = true;
throw ParseException();
- })
+ }, false)
);
} catch (const ParseException&) {
invalid = true;
diff --git a/src/js/binaryen.idl b/src/js/binaryen.idl
new file mode 100644
index 000000000..3b52b5912
--- /dev/null
+++ b/src/js/binaryen.idl
@@ -0,0 +1,74 @@
+
+interface Literal {
+ void Literal(double x);
+ double getf64();
+};
+
+interface Name {
+ void Name(DOMString x);
+
+ [Const] DOMString c_str();
+};
+
+interface Module {
+};
+
+interface AllocatingModule {
+ void AllocatingModule();
+};
+
+AllocatingModule implements Module;
+
+[Prefix="ModuleInstance::", NoDelete]
+interface ExternalInterface {
+};
+
+interface ShellExternalInterface {
+ void ShellExternalInterface();
+};
+
+ShellExternalInterface implements ExternalInterface;
+
+interface ModuleInstance {
+ void ModuleInstance([Ref] Module m, ExternalInterface i);
+
+ [Value] Literal callExport([Ref] Name name, [Ref] LiteralList arguments);
+};
+
+[Prefix="ModuleInstance::"]
+interface LiteralList {
+ void LiteralList();
+
+ void push_back([Ref] Literal l);
+};
+
+// S-Expressions
+
+interface Element {
+ boolean isList();
+ boolean isStr();
+ void dump();
+
+ // list methods
+ [Operator="[]"] Element getChild(long i);
+ long size();
+
+ // string methods
+ [Const] DOMString c_str();
+};
+
+interface SExpressionParser {
+ void SExpressionParser(DOMString input);
+ attribute Element root;
+};
+
+interface SExpressionWasmBuilder {
+ void SExpressionWasmBuilder([Ref] AllocatingModule wasm, [Ref] Element input, boolean debug);
+};
+
+// Wasm printing
+
+interface WasmPrinter {
+ static void printModule(Module m);
+};
+
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 77dcb6154..056b61939 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -19,6 +19,7 @@
//
#include <wasm.h>
+#include <wasm-printing.h>
#include <pass.h>
namespace wasm {
@@ -553,7 +554,7 @@ static RegisterPass<MinifiedPrinter> registerMinifyPass("print-minified", "print
// Print individual expressions
-std::ostream& printWasm(Expression* expression, std::ostream& o, bool minify = false) {
+std::ostream& WasmPrinter::printExpression(Expression* expression, std::ostream& o, bool minify) {
PrintSExpression print(o, minify);
print.visit(expression);
return o;
diff --git a/src/s2wasm-main.cpp b/src/s2wasm-main.cpp
index 8cbb7f5f5..80284975b 100644
--- a/src/s2wasm-main.cpp
+++ b/src/s2wasm-main.cpp
@@ -104,7 +104,7 @@ int main(int argc, const char *argv[]) {
if (options.debug) std::cerr << "Printing..." << std::endl;
Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release);
- printWasm(&wasm, output.getStream());
+ WasmPrinter::printModule(&wasm, output.getStream());
output << meta.str() << std::endl;
if (options.debug) std::cerr << "Done." << std::endl;
diff --git a/src/s2wasm.h b/src/s2wasm.h
index 4188003fd..f442de508 100644
--- a/src/s2wasm.h
+++ b/src/s2wasm.h
@@ -1330,7 +1330,7 @@ public:
// extra emscripten processing
void emscriptenGlue(std::ostream& o) {
if (debug) {
- printWasm(&wasm, std::cerr);
+ WasmPrinter::printModule(&wasm, std::cerr);
}
wasm.removeImport(EMSCRIPTEN_ASM_CONST); // we create _sig versions
diff --git a/src/shared-constants.h b/src/shared-constants.h
index 47fa60947..626c5423e 100644
--- a/src/shared-constants.h
+++ b/src/shared-constants.h
@@ -90,7 +90,14 @@ cashew::IString GLOBAL("global"),
MATH_NEAREST("Math_NEAREST"),
MATH_SQRT("Math_sqrt"),
MATH_MIN("Math_max"),
- MATH_MAX("Math_min");
+ MATH_MAX("Math_min"),
+ ASSERT_RETURN("assert_return"),
+ ASSERT_TRAP("assert_trap"),
+ ASSERT_INVALID("assert_invalid"),
+ SPECTEST("spectest"),
+ PRINT("print"),
+ INVOKE("invoke"),
+ EXIT("exit");
}
diff --git a/src/shell-interface.h b/src/shell-interface.h
new file mode 100644
index 000000000..daaf23501
--- /dev/null
+++ b/src/shell-interface.h
@@ -0,0 +1,180 @@
+/*
+ * 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.
+ */
+
+//
+// Implementation of the shell interpreter execution environment
+//
+
+#include "shared-constants.h"
+#include "wasm.h"
+#include "wasm-interpreter.h"
+
+namespace wasm {
+
+struct ExitException {};
+struct TrapException {};
+struct ParseException {};
+
+struct ShellExternalInterface : ModuleInstance::ExternalInterface {
+ // The underlying memory can be accessed through unaligned pointers which
+ // isn't well-behaved in C++. WebAssembly nonetheless expects it to behave
+ // properly. Avoid emitting unaligned load/store by checking for alignment
+ // explicitly, and performing memcpy if unaligned.
+ //
+ // The allocated memory tries to have the same alignment as the memory being
+ // simulated.
+ class Memory {
+ // Use char because it doesn't run afoul of aliasing rules.
+ std::vector<char> memory;
+ template <typename T>
+ static bool aligned(const char* address) {
+ static_assert(!(sizeof(T) & (sizeof(T) - 1)), "must be a power of 2");
+ return 0 == (reinterpret_cast<uintptr_t>(address) & (sizeof(T) - 1));
+ }
+ Memory(Memory&) = delete;
+ Memory& operator=(const Memory&) = delete;
+
+ public:
+ Memory() {}
+ void resize(size_t newSize) {
+ // Ensure the smallest allocation is large enough that most allocators
+ // will provide page-aligned storage. This hopefully allows the
+ // interpreter's memory to be as aligned as the memory being simulated,
+ // ensuring that the performance doesn't needlessly degrade.
+ //
+ // The code is optimistic this will work until WG21's p0035r0 happens.
+ const size_t minSize = 1 << 12;
+ size_t oldSize = memory.size();
+ memory.resize(std::max(minSize, newSize));
+ if (newSize < oldSize && newSize < minSize) {
+ std::memset(&memory[newSize], 0, minSize - newSize);
+ }
+ }
+ template <typename T>
+ void set(size_t address, T value) {
+ if (aligned<T>(&memory[address])) {
+ *reinterpret_cast<T*>(&memory[address]) = value;
+ } else {
+ std::memcpy(&memory[address], &value, sizeof(T));
+ }
+ }
+ template <typename T>
+ T get(size_t address) {
+ if (aligned<T>(&memory[address])) {
+ return *reinterpret_cast<T*>(&memory[address]);
+ } else {
+ T loaded;
+ std::memcpy(&loaded, &memory[address], sizeof(T));
+ return loaded;
+ }
+ }
+ } memory;
+
+ ShellExternalInterface() : memory() {}
+
+ void init(Module& wasm) override {
+ memory.resize(wasm.memory.initial * wasm::Memory::kPageSize);
+ // apply memory segments
+ for (auto segment : wasm.memory.segments) {
+ assert(segment.offset + segment.size <= wasm.memory.initial * wasm::Memory::kPageSize);
+ for (size_t i = 0; i != segment.size; ++i) {
+ memory.set(segment.offset + i, segment.data[i]);
+ }
+ }
+ }
+
+ Literal callImport(Import *import, ModuleInstance::LiteralList& arguments) override {
+ if (import->module == SPECTEST && import->base == PRINT) {
+ for (auto argument : arguments) {
+ std::cout << argument << '\n';
+ }
+ return Literal();
+ } else if (import->module == ENV && import->base == EXIT) {
+ // XXX hack for torture tests
+ std::cout << "exit()\n";
+ throw ExitException();
+ }
+ std::cout << "callImport " << import->name.str << "\n";
+ abort();
+ }
+
+ Literal load(Load* load, size_t addr) override {
+ switch (load->type) {
+ case i32: {
+ switch (load->bytes) {
+ case 1: return load->signed_ ? Literal((int32_t)memory.get<int8_t>(addr)) : Literal((int32_t)memory.get<uint8_t>(addr));
+ case 2: return load->signed_ ? Literal((int32_t)memory.get<int16_t>(addr)) : Literal((int32_t)memory.get<uint16_t>(addr));
+ case 4: return load->signed_ ? Literal((int32_t)memory.get<int32_t>(addr)) : Literal((int32_t)memory.get<uint32_t>(addr));
+ default: abort();
+ }
+ break;
+ }
+ case i64: {
+ switch (load->bytes) {
+ case 1: return load->signed_ ? Literal((int64_t)memory.get<int8_t>(addr)) : Literal((int64_t)memory.get<uint8_t>(addr));
+ case 2: return load->signed_ ? Literal((int64_t)memory.get<int16_t>(addr)) : Literal((int64_t)memory.get<uint16_t>(addr));
+ case 4: return load->signed_ ? Literal((int64_t)memory.get<int32_t>(addr)) : Literal((int64_t)memory.get<uint32_t>(addr));
+ case 8: return load->signed_ ? Literal((int64_t)memory.get<int64_t>(addr)) : Literal((int64_t)memory.get<uint64_t>(addr));
+ default: abort();
+ }
+ break;
+ }
+ case f32: return Literal(memory.get<float>(addr));
+ case f64: return Literal(memory.get<double>(addr));
+ default: abort();
+ }
+ }
+
+ void store(Store* store, size_t addr, Literal value) override {
+ switch (store->type) {
+ case i32: {
+ switch (store->bytes) {
+ case 1: memory.set<int8_t>(addr, value.geti32()); break;
+ case 2: memory.set<int16_t>(addr, value.geti32()); break;
+ case 4: memory.set<int32_t>(addr, value.geti32()); break;
+ default: abort();
+ }
+ break;
+ }
+ case i64: {
+ switch (store->bytes) {
+ case 1: memory.set<int8_t>(addr, (int8_t)value.geti64()); break;
+ case 2: memory.set<int16_t>(addr, (int16_t)value.geti64()); break;
+ case 4: memory.set<int32_t>(addr, (int32_t)value.geti64()); break;
+ case 8: memory.set<int64_t>(addr, value.geti64()); break;
+ default: abort();
+ }
+ break;
+ }
+ // write floats carefully, ensuring all bits reach memory
+ case f32: memory.set<int32_t>(addr, value.reinterpreti32()); break;
+ case f64: memory.set<int64_t>(addr, value.reinterpreti64()); break;
+ default: abort();
+ }
+ }
+
+ void growMemory(size_t /*oldSize*/, size_t newSize) override {
+ memory.resize(newSize);
+ }
+
+ void trap(const char* why) override {
+ std::cerr << "[trap " << why << "]\n";
+ throw TrapException();
+ }
+};
+
+}
+
diff --git a/src/wasm-as.cpp b/src/wasm-as.cpp
index c2a8abc6e..37085a350 100644
--- a/src/wasm-as.cpp
+++ b/src/wasm-as.cpp
@@ -49,7 +49,7 @@ int main(int argc, const char *argv[]) {
if (options.debug) std::cerr << "w-parsing..." << std::endl;
AllocatingModule wasm;
- SExpressionWasmBuilder builder(wasm, *root[0], [&]() { abort(); });
+ SExpressionWasmBuilder builder(wasm, *root[0], [&]() { abort(); }, false);
if (options.debug) std::cerr << "binarification..." << std::endl;
BufferWithRandomAccess buffer(options.debug);
diff --git a/src/wasm-dis.cpp b/src/wasm-dis.cpp
index c3197a1a2..5e1e61682 100644
--- a/src/wasm-dis.cpp
+++ b/src/wasm-dis.cpp
@@ -50,7 +50,7 @@ int main(int argc, const char *argv[]) {
if (options.debug) std::cerr << "Printing..." << std::endl;
Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release);
- printWasm(&wasm, output.getStream());
+ WasmPrinter::printModule(&wasm, output.getStream());
output << '\n';
if (options.debug) std::cerr << "Done." << std::endl;
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 2be386f95..ed6411258 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -109,8 +109,8 @@ public:
}
}
- Literal callExport(IString name, LiteralList& arguments) {
- Export *export_ = wasm.getExport(name);
+ Literal callExport(Name name, LiteralList& arguments) {
+ Export *export_ = wasm.checkExport(name);
if (!export_) externalInterface->trap("callExport not found");
return callFunction(export_->value, arguments);
}
diff --git a/src/wasm-js.cpp b/src/wasm-js.cpp
index 6612e1e00..c9cb06118 100644
--- a/src/wasm-js.cpp
+++ b/src/wasm-js.cpp
@@ -132,7 +132,7 @@ extern "C" void EMSCRIPTEN_KEEPALIVE load_s_expr2wasm(char *input) {
sExpressionWasmBuilder = new SExpressionWasmBuilder(*module, *root[0], [&]() {
std::cerr << "error in parsing s-expressions to wasm\n";
abort();
- });
+ }, false);
finalizeModule();
}
diff --git a/src/wasm-printing.h b/src/wasm-printing.h
index 5b47a38bb..2fab99938 100644
--- a/src/wasm-printing.h
+++ b/src/wasm-printing.h
@@ -17,30 +17,38 @@
#ifndef __wasm_printing_h__
#define __wasm_printing_h__
+#include <ostream>
+
#include "wasm.h"
#include "pass.h"
namespace wasm {
-inline std::ostream& printWasm(Module* module, std::ostream& o) {
- PassRunner passRunner(nullptr);
- passRunner.add<Printer>(o);
- passRunner.run(module);
- return o;
-}
+struct WasmPrinter {
+ static std::ostream& printModule(Module* module, std::ostream& o) {
+ PassRunner passRunner(nullptr);
+ passRunner.add<Printer>(o);
+ passRunner.run(module);
+ return o;
+ }
+
+ static std::ostream& printModule(Module* module) {
+ return printModule(module, std::cout);
+ }
-extern std::ostream& printWasm(Expression* expression, std::ostream& o, bool minify = false);
+ static std::ostream& printExpression(Expression* expression, std::ostream& o, bool minify = false);
+};
}
namespace std {
-std::ostream& operator<<(std::ostream& o, wasm::Module* module) {
- return wasm::printWasm(module, o);
+inline std::ostream& operator<<(std::ostream& o, wasm::Module* module) {
+ return wasm::WasmPrinter::printModule(module, o);
}
-std::ostream& operator<<(std::ostream& o, wasm::Expression* expression) {
- return wasm::printWasm(expression, o);
+inline std::ostream& operator<<(std::ostream& o, wasm::Expression* expression) {
+ return wasm::WasmPrinter::printExpression(expression, o);
}
}
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index c13cd3512..0d2ecd570 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -111,6 +111,10 @@ public:
}
return o;
}
+
+ void dump() {
+ std::cout << "dumping " << this << " : " << *this << ".\n";
+ }
};
//
@@ -255,6 +259,9 @@ public:
}
}
+ // constructor without onError
+ SExpressionWasmBuilder(AllocatingModule& wasm, Element& module, bool debug=false) : SExpressionWasmBuilder(wasm, module, [&]() { abort(); }, debug) {}
+
private:
// pre-parse types and function definitions, so we know function return types before parsing their contents
diff --git a/src/wasm2asm-main.cpp b/src/wasm2asm-main.cpp
index 2234f2343..d67dc7a88 100644
--- a/src/wasm2asm-main.cpp
+++ b/src/wasm2asm-main.cpp
@@ -52,7 +52,7 @@ int main(int argc, const char *argv[]) {
if (options.debug) std::cerr << "w-parsing..." << std::endl;
AllocatingModule wasm;
- SExpressionWasmBuilder builder(wasm, *root[0], [&]() { abort(); });
+ SExpressionWasmBuilder builder(wasm, *root[0], [&]() { abort(); }, false);
if (options.debug) std::cerr << "asming..." << std::endl;
Wasm2AsmBuilder wasm2asm(options.debug);