Commit 2e71a587 authored by Matthias Liedtke's avatar Matthias Liedtke Committed by V8 LUCI CQ

[wasm-gc] Remove obsolete RTT statements from function body decoder

This change removes:
- struct.new_with_rtt
- struct.new_default_with_rtt
- array.new_fixed
- array.new_data
- array.new_with_rtt
- array.new_default_with_rtt
- ref.test
- ref.cast
- br_on_cast
- br_on_cast_fail
- rtt.canon

Bug: v8:7748
Change-Id: Iadf73c294904ec20cefe1053a2969aa1dbb91a39
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3779689
Auto-Submit: Matthias Liedtke <mliedtke@google.com>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarManos Koukoutos <manoskouk@chromium.org>
Commit-Queue: Matthias Liedtke <mliedtke@google.com>
Cr-Commit-Position: refs/heads/main@{#81892}
parent 14262e04
...@@ -2039,9 +2039,7 @@ class WasmDecoder : public Decoder { ...@@ -2039,9 +2039,7 @@ class WasmDecoder : public Decoder {
decoder->read_two_byte_opcode<validate>(pc, &length, "gc_index"); decoder->read_two_byte_opcode<validate>(pc, &length, "gc_index");
switch (opcode) { switch (opcode) {
case kExprStructNew: case kExprStructNew:
case kExprStructNewWithRtt: case kExprStructNewDefault: {
case kExprStructNewDefault:
case kExprStructNewDefaultWithRtt: {
StructIndexImmediate<validate> imm(decoder, pc + length); StructIndexImmediate<validate> imm(decoder, pc + length);
if (io) io->TypeIndex(imm); if (io) io->TypeIndex(imm);
return length + imm.length; return length + imm.length;
...@@ -2055,9 +2053,7 @@ class WasmDecoder : public Decoder { ...@@ -2055,9 +2053,7 @@ class WasmDecoder : public Decoder {
return length + imm.length; return length + imm.length;
} }
case kExprArrayNew: case kExprArrayNew:
case kExprArrayNewWithRtt:
case kExprArrayNewDefault: case kExprArrayNewDefault:
case kExprArrayNewDefaultWithRtt:
case kExprArrayGet: case kExprArrayGet:
case kExprArrayGetS: case kExprArrayGetS:
case kExprArrayGetU: case kExprArrayGetU:
...@@ -2067,7 +2063,6 @@ class WasmDecoder : public Decoder { ...@@ -2067,7 +2063,6 @@ class WasmDecoder : public Decoder {
if (io) io->TypeIndex(imm); if (io) io->TypeIndex(imm);
return length + imm.length; return length + imm.length;
} }
case kExprArrayNewFixed:
case kExprArrayNewFixedStatic: { case kExprArrayNewFixedStatic: {
ArrayIndexImmediate<validate> array_imm(decoder, pc + length); ArrayIndexImmediate<validate> array_imm(decoder, pc + length);
IndexImmediate<validate> length_imm( IndexImmediate<validate> length_imm(
...@@ -2083,7 +2078,6 @@ class WasmDecoder : public Decoder { ...@@ -2083,7 +2078,6 @@ class WasmDecoder : public Decoder {
if (io) io->ArrayCopy(dst_imm, src_imm); if (io) io->ArrayCopy(dst_imm, src_imm);
return length + dst_imm.length + src_imm.length; return length + dst_imm.length + src_imm.length;
} }
case kExprArrayNewData:
case kExprArrayNewDataStatic: case kExprArrayNewDataStatic:
case kExprArrayNewElemStatic: { case kExprArrayNewElemStatic: {
ArrayIndexImmediate<validate> array_imm(decoder, pc + length); ArrayIndexImmediate<validate> array_imm(decoder, pc + length);
...@@ -2093,8 +2087,6 @@ class WasmDecoder : public Decoder { ...@@ -2093,8 +2087,6 @@ class WasmDecoder : public Decoder {
if (io) io->DataSegmentIndex(data_imm); if (io) io->DataSegmentIndex(data_imm);
return length + array_imm.length + data_imm.length; return length + array_imm.length + data_imm.length;
} }
case kExprBrOnCast:
case kExprBrOnCastFail:
case kExprBrOnArray: case kExprBrOnArray:
case kExprBrOnData: case kExprBrOnData:
case kExprBrOnFunc: case kExprBrOnFunc:
...@@ -2107,7 +2099,6 @@ class WasmDecoder : public Decoder { ...@@ -2107,7 +2099,6 @@ class WasmDecoder : public Decoder {
if (io) io->BranchDepth(imm); if (io) io->BranchDepth(imm);
return length + imm.length; return length + imm.length;
} }
case kExprRttCanon:
case kExprRefTestStatic: case kExprRefTestStatic:
case kExprRefCastStatic: case kExprRefCastStatic:
case kExprRefCastNopStatic: { case kExprRefCastNopStatic: {
...@@ -2135,8 +2126,6 @@ class WasmDecoder : public Decoder { ...@@ -2135,8 +2126,6 @@ class WasmDecoder : public Decoder {
case kExprRefIsData: case kExprRefIsData:
case kExprRefIsFunc: case kExprRefIsFunc:
case kExprRefIsI31: case kExprRefIsI31:
case kExprRefTest:
case kExprRefCast:
return length; return length;
case kExprStringNewWtf16: case kExprStringNewWtf16:
case kExprStringEncodeWtf16: case kExprStringEncodeWtf16:
...@@ -2326,7 +2315,6 @@ class WasmDecoder : public Decoder { ...@@ -2326,7 +2315,6 @@ class WasmDecoder : public Decoder {
uint32_t unused_length; uint32_t unused_length;
opcode = this->read_two_byte_opcode<validate>(pc, &unused_length); opcode = this->read_two_byte_opcode<validate>(pc, &unused_length);
switch (opcode) { switch (opcode) {
case kExprStructNewDefaultWithRtt:
case kExprStructGet: case kExprStructGet:
case kExprStructGetS: case kExprStructGetS:
case kExprStructGetU: case kExprStructGetU:
...@@ -2344,43 +2332,28 @@ class WasmDecoder : public Decoder { ...@@ -2344,43 +2332,28 @@ class WasmDecoder : public Decoder {
case kExprStructSet: case kExprStructSet:
return {2, 0}; return {2, 0};
case kExprArrayNew: case kExprArrayNew:
case kExprArrayNewDefaultWithRtt:
case kExprArrayNewDataStatic: case kExprArrayNewDataStatic:
case kExprArrayNewElemStatic: case kExprArrayNewElemStatic:
case kExprArrayGet: case kExprArrayGet:
case kExprArrayGetS: case kExprArrayGetS:
case kExprArrayGetU: case kExprArrayGetU:
case kExprRefTest:
case kExprRefCast:
case kExprBrOnCast:
case kExprBrOnCastFail:
return {2, 1}; return {2, 1};
case kExprArraySet: case kExprArraySet:
return {3, 0}; return {3, 0};
case kExprArrayCopy: case kExprArrayCopy:
return {5, 0}; return {5, 0};
case kExprRttCanon:
case kExprStructNewDefault: case kExprStructNewDefault:
return {0, 1}; return {0, 1};
case kExprArrayNewWithRtt:
case kExprArrayNewData:
return {3, 1};
case kExprStructNewWithRtt: {
StructIndexImmediate<validate> imm(this, pc + 2);
CHECK(Validate(pc + 2, imm));
return {imm.struct_type->field_count() + 1, 1};
}
case kExprStructNew: { case kExprStructNew: {
StructIndexImmediate<validate> imm(this, pc + 2); StructIndexImmediate<validate> imm(this, pc + 2);
CHECK(Validate(pc + 2, imm)); CHECK(Validate(pc + 2, imm));
return {imm.struct_type->field_count(), 1}; return {imm.struct_type->field_count(), 1};
} }
case kExprArrayNewFixed:
case kExprArrayNewFixedStatic: { case kExprArrayNewFixedStatic: {
ArrayIndexImmediate<validate> array_imm(this, pc + 2); ArrayIndexImmediate<validate> array_imm(this, pc + 2);
IndexImmediate<validate> length_imm(this, pc + 2 + array_imm.length, IndexImmediate<validate> length_imm(this, pc + 2 + array_imm.length,
"array length"); "array length");
return {length_imm.index + (opcode == kExprArrayNewFixed ? 1 : 0), 1}; return {length_imm.index, 1};
} }
case kExprStringConst: case kExprStringConst:
return { 0, 1 }; return { 0, 1 };
...@@ -4332,18 +4305,13 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4332,18 +4305,13 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
int DecodeGCOpcode(WasmOpcode opcode, uint32_t opcode_length) { int DecodeGCOpcode(WasmOpcode opcode, uint32_t opcode_length) {
switch (opcode) { switch (opcode) {
case kExprStructNew: case kExprStructNew: {
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); ValueType rtt_type = ValueType::Rtt(imm.index);
Value rtt = opcode == kExprStructNew Value rtt = CreateValue(rtt_type);
? CreateValue(rtt_type) CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
: Peek(0, imm.struct_type->field_count(), rtt_type); Push(rtt);
if (opcode == kExprStructNew) {
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
Push(rtt);
}
ArgVector args = PeekArgs(imm.struct_type, 1); ArgVector args = PeekArgs(imm.struct_type, 1);
Value value = CreateValue(ValueType::Ref(imm.index)); Value value = CreateValue(ValueType::Ref(imm.index));
CALL_INTERFACE_IF_OK_AND_REACHABLE(StructNewWithRtt, imm, rtt, CALL_INTERFACE_IF_OK_AND_REACHABLE(StructNewWithRtt, imm, rtt,
...@@ -4353,8 +4321,7 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4353,8 +4321,7 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
Push(value); Push(value);
return opcode_length + imm.length; return opcode_length + imm.length;
} }
case kExprStructNewDefault: case kExprStructNewDefault: {
case kExprStructNewDefaultWithRtt: {
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;
if (validate) { if (validate) {
...@@ -4370,12 +4337,9 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4370,12 +4337,9 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
} }
} }
ValueType rtt_type = ValueType::Rtt(imm.index); ValueType rtt_type = ValueType::Rtt(imm.index);
Value rtt = opcode == kExprStructNewDefault ? CreateValue(rtt_type) Value rtt = CreateValue(rtt_type);
: Peek(0, 0, rtt_type); CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
if (opcode == kExprStructNewDefault) { Push(rtt);
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
Push(rtt);
}
Value value = CreateValue(ValueType::Ref(imm.index)); Value value = CreateValue(ValueType::Ref(imm.index));
CALL_INTERFACE_IF_OK_AND_REACHABLE(StructNewDefault, imm, rtt, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(StructNewDefault, imm, rtt, &value);
Drop(rtt); Drop(rtt);
...@@ -4448,17 +4412,13 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4448,17 +4412,13 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
Drop(2); Drop(2);
return opcode_length + field.length; return opcode_length + field.length;
} }
case kExprArrayNew: case kExprArrayNew: {
case kExprArrayNewWithRtt: {
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;
ValueType rtt_type = ValueType::Rtt(imm.index); ValueType rtt_type = ValueType::Rtt(imm.index);
Value rtt = opcode == kExprArrayNew ? CreateValue(rtt_type) Value rtt = CreateValue(rtt_type);
: Peek(0, 2, rtt_type); CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
if (opcode == kExprArrayNew) { Push(rtt);
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
Push(rtt);
}
Value length = Peek(1, 1, kWasmI32); Value length = Peek(1, 1, kWasmI32);
Value initial_value = Value initial_value =
Peek(2, 0, imm.array_type->element_type().Unpacked()); Peek(2, 0, imm.array_type->element_type().Unpacked());
...@@ -4469,8 +4429,7 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4469,8 +4429,7 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
Push(value); Push(value);
return opcode_length + imm.length; return opcode_length + imm.length;
} }
case kExprArrayNewDefault: case kExprArrayNewDefault: {
case kExprArrayNewDefaultWithRtt: {
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;
if (!VALIDATE(imm.array_type->element_type().is_defaultable())) { if (!VALIDATE(imm.array_type->element_type().is_defaultable())) {
...@@ -4481,12 +4440,9 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4481,12 +4440,9 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
return 0; return 0;
} }
ValueType rtt_type = ValueType::Rtt(imm.index); ValueType rtt_type = ValueType::Rtt(imm.index);
Value rtt = opcode == kExprArrayNewDefault ? CreateValue(rtt_type) Value rtt = CreateValue(rtt_type);
: Peek(0, 1, rtt_type); CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
if (opcode == kExprArrayNewDefault) { Push(rtt);
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
Push(rtt);
}
Value length = Peek(1, 0, kWasmI32); Value length = Peek(1, 0, kWasmI32);
Value value = CreateValue(ValueType::Ref(imm.index)); Value value = CreateValue(ValueType::Ref(imm.index));
CALL_INTERFACE_IF_OK_AND_REACHABLE(ArrayNewDefault, imm, length, rtt, CALL_INTERFACE_IF_OK_AND_REACHABLE(ArrayNewDefault, imm, length, rtt,
...@@ -4495,7 +4451,6 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4495,7 +4451,6 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
Push(value); Push(value);
return opcode_length + imm.length; return opcode_length + imm.length;
} }
case kExprArrayNewData:
case kExprArrayNewDataStatic: { case kExprArrayNewDataStatic: {
ArrayIndexImmediate<validate> array_imm(this, ArrayIndexImmediate<validate> array_imm(this,
this->pc_ + opcode_length); this->pc_ + opcode_length);
...@@ -4523,12 +4478,9 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4523,12 +4478,9 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
if (!this->ValidateDataSegment(data_index_pc, data_segment)) return 0; if (!this->ValidateDataSegment(data_index_pc, data_segment)) return 0;
ValueType rtt_type = ValueType::Rtt(array_imm.index); ValueType rtt_type = ValueType::Rtt(array_imm.index);
Value rtt = opcode == kExprArrayNewDataStatic ? CreateValue(rtt_type) Value rtt = CreateValue(rtt_type);
: Peek(0, 2, rtt_type); CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, array_imm.index, &rtt);
if (opcode == kExprArrayNewDataStatic) { Push(rtt);
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, array_imm.index, &rtt);
Push(rtt);
}
Value length = Peek(1, 1, kWasmI32); Value length = Peek(1, 1, kWasmI32);
Value offset = Peek(2, 0, kWasmI32); Value offset = Peek(2, 0, kWasmI32);
...@@ -4693,7 +4645,6 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4693,7 +4645,6 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
Drop(5); Drop(5);
return opcode_length + dst_imm.length + src_imm.length; return opcode_length + dst_imm.length + src_imm.length;
} }
case kExprArrayNewFixed:
case kExprArrayNewFixedStatic: { case kExprArrayNewFixedStatic: {
ArrayIndexImmediate<validate> array_imm(this, ArrayIndexImmediate<validate> array_imm(this,
this->pc_ + opcode_length); this->pc_ + opcode_length);
...@@ -4709,13 +4660,9 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4709,13 +4660,9 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
length_imm.index, kV8MaxWasmArrayNewFixedLength); length_imm.index, kV8MaxWasmArrayNewFixedLength);
return 0; return 0;
} }
Value rtt = opcode == kExprArrayNewFixed Value rtt = CreateValue(ValueType::Rtt(array_imm.index));
? Peek(0, elem_count, ValueType::Rtt(array_imm.index)) CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, array_imm.index, &rtt);
: CreateValue(ValueType::Rtt(array_imm.index)); Push(rtt);
if (opcode == kExprArrayNewFixedStatic) {
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, array_imm.index, &rtt);
Push(rtt);
}
ValueType element_type = array_imm.array_type->element_type(); ValueType element_type = array_imm.array_type->element_type();
std::vector<ValueType> element_types(elem_count, std::vector<ValueType> element_types(elem_count,
element_type.Unpacked()); element_type.Unpacked());
...@@ -4754,35 +4701,15 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4754,35 +4701,15 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
Push(value); Push(value);
return opcode_length; return opcode_length;
} }
case kExprRttCanon: { case kExprRefTestStatic: {
NON_CONST_ONLY
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(imm.index)); opcode_length += imm.length;
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &value); Value rtt = CreateValue(ValueType::Rtt(imm.index));
Push(value); CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
return opcode_length + imm.length; Push(rtt);
}
case kExprRefTest:
case kExprRefTestStatic: {
NON_CONST_ONLY
// "Tests whether {obj}'s runtime type is a runtime subtype of {rtt}."
Value rtt = Peek(0); // This is safe for the ...Static instruction.
if (opcode == kExprRefTestStatic) {
IndexImmediate<validate> imm(this, this->pc_ + opcode_length,
"type index");
if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0;
opcode_length += imm.length;
rtt = CreateValue(ValueType::Rtt(imm.index));
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
Push(rtt);
} else {
DCHECK_EQ(opcode, kExprRefTest);
if (!VALIDATE(rtt.type.is_rtt() || rtt.type.is_bottom())) {
PopTypeError(1, rtt, "rtt");
return 0;
}
}
Value obj = Peek(1); Value obj = Peek(1);
Value value = CreateValue(kWasmI32); Value value = CreateValue(kWasmI32);
if (!VALIDATE(IsSubtypeOf(obj.type, kWasmFuncRef, this->module_) || if (!VALIDATE(IsSubtypeOf(obj.type, kWasmFuncRef, this->module_) ||
...@@ -4847,25 +4774,15 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4847,25 +4774,15 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
Push(value); Push(value);
return opcode_length; return opcode_length;
} }
case kExprRefCast:
case kExprRefCastStatic: { case kExprRefCastStatic: {
NON_CONST_ONLY NON_CONST_ONLY
Value rtt = Peek(0); // This is safe for the ...Static instruction. IndexImmediate<validate> imm(this, this->pc_ + opcode_length,
if (opcode == kExprRefCastStatic) { "type index");
IndexImmediate<validate> imm(this, this->pc_ + opcode_length, if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0;
"type index"); opcode_length += imm.length;
if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0; Value rtt = CreateValue(ValueType::Rtt(imm.index));
opcode_length += imm.length; CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
rtt = CreateValue(ValueType::Rtt(imm.index)); Push(rtt);
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
Push(rtt);
} else {
DCHECK_EQ(opcode, kExprRefCast);
if (!VALIDATE(rtt.type.is_rtt() || rtt.type.is_bottom())) {
PopTypeError(1, rtt, "rtt");
return 0;
}
}
Value obj = Peek(1); Value obj = Peek(1);
if (!VALIDATE(IsSubtypeOf(obj.type, kWasmFuncRef, this->module_) || if (!VALIDATE(IsSubtypeOf(obj.type, kWasmFuncRef, this->module_) ||
IsSubtypeOf(obj.type, ValueType::RefNull(HeapType::kData), IsSubtypeOf(obj.type, ValueType::RefNull(HeapType::kData),
...@@ -4875,13 +4792,10 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4875,13 +4792,10 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
return 0; return 0;
} }
// If either value is bottom, we emit the most specific type possible. // If either value is bottom, we emit the most specific type possible.
Value value = CreateValue( DCHECK(!rtt.type.is_bottom());
rtt.type.is_bottom() Value value = CreateValue(ValueType::RefMaybeNull(
? kWasmBottom imm.index,
: ValueType::RefMaybeNull(rtt.type.ref_index(), obj.type.is_bottom() ? kNonNullable : obj.type.nullability()));
obj.type.is_bottom()
? kNonNullable
: obj.type.nullability()));
if (current_code_reachable_and_ok_) { if (current_code_reachable_and_ok_) {
// This logic ensures that code generation can assume that functions // This logic ensures that code generation can assume that functions
// can only be cast to function types, and data objects to data types. // can only be cast to function types, and data objects to data types.
...@@ -4911,7 +4825,6 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4911,7 +4825,6 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
Push(value); Push(value);
return opcode_length; return opcode_length;
} }
case kExprBrOnCast:
case kExprBrOnCastStatic: { case kExprBrOnCastStatic: {
NON_CONST_ONLY NON_CONST_ONLY
BranchDepthImmediate<validate> branch_depth(this, BranchDepthImmediate<validate> branch_depth(this,
...@@ -4921,23 +4834,14 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4921,23 +4834,14 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
return 0; return 0;
} }
uint32_t pc_offset = opcode_length + branch_depth.length; uint32_t pc_offset = opcode_length + branch_depth.length;
Value rtt = Peek(0); // This is safe for the ...Static instruction. IndexImmediate<validate> imm(this, this->pc_ + pc_offset, "type index");
if (opcode == kExprBrOnCastStatic) { if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0;
IndexImmediate<validate> imm(this, this->pc_ + pc_offset, pc_offset += imm.length;
"type index"); Value rtt = CreateValue(ValueType::Rtt(imm.index));
if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0; CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
pc_offset += imm.length; // Don't bother pushing the rtt, as we'd drop it again immediately
rtt = CreateValue(ValueType::Rtt(imm.index)); // anyway.
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt); Value obj = Peek(0);
Push(rtt);
} else {
DCHECK_EQ(opcode, kExprBrOnCast);
if (!VALIDATE(rtt.type.is_rtt() || rtt.type.is_bottom())) {
PopTypeError(1, rtt, "rtt");
return 0;
}
}
Value obj = Peek(1);
if (!VALIDATE(IsSubtypeOf(obj.type, kWasmFuncRef, this->module_) || if (!VALIDATE(IsSubtypeOf(obj.type, kWasmFuncRef, this->module_) ||
IsSubtypeOf(obj.type, ValueType::RefNull(HeapType::kData), IsSubtypeOf(obj.type, ValueType::RefNull(HeapType::kData),
this->module_) || this->module_) ||
...@@ -4956,10 +4860,8 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4956,10 +4860,8 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
// significantly more convenient to pass around the values that // significantly more convenient to pass around the values that
// will be on the stack when the branch is taken. // will be on the stack when the branch is taken.
// TODO(jkummerow): Reconsider this choice. // TODO(jkummerow): Reconsider this choice.
Drop(2); // {obj} and {rtt}. Drop(obj);
Push(CreateValue(rtt.type.is_bottom() Push(CreateValue(ValueType::Ref(imm.index)));
? kWasmBottom
: ValueType::Ref(rtt.type.ref_index())));
// The {value_on_branch} parameter we pass to the interface must // The {value_on_branch} parameter we pass to the interface must
// be pointer-identical to the object on the stack. // be pointer-identical to the object on the stack.
Value* value_on_branch = stack_value(1); Value* value_on_branch = stack_value(1);
...@@ -4993,7 +4895,6 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4993,7 +4895,6 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
Push(obj); // Restore stack state on fallthrough. Push(obj); // Restore stack state on fallthrough.
return pc_offset; return pc_offset;
} }
case kExprBrOnCastFail:
case kExprBrOnCastStaticFail: { case kExprBrOnCastStaticFail: {
NON_CONST_ONLY NON_CONST_ONLY
BranchDepthImmediate<validate> branch_depth(this, BranchDepthImmediate<validate> branch_depth(this,
...@@ -5003,23 +4904,12 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -5003,23 +4904,12 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
return 0; return 0;
} }
uint32_t pc_offset = opcode_length + branch_depth.length; uint32_t pc_offset = opcode_length + branch_depth.length;
Value rtt = Peek(0); // This is safe for the ...Static instruction. IndexImmediate<validate> imm(this, this->pc_ + pc_offset, "type index");
if (opcode == kExprBrOnCastStaticFail) { if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0;
IndexImmediate<validate> imm(this, this->pc_ + pc_offset, pc_offset += imm.length;
"type index"); Value rtt = CreateValue(ValueType::Rtt(imm.index));
if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0; CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
pc_offset += imm.length; Value obj = Peek(0);
rtt = CreateValue(ValueType::Rtt(imm.index));
CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt);
Push(rtt);
} else {
DCHECK_EQ(opcode, kExprBrOnCastFail);
if (!VALIDATE(rtt.type.is_rtt() || rtt.type.is_bottom())) {
PopTypeError(1, rtt, "rtt");
return 0;
}
}
Value obj = Peek(1);
if (!VALIDATE(IsSubtypeOf(obj.type, kWasmFuncRef, this->module_) || if (!VALIDATE(IsSubtypeOf(obj.type, kWasmFuncRef, this->module_) ||
IsSubtypeOf(obj.type, ValueType::RefNull(HeapType::kData), IsSubtypeOf(obj.type, ValueType::RefNull(HeapType::kData),
this->module_) || this->module_) ||
...@@ -5039,11 +4929,8 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -5039,11 +4929,8 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
// when the branch is taken. In this case, we leave {obj} on the stack // when the branch is taken. In this case, we leave {obj} on the stack
// to type check the branch. // to type check the branch.
// TODO(jkummerow): Reconsider this choice. // TODO(jkummerow): Reconsider this choice.
Drop(rtt);
if (!VALIDATE(TypeCheckBranch<true>(c, 0))) return 0; if (!VALIDATE(TypeCheckBranch<true>(c, 0))) return 0;
Value result_on_fallthrough = CreateValue( Value result_on_fallthrough = CreateValue(ValueType::Ref(imm.index));
rtt.type.is_bottom() ? kWasmBottom
: ValueType::Ref(rtt.type.ref_index()));
if (V8_LIKELY(current_code_reachable_and_ok_)) { if (V8_LIKELY(current_code_reachable_and_ok_)) {
// This logic ensures that code generation can assume that functions // This logic ensures that code generation can assume that functions
// can only be cast to function types, and data objects to data types. // can only be cast to function types, and data objects to data types.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment