diff options
Diffstat (limited to 'src/wasm/wasm-validator.cpp')
-rw-r--r-- | src/wasm/wasm-validator.cpp | 60 |
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) { |