[wasm-gc] Enable runtime subtyping checks for functions
Bug: v8:7748 Change-Id: Ic65c09726994fddf73979b5f25b98f7ce4c5d6ef Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3574556 Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Commit-Queue: Manos Koukoutos <manoskouk@chromium.org> Cr-Commit-Position: refs/heads/main@{#79870}
This commit is contained in:
parent
022657040b
commit
b09d550605
@ -5795,15 +5795,6 @@ void WasmGraphBuilder::TypeCheck(
|
||||
|
||||
Node* map = gasm_->LoadMap(object);
|
||||
|
||||
if (config.reference_kind == kFunction) {
|
||||
// Currently, the only way for a function to match an rtt is if its map
|
||||
// is equal to that rtt.
|
||||
callbacks.fail_if_not(gasm_->TaggedEqual(map, rtt), BranchHint::kTrue);
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK(config.reference_kind == kArrayOrStruct);
|
||||
|
||||
// First, check if types happen to be equal. This has been shown to give large
|
||||
// speedups.
|
||||
callbacks.succeed_if(gasm_->TaggedEqual(map, rtt), BranchHint::kTrue);
|
||||
|
@ -223,13 +223,8 @@ class WasmGraphBuilder {
|
||||
kWasmApiFunctionRefMode,
|
||||
kNoSpecialParameterMode
|
||||
};
|
||||
enum ReferenceKind : bool { // --
|
||||
kArrayOrStruct = true,
|
||||
kFunction = false
|
||||
};
|
||||
struct ObjectReferenceKnowledge {
|
||||
bool object_can_be_null;
|
||||
ReferenceKind reference_kind;
|
||||
uint8_t rtt_depth;
|
||||
};
|
||||
enum EnforceBoundsCheck : bool { // --
|
||||
|
@ -5573,17 +5573,6 @@ class LiftoffCompiler {
|
||||
__ LoadMap(tmp1.gp(), obj_reg.gp());
|
||||
// {tmp1} now holds the object's map.
|
||||
|
||||
if (decoder->module_->has_signature(rtt.type.ref_index())) {
|
||||
// Function case: currently, the only way for the type check to succeed is
|
||||
// that the function's map equals the rtt.
|
||||
__ emit_cond_jump(kUnequal, no_match, rtt.type.kind(), tmp1.gp(),
|
||||
rtt_reg.gp());
|
||||
__ bind(&match);
|
||||
return obj_reg;
|
||||
}
|
||||
|
||||
// Array/struct case until the rest of the function.
|
||||
|
||||
// Check for rtt equality, and if not, check if the rtt is a struct/array
|
||||
// rtt.
|
||||
__ emit_cond_jump(kEqual, &match, rtt.type.kind(), tmp1.gp(), rtt_reg.gp());
|
||||
|
@ -1161,10 +1161,6 @@ class WasmGraphBuildingInterface {
|
||||
result.object_can_be_null = object_type.is_nullable();
|
||||
DCHECK(object_type.is_object_reference()); // Checked by validation.
|
||||
// In the bottom case, the result is irrelevant.
|
||||
result.reference_kind =
|
||||
!rtt_type.is_bottom() && module->has_signature(rtt_type.ref_index())
|
||||
? compiler::WasmGraphBuilder::kFunction
|
||||
: compiler::WasmGraphBuilder::kArrayOrStruct;
|
||||
result.rtt_depth = rtt_type.is_bottom()
|
||||
? 0 /* unused */
|
||||
: static_cast<uint8_t>(GetSubtypingDepth(
|
||||
|
@ -253,7 +253,6 @@ void CreateMapForType(Isolate* isolate, const WasmModule* module,
|
||||
map = CreateArrayMap(isolate, module, type_index, rtt_parent, instance);
|
||||
break;
|
||||
case TypeDefinition::kFunction:
|
||||
// TODO(7748): Create funcref RTTs lazily?
|
||||
map = CreateFuncRefMap(isolate, module, rtt_parent, instance);
|
||||
break;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "src/base/vector.h"
|
||||
#include "src/codegen/signature.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "src/wasm/module-decoder.h"
|
||||
#include "src/wasm/struct-types.h"
|
||||
@ -491,6 +492,28 @@ WASM_COMPILED_EXEC_TEST(RefCast) {
|
||||
{F(kWasmI32, true), F(kWasmF32, false)}, supertype_index);
|
||||
const byte subtype2_index = tester.DefineStruct(
|
||||
{F(kWasmI32, true), F(kWasmI64, false)}, supertype_index);
|
||||
auto super_sig = FixedSizeSignature<ValueType>::Params(
|
||||
ValueType::Ref(subtype1_index, kNullable))
|
||||
.Returns(ValueType::Ref(supertype_index, kNullable));
|
||||
auto sub_sig1 = FixedSizeSignature<ValueType>::Params(
|
||||
ValueType::Ref(supertype_index, kNullable))
|
||||
.Returns(ValueType::Ref(subtype1_index, kNullable));
|
||||
auto sub_sig2 = FixedSizeSignature<ValueType>::Params(
|
||||
ValueType::Ref(supertype_index, kNullable))
|
||||
.Returns(ValueType::Ref(subtype2_index, kNullable));
|
||||
const byte function_type_index = tester.DefineSignature(&super_sig);
|
||||
const byte function_subtype1_index =
|
||||
tester.DefineSignature(&sub_sig1, function_type_index);
|
||||
const byte function_subtype2_index =
|
||||
tester.DefineSignature(&sub_sig2, function_type_index);
|
||||
const byte function_index = tester.DefineFunction(
|
||||
function_subtype1_index, {},
|
||||
{WASM_STRUCT_NEW_DEFAULT_WITH_RTT(subtype1_index,
|
||||
WASM_RTT_CANON(subtype1_index)),
|
||||
WASM_END});
|
||||
// Just so this function counts as "declared".
|
||||
tester.AddGlobal(ValueType::Ref(function_type_index, kNullable), false,
|
||||
WasmInitExpr::RefFuncConst(function_index));
|
||||
|
||||
const byte kTestSuccessful = tester.DefineFunction(
|
||||
tester.sigs.i_v(), {ValueType::Ref(supertype_index, kNullable)},
|
||||
@ -510,9 +533,32 @@ WASM_COMPILED_EXEC_TEST(RefCast) {
|
||||
WASM_REF_CAST(WASM_LOCAL_GET(0), WASM_RTT_CANON(subtype2_index))),
|
||||
WASM_END});
|
||||
|
||||
const byte kFuncTestSuccessfulSuper = tester.DefineFunction(
|
||||
tester.sigs.i_v(), {ValueType::Ref(function_type_index, kNullable)},
|
||||
{WASM_LOCAL_SET(0, WASM_REF_FUNC(function_index)),
|
||||
WASM_REF_CAST(WASM_LOCAL_GET(0), WASM_RTT_CANON(function_type_index)),
|
||||
WASM_DROP, WASM_I32V(0), WASM_END});
|
||||
|
||||
const byte kFuncTestSuccessfulSub = tester.DefineFunction(
|
||||
tester.sigs.i_v(), {ValueType::Ref(function_type_index, kNullable)},
|
||||
{WASM_LOCAL_SET(0, WASM_REF_FUNC(function_index)),
|
||||
WASM_REF_CAST(WASM_LOCAL_GET(0),
|
||||
WASM_RTT_CANON(function_subtype1_index)),
|
||||
WASM_DROP, WASM_I32V(0), WASM_END});
|
||||
|
||||
const byte kFuncTestFailed = tester.DefineFunction(
|
||||
tester.sigs.i_v(), {ValueType::Ref(function_type_index, kNullable)},
|
||||
{WASM_LOCAL_SET(0, WASM_REF_FUNC(function_index)),
|
||||
WASM_REF_CAST(WASM_LOCAL_GET(0),
|
||||
WASM_RTT_CANON(function_subtype2_index)),
|
||||
WASM_DROP, WASM_I32V(1), WASM_END});
|
||||
|
||||
tester.CompileModule();
|
||||
tester.CheckResult(kTestSuccessful, 0);
|
||||
tester.CheckHasThrown(kTestFailed);
|
||||
tester.CheckResult(kFuncTestSuccessfulSuper, 0);
|
||||
tester.CheckResult(kFuncTestSuccessfulSub, 0);
|
||||
tester.CheckHasThrown(kFuncTestFailed);
|
||||
}
|
||||
|
||||
WASM_COMPILED_EXEC_TEST(RefCastStatic) {
|
||||
|
Loading…
Reference in New Issue
Block a user