diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2019-07-23 17:12:22 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-23 17:12:22 -0700 |
commit | a2741b360b444a26cd87327a3d60a601bb33119f (patch) | |
tree | e7ea331a4236f33c4f8e28b8ef30a8a09ab29740 /src/wasm/wasm-validator.cpp | |
parent | 0beba8aad60e4bdadcd3fc3e5126e7befb7b7994 (diff) | |
download | binaryen-a2741b360b444a26cd87327a3d60a601bb33119f.tar.gz binaryen-a2741b360b444a26cd87327a3d60a601bb33119f.tar.bz2 binaryen-a2741b360b444a26cd87327a3d60a601bb33119f.zip |
Finalize tail call support (#2246)
Adds tail call support to fuzzer and makes small changes to handle return calls in multiple utilities and passes. Makes larger changes to DAE and inlining passes to properly handle tail calls.
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) { |