summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-validator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm/wasm-validator.cpp')
-rw-r--r--src/wasm/wasm-validator.cpp60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 8098116be..372c5bf6d 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -549,6 +549,10 @@ void FunctionValidator::noteBreak(Name name,
}
void FunctionValidator::visitBreak(Break* curr) {
noteBreak(curr->name, curr->value, curr);
+ if (curr->value) {
+ shouldBeTrue(
+ curr->value->type != none, curr, "break value must not have none type");
+ }
if (curr->condition) {
shouldBeTrue(curr->condition->type == unreachable ||
curr->condition->type == i32,
@@ -593,6 +597,33 @@ void FunctionValidator::visitCall(Call* curr) {
getStream() << "(on argument " << i << ")\n";
}
}
+ if (curr->isReturn) {
+ shouldBeEqual(curr->type,
+ unreachable,
+ curr,
+ "return_call should have unreachable type");
+ shouldBeEqual(
+ getFunction()->result,
+ target->result,
+ curr,
+ "return_call callee return type must match caller return type");
+ } else {
+ if (curr->type == unreachable) {
+ bool hasUnreachableOperand =
+ std::any_of(curr->operands.begin(),
+ curr->operands.end(),
+ [](Expression* op) { return op->type == unreachable; });
+ shouldBeTrue(
+ hasUnreachableOperand,
+ curr,
+ "calls may only be unreachable if they have unreachable operands");
+ } else {
+ shouldBeEqual(curr->type,
+ target->result,
+ curr,
+ "call type must match callee return type");
+ }
+ }
}
void FunctionValidator::visitCallIndirect(CallIndirect* curr) {
@@ -622,6 +653,35 @@ void FunctionValidator::visitCallIndirect(CallIndirect* curr) {
getStream() << "(on argument " << i << ")\n";
}
}
+ if (curr->isReturn) {
+ shouldBeEqual(curr->type,
+ unreachable,
+ curr,
+ "return_call_indirect should have unreachable type");
+ shouldBeEqual(
+ getFunction()->result,
+ type->result,
+ curr,
+ "return_call_indirect callee return type must match caller return type");
+ } else {
+ if (curr->type == unreachable) {
+ if (curr->target->type != unreachable) {
+ bool hasUnreachableOperand =
+ std::any_of(curr->operands.begin(),
+ curr->operands.end(),
+ [](Expression* op) { return op->type == unreachable; });
+ shouldBeTrue(hasUnreachableOperand,
+ curr,
+ "call_indirects may only be unreachable if they have "
+ "unreachable operands");
+ }
+ } else {
+ shouldBeEqual(curr->type,
+ type->result,
+ curr,
+ "call_indirect type must match callee return type");
+ }
+ }
}
void FunctionValidator::visitConst(Const* curr) {