summaryrefslogtreecommitdiff
path: root/src/wasm-interpreter.h
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-09-21 19:33:11 -0700
committerGitHub <noreply@github.com>2016-09-21 19:33:11 -0700
commit8be82627c6a8cbded0dab67ad1f31906a54ba78c (patch)
treeb7b14f1899ffe39a7562007474a58948685146c8 /src/wasm-interpreter.h
parent7292ef9c863a0766c697cc0a77516447ff652820 (diff)
parent740e36eab98d679387fea60cd642591a69ce809f (diff)
downloadbinaryen-8be82627c6a8cbded0dab67ad1f31906a54ba78c.tar.gz
binaryen-8be82627c6a8cbded0dab67ad1f31906a54ba78c.tar.bz2
binaryen-8be82627c6a8cbded0dab67ad1f31906a54ba78c.zip
Merge pull request #703 from WebAssembly/spec-update
Spec update - get us passing the 0xc spec tests (minus stacky stuff)
Diffstat (limited to 'src/wasm-interpreter.h')
-rw-r--r--src/wasm-interpreter.h36
1 files changed, 26 insertions, 10 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 292d6a521..942ba1ab6 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -51,14 +51,14 @@ class Flow {
public:
Flow() {}
Flow(Literal value) : value(value) {}
- Flow(IString breakTo) : breakTo(breakTo) {}
+ Flow(Name breakTo) : breakTo(breakTo) {}
Literal value;
- IString breakTo; // if non-null, a break is going on
+ Name breakTo; // if non-null, a break is going on
bool breaking() { return breakTo.is(); }
- void clearIf(IString target) {
+ void clearIf(Name target) {
if (breakTo == target) {
breakTo.clear();
}
@@ -155,18 +155,19 @@ public:
Flow visitBreak(Break *curr) {
NOTE_ENTER("Break");
bool condition = true;
- Flow flow(curr->name);
+ Flow flow;
if (curr->value) {
flow = visit(curr->value);
if (flow.breaking()) return flow;
- flow.breakTo = curr->name;
}
if (curr->condition) {
Flow conditionFlow = visit(curr->condition);
if (conditionFlow.breaking()) return conditionFlow;
condition = conditionFlow.value.getInteger() != 0;
+ if (!condition) return flow;
}
- return condition ? flow : Flow();
+ flow.breakTo = curr->name;
+ return flow;
}
Flow visitSwitch(Switch *curr) {
NOTE_ENTER("Switch");
@@ -553,12 +554,23 @@ public:
}
}
+ // call an exported function
Literal callExport(Name name, LiteralList& arguments) {
Export *export_ = wasm.checkExport(name);
if (!export_) externalInterface->trap("callExport not found");
return callFunction(export_->value, arguments);
}
+ // get an exported global
+ Literal getExport(Name name) {
+ Export *export_ = wasm.checkExport(name);
+ if (!export_) externalInterface->trap("getExport external not found");
+ Name internalName = export_->value;
+ auto iter = globals.find(internalName);
+ if (iter == globals.end()) externalInterface->trap("getExport internal not found");
+ return iter->second;
+ }
+
std::string printFunctionStack() {
std::string ret = "/== (binaryen interpreter stack trace)\n";
for (int i = int(functionStack.size()) - 1; i >= 0; i--) {
@@ -577,7 +589,7 @@ private:
std::vector<Name> functionStack;
// Call a function, starting an invocation.
- Literal callFunction(IString name, LiteralList& arguments) {
+ Literal callFunction(Name name, LiteralList& arguments) {
// if the last call ended in a jump up the stack, it might have left stuff for us to clean up here
callDepth = 0;
functionStack.clear();
@@ -586,7 +598,7 @@ private:
public:
// Internal function call. Must be public so that callTable implementations can use it (refactor?)
- Literal callFunctionInternal(IString name, LiteralList& arguments) {
+ Literal callFunctionInternal(Name name, LiteralList& arguments) {
class FunctionScope {
public:
@@ -695,6 +707,7 @@ public:
auto name = curr->name;
NOTE_EVAL1(name);
NOTE_EVAL1(instance.globals[name]);
+ assert(instance.globals.find(name) != instance.globals.end());
return instance.globals[name];
}
Flow visitSetGlobal(SetGlobal *curr) {
@@ -744,7 +757,7 @@ public:
return Literal(int32_t(ret));
}
case HasFeature: {
- IString id = curr->nameOperand;
+ Name id = curr->nameOperand;
if (id == WASM) return Literal(1);
return Literal((int32_t)0);
}
@@ -775,7 +788,10 @@ public:
assert(!flow.breaking() || flow.breakTo == RETURN_FLOW); // cannot still be breaking, it means we missed our stop
Literal ret = flow.value;
if (function->result == none) ret = Literal();
- assert(function->result == ret.type);
+ if (function->result != ret.type) {
+ std::cerr << "calling " << function->name << " resulted in " << ret << " but the function type is " << function->result << '\n';
+ abort();
+ }
callDepth = previousCallDepth; // may decrease more than one, if we jumped up the stack
// if we jumped up the stack, we also need to pop higher frames
while (functionStack.size() > previousFunctionStackSize) {