[wasm-gc] Remove rtts with depth

Since inheritance depth of every type is known in the isorecursive
hybrid type system, rtts with depth are removed. This enables
simplification of type checks in Liftoff and Turbofan, as well as
decoding of object allocation instructions.

Bug: v8:7748
Change-Id: I6b52579b584191d92644de1c6e805d9f054641d3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3422626
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78860}
This commit is contained in:
Manos Koukoutos 2022-01-28 14:53:45 +00:00 committed by V8 LUCI CQ
parent 0cfbf51efb
commit 8bb8bfdefc
42 changed files with 110 additions and 368 deletions

View File

@ -2499,7 +2499,6 @@ Node* WasmGraphBuilder::Throw(uint32_t tag_index, const wasm::WasmTag* tag,
case wasm::kRef: case wasm::kRef:
case wasm::kOptRef: case wasm::kOptRef:
case wasm::kRtt: case wasm::kRtt:
case wasm::kRttWithDepth:
gasm_->StoreFixedArrayElementAny(values_array, index, value); gasm_->StoreFixedArrayElementAny(values_array, index, value);
++index; ++index;
break; break;
@ -2631,7 +2630,6 @@ Node* WasmGraphBuilder::GetExceptionValues(Node* except_obj,
case wasm::kRef: case wasm::kRef:
case wasm::kOptRef: case wasm::kOptRef:
case wasm::kRtt: case wasm::kRtt:
case wasm::kRttWithDepth:
value = gasm_->LoadFixedArrayElementAny(values_array, index); value = gasm_->LoadFixedArrayElementAny(values_array, index);
++index; ++index;
break; break;
@ -5745,16 +5743,12 @@ void WasmGraphBuilder::TypeCheck(
Node* type_info = gasm_->LoadWasmTypeInfo(map); Node* type_info = gasm_->LoadWasmTypeInfo(map);
Node* supertypes = gasm_->LoadSupertypes(type_info); Node* supertypes = gasm_->LoadSupertypes(type_info);
Node* rtt_depth = Node* rtt_depth = gasm_->UintPtrConstant(config.rtt_depth);
config.rtt_depth >= 0
? gasm_->IntPtrConstant(config.rtt_depth)
: BuildChangeSmiToIntPtr(gasm_->LoadFixedArrayLengthAsSmi(
gasm_->LoadSupertypes(gasm_->LoadWasmTypeInfo(rtt))));
// If the depth of the rtt is known to be less that the minimum supertype // If the depth of the rtt is known to be less that the minimum supertype
// array length, we can access the supertype without bounds-checking the // array length, we can access the supertype without bounds-checking the
// supertype array. // supertype array.
if (config.rtt_depth < 0 || static_cast<uint32_t>(config.rtt_depth) >= if (config.rtt_depth >= wasm::kMinimumSupertypeArraySize) {
wasm::kMinimumSupertypeArraySize) {
Node* supertypes_length = Node* supertypes_length =
BuildChangeSmiToIntPtr(gasm_->LoadFixedArrayLengthAsSmi(supertypes)); BuildChangeSmiToIntPtr(gasm_->LoadFixedArrayLengthAsSmi(supertypes));
callbacks.fail_if_not(gasm_->UintLessThan(rtt_depth, supertypes_length), callbacks.fail_if_not(gasm_->UintLessThan(rtt_depth, supertypes_length),
@ -6420,7 +6414,6 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
UNREACHABLE(); UNREACHABLE();
} }
case wasm::kRtt: case wasm::kRtt:
case wasm::kRttWithDepth:
case wasm::kI8: case wasm::kI8:
case wasm::kI16: case wasm::kI16:
case wasm::kS128: case wasm::kS128:
@ -6593,7 +6586,6 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
return BuildChangeBigIntToInt64(input, js_context, frame_state); return BuildChangeBigIntToInt64(input, js_context, frame_state);
case wasm::kRtt: case wasm::kRtt:
case wasm::kRttWithDepth:
case wasm::kS128: case wasm::kS128:
case wasm::kI8: case wasm::kI8:
case wasm::kI16: case wasm::kI16:
@ -6649,7 +6641,6 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
case wasm::kOptRef: case wasm::kOptRef:
case wasm::kI64: case wasm::kI64:
case wasm::kRtt: case wasm::kRtt:
case wasm::kRttWithDepth:
case wasm::kS128: case wasm::kS128:
case wasm::kI8: case wasm::kI8:
case wasm::kI16: case wasm::kI16:
@ -6815,7 +6806,6 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
case wasm::kOptRef: case wasm::kOptRef:
case wasm::kI64: case wasm::kI64:
case wasm::kRtt: case wasm::kRtt:
case wasm::kRttWithDepth:
case wasm::kS128: case wasm::kS128:
case wasm::kI8: case wasm::kI8:
case wasm::kI16: case wasm::kI16:
@ -6866,7 +6856,6 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
case wasm::kOptRef: case wasm::kOptRef:
case wasm::kI64: case wasm::kI64:
case wasm::kRtt: case wasm::kRtt:
case wasm::kRttWithDepth:
case wasm::kS128: case wasm::kS128:
case wasm::kI8: case wasm::kI8:
case wasm::kI16: case wasm::kI16:

View File

@ -230,7 +230,7 @@ class WasmGraphBuilder {
struct ObjectReferenceKnowledge { struct ObjectReferenceKnowledge {
bool object_can_be_null; bool object_can_be_null;
ReferenceKind reference_kind; ReferenceKind reference_kind;
int8_t rtt_depth; uint8_t rtt_depth;
}; };
enum EnforceBoundsCheck : bool { // -- enum EnforceBoundsCheck : bool { // --
kNeedsBoundsCheck = true, kNeedsBoundsCheck = true,

View File

@ -1044,8 +1044,7 @@ Handle<WasmValueObject> WasmValueObject::New(
} }
break; break;
} }
case wasm::kRtt: case wasm::kRtt: {
case wasm::kRttWithDepth: {
// TODO(7748): Expose RTTs to DevTools. // TODO(7748): Expose RTTs to DevTools.
t = isolate->factory()->InternalizeString(base::StaticCharVector("rtt")); t = isolate->factory()->InternalizeString(base::StaticCharVector("rtt"));
v = isolate->factory()->InternalizeString( v = isolate->factory()->InternalizeString(

View File

@ -1810,8 +1810,7 @@ void WasmStruct::WasmStructPrint(std::ostream& os) {
break; break;
case wasm::kRef: case wasm::kRef:
case wasm::kOptRef: case wasm::kOptRef:
case wasm::kRtt: case wasm::kRtt: {
case wasm::kRttWithDepth: {
Tagged_t raw = base::ReadUnalignedValue<Tagged_t>(field_address); Tagged_t raw = base::ReadUnalignedValue<Tagged_t>(field_address);
#if V8_COMPRESS_POINTERS #if V8_COMPRESS_POINTERS
Address obj = DecompressTaggedPointer(address(), raw); Address obj = DecompressTaggedPointer(address(), raw);
@ -1868,7 +1867,6 @@ void WasmArray::WasmArrayPrint(std::ostream& os) {
case wasm::kRef: case wasm::kRef:
case wasm::kOptRef: case wasm::kOptRef:
case wasm::kRtt: case wasm::kRtt:
case wasm::kRttWithDepth:
os << "\n Printing elements of this type is unimplemented, sorry"; os << "\n Printing elements of this type is unimplemented, sorry";
// TODO(7748): Implement. // TODO(7748): Implement.
break; break;

View File

@ -883,7 +883,6 @@ inline WasmValueType GetWasmValueType(wasm::ValueType type) {
TYPE_CASE(OptRef) TYPE_CASE(OptRef)
case wasm::kRtt: case wasm::kRtt:
case wasm::kRttWithDepth:
// Rtt values are not supposed to be made available to JavaScript side. // Rtt values are not supposed to be made available to JavaScript side.
UNREACHABLE(); UNREACHABLE();

View File

@ -310,7 +310,6 @@ inline void Store(LiftoffAssembler* assm, LiftoffRegister src, MemOperand dst,
case kOptRef: case kOptRef:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
assm->str(src.gp(), dst); assm->str(src.gp(), dst);
break; break;
case kI64: case kI64:
@ -345,7 +344,6 @@ inline void Load(LiftoffAssembler* assm, LiftoffRegister dst, MemOperand src,
case kOptRef: case kOptRef:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
assm->ldr(dst.gp(), src); assm->ldr(dst.gp(), src);
break; break;
case kI64: case kI64:

View File

@ -85,7 +85,6 @@ inline CPURegister GetRegFromType(const LiftoffRegister& reg, ValueKind kind) {
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
return reg.gp().X(); return reg.gp().X();
case kF32: case kF32:
return reg.fp().S(); return reg.fp().S();
@ -1567,7 +1566,6 @@ void LiftoffAssembler::emit_cond_jump(LiftoffCondition liftoff_cond,
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
DCHECK(rhs.is_valid()); DCHECK(rhs.is_valid());
DCHECK(liftoff_cond == kEqual || liftoff_cond == kUnequal); DCHECK(liftoff_cond == kEqual || liftoff_cond == kUnequal);
V8_FALLTHROUGH; V8_FALLTHROUGH;

View File

@ -76,7 +76,6 @@ inline void Load(LiftoffAssembler* assm, LiftoffRegister dst, Register base,
case kOptRef: case kOptRef:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
assm->mov(dst.gp(), src); assm->mov(dst.gp(), src);
break; break;
case kI64: case kI64:
@ -105,7 +104,6 @@ inline void Store(LiftoffAssembler* assm, Register base, int32_t offset,
case kOptRef: case kOptRef:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
assm->mov(dst, src.gp()); assm->mov(dst, src.gp());
break; break;
case kI64: case kI64:
@ -136,7 +134,6 @@ inline void push(LiftoffAssembler* assm, LiftoffRegister reg, ValueKind kind,
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
assm->AllocateStackSpace(padding); assm->AllocateStackSpace(padding);
assm->push(reg.gp()); assm->push(reg.gp());
break; break;
@ -1206,7 +1203,6 @@ void LiftoffAssembler::Spill(int offset, LiftoffRegister reg, ValueKind kind) {
case kOptRef: case kOptRef:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
mov(dst, reg.gp()); mov(dst, reg.gp());
break; break;
case kI64: case kI64:
@ -2470,7 +2466,6 @@ void LiftoffAssembler::emit_cond_jump(LiftoffCondition liftoff_cond,
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
DCHECK(liftoff_cond == kEqual || liftoff_cond == kUnequal); DCHECK(liftoff_cond == kEqual || liftoff_cond == kUnequal);
V8_FALLTHROUGH; V8_FALLTHROUGH;
case kI32: case kI32:

View File

@ -590,7 +590,6 @@ class LiftoffCompiler {
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
case kI8: case kI8:
case kI16: case kI16:
bailout_reason = kGC; bailout_reason = kGC;
@ -4262,8 +4261,7 @@ class LiftoffCompiler {
} }
case wasm::kRef: case wasm::kRef:
case wasm::kOptRef: case wasm::kOptRef:
case wasm::kRtt: case wasm::kRtt: {
case wasm::kRttWithDepth: {
--(*index_in_array); --(*index_in_array);
__ StoreTaggedPointer( __ StoreTaggedPointer(
values_array, no_reg, values_array, no_reg,
@ -4321,8 +4319,7 @@ class LiftoffCompiler {
} }
case wasm::kRef: case wasm::kRef:
case wasm::kOptRef: case wasm::kOptRef:
case wasm::kRtt: case wasm::kRtt: {
case wasm::kRttWithDepth: {
__ LoadTaggedPointer( __ LoadTaggedPointer(
value.gp(), values_array.gp(), no_reg, value.gp(), values_array.gp(), no_reg,
wasm::ObjectAccess::ElementOffsetInTaggedFixedArray(*index), wasm::ObjectAccess::ElementOffsetInTaggedFixedArray(*index),
@ -5446,7 +5443,7 @@ class LiftoffCompiler {
__ LoadTaggedPointer( __ LoadTaggedPointer(
rtt.gp(), rtt.gp(), no_reg, rtt.gp(), rtt.gp(), no_reg,
wasm::ObjectAccess::ElementOffsetInTaggedFixedArray(type_index), {}); wasm::ObjectAccess::ElementOffsetInTaggedFixedArray(type_index), {});
__ PushRegister(kRttWithDepth, rtt); __ PushRegister(kRtt, rtt);
} }
enum NullSucceeds : bool { // -- enum NullSucceeds : bool { // --
@ -5507,37 +5504,21 @@ class LiftoffCompiler {
wasm::ObjectAccess::ToTagged(WasmTypeInfo::kSupertypesOffset); wasm::ObjectAccess::ToTagged(WasmTypeInfo::kSupertypesOffset);
__ LoadTaggedPointer(tmp1.gp(), tmp1.gp(), no_reg, kSuperTypesOffset, __ LoadTaggedPointer(tmp1.gp(), tmp1.gp(), no_reg, kSuperTypesOffset,
pinned); pinned);
if (rtt.type.has_depth()) { // Step 3: check the list's length if needed.
// Step 3: check the list's length if needed. uint32_t rtt_depth =
if (rtt.type.depth() >= kMinimumSupertypeArraySize) { GetSubtypingDepth(decoder->module_, rtt.type.ref_index());
LiftoffRegister list_length = tmp2; if (rtt_depth >= kMinimumSupertypeArraySize) {
__ LoadFixedArrayLengthAsInt32(list_length, tmp1.gp(), pinned); LiftoffRegister list_length = tmp2;
__ emit_i32_cond_jumpi(kUnsignedLessEqual, no_match, list_length.gp(), __ LoadFixedArrayLengthAsInt32(list_length, tmp1.gp(), pinned);
rtt.type.depth()); __ emit_i32_cond_jumpi(kUnsignedLessEqual, no_match, list_length.gp(),
} rtt_depth);
// Step 4: load the candidate list slot into {tmp1}, and compare it.
__ LoadTaggedPointer(
tmp1.gp(), tmp1.gp(), no_reg,
wasm::ObjectAccess::ElementOffsetInTaggedFixedArray(rtt.type.depth()),
pinned);
__ emit_cond_jump(kUnequal, no_match, rtt.type.kind(), tmp1.gp(),
rtt_reg.gp());
} else {
// Step 3: if rtt's depth is unknown, we invoke a builtin to compute the
// result, as we might not have enough available registers.
// Preserve {obj_reg} across the call.
LiftoffRegList saved_regs = LiftoffRegList::ForRegs(obj_reg);
__ PushRegisters(saved_regs);
LiftoffAssembler::VarState rtt_state(kPointerKind, rtt_reg, 0);
LiftoffAssembler::VarState tmp1_state(kPointerKind, tmp1, 0);
CallRuntimeStub(WasmCode::kWasmSubtypeCheck,
MakeSig::Returns(kI32).Params(kOptRef, rtt.type.kind()),
{tmp1_state, rtt_state}, decoder->position());
__ PopRegisters(saved_regs);
__ Move(tmp1.gp(), kReturnRegister0, kI32);
__ emit_i32_cond_jumpi(kEqual, no_match, tmp1.gp(), 0);
} }
// Step 4: load the candidate list slot into {tmp1}, and compare it.
__ LoadTaggedPointer(
tmp1.gp(), tmp1.gp(), no_reg,
wasm::ObjectAccess::ElementOffsetInTaggedFixedArray(rtt_depth), pinned);
__ emit_cond_jump(kUnequal, no_match, rtt.type.kind(), tmp1.gp(),
rtt_reg.gp());
// Fall through to {match}. // Fall through to {match}.
__ bind(&match); __ bind(&match);
@ -6258,7 +6239,6 @@ class LiftoffCompiler {
case kOptRef: case kOptRef:
return LoadNullValue(reg.gp(), pinned); return LoadNullValue(reg.gp(), pinned);
case kRtt: case kRtt:
case kRttWithDepth:
case kVoid: case kVoid:
case kBottom: case kBottom:
case kRef: case kRef:
@ -6399,7 +6379,7 @@ class LiftoffCompiler {
// MVP: // MVP:
kI32, kI64, kF32, kF64, kI32, kI64, kF32, kF64,
// Extern ref: // Extern ref:
kRef, kOptRef, kRtt, kRttWithDepth, kI8, kI16}; kRef, kOptRef, kRtt, kI8, kI16};
LiftoffAssembler asm_; LiftoffAssembler asm_;

View File

@ -69,7 +69,6 @@ static inline constexpr RegClass reg_class_for(ValueKind kind) {
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
return kGpReg; return kGpReg;
default: default:
return kNoReg; // unsupported kind return kNoReg; // unsupported kind

View File

@ -106,7 +106,6 @@ inline void Load(LiftoffAssembler* assm, LiftoffRegister dst, MemOperand src,
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
assm->Ld_d(dst.gp(), src); assm->Ld_d(dst.gp(), src);
break; break;
case kF32: case kF32:
@ -134,7 +133,6 @@ inline void Store(LiftoffAssembler* assm, Register base, int32_t offset,
case kOptRef: case kOptRef:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
assm->St_d(src.gp(), dst); assm->St_d(src.gp(), dst);
break; break;
case kF32: case kF32:
@ -623,7 +621,6 @@ void LiftoffAssembler::Spill(int offset, LiftoffRegister reg, ValueKind kind) {
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
St_d(reg.gp(), dst); St_d(reg.gp(), dst);
break; break;
case kF32: case kF32:
@ -676,7 +673,6 @@ void LiftoffAssembler::Fill(LiftoffRegister reg, int offset, ValueKind kind) {
case kOptRef: case kOptRef:
// TODO(LOONG_dev): LOONG64 Check, MIPS64 dosn't need, ARM64/LOONG64 need? // TODO(LOONG_dev): LOONG64 Check, MIPS64 dosn't need, ARM64/LOONG64 need?
case kRtt: case kRtt:
case kRttWithDepth:
Ld_d(reg.gp(), src); Ld_d(reg.gp(), src);
break; break;
case kF32: case kF32:

View File

@ -95,7 +95,6 @@ inline void Load(LiftoffAssembler* assm, LiftoffRegister dst, Register base,
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
assm->lw(dst.gp(), src); assm->lw(dst.gp(), src);
break; break;
case kI64: case kI64:
@ -123,7 +122,6 @@ inline void Store(LiftoffAssembler* assm, Register base, int32_t offset,
case kOptRef: case kOptRef:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
assm->Usw(src.gp(), dst); assm->Usw(src.gp(), dst);
break; break;
case kI64: case kI64:
@ -819,7 +817,6 @@ void LiftoffAssembler::Spill(int offset, LiftoffRegister reg, ValueKind kind) {
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
sw(reg.gp(), dst); sw(reg.gp(), dst);
break; break;
case kI64: case kI64:

View File

@ -106,7 +106,6 @@ inline void Load(LiftoffAssembler* assm, LiftoffRegister dst, MemOperand src,
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
assm->Ld(dst.gp(), src); assm->Ld(dst.gp(), src);
break; break;
case kF32: case kF32:
@ -134,7 +133,6 @@ inline void Store(LiftoffAssembler* assm, Register base, int32_t offset,
case kOptRef: case kOptRef:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
assm->Usd(src.gp(), dst); assm->Usd(src.gp(), dst);
break; break;
case kF32: case kF32:
@ -750,7 +748,6 @@ void LiftoffAssembler::Spill(int offset, LiftoffRegister reg, ValueKind kind) {
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
Sd(reg.gp(), dst); Sd(reg.gp(), dst);
break; break;
case kF32: case kF32:

View File

@ -815,7 +815,6 @@ void LiftoffAssembler::LoadCallerFrameSlot(LiftoffRegister dst,
case kRef: case kRef:
case kRtt: case kRtt:
case kOptRef: case kOptRef:
case kRttWithDepth:
case kI64: { case kI64: {
LoadU64(dst.gp(), MemOperand(fp, offset), r0); LoadU64(dst.gp(), MemOperand(fp, offset), r0);
break; break;
@ -890,7 +889,6 @@ void LiftoffAssembler::LoadReturnStackSlot(LiftoffRegister dst, int offset,
case kRef: case kRef:
case kRtt: case kRtt:
case kOptRef: case kOptRef:
case kRttWithDepth:
case kI64: { case kI64: {
LoadU64(dst.gp(), MemOperand(sp, offset), r0); LoadU64(dst.gp(), MemOperand(sp, offset), r0);
break; break;
@ -969,7 +967,6 @@ void LiftoffAssembler::Spill(int offset, LiftoffRegister reg, ValueKind kind) {
case kOptRef: case kOptRef:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
StoreU64(reg.gp(), liftoff::GetStackSlot(offset), r0); StoreU64(reg.gp(), liftoff::GetStackSlot(offset), r0);
break; break;
case kF32: case kF32:
@ -1018,7 +1015,6 @@ void LiftoffAssembler::Fill(LiftoffRegister reg, int offset, ValueKind kind) {
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
LoadU64(reg.gp(), liftoff::GetStackSlot(offset), r0); LoadU64(reg.gp(), liftoff::GetStackSlot(offset), r0);
break; break;
case kF32: case kF32:
@ -1602,7 +1598,6 @@ void LiftoffAssembler::emit_cond_jump(LiftoffCondition liftoff_cond,
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
DCHECK(liftoff_cond == kEqual || liftoff_cond == kUnequal); DCHECK(liftoff_cond == kEqual || liftoff_cond == kUnequal);
V8_FALLTHROUGH; V8_FALLTHROUGH;
case kI64: case kI64:
@ -2997,7 +2992,6 @@ void LiftoffAssembler::CallC(const ValueKindSig* sig,
case kOptRef: case kOptRef:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
LoadU64(result_reg->gp(), MemOperand(sp)); LoadU64(result_reg->gp(), MemOperand(sp));
break; break;
case kF32: case kF32:
@ -3077,7 +3071,6 @@ void LiftoffStackSlots::Construct(int param_slots) {
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
case kI64: { case kI64: {
asm_->AllocateStackSpace(stack_decrement - kSystemPointerSize); asm_->AllocateStackSpace(stack_decrement - kSystemPointerSize);
UseScratchRegisterScope temps(asm_); UseScratchRegisterScope temps(asm_);
@ -3120,7 +3113,6 @@ void LiftoffStackSlots::Construct(int param_slots) {
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
asm_->push(src.reg().gp()); asm_->push(src.reg().gp());
break; break;
case kF32: case kF32:

View File

@ -990,7 +990,6 @@ void LiftoffAssembler::Spill(int offset, LiftoffRegister reg, ValueKind kind) {
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
Sd(reg.gp(), dst); Sd(reg.gp(), dst);
break; break;
case kF32: case kF32:

View File

@ -1251,7 +1251,6 @@ void LiftoffAssembler::LoadCallerFrameSlot(LiftoffRegister dst,
case kRef: case kRef:
case kRtt: case kRtt:
case kOptRef: case kOptRef:
case kRttWithDepth:
case kI64: { case kI64: {
LoadU64(dst.gp(), MemOperand(fp, offset)); LoadU64(dst.gp(), MemOperand(fp, offset));
break; break;
@ -1330,7 +1329,6 @@ void LiftoffAssembler::LoadReturnStackSlot(LiftoffRegister dst, int offset,
case kRef: case kRef:
case kRtt: case kRtt:
case kOptRef: case kOptRef:
case kRttWithDepth:
case kI64: { case kI64: {
LoadU64(dst.gp(), MemOperand(sp, offset)); LoadU64(dst.gp(), MemOperand(sp, offset));
break; break;
@ -1432,7 +1430,6 @@ void LiftoffAssembler::Spill(int offset, LiftoffRegister reg, ValueKind kind) {
case kOptRef: case kOptRef:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
StoreU64(reg.gp(), liftoff::GetStackSlot(offset)); StoreU64(reg.gp(), liftoff::GetStackSlot(offset));
break; break;
case kF32: case kF32:
@ -1483,7 +1480,6 @@ void LiftoffAssembler::Fill(LiftoffRegister reg, int offset, ValueKind kind) {
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
LoadU64(reg.gp(), liftoff::GetStackSlot(offset)); LoadU64(reg.gp(), liftoff::GetStackSlot(offset));
break; break;
case kF32: case kF32:
@ -2142,7 +2138,6 @@ void LiftoffAssembler::emit_cond_jump(LiftoffCondition liftoff_cond,
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
DCHECK(liftoff_cond == kEqual || liftoff_cond == kUnequal); DCHECK(liftoff_cond == kEqual || liftoff_cond == kUnequal);
V8_FALLTHROUGH; V8_FALLTHROUGH;
case kI64: case kI64:
@ -2882,7 +2877,6 @@ void LiftoffAssembler::CallC(const ValueKindSig* sig,
case kOptRef: case kOptRef:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
LoadU64(result_reg->gp(), MemOperand(sp)); LoadU64(result_reg->gp(), MemOperand(sp));
break; break;
case kF32: case kF32:
@ -2988,7 +2982,6 @@ void LiftoffStackSlots::Construct(int param_slots) {
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
case kI64: { case kI64: {
asm_->AllocateStackSpace(stack_decrement - kSystemPointerSize); asm_->AllocateStackSpace(stack_decrement - kSystemPointerSize);
UseScratchRegisterScope temps(asm_); UseScratchRegisterScope temps(asm_);
@ -3036,7 +3029,6 @@ void LiftoffStackSlots::Construct(int param_slots) {
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
asm_->push(src.reg().gp()); asm_->push(src.reg().gp());
break; break;
case kF32: case kF32:

View File

@ -99,7 +99,6 @@ inline void Load(LiftoffAssembler* assm, LiftoffRegister dst, Operand src,
case kOptRef: case kOptRef:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
assm->movq(dst.gp(), src); assm->movq(dst.gp(), src);
break; break;
case kF32: case kF32:
@ -128,7 +127,6 @@ inline void Store(LiftoffAssembler* assm, Operand dst, LiftoffRegister src,
case kOptRef: case kOptRef:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
assm->StoreTaggedField(dst, src.gp()); assm->StoreTaggedField(dst, src.gp());
break; break;
case kF32: case kF32:
@ -927,7 +925,6 @@ void LiftoffAssembler::Spill(int offset, LiftoffRegister reg, ValueKind kind) {
case kOptRef: case kOptRef:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
movq(dst, reg.gp()); movq(dst, reg.gp());
break; break;
case kF32: case kF32:
@ -2145,7 +2142,6 @@ void LiftoffAssembler::emit_cond_jump(LiftoffCondition liftoff_cond,
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
DCHECK(liftoff_cond == kEqual || liftoff_cond == kUnequal); DCHECK(liftoff_cond == kEqual || liftoff_cond == kUnequal);
V8_FALLTHROUGH; V8_FALLTHROUGH;
case kI64: case kI64:

View File

@ -1562,7 +1562,6 @@ void PushArgs(const i::wasm::FunctionSig* sig, const Val args[],
packer->Push(WasmRefToV8(store->i_isolate(), args[i].ref())->ptr()); packer->Push(WasmRefToV8(store->i_isolate(), args[i].ref())->ptr());
break; break;
case i::wasm::kRtt: case i::wasm::kRtt:
case i::wasm::kRttWithDepth:
case i::wasm::kS128: case i::wasm::kS128:
// TODO(7748): Implement. // TODO(7748): Implement.
UNIMPLEMENTED(); UNIMPLEMENTED();
@ -1602,7 +1601,6 @@ void PopArgs(const i::wasm::FunctionSig* sig, Val results[],
break; break;
} }
case i::wasm::kRtt: case i::wasm::kRtt:
case i::wasm::kRttWithDepth:
case i::wasm::kS128: case i::wasm::kS128:
// TODO(7748): Implement. // TODO(7748): Implement.
UNIMPLEMENTED(); UNIMPLEMENTED();
@ -1865,7 +1863,6 @@ auto Global::get() const -> Val {
return Val(V8RefValueToWasm(store, v8_global->GetRef())); return Val(V8RefValueToWasm(store, v8_global->GetRef()));
} }
case i::wasm::kRtt: case i::wasm::kRtt:
case i::wasm::kRttWithDepth:
case i::wasm::kS128: case i::wasm::kS128:
// TODO(7748): Implement these. // TODO(7748): Implement these.
UNIMPLEMENTED(); UNIMPLEMENTED();

View File

@ -313,44 +313,9 @@ ValueType read_value_type(Decoder* decoder, const byte* pc,
return heap_type.is_bottom() ? kWasmBottom return heap_type.is_bottom() ? kWasmBottom
: ValueType::Ref(heap_type, nullability); : ValueType::Ref(heap_type, nullability);
} }
case kRttWithDepthCode: { // TODO(7748): This is here only for backwards compatibility, and the parsed
if (!VALIDATE(enabled.has_gc())) { // depth is ignored.
DecodeError<validate>( case kRttWithDepthCode:
decoder, pc,
"invalid value type 'rtt', enable with --experimental-wasm-gc");
return kWasmBottom;
}
uint32_t depth = decoder->read_u32v<validate>(pc + 1, length, "depth");
*length += 1;
if (!VALIDATE(depth <= kV8MaxRttSubtypingDepth)) {
DecodeError<validate>(
decoder, pc,
"subtyping depth %u is greater than the maximum depth "
"%u supported by V8",
depth, kV8MaxRttSubtypingDepth);
return kWasmBottom;
}
uint32_t type_index_length;
uint32_t type_index =
decoder->read_u32v<validate>(pc + *length, &type_index_length);
*length += type_index_length;
if (!VALIDATE(type_index < kV8MaxWasmTypes)) {
DecodeError<validate>(
decoder, pc,
"Type index %u is greater than the maximum number %zu "
"of type definitions supported by V8",
type_index, kV8MaxWasmTypes);
return kWasmBottom;
}
// We use capacity over size so this works mid-DecodeTypeSection.
if (!VALIDATE(module == nullptr ||
type_index < module->types.capacity())) {
DecodeError<validate>(decoder, pc, "Type index %u is out of bounds",
type_index);
return kWasmBottom;
}
return ValueType::Rtt(type_index, depth);
}
case kRttCode: { case kRttCode: {
if (!VALIDATE(enabled.has_gc())) { if (!VALIDATE(enabled.has_gc())) {
DecodeError<validate>( DecodeError<validate>(
@ -358,8 +323,22 @@ ValueType read_value_type(Decoder* decoder, const byte* pc,
"invalid value type 'rtt', enable with --experimental-wasm-gc"); "invalid value type 'rtt', enable with --experimental-wasm-gc");
return kWasmBottom; return kWasmBottom;
} }
uint32_t type_index = decoder->read_u32v<validate>(pc + 1, length); if (code == kRttWithDepthCode) {
*length += 1; uint32_t depth = decoder->read_u32v<validate>(pc + 1, length, "depth");
*length += 1;
if (!VALIDATE(depth <= kV8MaxRttSubtypingDepth)) {
DecodeError<validate>(
decoder, pc,
"subtyping depth %u is greater than the maximum depth "
"%u supported by V8",
depth, kV8MaxRttSubtypingDepth);
return kWasmBottom;
}
}
uint32_t type_index_length;
uint32_t type_index =
decoder->read_u32v<validate>(pc + *length, &type_index_length);
*length += type_index_length;
if (!VALIDATE(type_index < kV8MaxWasmTypes)) { if (!VALIDATE(type_index < kV8MaxWasmTypes)) {
DecodeError<validate>( DecodeError<validate>(
decoder, pc, decoder, pc,
@ -4051,28 +4030,13 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
case kExprStructNewWithRtt: { case kExprStructNewWithRtt: {
StructIndexImmediate<validate> imm(this, this->pc_ + opcode_length); StructIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0; if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
ValueType rtt_type = ValueType::Rtt(imm.index);
Value rtt = opcode == kExprStructNew Value rtt = opcode == kExprStructNew
? CreateValue(ValueType::Rtt(imm.index)) ? CreateValue(rtt_type)
: Peek(0, imm.struct_type->field_count()); : Peek(0, imm.struct_type->field_count(), rtt_type);
if (opcode == kExprStructNew) { if (opcode == kExprStructNew) {
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt); CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
Push(rtt); Push(rtt);
} else {
DCHECK_EQ(opcode, kExprStructNewWithRtt);
if (!VALIDATE(rtt.type.is_rtt() || rtt.type.is_bottom())) {
PopTypeError(imm.struct_type->field_count(), rtt, "rtt");
return 0;
}
// TODO(7748): Drop this check if {imm} is dropped from the proposal
// à la https://github.com/WebAssembly/function-references/pull/31.
if (!VALIDATE(rtt.type.is_bottom() ||
(rtt.type.ref_index() == imm.index &&
rtt.type.has_depth()))) {
PopTypeError(
imm.struct_type->field_count(), rtt,
"rtt with depth for type " + std::to_string(imm.index));
return 0;
}
} }
ArgVector args = PeekArgs(imm.struct_type, 1); ArgVector args = PeekArgs(imm.struct_type, 1);
Value value = CreateValue(ValueType::Ref(imm.index, kNonNullable)); Value value = CreateValue(ValueType::Ref(imm.index, kNonNullable));
@ -4099,27 +4063,12 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
} }
} }
} }
Value rtt = opcode == kExprStructNewDefault ValueType rtt_type = ValueType::Rtt(imm.index);
? CreateValue(ValueType::Rtt(imm.index)) Value rtt = opcode == kExprStructNewDefault ? CreateValue(rtt_type)
: Peek(0, 0); : Peek(0, 0, rtt_type);
if (opcode == kExprStructNewDefault) { if (opcode == kExprStructNewDefault) {
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt); CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
Push(rtt); Push(rtt);
} else {
DCHECK_EQ(opcode, kExprStructNewDefaultWithRtt);
if (!VALIDATE(rtt.type.is_rtt() || rtt.type.is_bottom())) {
PopTypeError(0, rtt, "rtt");
return 0;
}
// TODO(7748): Drop this check if {imm} is dropped from the proposal
// à la https://github.com/WebAssembly/function-references/pull/31.
if (!VALIDATE(rtt.type.is_bottom() ||
(rtt.type.ref_index() == imm.index &&
rtt.type.has_depth()))) {
PopTypeError(
0, rtt, "rtt with depth for type " + std::to_string(imm.index));
return 0;
}
} }
Value value = CreateValue(ValueType::Ref(imm.index, kNonNullable)); Value value = CreateValue(ValueType::Ref(imm.index, kNonNullable));
CALL_INTERFACE_IF_OK_AND_REACHABLE(StructNewDefault, imm, rtt, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(StructNewDefault, imm, rtt, &value);
@ -4198,27 +4147,12 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
NON_CONST_ONLY NON_CONST_ONLY
ArrayIndexImmediate<validate> imm(this, this->pc_ + opcode_length); ArrayIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0; if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
Value rtt = opcode == kExprArrayNew ValueType rtt_type = ValueType::Rtt(imm.index);
? CreateValue(ValueType::Rtt(imm.index)) Value rtt = opcode == kExprArrayNew ? CreateValue(rtt_type)
: Peek(0, 2); : Peek(0, 2, rtt_type);
if (opcode == kExprArrayNew) { if (opcode == kExprArrayNew) {
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt); CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
Push(rtt); Push(rtt);
} else {
DCHECK_EQ(opcode, kExprArrayNewWithRtt);
if (!VALIDATE(rtt.type.is_rtt() || rtt.type.is_bottom())) {
PopTypeError(2, rtt, "rtt");
return 0;
}
// TODO(7748): Drop this check if {imm} is dropped from the proposal
// à la https://github.com/WebAssembly/function-references/pull/31.
if (!VALIDATE(rtt.type.is_bottom() ||
(rtt.type.ref_index() == imm.index &&
rtt.type.has_depth()))) {
PopTypeError(
2, rtt, "rtt with depth for type " + std::to_string(imm.index));
return 0;
}
} }
Value length = Peek(1, 1, kWasmI32); Value length = Peek(1, 1, kWasmI32);
Value initial_value = Value initial_value =
@ -4242,27 +4176,12 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
imm.array_type->element_type().name().c_str()); imm.array_type->element_type().name().c_str());
return 0; return 0;
} }
Value rtt = opcode == kExprArrayNewDefault ValueType rtt_type = ValueType::Rtt(imm.index);
? CreateValue(ValueType::Rtt(imm.index)) Value rtt = opcode == kExprArrayNewDefault ? CreateValue(rtt_type)
: Peek(0, 1); : Peek(0, 1, rtt_type);
if (opcode == kExprArrayNewDefault) { if (opcode == kExprArrayNewDefault) {
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt); CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
Push(rtt); Push(rtt);
} else {
DCHECK_EQ(opcode, kExprArrayNewDefaultWithRtt);
if (!VALIDATE(rtt.type.is_rtt() || rtt.type.is_bottom())) {
PopTypeError(1, rtt, "rtt");
return 0;
}
// TODO(7748): Drop this check if {imm} is dropped from the proposal
// à la https://github.com/WebAssembly/function-references/pull/31.
if (!VALIDATE(rtt.type.is_bottom() ||
(rtt.type.ref_index() == imm.index &&
rtt.type.has_depth()))) {
PopTypeError(
1, rtt, "rtt with depth for type " + std::to_string(imm.index));
return 0;
}
} }
Value length = Peek(1, 0, kWasmI32); Value length = Peek(1, 0, kWasmI32);
Value value = CreateValue(ValueType::Ref(imm.index, kNonNullable)); Value value = CreateValue(ValueType::Ref(imm.index, kNonNullable));
@ -4487,8 +4406,7 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
IndexImmediate<validate> imm(this, this->pc_ + opcode_length, IndexImmediate<validate> imm(this, this->pc_ + opcode_length,
"type index"); "type index");
if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0; if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0;
Value value = CreateValue(ValueType::Rtt( Value value = CreateValue(ValueType::Rtt(imm.index));
imm.index, GetSubtypingDepth(this->module_, imm.index)));
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &value);
Push(value); Push(value);
return opcode_length + imm.length; return opcode_length + imm.length;
@ -4503,8 +4421,7 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
"type index"); "type index");
if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0; if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0;
opcode_length += imm.length; opcode_length += imm.length;
rtt = CreateValue(ValueType::Rtt( rtt = CreateValue(ValueType::Rtt(imm.index));
imm.index, GetSubtypingDepth(this->module_, imm.index)));
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt); CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
Push(rtt); Push(rtt);
} else { } else {
@ -4560,8 +4477,7 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
"type index"); "type index");
if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0; if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0;
opcode_length += imm.length; opcode_length += imm.length;
rtt = CreateValue(ValueType::Rtt( rtt = CreateValue(ValueType::Rtt(imm.index));
imm.index, GetSubtypingDepth(this->module_, imm.index)));
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt); CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
Push(rtt); Push(rtt);
} else { } else {
@ -4631,8 +4547,7 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
"type index"); "type index");
if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0; if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0;
pc_offset += imm.length; pc_offset += imm.length;
rtt = CreateValue(ValueType::Rtt( rtt = CreateValue(ValueType::Rtt(imm.index));
imm.index, GetSubtypingDepth(this->module_, imm.index)));
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt); CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
Push(rtt); Push(rtt);
} else { } else {
@ -4713,8 +4628,7 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
"type index"); "type index");
if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0; if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0;
pc_offset += imm.length; pc_offset += imm.length;
rtt = CreateValue(ValueType::Rtt( rtt = CreateValue(ValueType::Rtt(imm.index));
imm.index, GetSubtypingDepth(this->module_, imm.index)));
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt); CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
Push(rtt); Push(rtt);
} else { } else {

View File

@ -1148,10 +1148,13 @@ class WasmGraphBuildingInterface {
DCHECK(object_type.is_object_reference()); // Checked by validation. DCHECK(object_type.is_object_reference()); // Checked by validation.
// In the bottom case, the result is irrelevant. // In the bottom case, the result is irrelevant.
result.reference_kind = result.reference_kind =
rtt_type != kWasmBottom && module->has_signature(rtt_type.ref_index()) !rtt_type.is_bottom() && module->has_signature(rtt_type.ref_index())
? compiler::WasmGraphBuilder::kFunction ? compiler::WasmGraphBuilder::kFunction
: compiler::WasmGraphBuilder::kArrayOrStruct; : compiler::WasmGraphBuilder::kArrayOrStruct;
result.rtt_depth = rtt_type.has_depth() ? rtt_type.depth() : -1; result.rtt_depth = rtt_type.is_bottom()
? 0 /* unused */
: static_cast<uint8_t>(GetSubtypingDepth(
module, rtt_type.ref_index()));
return result; return result;
} }
@ -1460,7 +1463,6 @@ class WasmGraphBuildingInterface {
case kOptRef: case kOptRef:
return builder_->RefNull(); return builder_->RefNull();
case kRtt: case kRtt:
case kRttWithDepth:
case kVoid: case kVoid:
case kBottom: case kBottom:
case kRef: case kRef:

View File

@ -117,7 +117,6 @@ WasmValue DefaultValueForType(ValueType type, Isolate* isolate) {
return WasmValue(isolate->factory()->null_value(), type); return WasmValue(isolate->factory()->null_value(), type);
case kVoid: case kVoid:
case kRtt: case kRtt:
case kRttWithDepth:
case kRef: case kRef:
case kBottom: case kBottom:
UNREACHABLE(); UNREACHABLE();
@ -192,7 +191,7 @@ void InitExprInterface::RttCanon(FullDecoder* decoder, uint32_t type_index,
if (!generate_result()) return; if (!generate_result()) return;
result->runtime_value = WasmValue( result->runtime_value = WasmValue(
handle(instance_->managed_object_maps().get(type_index), isolate_), handle(instance_->managed_object_maps().get(type_index), isolate_),
ValueType::Rtt(type_index, 0)); ValueType::Rtt(type_index));
} }
void InitExprInterface::DoReturn(FullDecoder* decoder, void InitExprInterface::DoReturn(FullDecoder* decoder,

View File

@ -37,10 +37,6 @@ size_t LocalDeclEncoder::Emit(byte* buffer) const {
LEBHelper::write_u32v(&pos, locals_count); LEBHelper::write_u32v(&pos, locals_count);
*pos = locals_type.value_type_code(); *pos = locals_type.value_type_code();
++pos; ++pos;
if (locals_type.has_depth()) {
*pos = locals_type.depth();
++pos;
}
if (locals_type.is_rtt()) { if (locals_type.is_rtt()) {
LEBHelper::write_u32v(&pos, locals_type.ref_index()); LEBHelper::write_u32v(&pos, locals_type.ref_index());
} }
@ -72,7 +68,6 @@ size_t LocalDeclEncoder::Size() const {
size += size +=
LEBHelper::sizeof_u32v(p.first) + // number of locals LEBHelper::sizeof_u32v(p.first) + // number of locals
1 + // Opcode 1 + // Opcode
(p.second.has_depth() ? 1 : 0) + // Inheritance depth
(p.second.encoding_needs_heap_type() (p.second.encoding_needs_heap_type()
? LEBHelper::sizeof_i32v(p.second.heap_type().code()) ? LEBHelper::sizeof_i32v(p.second.heap_type().code())
: 0) + : 0) +

View File

@ -1421,7 +1421,6 @@ bool InstanceBuilder::ProcessImportedWasmGlobalObject(
value = WasmValue(global_object->GetF64()); value = WasmValue(global_object->GetF64());
break; break;
case kRtt: case kRtt:
case kRttWithDepth:
case kRef: case kRef:
case kOptRef: case kOptRef:
value = WasmValue(global_object->GetRef(), global_object->type()); value = WasmValue(global_object->GetRef(), global_object->type());

View File

@ -41,13 +41,12 @@ class Simd128;
V(I8, 0, I8, Int8, 'b', "i8") \ V(I8, 0, I8, Int8, 'b', "i8") \
V(I16, 1, I16, Int16, 'h', "i16") V(I16, 1, I16, Int16, 'h', "i16")
#define FOREACH_VALUE_TYPE(V) \ #define FOREACH_VALUE_TYPE(V) \
V(Void, -1, Void, None, 'v', "<void>") \ V(Void, -1, Void, None, 'v', "<void>") \
FOREACH_NUMERIC_VALUE_TYPE(V) \ FOREACH_NUMERIC_VALUE_TYPE(V) \
V(Rtt, kTaggedSizeLog2, Rtt, TaggedPointer, 't', "rtt") \ V(Rtt, kTaggedSizeLog2, Rtt, TaggedPointer, 't', "rtt") \
V(RttWithDepth, kTaggedSizeLog2, RttWithDepth, TaggedPointer, 'k', "rtt") \ V(Ref, kTaggedSizeLog2, Ref, AnyTagged, 'r', "ref") \
V(Ref, kTaggedSizeLog2, Ref, AnyTagged, 'r', "ref") \ V(OptRef, kTaggedSizeLog2, OptRef, AnyTagged, 'n', "ref null") \
V(OptRef, kTaggedSizeLog2, OptRef, AnyTagged, 'n', "ref null") \
V(Bottom, -1, Void, None, '*', "<bot>") V(Bottom, -1, Void, None, '*', "<bot>")
constexpr int kMaxValueTypeSize = 16; // bytes constexpr int kMaxValueTypeSize = 16; // bytes
@ -208,8 +207,7 @@ constexpr bool is_numeric(ValueKind kind) {
} }
constexpr bool is_reference(ValueKind kind) { constexpr bool is_reference(ValueKind kind) {
return kind == kRef || kind == kOptRef || kind == kRtt || return kind == kRef || kind == kOptRef || kind == kRtt;
kind == kRttWithDepth;
} }
constexpr bool is_object_reference(ValueKind kind) { constexpr bool is_object_reference(ValueKind kind) {
@ -280,9 +278,7 @@ constexpr ValueKind unpacked(ValueKind kind) {
return is_packed(kind) ? kI32 : kind; return is_packed(kind) ? kI32 : kind;
} }
constexpr bool is_rtt(ValueKind kind) { constexpr bool is_rtt(ValueKind kind) { return kind == kRtt; }
return kind == kRtt || kind == kRttWithDepth;
}
constexpr bool is_defaultable(ValueKind kind) { constexpr bool is_defaultable(ValueKind kind) {
DCHECK(kind != kBottom && kind != kVoid); DCHECK(kind != kBottom && kind != kVoid);
@ -319,14 +315,6 @@ class ValueType {
HeapTypeField::encode(type_index)); HeapTypeField::encode(type_index));
} }
static constexpr ValueType Rtt(uint32_t type_index,
uint8_t inheritance_depth) {
DCHECK(HeapType(type_index).is_index());
return ValueType(KindField::encode(kRttWithDepth) |
HeapTypeField::encode(type_index) |
DepthField::encode(inheritance_depth));
}
// Useful when deserializing a type stored in a runtime object. // Useful when deserializing a type stored in a runtime object.
static constexpr ValueType FromRawBitField(uint32_t bit_field) { static constexpr ValueType FromRawBitField(uint32_t bit_field) {
return ValueType(bit_field); return ValueType(bit_field);
@ -349,7 +337,6 @@ class ValueType {
} }
constexpr bool is_rtt() const { return wasm::is_rtt(kind()); } constexpr bool is_rtt() const { return wasm::is_rtt(kind()); }
constexpr bool has_depth() const { return kind() == kRttWithDepth; }
constexpr bool has_index() const { constexpr bool has_index() const {
return is_rtt() || (is_object_reference() && heap_type().is_index()); return is_rtt() || (is_object_reference() && heap_type().is_index());
@ -383,10 +370,6 @@ class ValueType {
DCHECK(is_object_reference()); DCHECK(is_object_reference());
return HeapType(heap_representation()); return HeapType(heap_representation());
} }
constexpr uint8_t depth() const {
DCHECK(has_depth());
return DepthField::decode(bit_field_);
}
constexpr uint32_t ref_index() const { constexpr uint32_t ref_index() const {
DCHECK(has_index()); DCHECK(has_index());
return HeapTypeField::decode(bit_field_); return HeapTypeField::decode(bit_field_);
@ -488,8 +471,6 @@ class ValueType {
return kVoidCode; return kVoidCode;
case kRtt: case kRtt:
return kRttCode; return kRttCode;
case kRttWithDepth:
return kRttWithDepthCode;
#define NUMERIC_TYPE_CASE(kind, ...) \ #define NUMERIC_TYPE_CASE(kind, ...) \
case k##kind: \ case k##kind: \
return k##kind##Code; return k##kind##Code;
@ -519,7 +500,7 @@ class ValueType {
} }
} }
static constexpr int kLastUsedBit = 30; static constexpr int kLastUsedBit = 24;
/****************************** Pretty-printing *****************************/ /****************************** Pretty-printing *****************************/
constexpr char short_name() const { return wasm::short_name(kind()); } constexpr char short_name() const { return wasm::short_name(kind()); }
@ -536,10 +517,6 @@ class ValueType {
buf << heap_type().name() << "ref"; buf << heap_type().name() << "ref";
} }
break; break;
case kRttWithDepth:
buf << "(rtt " << static_cast<uint32_t>(depth()) << " " << ref_index()
<< ")";
break;
case kRtt: case kRtt:
buf << "(rtt " << ref_index() << ")"; buf << "(rtt " << ref_index() << ")";
break; break;
@ -553,21 +530,16 @@ class ValueType {
// needed. // needed.
static constexpr int kKindBits = 5; static constexpr int kKindBits = 5;
static constexpr int kHeapTypeBits = 20; static constexpr int kHeapTypeBits = 20;
static constexpr int kDepthBits = 6;
private: private:
STATIC_ASSERT(kV8MaxWasmTypes < (1u << kHeapTypeBits)); STATIC_ASSERT(kV8MaxWasmTypes < (1u << kHeapTypeBits));
// Note: we currently conservatively allow only 5 bits, but have room to
// store 6, so we can raise the limit if needed.
STATIC_ASSERT(kV8MaxRttSubtypingDepth < (1u << kDepthBits));
using KindField = base::BitField<ValueKind, 0, kKindBits>; using KindField = base::BitField<ValueKind, 0, kKindBits>;
using HeapTypeField = KindField::Next<uint32_t, kHeapTypeBits>; using HeapTypeField = KindField::Next<uint32_t, kHeapTypeBits>;
using DepthField = HeapTypeField::Next<uint8_t, kDepthBits>;
// This is implemented defensively against field order changes. // This is implemented defensively against field order changes.
STATIC_ASSERT(kLastUsedBit == std::max(KindField::kLastUsedBit, STATIC_ASSERT(kLastUsedBit ==
std::max(HeapTypeField::kLastUsedBit, std::max(KindField::kLastUsedBit, HeapTypeField::kLastUsedBit));
DepthField::kLastUsedBit)));
constexpr explicit ValueType(uint32_t bit_field) : bit_field_(bit_field) {} constexpr explicit ValueType(uint32_t bit_field) : bit_field_(bit_field) {}

View File

@ -44,6 +44,7 @@ enum ValueTypeCode : uint8_t {
kOptRefCode = 0x6c, kOptRefCode = 0x6c,
kRefCode = 0x6b, kRefCode = 0x6b,
kI31RefCode = 0x6a, kI31RefCode = 0x6a,
// TODO(7748): Only here for backwards compatibility, remove when able.
kRttWithDepthCode = 0x69, kRttWithDepthCode = 0x69,
kRttCode = 0x68, kRttCode = 0x68,
kDataRefCode = 0x67, kDataRefCode = 0x67,

View File

@ -657,8 +657,7 @@ class DebugInfoImpl {
return WasmValue(Simd128(ReadUnalignedValue<int16>(stack_address))); return WasmValue(Simd128(ReadUnalignedValue<int16>(stack_address)));
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt: {
case kRttWithDepth: {
Handle<Object> obj(Object(ReadUnalignedValue<Address>(stack_address)), Handle<Object> obj(Object(ReadUnalignedValue<Address>(stack_address)),
isolate); isolate);
return WasmValue(obj, value->type); return WasmValue(obj, value->type);

View File

@ -46,7 +46,7 @@ ValueType WasmInitExpr::type(const WasmModule* module,
case kArrayInitStatic: case kArrayInitStatic:
return ValueType::Ref(immediate().index, kNonNullable); return ValueType::Ref(immediate().index, kNonNullable);
case kRttCanon: case kRttCanon:
return ValueType::Rtt(immediate().heap_type, 0); return ValueType::Rtt(immediate().heap_type);
} }
} }

View File

@ -1536,7 +1536,6 @@ void WebAssemblyGlobal(const v8::FunctionCallbackInfo<v8::Value>& args) {
break; break;
} }
case i::wasm::kRtt: case i::wasm::kRtt:
case i::wasm::kRttWithDepth:
// TODO(7748): Implement. // TODO(7748): Implement.
UNIMPLEMENTED(); UNIMPLEMENTED();
case i::wasm::kI8: case i::wasm::kI8:
@ -1731,7 +1730,6 @@ void EncodeExceptionValues(v8::Isolate* isolate,
} }
break; break;
case i::wasm::kRtt: case i::wasm::kRtt:
case i::wasm::kRttWithDepth:
case i::wasm::kI8: case i::wasm::kI8:
case i::wasm::kI16: case i::wasm::kI16:
case i::wasm::kVoid: case i::wasm::kVoid:
@ -2283,7 +2281,6 @@ void WebAssemblyExceptionGetArg(
} }
break; break;
case i::wasm::kRtt: case i::wasm::kRtt:
case i::wasm::kRttWithDepth:
case i::wasm::kI8: case i::wasm::kI8:
case i::wasm::kI16: case i::wasm::kI16:
case i::wasm::kVoid: case i::wasm::kVoid:
@ -2345,7 +2342,6 @@ void WebAssemblyExceptionGetArg(
} }
break; break;
case i::wasm::kRtt: case i::wasm::kRtt:
case i::wasm::kRttWithDepth:
case i::wasm::kI8: case i::wasm::kI8:
case i::wasm::kI16: case i::wasm::kI16:
case i::wasm::kVoid: case i::wasm::kVoid:
@ -2437,7 +2433,6 @@ void WebAssemblyGlobalGetValueCommon(
} }
break; break;
case i::wasm::kRtt: case i::wasm::kRtt:
case i::wasm::kRttWithDepth:
UNIMPLEMENTED(); // TODO(7748): Implement. UNIMPLEMENTED(); // TODO(7748): Implement.
case i::wasm::kI8: case i::wasm::kI8:
case i::wasm::kI16: case i::wasm::kI16:
@ -2532,7 +2527,6 @@ void WebAssemblyGlobalSetValue(
} }
break; break;
case i::wasm::kRtt: case i::wasm::kRtt:
case i::wasm::kRttWithDepth:
// TODO(7748): Implement. // TODO(7748): Implement.
UNIMPLEMENTED(); UNIMPLEMENTED();
case i::wasm::kI8: case i::wasm::kI8:

View File

@ -134,7 +134,6 @@ void WriteValueType(ZoneBuffer* buffer, const ValueType& type) {
buffer->write_i32v(type.heap_type().code()); buffer->write_i32v(type.heap_type().code());
} }
if (type.is_rtt()) { if (type.is_rtt()) {
if (type.has_depth()) buffer->write_u32v(type.depth());
buffer->write_u32v(type.ref_index()); buffer->write_u32v(type.ref_index());
} }
} }
@ -520,7 +519,6 @@ void WriteInitializerExpressionWithEnd(ZoneBuffer* buffer,
case kBottom: case kBottom:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
UNREACHABLE(); UNREACHABLE();
} }
break; break;

View File

@ -386,7 +386,6 @@ Handle<Object> WasmObject::ReadValueAt(Isolate* isolate, Handle<HeapObject> obj,
} }
case wasm::kRtt: case wasm::kRtt:
case wasm::kRttWithDepth:
// Rtt values are not supposed to be made available to JavaScript side. // Rtt values are not supposed to be made available to JavaScript side.
UNREACHABLE(); UNREACHABLE();
@ -422,7 +421,6 @@ MaybeHandle<Object> WasmObject::ToWasmValue(Isolate* isolate,
UNREACHABLE(); UNREACHABLE();
case wasm::kRtt: case wasm::kRtt:
case wasm::kRttWithDepth:
// Rtt values are not supposed to be made available to JavaScript side. // Rtt values are not supposed to be made available to JavaScript side.
UNREACHABLE(); UNREACHABLE();
@ -500,7 +498,6 @@ void WasmObject::WriteValueAt(Isolate* isolate, Handle<HeapObject> obj,
UNREACHABLE(); UNREACHABLE();
case wasm::kRtt: case wasm::kRtt:
case wasm::kRttWithDepth:
// Rtt values are not supposed to be made available to JavaScript side. // Rtt values are not supposed to be made available to JavaScript side.
UNREACHABLE(); UNREACHABLE();

View File

@ -1562,7 +1562,6 @@ wasm::WasmValue WasmStruct::GetFieldValue(uint32_t index) {
return wasm::WasmValue(ref, field_type); return wasm::WasmValue(ref, field_type);
} }
case wasm::kRtt: case wasm::kRtt:
case wasm::kRttWithDepth:
// TODO(7748): Expose RTTs to DevTools. // TODO(7748): Expose RTTs to DevTools.
UNIMPLEMENTED(); UNIMPLEMENTED();
case wasm::kVoid: case wasm::kVoid:
@ -1592,7 +1591,6 @@ wasm::WasmValue WasmArray::GetElement(uint32_t index) {
return wasm::WasmValue(ref, element_type); return wasm::WasmValue(ref, element_type);
} }
case wasm::kRtt: case wasm::kRtt:
case wasm::kRttWithDepth:
// TODO(7748): Expose RTTs to DevTools. // TODO(7748): Expose RTTs to DevTools.
UNIMPLEMENTED(); UNIMPLEMENTED();
case wasm::kVoid: case wasm::kVoid:
@ -1834,7 +1832,6 @@ uint32_t WasmExceptionPackage::GetEncodedSize(const wasm::WasmTag* tag) {
encoded_size += 1; encoded_size += 1;
break; break;
case wasm::kRtt: case wasm::kRtt:
case wasm::kRttWithDepth:
case wasm::kVoid: case wasm::kVoid:
case wasm::kBottom: case wasm::kBottom:
case wasm::kI8: case wasm::kI8:
@ -2336,7 +2333,6 @@ bool TypecheckJSObject(Isolate* isolate, const WasmModule* module,
} }
} }
case kRtt: case kRtt:
case kRttWithDepth:
// TODO(7748): Implement when the JS API for rtts is decided on. // TODO(7748): Implement when the JS API for rtts is decided on.
*error_message = *error_message =
"passing rtts between Webassembly and Javascript is not supported " "passing rtts between Webassembly and Javascript is not supported "

View File

@ -149,16 +149,6 @@ V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl(
return supertype.kind() == kRtt && return supertype.kind() == kRtt &&
EquivalentIndices(subtype.ref_index(), supertype.ref_index(), EquivalentIndices(subtype.ref_index(), supertype.ref_index(),
sub_module, super_module); sub_module, super_module);
case kRttWithDepth:
return (supertype.kind() == kRtt &&
((sub_module == super_module &&
subtype.ref_index() == supertype.ref_index()) ||
EquivalentIndices(subtype.ref_index(), supertype.ref_index(),
sub_module, super_module))) ||
(supertype.kind() == kRttWithDepth &&
supertype.depth() == subtype.depth() &&
EquivalentIndices(subtype.ref_index(), supertype.ref_index(),
sub_module, super_module));
case kRef: case kRef:
case kOptRef: case kOptRef:
break; break;
@ -250,9 +240,6 @@ V8_NOINLINE bool EquivalentTypes(ValueType type1, ValueType type2,
DCHECK(type1.has_index() && type2.has_index() && DCHECK(type1.has_index() && type2.has_index() &&
(type1 != type2 || module1 != module2)); (type1 != type2 || module1 != module2));
DCHECK_IMPLIES(type1.has_depth(), type2.has_depth()); // Due to 'if' above.
if (type1.has_depth() && type1.depth() != type2.depth()) return false;
DCHECK(type1.has_index() && module1->has_type(type1.ref_index()) && DCHECK(type1.has_index() && module1->has_type(type1.ref_index()) &&
type2.has_index() && module2->has_type(type2.ref_index())); type2.has_index() && module2->has_type(type2.ref_index()));

View File

@ -71,7 +71,7 @@ V8_INLINE bool IsSubtypeOf(ValueType subtype, ValueType supertype,
} }
// We have this function call IsSubtypeOf instead of the opposite because type // We have this function call IsSubtypeOf instead of the opposite because type
// checks are much more common than heap type checks.} // checks are much more common than heap type checks.
V8_INLINE bool IsHeapSubtypeOf(uint32_t subtype_index, V8_INLINE bool IsHeapSubtypeOf(uint32_t subtype_index,
HeapType::Representation supertype, HeapType::Representation supertype,
const WasmModule* module) { const WasmModule* module) {

View File

@ -202,7 +202,6 @@ class WasmValue {
case kOptRef: case kOptRef:
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
return "Handle [" + std::to_string(to_ref().address()) + "]"; return "Handle [" + std::to_string(to_ref().address()) + "]";
case kVoid: case kVoid:
case kBottom: case kBottom:

View File

@ -561,7 +561,7 @@ WASM_COMPILED_EXEC_TEST(BrOnCast) {
const byte type_index = tester.DefineStruct({F(kWasmI32, true)}); const byte type_index = tester.DefineStruct({F(kWasmI32, true)});
const byte other_type_index = tester.DefineStruct({F(kWasmF32, true)}); const byte other_type_index = tester.DefineStruct({F(kWasmF32, true)});
const byte rtt_index = const byte rtt_index =
tester.AddGlobal(ValueType::Rtt(type_index, 0), false, tester.AddGlobal(ValueType::Rtt(type_index), false,
WasmInitExpr::RttCanon( WasmInitExpr::RttCanon(
static_cast<HeapType::Representation>(type_index))); static_cast<HeapType::Representation>(type_index)));
const byte kTestStruct = tester.DefineFunction( const byte kTestStruct = tester.DefineFunction(
@ -1347,11 +1347,11 @@ WASM_COMPILED_EXEC_TEST(BasicRtt) {
const byte subtype_index = tester.DefineStruct( const byte subtype_index = tester.DefineStruct(
{F(wasm::kWasmI32, true), F(wasm::kWasmI32, true)}, type_index); {F(wasm::kWasmI32, true), F(wasm::kWasmI32, true)}, type_index);
ValueType kRttTypes[] = {ValueType::Rtt(type_index, 0)}; ValueType kRttTypes[] = {ValueType::Rtt(type_index)};
FunctionSig sig_t_v(1, 0, kRttTypes); FunctionSig sig_t_v(1, 0, kRttTypes);
ValueType kRttSubtypes[] = {ValueType::Rtt(subtype_index, 1)}; ValueType kRttSubtypes[] = {ValueType::Rtt(subtype_index)};
FunctionSig sig_t2_v(1, 0, kRttSubtypes); FunctionSig sig_t2_v(1, 0, kRttSubtypes);
ValueType kRttTypesDeeper[] = {ValueType::Rtt(type_index, 1)}; ValueType kRttTypesDeeper[] = {ValueType::Rtt(type_index)};
FunctionSig sig_t3_v(1, 0, kRttTypesDeeper); FunctionSig sig_t3_v(1, 0, kRttTypesDeeper);
ValueType kRefTypes[] = {ref(type_index)}; ValueType kRefTypes[] = {ref(type_index)};
FunctionSig sig_q_v(1, 0, kRefTypes); FunctionSig sig_q_v(1, 0, kRefTypes);
@ -1643,7 +1643,7 @@ WASM_COMPILED_EXEC_TEST(ArrayNewMap) {
&sig, {}, &sig, {},
{WASM_ARRAY_NEW(type_index, WASM_I32V(10), WASM_I32V(42)), kExprEnd}); {WASM_ARRAY_NEW(type_index, WASM_I32V(10), WASM_I32V(42)), kExprEnd});
ValueType rtt_type = ValueType::Rtt(type_index, 0); ValueType rtt_type = ValueType::Rtt(type_index);
FunctionSig rtt_canon_sig(1, 0, &rtt_type); FunctionSig rtt_canon_sig(1, 0, &rtt_type);
const byte kRttCanon = tester.DefineFunction( const byte kRttCanon = tester.DefineFunction(
&rtt_canon_sig, {}, {WASM_RTT_CANON(type_index), kExprEnd}); &rtt_canon_sig, {}, {WASM_RTT_CANON(type_index), kExprEnd});
@ -1677,7 +1677,7 @@ WASM_COMPILED_EXEC_TEST(FunctionRefs) {
ValueType func_type = ValueType::Ref(sig_index, kNullable); ValueType func_type = ValueType::Ref(sig_index, kNullable);
FunctionSig sig_func(1, 0, &func_type); FunctionSig sig_func(1, 0, &func_type);
ValueType rtt0 = ValueType::Rtt(sig_index, 0); ValueType rtt0 = ValueType::Rtt(sig_index);
FunctionSig sig_rtt0(1, 0, &rtt0); FunctionSig sig_rtt0(1, 0, &rtt0);
const byte rtt_canon = tester.DefineFunction( const byte rtt_canon = tester.DefineFunction(
&sig_rtt0, {}, {WASM_RTT_CANON(sig_index), kExprEnd}); &sig_rtt0, {}, {WASM_RTT_CANON(sig_index), kExprEnd});
@ -2030,12 +2030,12 @@ WASM_COMPILED_EXEC_TEST(CastsBenchmark) {
WasmInitExpr::RefNullConst( WasmInitExpr::RefNullConst(
static_cast<HeapType::Representation>(ListType))); static_cast<HeapType::Representation>(ListType)));
const byte RttSuper = tester.AddGlobal( const byte RttSuper = tester.AddGlobal(
ValueType::Rtt(SuperType, 0), false, ValueType::Rtt(SuperType), false,
WasmInitExpr::RttCanon(static_cast<HeapType::Representation>(SuperType))); WasmInitExpr::RttCanon(static_cast<HeapType::Representation>(SuperType)));
const byte RttSub = tester.AddGlobal(ValueType::Rtt(SubType, 1), false, const byte RttSub = tester.AddGlobal(ValueType::Rtt(SubType), false,
WasmInitExpr::RttCanon(SubType)); WasmInitExpr::RttCanon(SubType));
const byte RttList = tester.AddGlobal( const byte RttList = tester.AddGlobal(
ValueType::Rtt(ListType, 0), false, ValueType::Rtt(ListType), false,
WasmInitExpr::RttCanon(static_cast<HeapType::Representation>(ListType))); WasmInitExpr::RttCanon(static_cast<HeapType::Representation>(ListType)));
const uint32_t kListLength = 1024; const uint32_t kListLength = 1024;

View File

@ -1442,7 +1442,6 @@ class WasmInterpreterInternals {
} }
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
case kVoid: case kVoid:
case kBottom: case kBottom:
case kI8: case kI8:
@ -3166,7 +3165,6 @@ class WasmInterpreterInternals {
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt:
case kRttWithDepth:
encoded_values->set(encoded_index++, *value.to_ref()); encoded_values->set(encoded_index++, *value.to_ref());
break; break;
case kI8: case kI8:
@ -3253,8 +3251,7 @@ class WasmInterpreterInternals {
} }
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt: {
case kRttWithDepth: {
Handle<Object> ref(encoded_values->get(encoded_index++), isolate_); Handle<Object> ref(encoded_values->get(encoded_index++), isolate_);
value = WasmValue(ref, sig->GetParam(i)); value = WasmValue(ref, sig->GetParam(i));
break; break;
@ -3630,8 +3627,7 @@ class WasmInterpreterInternals {
#undef CASE_TYPE #undef CASE_TYPE
case kRef: case kRef:
case kOptRef: case kOptRef:
case kRtt: case kRtt: {
case kRttWithDepth: {
// TODO(7748): Type checks or DCHECKs for ref types? // TODO(7748): Type checks or DCHECKs for ref types?
HandleScope handle_scope(isolate_); // Avoid leaking handles. HandleScope handle_scope(isolate_); // Avoid leaking handles.
Handle<FixedArray> global_buffer; // The buffer of the global. Handle<FixedArray> global_buffer; // The buffer of the global.
@ -4050,7 +4046,6 @@ class WasmInterpreterInternals {
PrintF("ref:0x%" V8PRIxPTR, val.to_ref()->ptr()); PrintF("ref:0x%" V8PRIxPTR, val.to_ref()->ptr());
break; break;
case kRtt: case kRtt:
case kRttWithDepth:
PrintF("rtt:0x%" V8PRIxPTR, val.to_ref()->ptr()); PrintF("rtt:0x%" V8PRIxPTR, val.to_ref()->ptr());
break; break;
case kI8: case kI8:

View File

@ -584,8 +584,6 @@ inline WasmOpcode LoadStoreOpcodeOf(MachineType type, bool store) {
__VA_ARGS__, WASM_GC_OP(kExprArrayInitStatic), static_cast<byte>(index), \ __VA_ARGS__, WASM_GC_OP(kExprArrayInitStatic), static_cast<byte>(index), \
static_cast<byte>(length) static_cast<byte>(length)
#define WASM_RTT_WITH_DEPTH(depth, typeidx) \
kRttWithDepthCode, U32V_1(depth), U32V_1(typeidx)
#define WASM_RTT(typeidx) kRttCode, U32V_1(typeidx) #define WASM_RTT(typeidx) kRttCode, U32V_1(typeidx)
#define WASM_RTT_CANON(typeidx) \ #define WASM_RTT_CANON(typeidx) \
WASM_GC_OP(kExprRttCanon), static_cast<byte>(typeidx) WASM_GC_OP(kExprRttCanon), static_cast<byte>(typeidx)

View File

@ -73,7 +73,6 @@ base::OwnedVector<WasmValue> MakeDefaultInterpreterArguments(
break; break;
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
case kI8: case kI8:
case kI16: case kI16:
case kVoid: case kVoid:
@ -108,7 +107,6 @@ base::OwnedVector<Handle<Object>> MakeDefaultArguments(Isolate* isolate,
break; break;
case kRef: case kRef:
case kRtt: case kRtt:
case kRttWithDepth:
case kI8: case kI8:
case kI16: case kI16:
case kVoid: case kVoid:

View File

@ -147,13 +147,8 @@ function wasmRefType(heap_type) {
return {opcode: kWasmRef, heap_type: heap_type}; return {opcode: kWasmRef, heap_type: heap_type};
} }
let kWasmRttWithDepth = 0x69;
function wasmRtt(index, depth) {
if (index < 0) throw new Error("Expecting non-negative type index");
return {opcode: kWasmRttWithDepth, index: index, depth: depth};
}
let kWasmRtt = 0x68; let kWasmRtt = 0x68;
function wasmRttNoDepth(index) { function wasmRtt(index) {
if (index < 0) throw new Error("Expecting non-negative type index"); if (index < 0) throw new Error("Expecting non-negative type index");
return {opcode: kWasmRtt, index: index}; return {opcode: kWasmRtt, index: index};
} }

View File

@ -3984,8 +3984,8 @@ TEST_F(FunctionBodyDecoderTest, GCStruct) {
WASM_RTT_CANON(array_type_index)), WASM_RTT_CANON(array_type_index)),
kExprDrop}, kExprDrop},
kAppendEnd, kAppendEnd,
"struct.new_with_rtt[1] expected rtt with depth for type 0, " "struct.new_with_rtt[1] expected type (rtt 0), found "
"found rtt.canon of type (rtt 0 1)"); "rtt.canon of type (rtt 1)");
// Out-of-bounds index. // Out-of-bounds index.
ExpectFailure(sigs.v_v(), ExpectFailure(sigs.v_v(),
{WASM_STRUCT_NEW_WITH_RTT(42, WASM_I32V(0), {WASM_STRUCT_NEW_WITH_RTT(42, WASM_I32V(0),
@ -4123,8 +4123,8 @@ TEST_F(FunctionBodyDecoderTest, GCArray) {
array_type_index, WASM_REF_NULL(kFuncRefCode), WASM_I32V(5), array_type_index, WASM_REF_NULL(kFuncRefCode), WASM_I32V(5),
WASM_RTT_CANON(struct_type_index))}, WASM_RTT_CANON(struct_type_index))},
kAppendEnd, kAppendEnd,
"array.new_with_rtt[2] expected rtt with depth for type 0, " "array.new_with_rtt[2] expected type (rtt 0), found "
"found rtt.canon of type (rtt 0 1)"); "rtt.canon of type (rtt 1)");
// Wrong type index. // Wrong type index.
ExpectFailure( ExpectFailure(
sigs.v_v(), sigs.v_v(),
@ -4324,15 +4324,9 @@ TEST_F(FunctionBodyDecoderTest, RttCanon) {
uint8_t struct_type_index = builder.AddStruct({F(kWasmI64, true)}); uint8_t struct_type_index = builder.AddStruct({F(kWasmI64, true)});
for (uint32_t type_index : {array_type_index, struct_type_index}) { for (uint32_t type_index : {array_type_index, struct_type_index}) {
ValueType rtt1 = ValueType::Rtt(type_index, 0); ValueType rtt1 = ValueType::Rtt(type_index);
FunctionSig sig1(1, 0, &rtt1); FunctionSig sig1(1, 0, &rtt1);
ExpectValidates(&sig1, {WASM_RTT_CANON(type_index)}); ExpectValidates(&sig1, {WASM_RTT_CANON(type_index)});
// rtt.canon should fail for incorrect depth.
ValueType rtt2 = ValueType::Rtt(type_index, 1);
FunctionSig sig2(1, 0, &rtt2);
ExpectFailure(&sig2, {WASM_RTT_CANON(type_index)}, kAppendEnd,
"type error in fallthru[0]");
} }
} }

View File

@ -789,8 +789,8 @@ TEST_F(WasmModuleVerifyTest, RttCanonGlobalStruct) {
static const byte data[] = { static const byte data[] = {
SECTION(Type, ENTRY_COUNT(1), SECTION(Type, ENTRY_COUNT(1),
WASM_STRUCT_DEF(FIELD_COUNT(1), STRUCT_FIELD(kI32Code, true))), WASM_STRUCT_DEF(FIELD_COUNT(1), STRUCT_FIELD(kI32Code, true))),
SECTION(Global, ENTRY_COUNT(1), WASM_RTT_WITH_DEPTH(0, 0), 0, SECTION(Global, ENTRY_COUNT(1), WASM_RTT(0), 0, WASM_RTT_CANON(0),
WASM_RTT_CANON(0), kExprEnd)}; kExprEnd)};
ModuleResult result = DecodeModule(data, data + sizeof(data)); ModuleResult result = DecodeModule(data, data + sizeof(data));
EXPECT_OK(result); EXPECT_OK(result);
} }
@ -799,14 +799,15 @@ TEST_F(WasmModuleVerifyTest, RttCanonGlobalTypeError) {
WASM_FEATURE_SCOPE(typed_funcref); WASM_FEATURE_SCOPE(typed_funcref);
WASM_FEATURE_SCOPE(gc); WASM_FEATURE_SCOPE(gc);
static const byte data[] = { static const byte data[] = {
SECTION(Type, ENTRY_COUNT(1), SECTION(Type, ENTRY_COUNT(2),
WASM_STRUCT_DEF(FIELD_COUNT(1), STRUCT_FIELD(kI32Code, true)),
WASM_STRUCT_DEF(FIELD_COUNT(1), STRUCT_FIELD(kI32Code, true))), WASM_STRUCT_DEF(FIELD_COUNT(1), STRUCT_FIELD(kI32Code, true))),
SECTION(Global, ENTRY_COUNT(1), WASM_RTT_WITH_DEPTH(1, 0), 1, SECTION(Global, ENTRY_COUNT(1), WASM_RTT(0), 1, WASM_RTT_CANON(1),
WASM_RTT_CANON(0), kExprEnd)}; kExprEnd)};
ModuleResult result = DecodeModule(data, data + sizeof(data)); ModuleResult result = DecodeModule(data, data + sizeof(data));
EXPECT_NOT_OK( EXPECT_NOT_OK(
result, result,
"type error in init. expression[0] (expected (rtt 1 0), got (rtt 0 0))"); "type error in init. expression[0] (expected (rtt 0), got (rtt 1))");
} }
TEST_F(WasmModuleVerifyTest, StructNewInitExpr) { TEST_F(WasmModuleVerifyTest, StructNewInitExpr) {
@ -827,7 +828,7 @@ TEST_F(WasmModuleVerifyTest, StructNewInitExpr) {
SECTION(Global, ENTRY_COUNT(3), // -- SECTION(Global, ENTRY_COUNT(3), // --
kI32Code, 0, // type, mutability kI32Code, 0, // type, mutability
WASM_INIT_EXPR_I32V_1(10), // -- WASM_INIT_EXPR_I32V_1(10), // --
kRttWithDepthCode, 0, 0, 0, // type, mutability kRttCode, 0, 0, // type, mutability
WASM_RTT_CANON(0), kExprEnd, // -- WASM_RTT_CANON(0), kExprEnd, // --
kRefCode, 0, 0, // type, mutability kRefCode, 0, 0, // type, mutability
WASM_INIT_EXPR_STRUCT_NEW(0, WASM_GLOBAL_GET(0), WASM_INIT_EXPR_STRUCT_NEW(0, WASM_GLOBAL_GET(0),
@ -853,8 +854,8 @@ TEST_F(WasmModuleVerifyTest, StructNewInitExpr) {
kRefCode, 0, 0, // type, mutability kRefCode, 0, 0, // type, mutability
WASM_INIT_EXPR_STRUCT_NEW(0, WASM_I32V(42), WASM_RTT_CANON(1)))}; WASM_INIT_EXPR_STRUCT_NEW(0, WASM_I32V(42), WASM_RTT_CANON(1)))};
EXPECT_FAILURE_WITH_MSG(subexpr_type_error, EXPECT_FAILURE_WITH_MSG(subexpr_type_error,
"struct.new_with_rtt[1] expected rtt with depth for " "struct.new_with_rtt[1] expected type (rtt 0), found "
"type 0, found rtt.canon of type (rtt 0 1)"); "rtt.canon of type (rtt 1)");
} }
TEST_F(WasmModuleVerifyTest, ArrayInitInitExpr) { TEST_F(WasmModuleVerifyTest, ArrayInitInitExpr) {
@ -2133,7 +2134,7 @@ TEST_F(WasmModuleVerifyTest, IllegalTableTypes) {
{kOptRefCode, 1}, {kOptRefCode, 1},
{kOptRefCode, kI31RefCode}, {kOptRefCode, kI31RefCode},
{kI31RefCode}, {kI31RefCode},
{kRttWithDepthCode, 2, 0}}; {kRttCode, 0}};
for (Vec type : table_types) { for (Vec type : table_types) {
Vec data = { Vec data = {

View File

@ -182,26 +182,14 @@ TEST_F(WasmSubtypingTest, Subtyping) {
VALID_SUBTYPE(ref(9), ref(8)); VALID_SUBTYPE(ref(9), ref(8));
// Identical rtts are subtypes of each other. // Identical rtts are subtypes of each other.
SUBTYPE(ValueType::Rtt(5, 3), ValueType::Rtt(5, 3));
SUBTYPE(ValueType::Rtt(5), ValueType::Rtt(5)); SUBTYPE(ValueType::Rtt(5), ValueType::Rtt(5));
// Rtts of unrelated types are unrelated. // Rtts of unrelated types are unrelated.
NOT_SUBTYPE(ValueType::Rtt(1, 1), ValueType::Rtt(2, 1));
NOT_SUBTYPE(ValueType::Rtt(1), ValueType::Rtt(2)); NOT_SUBTYPE(ValueType::Rtt(1), ValueType::Rtt(2));
NOT_SUBTYPE(ValueType::Rtt(1, 0), ValueType::Rtt(2));
// Rtts of different depth are unrelated.
NOT_SUBTYPE(ValueType::Rtt(5, 1), ValueType::Rtt(5, 3));
NOT_SUBTYPE(ValueType::Rtt(5, 8), ValueType::Rtt(5, 3));
// Rtts of identical types are subtype-related. // Rtts of identical types are subtype-related.
// TODO(7748): Implement type canonicalization. // TODO(7748): Implement type canonicalization.
// SUBTYPE(ValueType::Rtt(8, 1), ValueType::Rtt(9, 1));
// SUBTYPE(ValueType::Rtt(8), ValueType::Rtt(9)); // SUBTYPE(ValueType::Rtt(8), ValueType::Rtt(9));
// Rtts of subtypes are not related. // Rtts of subtypes are not related.
NOT_SUBTYPE(ValueType::Rtt(1, 1), ValueType::Rtt(0, 1));
NOT_SUBTYPE(ValueType::Rtt(1), ValueType::Rtt(0)); NOT_SUBTYPE(ValueType::Rtt(1), ValueType::Rtt(0));
// rtt(t, d) <: rtt(t)
for (uint8_t depth : {0, 1, 5}) {
SUBTYPE(ValueType::Rtt(1, depth), ValueType::Rtt(1));
}
// Function subtyping; // Function subtyping;
// Unrelated function types are unrelated. // Unrelated function types are unrelated.