summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wasm-binary.cpp44
-rw-r--r--src/wasm/wasm-emscripten.cpp2
-rw-r--r--src/wasm/wasm-s-parser.cpp22
-rw-r--r--src/wasm/wasm-stack.cpp18
-rw-r--r--src/wasm/wasm-validator.cpp29
-rw-r--r--src/wasm/wasm.cpp28
6 files changed, 60 insertions, 83 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 2910bb383..e958dca6e 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -2452,6 +2452,14 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
case BinaryConsts::BrOnExn:
visitBrOnExn((curr = allocator.alloc<BrOnExn>())->cast<BrOnExn>());
break;
+ case BinaryConsts::MemorySize:
+ visitMemorySize(
+ (curr = allocator.alloc<MemorySize>())->cast<MemorySize>());
+ break;
+ case BinaryConsts::MemoryGrow:
+ visitMemoryGrow(
+ (curr = allocator.alloc<MemoryGrow>())->cast<MemoryGrow>());
+ break;
case BinaryConsts::AtomicPrefix: {
code = static_cast<uint8_t>(getU32LEB());
if (maybeVisitLoad(curr, code, /*isAtomic=*/true)) {
@@ -2551,9 +2559,6 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
if (maybeVisitStore(curr, code, /*isAtomic=*/false)) {
break;
}
- if (maybeVisitHost(curr, code)) {
- break;
- }
throwError("bad node code " + std::to_string(code));
break;
}
@@ -4763,32 +4768,23 @@ void WasmBinaryBuilder::visitReturn(Return* curr) {
curr->finalize();
}
-bool WasmBinaryBuilder::maybeVisitHost(Expression*& out, uint8_t code) {
- Host* curr;
- switch (code) {
- case BinaryConsts::MemorySize: {
- curr = allocator.alloc<Host>();
- curr->op = MemorySize;
- break;
- }
- case BinaryConsts::MemoryGrow: {
- curr = allocator.alloc<Host>();
- curr->op = MemoryGrow;
- curr->operands.resize(1);
- curr->operands[0] = popNonVoidExpression();
- break;
- }
- default:
- return false;
+void WasmBinaryBuilder::visitMemorySize(MemorySize* curr) {
+ BYN_TRACE("zz node: MemorySize\n");
+ auto reserved = getU32LEB();
+ if (reserved != 0) {
+ throwError("Invalid reserved field on memory.size");
}
- BYN_TRACE("zz node: Host\n");
+ curr->finalize();
+}
+
+void WasmBinaryBuilder::visitMemoryGrow(MemoryGrow* curr) {
+ BYN_TRACE("zz node: MemoryGrow\n");
+ curr->delta = popNonVoidExpression();
auto reserved = getU32LEB();
if (reserved != 0) {
- throwError("Invalid reserved field on memory.grow/memory.size");
+ throwError("Invalid reserved field on memory.grow");
}
curr->finalize();
- out = curr;
- return true;
}
void WasmBinaryBuilder::visitNop(Nop* curr) { BYN_TRACE("zz node: Nop\n"); }
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp
index e41d0df48..a0f0ade9d 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -122,7 +122,7 @@ Function* EmscriptenGlueGenerator::generateMemoryGrowthFunction() {
Function* growFunction =
builder.makeFunction(name, std::move(params), Type::i32, {});
growFunction->body =
- builder.makeHost(MemoryGrow, Name(), {builder.makeLocalGet(0, Type::i32)});
+ builder.makeMemoryGrow(builder.makeLocalGet(0, Type::i32));
addExportedFunction(wasm, growFunction);
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 97da80fea..2883519f2 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -1021,19 +1021,15 @@ Expression* SExpressionWasmBuilder::makeDrop(Element& s) {
return ret;
}
-Expression* SExpressionWasmBuilder::makeHost(Element& s, HostOp op) {
- auto ret = allocator.alloc<Host>();
- ret->op = op;
- parseCallOperands(s, 1, s.size(), ret);
- if (ret->op == HostOp::MemoryGrow) {
- if (ret->operands.size() != 1) {
- throw ParseException("memory.grow needs one operand", s.line, s.col);
- }
- } else {
- if (ret->operands.size() != 0) {
- throw ParseException("host needs zero operands", s.line, s.col);
- }
- }
+Expression* SExpressionWasmBuilder::makeMemorySize(Element& s) {
+ auto ret = allocator.alloc<MemorySize>();
+ ret->finalize();
+ return ret;
+}
+
+Expression* SExpressionWasmBuilder::makeMemoryGrow(Element& s) {
+ auto ret = allocator.alloc<MemoryGrow>();
+ ret->delta = parseExpression(s[1]);
ret->finalize();
return ret;
}
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 64622e814..edfdf31d1 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -1671,17 +1671,13 @@ void BinaryInstWriter::visitReturn(Return* curr) {
o << int8_t(BinaryConsts::Return);
}
-void BinaryInstWriter::visitHost(Host* curr) {
- switch (curr->op) {
- case MemorySize: {
- o << int8_t(BinaryConsts::MemorySize);
- break;
- }
- case MemoryGrow: {
- o << int8_t(BinaryConsts::MemoryGrow);
- break;
- }
- }
+void BinaryInstWriter::visitMemorySize(MemorySize* curr) {
+ o << int8_t(BinaryConsts::MemorySize);
+ o << U32LEB(0); // Reserved flags field
+}
+
+void BinaryInstWriter::visitMemoryGrow(MemoryGrow* curr) {
+ o << int8_t(BinaryConsts::MemoryGrow);
o << U32LEB(0); // Reserved flags field
}
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 15fb66926..c141fdd6f 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -326,7 +326,8 @@ public:
void visitSelect(Select* curr);
void visitDrop(Drop* curr);
void visitReturn(Return* curr);
- void visitHost(Host* curr);
+ void visitMemorySize(MemorySize* curr);
+ void visitMemoryGrow(MemoryGrow* curr);
void visitRefIsNull(RefIsNull* curr);
void visitRefFunc(RefFunc* curr);
void visitTry(Try* curr);
@@ -1897,24 +1898,18 @@ void FunctionValidator::visitReturn(Return* curr) {
returnTypes.insert(curr->value ? curr->value->type : Type::none);
}
-void FunctionValidator::visitHost(Host* curr) {
+void FunctionValidator::visitMemorySize(MemorySize* curr) {
shouldBeTrue(
getModule()->memory.exists, curr, "Memory operations require a memory");
- switch (curr->op) {
- case MemoryGrow: {
- shouldBeEqual(curr->operands.size(),
- size_t(1),
- curr,
- "memory.grow must have 1 operand");
- shouldBeEqualOrFirstIsUnreachable(curr->operands[0]->type,
- Type(Type::i32),
- curr,
- "memory.grow must have i32 operand");
- break;
- }
- case MemorySize:
- break;
- }
+}
+
+void FunctionValidator::visitMemoryGrow(MemoryGrow* curr) {
+ shouldBeTrue(
+ getModule()->memory.exists, curr, "Memory operations require a memory");
+ shouldBeEqualOrFirstIsUnreachable(curr->delta->type,
+ Type(Type::i32),
+ curr,
+ "memory.grow must have i32 operand");
}
void FunctionValidator::visitRefIsNull(RefIsNull* curr) {
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index 9d43a33b1..d3c0b46e8 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -145,8 +145,10 @@ const char* getExpressionName(Expression* curr) {
return "drop";
case Expression::Id::ReturnId:
return "return";
- case Expression::Id::HostId:
- return "host";
+ case Expression::Id::MemorySizeId:
+ return "memory.size";
+ case Expression::Id::MemoryGrowId:
+ return "memory.grow";
case Expression::Id::NopId:
return "nop";
case Expression::Id::UnreachableId:
@@ -879,21 +881,13 @@ void Drop::finalize() {
}
}
-void Host::finalize() {
- switch (op) {
- case MemorySize: {
- type = Type::i32;
- break;
- }
- case MemoryGrow: {
- // if the single operand is not reachable, so are we
- if (operands[0]->type == Type::unreachable) {
- type = Type::unreachable;
- } else {
- type = Type::i32;
- }
- break;
- }
+void MemorySize::finalize() { type = Type::i32; }
+
+void MemoryGrow::finalize() {
+ if (delta->type == Type::unreachable) {
+ type = Type::unreachable;
+ } else {
+ type = Type::i32;
}
}