From fd3f7d8f683639d51c778a7cec1200ef254d66bb Mon Sep 17 00:00:00 2001 From: Thibaud Michaud Date: Wed, 8 Sep 2021 16:53:55 +0200 Subject: [PATCH] [wasm][tail-call] Allow subtypes in return calls R=clemensb@chromium.org Bug: v8:12108 Change-Id: Iad128d108df64a5a0c205f7ed69a06cdffb40c31 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3148133 Reviewed-by: Clemens Backes Commit-Queue: Thibaud Michaud Cr-Commit-Position: refs/heads/main@{#76790} --- src/wasm/function-body-decoder-impl.h | 6 ++++-- test/unittests/wasm/function-body-decoder-unittest.cc | 10 ++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/wasm/function-body-decoder-impl.h b/src/wasm/function-body-decoder-impl.h index 618e8f013c..5882fda8a6 100644 --- a/src/wasm/function-body-decoder-impl.h +++ b/src/wasm/function-body-decoder-impl.h @@ -1334,7 +1334,9 @@ class WasmDecoder : public Decoder { size_t num_returns = sig_->return_count(); if (num_returns != target_sig->return_count()) return false; for (size_t i = 0; i < num_returns; ++i) { - if (sig_->GetReturn(i) != target_sig->GetReturn(i)) return false; + if (!IsSubtypeOf(target_sig->GetReturn(i), sig_->GetReturn(i), + this->module_)) + return false; } return true; } @@ -3299,7 +3301,7 @@ class WasmFullDecoder : public WasmDecoder { if (!this->Validate(this->pc_ + 1, imm)) return 0; if (!VALIDATE(this->CanReturnCall(imm.sig))) { this->DecodeError("%s: %s", WasmOpcodes::OpcodeName(kExprReturnCall), - "tail call return types mismatch"); + "tail call type error"); return 0; } ArgVector args = PeekArgs(imm.sig); diff --git a/test/unittests/wasm/function-body-decoder-unittest.cc b/test/unittests/wasm/function-body-decoder-unittest.cc index 393256b0a4..94eda218bd 100644 --- a/test/unittests/wasm/function-body-decoder-unittest.cc +++ b/test/unittests/wasm/function-body-decoder-unittest.cc @@ -1711,6 +1711,16 @@ TEST_F(FunctionBodyDecoderTest, ReturnCallsWithTooFewArguments) { ExpectFailure(sig, {WASM_RETURN_CALL_FUNCTION(2, WASM_LOCAL_GET(0))}); } +TEST_F(FunctionBodyDecoderTest, ReturnCallWithSubtype) { + WASM_FEATURE_SCOPE(return_call); + + auto sig = MakeSig::Returns(kWasmExternRef); + auto callee_sig = MakeSig::Returns(kWasmExternNonNullableRef); + builder.AddFunction(&callee_sig); + + ExpectValidates(&sig, {WASM_RETURN_CALL_FUNCTION0(0)}); +} + TEST_F(FunctionBodyDecoderTest, ReturnCallsWithMismatchedSigs) { WASM_FEATURE_SCOPE(return_call);