diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-02-12 21:36:10 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-02-12 21:36:10 -0800 |
commit | 6395ca27a90fdb50f1b74ca0b17e25d39f80342e (patch) | |
tree | c603fee03901942c7bad83dc7c820cd2ab941cad /src | |
parent | adadace7899133b4a25dab47044a373879647ddb (diff) | |
parent | f061ca831b4ec6d9d3fab0043a42fce0a0b52cf7 (diff) | |
download | binaryen-6395ca27a90fdb50f1b74ca0b17e25d39f80342e.tar.gz binaryen-6395ca27a90fdb50f1b74ca0b17e25d39f80342e.tar.bz2 binaryen-6395ca27a90fdb50f1b74ca0b17e25d39f80342e.zip |
Merge pull request #196 from WebAssembly/spec-start
Fully support start in wasm modules
Diffstat (limited to 'src')
-rw-r--r-- | src/binaryen-shell.cpp | 108 | ||||
-rw-r--r-- | src/wasm-binary.h | 17 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 4 | ||||
-rw-r--r-- | src/wasm-validator.h | 15 |
4 files changed, 94 insertions, 50 deletions
diff --git a/src/binaryen-shell.cpp b/src/binaryen-shell.cpp index 4c973c50e..d450e4db7 100644 --- a/src/binaryen-shell.cpp +++ b/src/binaryen-shell.cpp @@ -242,20 +242,24 @@ static void run_asserts(size_t* i, bool* checked, AllocatingModule* wasm, std::unique_ptr<SExpressionWasmBuilder>* builder, bool print_before, bool print_after, Name entry) { - auto interface = new ShellExternalInterface(); - auto instance = new ModuleInstance(*wasm, interface); - if (entry.is() > 0) { - Function* function = wasm->functionsMap[entry]; - if (!function) { - std::cerr << "Unknown entry " << entry << std::endl; - } else { - ModuleInstance::LiteralList arguments; - for (NameType param : function->params) { - arguments.push_back(Literal(param.type)); - } - try { - instance->callExport(entry, arguments); - } catch (ExitException& x) { + ShellExternalInterface* interface = nullptr; + ModuleInstance* instance = nullptr; + if (wasm) { + interface = new ShellExternalInterface(); + instance = new ModuleInstance(*wasm, interface); + if (entry.is() > 0) { + Function* function = wasm->functionsMap[entry]; + if (!function) { + std::cerr << "Unknown entry " << entry << std::endl; + } else { + ModuleInstance::LiteralList arguments; + for (NameType param : function->params) { + arguments.push_back(Literal(param.type)); + } + try { + instance->callExport(entry, arguments); + } catch (ExitException& x) { + } } } } @@ -280,12 +284,14 @@ static void run_asserts(size_t* i, bool* checked, AllocatingModule* wasm, std::cout << wasm; } bool invalid = false; + std::unique_ptr<SExpressionWasmBuilder> builder; try { - *builder = std::unique_ptr<SExpressionWasmBuilder>( - new SExpressionWasmBuilder(wasm, *curr[1], [&]() { - invalid = true; - throw ParseException(); - })); + builder = std::unique_ptr<SExpressionWasmBuilder>( + new SExpressionWasmBuilder(wasm, *curr[1], [&]() { + invalid = true; + throw ParseException(); + }) + ); } catch (const ParseException& e) { invalid = true; } @@ -295,10 +301,12 @@ static void run_asserts(size_t* i, bool* checked, AllocatingModule* wasm, } assert(invalid); } else if (id == INVOKE) { + assert(wasm); Invocation invocation(curr, instance, *builder->get()); invocation.invoke(); } else { // an invoke test + assert(wasm); bool trapped = false; Literal result; try { @@ -390,39 +398,45 @@ int main(int argc, const char* argv[]) { bool checked = false; size_t i = 0; while (i < root.size()) { - if (options.debug) std::cerr << "parsing s-expressions to wasm...\n"; - AllocatingModule wasm; - std::unique_ptr<SExpressionWasmBuilder> builder( - new SExpressionWasmBuilder(wasm, *root[i], [&]() { abort(); }, options.debug)); - i++; - - if (print_before) { - Colors::bold(std::cout); - std::cerr << "printing before:\n"; - Colors::normal(std::cout); - std::cout << wasm; - } + Element& curr = *root[i]; + IString id = curr[0]->str(); + if (id == MODULE) { + if (options.debug) std::cerr << "parsing s-expressions to wasm...\n"; + AllocatingModule wasm; + std::unique_ptr<SExpressionWasmBuilder> builder( + new SExpressionWasmBuilder(wasm, *root[i], [&]() { abort(); }, options.debug)); + i++; + + if (print_before) { + Colors::bold(std::cout); + std::cerr << "printing before:\n"; + Colors::normal(std::cout); + std::cout << wasm; + } - MixedArena moreModuleAllocations; + MixedArena moreModuleAllocations; - if (passes.size() > 0) { - if (options.debug) std::cerr << "running passes...\n"; - PassRunner passRunner(&moreModuleAllocations); - for (auto& passName : passes) { - passRunner.add(passName); + if (passes.size() > 0) { + if (options.debug) std::cerr << "running passes...\n"; + PassRunner passRunner(&moreModuleAllocations); + for (auto& passName : passes) { + passRunner.add(passName); + } + passRunner.run(&wasm); } - passRunner.run(&wasm); - } - if (print_after) { - Colors::bold(std::cout); - std::cerr << "printing after:\n"; - Colors::normal(std::cout); - std::cout << wasm; + if (print_after) { + Colors::bold(std::cout); + std::cerr << "printing after:\n"; + Colors::normal(std::cout); + std::cout << wasm; + } + run_asserts(&i, &checked, &wasm, &root, &builder, print_before, + print_after, entry); + } else { + run_asserts(&i, &checked, nullptr, &root, nullptr, print_before, + print_after, entry); } - - run_asserts(&i, &checked, &wasm, &root, &builder, print_before, - print_after, entry); } if (checked) { diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 2c884a4f5..b1db70a97 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -155,7 +155,8 @@ enum Section { Functions = 2, DataSegments = 4, FunctionTable = 5, - End = 6 + End = 6, + Start = 7 }; enum FunctionEntry { @@ -380,6 +381,7 @@ public: } void write() { + writeStart(); writeMemory(); writeSignatures(); writeFunctions(); @@ -389,6 +391,13 @@ public: finishUp(); } + void writeStart() { + if (!wasm->start.is()) return; + if (debug) std::cerr << "== writeStart" << std::endl; + o << int8_t(BinaryConsts::Start); + emitString(wasm->start.str); + } + void writeMemory() { if (wasm->memory.max == 0) return; if (debug) std::cerr << "== writeMemory" << std::endl; @@ -980,6 +989,7 @@ public: } switch (section) { + case BinaryConsts::Start: readStart(); break; case BinaryConsts::Memory: readMemory(); break; case BinaryConsts::Signatures: readSignatures(); break; case BinaryConsts::Functions: readFunctions(); break; @@ -1082,6 +1092,11 @@ public: assert(x == y); } + void readStart() { + if (debug) std::cerr << "== readStart" << std::endl; + wasm.start = getString(); + } + void readMemory() { if (debug) std::cerr << "== readMemory" << std::endl; size_t initial = getInt8(); diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 267615a55..59e42783d 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -100,6 +100,10 @@ public: ModuleInstance(Module& wasm, ExternalInterface* externalInterface) : wasm(wasm), externalInterface(externalInterface) { memorySize = wasm.memory.initial; externalInterface->init(wasm); + if (wasm.start.is()) { + LiteralList arguments; + callFunction(wasm.start, arguments); + } } Literal callExport(IString name, LiteralList& arguments) { diff --git a/src/wasm-validator.h b/src/wasm-validator.h index fad33a081..04493bb5b 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -104,6 +104,7 @@ public: shouldBeFalse(top > curr->initial); } void visitModule(Module *curr) { + // exports for (auto& exp : curr->exports) { Name name = exp->name; bool found = false; @@ -115,6 +116,14 @@ public: } shouldBeTrue(found); } + // start + if (curr->start.is()) { + auto iter = curr->functionsMap.find(curr->start); + if (shouldBeTrue(iter != curr->functionsMap.end())) { + auto func = iter->second; + shouldBeTrue(func->params.size() == 0); // must be nullary + } + } } private: @@ -135,11 +144,13 @@ private: // helpers - void shouldBeTrue(bool result) { + bool shouldBeTrue(bool result) { if (!result) valid = false; + return result; } - void shouldBeFalse(bool result) { + bool shouldBeFalse(bool result) { if (result) valid = false; + return result; } void validateAlignment(size_t align) { |