diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/asm2wasm-main.cpp | 2 | ||||
-rw-r--r-- | src/binaryen-js.cpp | 31 | ||||
-rw-r--r-- | src/binaryen-shell.cpp | 169 | ||||
-rw-r--r-- | src/js/binaryen.idl | 74 | ||||
-rw-r--r-- | src/passes/Print.cpp | 3 | ||||
-rw-r--r-- | src/s2wasm-main.cpp | 2 | ||||
-rw-r--r-- | src/s2wasm.h | 2 | ||||
-rw-r--r-- | src/shared-constants.h | 9 | ||||
-rw-r--r-- | src/shell-interface.h | 180 | ||||
-rw-r--r-- | src/wasm-as.cpp | 2 | ||||
-rw-r--r-- | src/wasm-dis.cpp | 2 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 4 | ||||
-rw-r--r-- | src/wasm-js.cpp | 2 | ||||
-rw-r--r-- | src/wasm-printing.h | 30 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 7 | ||||
-rw-r--r-- | src/wasm2asm-main.cpp | 2 |
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); |