summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/wasm-interpreter.h3
-rw-r--r--src/wasm-s-parser.h36
-rw-r--r--src/wasm.h2
3 files changed, 27 insertions, 14 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 59e42783d..2a841f6fd 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -579,6 +579,7 @@ private:
case GrowMemory: {
Flow flow = visit(curr->operands[0]);
if (flow.breaking()) return flow;
+ int32_t ret = instance.memorySize;
uint32_t delta = flow.value.geti32();
if (delta % pageSize != 0) trap("growMemory: delta not multiple");
if (delta > uint32_t(-1) - pageSize) trap("growMemory: delta relatively too big");
@@ -587,7 +588,7 @@ private:
if (newSize > instance.wasm.memory.max) trap("growMemory: exceeds max");
instance.externalInterface->growMemory(instance.memorySize, newSize);
instance.memorySize = newSize;
- return Literal();
+ return Literal(ret);
}
case HasFeature: {
IString id = curr->nameOperand;
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index a6b8e61b6..d0206bcc2 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -222,6 +222,7 @@ class SExpressionWasmBuilder {
AllocatingModule& wasm;
MixedArena& allocator;
std::function<void ()> onError;
+ std::vector<Name> functionNames;
int functionCounter;
int importCounter;
std::map<Name, WasmType> functionTypes; // we need to know function return types before we parse their contents
@@ -258,6 +259,7 @@ private:
// unnamed, use an index
name = Name::fromInt(functionCounter);
}
+ functionNames.push_back(name);
functionCounter++;
for (;i < s.size(); i++) {
Element& curr = *s[i];
@@ -868,18 +870,21 @@ private:
i++;
}
}
-
- Expression* makeBreak(Element& s) {
- auto ret = allocator.alloc<Break>();
- size_t i = 1;
- if (s[i]->dollared()) {
- ret->name = s[i]->str();
+ Name getLabel(Element& s) {
+ if (s.dollared()) {
+ return s.str();
} else {
+ size_t offset = atol(s.c_str());
+ if (offset >= labelStack.size())
+ return getPrefixedName("invalid");
// offset, break to nth outside label
- size_t offset = atol(s[i]->c_str());
- assert(offset < labelStack.size());
- ret->name = labelStack[labelStack.size() - 1 - offset];
+ return labelStack[labelStack.size() - 1 - offset];
}
+ }
+ Expression* makeBreak(Element& s) {
+ auto ret = allocator.alloc<Break>();
+ size_t i = 1;
+ ret->name = getLabel(*s[i]);
i++;
if (i == s.size()) return ret;
if (s[0]->str() == BR_IF) {
@@ -911,16 +916,17 @@ private:
} else {
ret->name = getPrefixedName("switch");
}
+ labelStack.push_back(ret->name);
ret->value = parseExpression(s[i]);
i++;
Element& table = *s[i];
i++;
for (size_t j = 1; j < table.size(); j++) {
Element& curr = *table[j];
- ret->targets.push_back(curr[1]->str());
+ ret->targets.push_back(getLabel(*curr[1]));
}
Element& curr = *s[i];
- ret->default_ = curr[1]->str();
+ ret->default_ = getLabel(*curr[1]);
i++;
for (; i < s.size(); i++) {
Element& curr = *s[i];
@@ -929,6 +935,7 @@ private:
ret->cases.emplace_back(curr[1]->str(), makeMaybeBlock(curr, 2, curr.size()));
}
ret->type = ret->cases.size() > 0 ? ret->cases[0].body->type : none;
+ labelStack.pop_back();
return ret;
}
@@ -1031,7 +1038,12 @@ private:
void parseTable(Element& s) {
for (size_t i = 1; i < s.size(); i++) {
- wasm.table.names.push_back(s[i]->str());
+ Name name = s[i]->str();
+ if (!s[i]->dollared()) {
+ // index, we haven't
+ name = functionNames[atoi(name.str)];
+ }
+ wasm.table.names.push_back(name);
}
}
diff --git a/src/wasm.h b/src/wasm.h
index 4c8dca331..ec2cd469e 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -1017,7 +1017,7 @@ public:
break;
}
case GrowMemory: {
- type = none;
+ type = i32;
break;
}
default: abort();