summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2015-10-31 12:30:30 -0700
committerAlon Zakai <alonzakai@gmail.com>2015-10-31 12:30:30 -0700
commitdcdf2e222f0b42c71ca41f7e37bc77decfef37f7 (patch)
tree5bc17c309ef4b7a8b631603a07d96df610bbbc75
parentb39e36e0b3cc74de46d62f7448058942240555c5 (diff)
downloadbinaryen-dcdf2e222f0b42c71ca41f7e37bc77decfef37f7.tar.gz
binaryen-dcdf2e222f0b42c71ca41f7e37bc77decfef37f7.tar.bz2
binaryen-dcdf2e222f0b42c71ca41f7e37bc77decfef37f7.zip
start to sketch out interpreter/js
-rwxr-xr-xbuild.sh2
-rw-r--r--src/wasm-interpreter.h4
-rw-r--r--src/wasm-js.cpp63
3 files changed, 66 insertions, 3 deletions
diff --git a/build.sh b/build.sh
index 37e345972..c7947ebed 100755
--- a/build.sh
+++ b/build.sh
@@ -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());
+}