Revert "[wasm-gc] Implement ref.test and ref.cast"
This reverts commit 3f74ece91b
.
Reason for revert: build breakage, rebasing issue
Original change's description:
> [wasm-gc] Implement ref.test and ref.cast
>
> Bug: v8:7748
> Change-Id: If0023edf2f27448c605bd8aa6402bf76c7983a6e
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2277889
> Reviewed-by: Andreas Haas <ahaas@chromium.org>
> Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#68640}
TBR=jkummerow@chromium.org,ahaas@chromium.org
Change-Id: Idd4eee1711aed3c0a9f89a36793738c72a34c783
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:7748
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2278462
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68641}
This commit is contained in:
parent
3f74ece91b
commit
5629424781
@ -251,22 +251,6 @@ builtin WasmAllocateStructWithRtt(implicit context: Context)(rtt: Map):
|
||||
return result;
|
||||
}
|
||||
|
||||
builtin WasmIsRttSubtype(implicit context: Context)(sub: Map, super: Map): Smi {
|
||||
let map = sub;
|
||||
while (true) {
|
||||
if (map == super) return SmiConstant(1); // "true"
|
||||
// This code relies on the fact that we use a non-WasmObject map as the
|
||||
// end of the chain, e.g. for "rtt any", which then doesn't have a
|
||||
// WasmTypeInfo.
|
||||
// TODO(7748): Use a more explicit sentinel mechanism?
|
||||
const maybeTypeInfo = map.constructor_or_back_pointer_or_native_context;
|
||||
if (!Is<WasmTypeInfo>(maybeTypeInfo)) return SmiConstant(0); // "false"
|
||||
const typeInfo = %RawDownCast<WasmTypeInfo>(maybeTypeInfo);
|
||||
map = typeInfo.parent;
|
||||
}
|
||||
unreachable;
|
||||
}
|
||||
|
||||
builtin WasmInt32ToNumber(value: int32): Number {
|
||||
return ChangeInt32ToTagged(value);
|
||||
}
|
||||
|
@ -5383,27 +5383,6 @@ Node* WasmGraphBuilder::RttSub(wasm::HeapType type, Node* parent_rtt) {
|
||||
LOAD_INSTANCE_FIELD(NativeContext, MachineType::TaggedPointer()));
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::RefTest(Node* object, Node* rtt) {
|
||||
Node* map =
|
||||
gasm_->Load(MachineType::TaggedPointer(), object, HeapObject::kMapOffset);
|
||||
// TODO(7748): Add a fast path for map == rtt.
|
||||
return BuildChangeSmiToInt32(CALL_BUILTIN(
|
||||
WasmIsRttSubtype, map, rtt,
|
||||
LOAD_INSTANCE_FIELD(NativeContext, MachineType::TaggedPointer())));
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::RefCast(Node* object, Node* rtt,
|
||||
wasm::WasmCodePosition position) {
|
||||
Node* map =
|
||||
gasm_->Load(MachineType::TaggedPointer(), object, HeapObject::kMapOffset);
|
||||
// TODO(7748): Add a fast path for map == rtt.
|
||||
Node* check_result = CALL_BUILTIN(
|
||||
WasmIsRttSubtype, map, rtt,
|
||||
LOAD_INSTANCE_FIELD(NativeContext, MachineType::TaggedPointer()));
|
||||
TrapIfFalse(wasm::kTrapIllegalCast, check_result, position);
|
||||
return object;
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::StructGet(Node* struct_object,
|
||||
const wasm::StructType* struct_type,
|
||||
uint32_t field_index, CheckForNull null_check,
|
||||
|
@ -406,8 +406,6 @@ class WasmGraphBuilder {
|
||||
Node* I31GetU(Node* input);
|
||||
Node* RttCanon(wasm::HeapType type);
|
||||
Node* RttSub(wasm::HeapType type, Node* parent_rtt);
|
||||
Node* RefTest(Node* object, Node* rtt);
|
||||
Node* RefCast(Node* object, Node* rtt, wasm::WasmCodePosition position);
|
||||
|
||||
bool has_simd() const { return has_simd_; }
|
||||
|
||||
|
@ -3642,17 +3642,6 @@ class LiftoffCompiler {
|
||||
unsupported(decoder, kGC, "rtt.sub");
|
||||
}
|
||||
|
||||
void RefTest(FullDecoder* decoder, const Value& obj, const Value& rtt,
|
||||
Value* result) {
|
||||
// TODO(7748): Implement.
|
||||
unsupported(decoder, kGC, "ref.test");
|
||||
}
|
||||
void RefCast(FullDecoder* decoder, const Value& obj, const Value& rtt,
|
||||
Value* result) {
|
||||
// TODO(7748): Implement.
|
||||
unsupported(decoder, kGC, "ref.cast");
|
||||
}
|
||||
|
||||
void PassThrough(FullDecoder* decoder, const Value& from, Value* to) {
|
||||
// TODO(7748): Implement.
|
||||
unsupported(decoder, kGC, "");
|
||||
|
@ -970,8 +970,6 @@ struct ControlBase {
|
||||
F(RttCanon, const HeapTypeImmediate<validate>& imm, Value* result) \
|
||||
F(RttSub, const HeapTypeImmediate<validate>& imm, const Value& parent, \
|
||||
Value* result) \
|
||||
F(RefTest, const Value& obj, const Value& rtt, Value* result) \
|
||||
F(RefCast, const Value& obj, const Value& rtt, Value* result) \
|
||||
F(PassThrough, const Value& from, Value* to)
|
||||
|
||||
// Generic Wasm bytecode decoder with utilities for decoding immediates,
|
||||
@ -1706,15 +1704,9 @@ class WasmDecoder : public Decoder {
|
||||
case kExprI31New:
|
||||
case kExprI31GetS:
|
||||
case kExprI31GetU:
|
||||
return 2;
|
||||
case kExprRefTest:
|
||||
case kExprRefCast: {
|
||||
HeapTypeImmediate<validate> ht1(WasmFeatures::All(), decoder,
|
||||
pc + 2);
|
||||
HeapTypeImmediate<validate> ht2(WasmFeatures::All(), decoder,
|
||||
pc + 2 + ht1.length);
|
||||
return 2 + ht1.length + ht2.length;
|
||||
}
|
||||
case kExprRefCast:
|
||||
return 2;
|
||||
|
||||
default:
|
||||
// This is unreachable except for malformed modules.
|
||||
@ -3436,66 +3428,6 @@ class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
CALL_INTERFACE_IF_REACHABLE(RttSub, imm, parent, value);
|
||||
return 2 + imm.length;
|
||||
}
|
||||
case kExprRefTest: {
|
||||
// "Tests whether {obj}'s runtime type is a runtime subtype of {rtt}."
|
||||
HeapTypeImmediate<validate> obj_type(this->enabled_, this,
|
||||
this->pc_ + len);
|
||||
if (!this->Validate(this->pc_ + len, obj_type)) break;
|
||||
len += obj_type.length;
|
||||
HeapTypeImmediate<validate> rtt_type(this->enabled_, this,
|
||||
this->pc_ + len);
|
||||
if (!this->Validate(this->pc_ + len, rtt_type)) break;
|
||||
len += rtt_type.length;
|
||||
// The static type of {obj} must be a supertype of the {rtt}'s type.
|
||||
if (!VALIDATE(IsSubtypeOf(ValueType::Ref(rtt_type.type, kNonNullable),
|
||||
ValueType::Ref(obj_type.type, kNonNullable),
|
||||
this->module_))) {
|
||||
this->errorf(this->pc_,
|
||||
"ref.test: rtt type must be subtype of object type");
|
||||
break;
|
||||
}
|
||||
Value rtt = Pop();
|
||||
if (!VALIDATE(rtt.type.kind() == ValueType::kRtt &&
|
||||
rtt.type.heap_type() == rtt_type.type)) {
|
||||
this->errorf(
|
||||
this->pc_ + len, "ref.test: expected rtt for type %s but got %s",
|
||||
rtt_type.type.name().c_str(), rtt.type.type_name().c_str());
|
||||
break;
|
||||
}
|
||||
Value obj = Pop(0, ValueType::Ref(obj_type.type, kNullable));
|
||||
Value* value = Push(kWasmI32);
|
||||
CALL_INTERFACE_IF_REACHABLE(RefTest, obj, rtt, value);
|
||||
break;
|
||||
}
|
||||
case kExprRefCast: {
|
||||
HeapTypeImmediate<validate> obj_type(this->enabled_, this,
|
||||
this->pc_ + len);
|
||||
len += obj_type.length;
|
||||
if (!this->Validate(this->pc_ + len, obj_type)) break;
|
||||
HeapTypeImmediate<validate> rtt_type(this->enabled_, this,
|
||||
this->pc_ + len);
|
||||
len += rtt_type.length;
|
||||
if (!this->Validate(this->pc_ + len, rtt_type)) break;
|
||||
if (!VALIDATE(IsSubtypeOf(ValueType::Ref(rtt_type.type, kNonNullable),
|
||||
ValueType::Ref(obj_type.type, kNonNullable),
|
||||
this->module_))) {
|
||||
this->errorf(this->pc_,
|
||||
"ret.cast: rtt type must be subtype of object type");
|
||||
break;
|
||||
}
|
||||
Value rtt = Pop();
|
||||
if (!VALIDATE(rtt.type.kind() == ValueType::kRtt &&
|
||||
rtt.type.heap_type() == rtt_type.type)) {
|
||||
this->errorf(
|
||||
this->pc_ + len, "ref.cast: expected rtt for type %s but got %s",
|
||||
rtt_type.type.name().c_str(), rtt.type.type_name().c_str());
|
||||
break;
|
||||
}
|
||||
Value obj = Pop(0, ValueType::Ref(obj_type.type, kNullable));
|
||||
Value* value = Push(ValueType::Ref(rtt_type.type, kNonNullable));
|
||||
CALL_INTERFACE_IF_REACHABLE(RefCast, obj, rtt, value);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
this->error("invalid gc opcode");
|
||||
return 0;
|
||||
|
@ -743,16 +743,6 @@ class WasmGraphBuildingInterface {
|
||||
result->node = BUILD(RttSub, imm.type, parent.node);
|
||||
}
|
||||
|
||||
void RefTest(FullDecoder* decoder, const Value& object, const Value& rtt,
|
||||
Value* result) {
|
||||
result->node = BUILD(RefTest, object.node, rtt.node);
|
||||
}
|
||||
|
||||
void RefCast(FullDecoder* decoder, const Value& object, const Value& rtt,
|
||||
Value* result) {
|
||||
result->node = BUILD(RefCast, object.node, rtt.node, decoder->position());
|
||||
}
|
||||
|
||||
void PassThrough(FullDecoder* decoder, const Value& from, Value* to) {
|
||||
to->node = from.node;
|
||||
}
|
||||
|
@ -549,13 +549,14 @@ TEST(BasicRTT) {
|
||||
WasmGCTester tester;
|
||||
uint32_t type_index = tester.DefineStruct({F(wasm::kWasmI32, true)});
|
||||
uint32_t subtype_index =
|
||||
tester.DefineStruct({F(wasm::kWasmI32, true), F(wasm::kWasmI32, true)});
|
||||
tester.DefineStruct({F(wasm::kWasmI32, true), F(wasm::kWasmF64, true)});
|
||||
ValueType kRttTypes[] = {ValueType::Rtt(type_index, 1)};
|
||||
FunctionSig sig_t_v(1, 0, kRttTypes);
|
||||
ValueType kRttSubtypes[] = {
|
||||
ValueType::Rtt(static_cast<HeapType>(subtype_index), 2)};
|
||||
FunctionSig sig_t2_v(1, 0, kRttSubtypes);
|
||||
ValueType kRefTypes[] = {ref(type_index)};
|
||||
ValueType kRefTypes[] = {
|
||||
ValueType::Ref(static_cast<HeapType>(type_index), kNonNullable)};
|
||||
FunctionSig sig_q_v(1, 0, kRefTypes);
|
||||
|
||||
tester.DefineFunction("f", &sig_t_v, {},
|
||||
@ -567,36 +568,6 @@ TEST(BasicRTT) {
|
||||
{WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(42),
|
||||
WASM_RTT_CANON(type_index)),
|
||||
kExprEnd});
|
||||
const int kFieldIndex = 1;
|
||||
const int kLocalStructIndex = 1; // Shifted in 'let' block.
|
||||
const int kLocalRttIndex = 0; // Let-bound, hence first local.
|
||||
// This implements the following function:
|
||||
// var local_struct: type0;
|
||||
// let (local_rtt = rtt.sub(rtt.canon(type0), type1) in {
|
||||
// local_struct = new type1 with rtt 'local_rtt';
|
||||
// return (ref.test local_struct local_rtt) +
|
||||
// ((ref.cast local_struct local_rtt)[field0]);
|
||||
// }
|
||||
// The expected return value is 1+42 = 43.
|
||||
tester.DefineFunction(
|
||||
"i", tester.sigs.i_v(), {optref(type_index)},
|
||||
/* TODO(jkummerow): The macro order here is a bit of a hack. */
|
||||
{WASM_RTT_CANON(type_index),
|
||||
WASM_LET_1_I(
|
||||
WASM_RTT(2, subtype_index), WASM_RTT_SUB(subtype_index),
|
||||
WASM_SET_LOCAL(kLocalStructIndex,
|
||||
WASM_STRUCT_NEW_WITH_RTT(
|
||||
subtype_index, WASM_I32V(11), WASM_I32V(42),
|
||||
WASM_GET_LOCAL(kLocalRttIndex))),
|
||||
WASM_I32_ADD(
|
||||
WASM_REF_TEST(type_index, subtype_index,
|
||||
WASM_GET_LOCAL(kLocalStructIndex),
|
||||
WASM_GET_LOCAL(kLocalRttIndex)),
|
||||
WASM_STRUCT_GET(subtype_index, kFieldIndex,
|
||||
WASM_REF_CAST(type_index, subtype_index,
|
||||
WASM_GET_LOCAL(kLocalStructIndex),
|
||||
WASM_GET_LOCAL(kLocalRttIndex)))),
|
||||
kExprEnd)});
|
||||
|
||||
tester.CompileModule();
|
||||
|
||||
|
@ -445,12 +445,6 @@ inline WasmOpcode LoadStoreOpcodeOf(MachineType type, bool store) {
|
||||
#define WASM_REF_IS_NULL(val) val, kExprRefIsNull
|
||||
#define WASM_REF_AS_NON_NULL(val) val, kExprRefAsNonNull
|
||||
#define WASM_REF_EQ(lhs, rhs) lhs, rhs, kExprRefEq
|
||||
#define WASM_REF_TEST(obj_type, rtt_type, ref, rtt) \
|
||||
ref, rtt, WASM_GC_OP(kExprRefTest), static_cast<byte>(obj_type), \
|
||||
static_cast<byte>(rtt_type)
|
||||
#define WASM_REF_CAST(obj_type, rtt_type, ref, rtt) \
|
||||
ref, rtt, WASM_GC_OP(kExprRefCast), static_cast<byte>(obj_type), \
|
||||
static_cast<byte>(rtt_type)
|
||||
|
||||
#define WASM_ARRAY_NEW(index, default_value, length) \
|
||||
default_value, length, WASM_GC_OP(kExprArrayNew), static_cast<byte>(index)
|
||||
@ -486,7 +480,6 @@ inline WasmOpcode LoadStoreOpcodeOf(MachineType type, bool store) {
|
||||
__VA_ARGS__, kExprReturnCallIndirect, static_cast<byte>(sig_index), TABLE_ZERO
|
||||
|
||||
#define WASM_REF_TYPE(typeidx) kLocalOptRef, U32V_1(typeidx)
|
||||
#define WASM_RTT(depth, typeidx) kLocalRtt, U32V_1(depth), U32V_1(typeidx)
|
||||
|
||||
// shift locals by 1; let (locals[0]: local_type) = value in ...
|
||||
#define WASM_LET_1_V(local_type, value, ...) \
|
||||
|
Loading…
Reference in New Issue
Block a user