diff options
-rwxr-xr-x | build.sh | 2 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 4 | ||||
-rw-r--r-- | src/wasm-js.cpp | 63 |
3 files changed, 66 insertions, 3 deletions
@@ -1,5 +1,5 @@ echo "building asm2wasm" g++ -std=c++11 src/asm2wasm-main.cpp src/parser.cpp src/simple_ast.cpp src/optimizer-shared.cpp -g -o bin/asm2wasm echo "building interpreter/js" -em++ -std=c++11 src/wasm-js.cpp -o bin/wasm.js +em++ -std=c++11 src/wasm-js.cpp src/parser.cpp src/simple_ast.cpp src/optimizer-shared.cpp -o bin/wasm.js diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index ede2f00df..5d6130641 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -17,7 +17,7 @@ public: typedef std::vector<Literal> LiteralList; struct ExternalInterface { - virtual Literal callImport(IString name, LiteralList& arguments) = 0; + virtual Literal callImport(Import* import, LiteralList& arguments) = 0; virtual Literal load(Load* load, Literal ptr) = 0; virtual Literal store(Store* store, Literal ptr, Literal value) = 0; }; @@ -146,7 +146,7 @@ public: LiteralList arguments; Flow flow = generateArguments(curr->operands, arguments); if (flow.breaking()) return flow; - return instance.externalInterface->callImport(curr->target, arguments); + return instance.externalInterface->callImport(&instance.wasm.imports[curr->target], arguments); } Flow visitCallIndirect(CallIndirect *curr) override { Flow target = visit(curr->target); diff --git a/src/wasm-js.cpp b/src/wasm-js.cpp index ccc589485..e2ef47bbb 100644 --- a/src/wasm-js.cpp +++ b/src/wasm-js.cpp @@ -1,4 +1,67 @@ +// +// wasm intepreter for asm2wasm output, in a js environment. receives asm.js, +// generates a runnable module suitable as a polyfill. +// + +#include <emscripten.h> + +#include "asm2wasm.h" #include "wasm-interpreter.h" +using namespace cashew; +using namespace wasm; + +// receives asm.js code, parses into wasm and returns an instance handle. +// this creates a module, an external interface, and a module instance, +// all of which are then the responsibility of the caller to free. +// note: this modifies the input. +extern "C" ModuleInstance* EMSCRIPTEN_KEEPALIVE load_asm(char *input) { + // emcc --separate-asm modules look like + // + // Module["asm"] = (function(global, env, buffer) { + // .. + // }); + // + // we need to clean that up. + size_t num = strlen(input); + assert(*input == 'M'); + while (*input != 'f') { + input++; + num--; + } + char *end = input + num - 1; + while (*end != '}') { + *end = 0; + end--; + } + + if (debug) std::cerr << "parsing...\n"; + cashew::Parser<Ref, DotZeroValueBuilder> builder; + Ref asmjs = builder.parseToplevel(input); + + Module* wasm = new Module(); + + if (debug) std::cerr << "wasming...\n"; + Asm2WasmBuilder asm2wasm(*wasm); + asm2wasm.processAsm(asmjs); + + if (debug) std::cerr << "optimizing...\n"; + asm2wasm.optimize(); + + if (debug) std::cerr << "returning instance.\n"; + + struct JSExternalInterface : ModuleInstance::ExternalInterface { + Literal callImport(Import *import, ModuleInstance::LiteralList& arguments) override { + } + + Literal load(Load* load, Literal ptr) override { + } + + Literal store(Store* store, Literal ptr, Literal value) override { + } + }; + + return new ModuleInstance(*wasm, new JSExternalInterface()); +} |