Skip to content

Commit fe00ecb

Browse files
manoskoukCommit Bot
authored andcommitted
[wasm-gc] Introduce HeapType class
Drive-by: Fix ref.is_null calling is_reference_type to typecheck its argument (which would also allow rtts). Bug: v8:7748 Change-Id: I2ad01d0f70ac15d37ac4cc344bd0280a7ca08073 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2264094 Commit-Queue: Manos Koukoutos <[email protected]> Reviewed-by: Jakob Kummerow <[email protected]> Reviewed-by: Andreas Haas <[email protected]> Cr-Commit-Position: refs/heads/master@{#68572}
1 parent 238088d commit fe00ecb

21 files changed

Lines changed: 239 additions & 208 deletions

src/api/api.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10372,7 +10372,7 @@ v8::Local<v8::Array> debug::WasmValue::bytes() {
1037210372

1037310373
v8::Local<v8::Value> debug::WasmValue::ref() {
1037410374
i::Handle<i::WasmValue> obj = Utils::OpenHandle(this);
10375-
DCHECK_EQ(i::wasm::kHeapExtern, obj->value_type());
10375+
DCHECK_EQ(i::wasm::HeapType::kExtern, obj->value_type());
1037610376

1037710377
i::Isolate* isolate = obj->GetIsolate();
1037810378
i::Handle<i::Object> bytes_or_ref(obj->bytes_or_ref(), isolate);

src/builtins/wasm.tq

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ extern macro Allocate(intptr): HeapObject;
3737
}
3838

3939
namespace wasm {
40-
const kFuncTableType:
41-
constexpr int31 generates 'wasm::HeapType::kHeapFunc';
40+
const kFuncTableType: constexpr int31 generates 'wasm::HeapType::kFunc';
4241

4342
extern macro WasmBuiltinsAssembler::LoadInstanceFromFrame(): WasmInstanceObject;
4443

src/compiler/wasm-compiler.cc

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5309,24 +5309,23 @@ Node* WasmGraphBuilder::ArrayNew(uint32_t array_index,
53095309
}
53105310

53115311
Node* WasmGraphBuilder::RttCanon(wasm::HeapType type) {
5312-
if (is_generic_heap_type(type)) {
5312+
if (type.is_generic()) {
53135313
// TODO(7748): Implement this.
53145314
UNIMPLEMENTED();
53155315
}
5316-
uint32_t type_index = static_cast<uint32_t>(type);
53175316
// This logic is duplicated from module-instantiate.cc.
53185317
// TODO(jkummerow): Find a nicer solution.
53195318
int map_index = 0;
53205319
const std::vector<uint8_t>& type_kinds = env_->module->type_kinds;
5321-
for (uint32_t i = 0; i < type_index; i++) {
5320+
for (uint32_t i = 0; i < type.ref_index(); i++) {
53225321
if (type_kinds[i] == wasm::kWasmStructTypeCode ||
53235322
type_kinds[i] == wasm::kWasmArrayTypeCode) {
53245323
map_index++;
53255324
}
53265325
}
53275326
Node* maps_list =
53285327
LOAD_INSTANCE_FIELD(ManagedObjectMaps, MachineType::TaggedPointer());
5329-
return LOAD_FIXED_ARRAY_SLOT_PTR(maps_list, type_index);
5328+
return LOAD_FIXED_ARRAY_SLOT_PTR(maps_list, type.ref_index());
53305329
}
53315330

53325331
Node* WasmGraphBuilder::StructGet(Node* struct_object,
@@ -5695,11 +5694,11 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
56955694
switch (type.kind()) {
56965695
case wasm::ValueType::kRef:
56975696
case wasm::ValueType::kOptRef: {
5698-
switch (type.heap_type()) {
5699-
case wasm::kHeapExtern:
5700-
case wasm::kHeapExn:
5697+
switch (type.heap()) {
5698+
case wasm::HeapType::kExtern:
5699+
case wasm::HeapType::kExn:
57015700
return input;
5702-
case wasm::kHeapFunc: {
5701+
case wasm::HeapType::kFunc: {
57035702
Node* check =
57045703
BuildChangeSmiToInt32(SetEffect(BuildCallToRuntimeWithContext(
57055704
Runtime::kWasmIsValidFuncRefValue, js_context, &input, 1)));

src/wasm/baseline/liftoff-compiler.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ class LiftoffCompiler {
399399
return kSimd;
400400
case ValueType::kOptRef:
401401
case ValueType::kRef:
402-
if (type.heap_type() == kHeapExn) {
402+
if (type.is_reference_to(HeapType::kExn)) {
403403
return kExceptionHandling;
404404
} else {
405405
return kRefTypes;

src/wasm/c-api.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ ValKind V8ValueTypeToWasm(i::wasm::ValueType v8_valtype) {
7373
return F64;
7474
case i::wasm::ValueType::kRef:
7575
case i::wasm::ValueType::kOptRef:
76-
switch (v8_valtype.heap_type()) {
77-
case i::wasm::kHeapFunc:
76+
switch (v8_valtype.heap()) {
77+
case i::wasm::HeapType::kFunc:
7878
return FUNCREF;
79-
case i::wasm::kHeapExtern:
79+
case i::wasm::HeapType::kExtern:
8080
// TODO(7748): Rename this to EXTERNREF if/when third-party API
8181
// changes.
8282
return ANYREF;
@@ -1828,11 +1828,11 @@ auto Table::type() const -> own<TableType> {
18281828
uint32_t max;
18291829
if (!table->maximum_length().ToUint32(&max)) max = 0xFFFFFFFFu;
18301830
ValKind kind;
1831-
switch (table->type().heap_type()) {
1832-
case i::wasm::kHeapFunc:
1831+
switch (table->type().heap()) {
1832+
case i::wasm::HeapType::kFunc:
18331833
kind = FUNCREF;
18341834
break;
1835-
case i::wasm::kHeapExtern:
1835+
case i::wasm::HeapType::kExtern:
18361836
kind = ANYREF;
18371837
break;
18381838
default:

src/wasm/function-body-decoder-impl.h

Lines changed: 47 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ ValueType read_value_type(Decoder* decoder, const byte* pc,
144144

145145
#define REF_TYPE_CASE(heap_type, nullable, feature) \
146146
case kLocal##heap_type##Ref: { \
147-
ValueType result = ValueType::Ref(kHeap##heap_type, nullable); \
147+
ValueType result = ValueType::Ref(HeapType::k##heap_type, nullable); \
148148
if (!VALIDATE(enabled.has_##feature())) { \
149149
decoder->errorf( \
150150
pc, "invalid value type '%s', enable with --experimental-wasm-%s", \
@@ -197,7 +197,7 @@ ValueType read_value_type(Decoder* decoder, const byte* pc,
197197
type_index, kV8MaxWasmTypes);
198198
return kWasmBottom;
199199
}
200-
return ValueType::Ref(static_cast<HeapType>(type_index), nullability);
200+
return ValueType::Ref(type_index, nullability);
201201
}
202202
UNREACHABLE();
203203
}
@@ -230,8 +230,7 @@ ValueType read_value_type(Decoder* decoder, const byte* pc,
230230
return kWasmBottom;
231231
}
232232
*length += 1 + depth_length;
233-
return ValueType::Rtt(static_cast<HeapType>(type_index),
234-
static_cast<uint8_t>(depth));
233+
return ValueType::Rtt(type_index, static_cast<uint8_t>(depth));
235234
}
236235
case kLocalS128:
237236
if (!VALIDATE(enabled.has_simd())) {
@@ -706,7 +705,7 @@ struct TableCopyImmediate {
706705
template <Decoder::ValidateFlag validate>
707706
struct HeapTypeImmediate {
708707
uint32_t length = 1;
709-
HeapType type = static_cast<HeapType>(kHeapFunc - 1);
708+
HeapType type = HeapType(HeapType::kFunc - 1);
710709
inline HeapTypeImmediate(const WasmFeatures& enabled, Decoder* decoder,
711710
const byte* pc) {
712711
// Check for negative 1-byte value first, e.g. -0x10 == funcref. If there's
@@ -715,11 +714,11 @@ struct HeapTypeImmediate {
715714
switch (static_cast<ValueTypeCode>(heap_index)) {
716715
#define REF_TYPE_CASE(heap_type, feature) \
717716
case kLocal##heap_type##Ref: { \
718-
type = kHeap##heap_type; \
717+
type = HeapType(HeapType::k##heap_type); \
719718
if (!VALIDATE(enabled.has_##feature())) { \
720719
decoder->errorf( \
721720
pc, "invalid heap type '%s', enable with --experimental-wasm-%s", \
722-
ValueType::heap_name(kHeap##heap_type).c_str(), #feature); \
721+
type.name().c_str(), #feature); \
723722
} \
724723
break; \
725724
}
@@ -732,13 +731,13 @@ struct HeapTypeImmediate {
732731
uint32_t type_index =
733732
decoder->read_u32v<validate>(pc, &length, "heap type immediate");
734733
if (!VALIDATE(type_index < kV8MaxWasmTypes)) {
735-
decoder->errorf(pc + 1,
734+
decoder->errorf(pc,
736735
"Type index %u is greater than the maximum number "
737736
"%zu of type definitions supported by V8",
738737
type_index, kV8MaxWasmTypes);
739738
break;
740739
}
741-
type = static_cast<HeapType>(type_index);
740+
type = HeapType(type_index);
742741
if (!VALIDATE(enabled.has_typed_funcref())) {
743742
decoder->errorf(pc,
744743
"invalid heap type %d, enable with "
@@ -1426,13 +1425,13 @@ class WasmDecoder : public Decoder {
14261425
}
14271426

14281427
inline bool Validate(const byte* pc, HeapTypeImmediate<validate>& imm) {
1429-
if (!VALIDATE(is_generic_heap_type(imm.type) ||
1430-
module_->has_array(static_cast<uint32_t>(imm.type)) ||
1431-
module_->has_struct(static_cast<uint32_t>(imm.type)))) {
1428+
if (!VALIDATE(imm.type.is_generic() ||
1429+
module_->has_array(imm.type.ref_index()) ||
1430+
module_->has_struct(imm.type.ref_index()))) {
14321431
errorf(
14331432
pc,
14341433
"Type index %u does not refer to a struct or array type definition",
1435-
imm.type);
1434+
imm.type.ref_index());
14361435
return false;
14371436
}
14381437
return true;
@@ -2541,27 +2540,31 @@ class WasmFullDecoder : public WasmDecoder<validate> {
25412540
CHECK_PROTOTYPE_OPCODE(reftypes);
25422541
Value value = Pop();
25432542
Value* result = Push(kWasmI32);
2544-
if (value.type.is_nullable()) {
2545-
CALL_INTERFACE_IF_REACHABLE(UnOp, opcode, value, result);
2546-
break;
2547-
}
2548-
if (value.type.is_reference_type()) {
2549-
// Due to the check above, we know that the value is not null.
2550-
CALL_INTERFACE_IF_REACHABLE(I32Const, result, 0);
2551-
break;
2543+
switch (value.type.kind()) {
2544+
case ValueType::kOptRef:
2545+
CALL_INTERFACE_IF_REACHABLE(UnOp, opcode, value, result);
2546+
break;
2547+
case ValueType::kRef:
2548+
// For non-nullable references, the result is always false.
2549+
CALL_INTERFACE_IF_REACHABLE(I32Const, result, 0);
2550+
break;
2551+
default:
2552+
if (validate) {
2553+
this->errorf(this->pc_,
2554+
"invalid argument type to ref.is_null. Expected "
2555+
"reference type, got %s",
2556+
value.type.type_name().c_str());
2557+
}
2558+
break;
25522559
}
2553-
this->errorf(this->pc_,
2554-
"invalid argument type to ref.is_null. Expected reference "
2555-
"type, got %s",
2556-
value.type.type_name().c_str());
25572560
break;
25582561
}
25592562
case kExprRefFunc: {
25602563
CHECK_PROTOTYPE_OPCODE(reftypes);
25612564
FunctionIndexImmediate<validate> imm(this, this->pc_ + 1);
25622565
len += imm.length;
25632566
if (!this->Validate(this->pc_ + 1, imm)) break;
2564-
Value* value = Push(ValueType::Ref(kHeapFunc, kNonNullable));
2567+
Value* value = Push(ValueType::Ref(HeapType::kFunc, kNonNullable));
25652568
CALL_INTERFACE_IF_REACHABLE(RefFunc, imm.index, value);
25662569
break;
25672570
}
@@ -2581,10 +2584,12 @@ class WasmFullDecoder : public WasmDecoder<validate> {
25812584
break;
25822585
}
25832586
default:
2584-
this->errorf(this->pc_,
2585-
"invalid agrument type to ref.as_non_null: Expected "
2586-
"reference type, got %s",
2587-
value.type.type_name().c_str());
2587+
if (validate) {
2588+
this->errorf(this->pc_,
2589+
"invalid agrument type to ref.as_non_null: Expected "
2590+
"reference type, got %s",
2591+
value.type.type_name().c_str());
2592+
}
25882593
break;
25892594
}
25902595
break;
@@ -3310,8 +3315,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
33103315
len += imm.length;
33113316
if (!this->Validate(this->pc_ + 2, imm)) break;
33123317
ArgVector args = PopArgs(imm.struct_type);
3313-
Value* value = Push(
3314-
ValueType::Ref(static_cast<HeapType>(imm.index), kNonNullable));
3318+
Value* value = Push(ValueType::Ref(imm.index, kNonNullable));
33153319
CALL_INTERFACE_IF_REACHABLE(StructNew, imm, args.begin(), value);
33163320
break;
33173321
}
@@ -3327,9 +3331,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
33273331
"Use struct.get_s or struct.get_u instead.");
33283332
break;
33293333
}
3330-
Value struct_obj = Pop(
3331-
0, ValueType::Ref(static_cast<HeapType>(field.struct_index.index),
3332-
kNullable));
3334+
Value struct_obj =
3335+
Pop(0, ValueType::Ref(field.struct_index.index, kNullable));
33333336
Value* value = Push(field_type);
33343337
CALL_INTERFACE_IF_REACHABLE(StructGet, struct_obj, field, true, value);
33353338
break;
@@ -3348,9 +3351,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
33483351
WasmOpcodes::OpcodeName(opcode));
33493352
break;
33503353
}
3351-
Value struct_obj = Pop(
3352-
0, ValueType::Ref(static_cast<HeapType>(field.struct_index.index),
3353-
kNullable));
3354+
Value struct_obj =
3355+
Pop(0, ValueType::Ref(field.struct_index.index, kNullable));
33543356
Value* value = Push(field_type.Unpacked());
33553357
CALL_INTERFACE_IF_REACHABLE(StructGet, struct_obj, field,
33563358
opcode == kExprStructGetS, value);
@@ -3366,9 +3368,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
33663368
break;
33673369
}
33683370
Value field_value = Pop(1, struct_type->field(field.index).Unpacked());
3369-
Value struct_obj = Pop(
3370-
0, ValueType::Ref(static_cast<HeapType>(field.struct_index.index),
3371-
kNullable));
3371+
Value struct_obj =
3372+
Pop(0, ValueType::Ref(field.struct_index.index, kNullable));
33723373
CALL_INTERFACE_IF_REACHABLE(StructSet, struct_obj, field, field_value);
33733374
break;
33743375
}
@@ -3378,8 +3379,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
33783379
if (!this->Validate(this->pc_ + 2, imm)) break;
33793380
Value length = Pop(1, kWasmI32);
33803381
Value initial_value = Pop(0, imm.array_type->element_type().Unpacked());
3381-
Value* value = Push(
3382-
ValueType::Ref(static_cast<HeapType>(imm.index), kNonNullable));
3382+
Value* value = Push(ValueType::Ref(imm.index, kNonNullable));
33833383
CALL_INTERFACE_IF_REACHABLE(ArrayNew, imm, length, initial_value,
33843384
value);
33853385
break;
@@ -3397,8 +3397,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
33973397
break;
33983398
}
33993399
Value index = Pop(1, kWasmI32);
3400-
Value array_obj =
3401-
Pop(0, ValueType::Ref(static_cast<HeapType>(imm.index), kNullable));
3400+
Value array_obj = Pop(0, ValueType::Ref(imm.index, kNullable));
34023401
Value* value = Push(imm.array_type->element_type().Unpacked());
34033402
// TODO(7748): Optimize this when array_obj is non-nullable ref.
34043403
CALL_INTERFACE_IF_REACHABLE(ArrayGet, array_obj, imm, index,
@@ -3416,8 +3415,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
34163415
break;
34173416
}
34183417
Value index = Pop(1, kWasmI32);
3419-
Value array_obj =
3420-
Pop(0, ValueType::Ref(static_cast<HeapType>(imm.index), kNullable));
3418+
Value array_obj = Pop(0, ValueType::Ref(imm.index, kNullable));
34213419
Value* value = Push(imm.array_type->element_type());
34223420
// TODO(7748): Optimize this when array_obj is non-nullable ref.
34233421
CALL_INTERFACE_IF_REACHABLE(ArrayGet, array_obj, imm, index, true,
@@ -3434,8 +3432,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
34343432
}
34353433
Value value = Pop(2, imm.array_type->element_type().Unpacked());
34363434
Value index = Pop(1, kWasmI32);
3437-
Value array_obj =
3438-
Pop(0, ValueType::Ref(static_cast<HeapType>(imm.index), kNullable));
3435+
Value array_obj = Pop(0, ValueType::Ref(imm.index, kNullable));
34393436
// TODO(7748): Optimize this when array_obj is non-nullable ref.
34403437
CALL_INTERFACE_IF_REACHABLE(ArraySet, array_obj, imm, index, value);
34413438
break;
@@ -3444,8 +3441,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
34443441
ArrayIndexImmediate<validate> imm(this, this->pc_ + 2);
34453442
len += imm.length;
34463443
if (!this->Validate(this->pc_ + 2, imm)) break;
3447-
Value array_obj =
3448-
Pop(0, ValueType::Ref(static_cast<HeapType>(imm.index), kNullable));
3444+
Value array_obj = Pop(0, ValueType::Ref(imm.index, kNullable));
34493445
Value* value = Push(kWasmI32);
34503446
CALL_INTERFACE_IF_REACHABLE(ArrayLen, array_obj, value);
34513447
break;

src/wasm/local-decl-encoder.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ size_t LocalDeclEncoder::Emit(byte* buffer) const {
3838
++pos;
3939
}
4040
if (locals_type.encoding_needs_heap_type()) {
41-
LEBHelper::write_u32v(&pos, locals_type.heap_type_code());
41+
LEBHelper::write_u32v(&pos, locals_type.heap_type().code());
4242
}
4343
}
4444
DCHECK_EQ(Size(), pos - buffer);
@@ -66,7 +66,7 @@ size_t LocalDeclEncoder::Size() const {
6666
1 + // Opcode
6767
(p.second.has_depth() ? 1 : 0) + // Inheritance depth
6868
(p.second.encoding_needs_heap_type()
69-
? LEBHelper::sizeof_u32v(p.second.heap_type_code())
69+
? LEBHelper::sizeof_u32v(p.second.heap_type().code())
7070
: 0); // ref. index
7171
}
7272
return size;

src/wasm/module-decoder.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ ValueType TypeOf(const WasmModule* module, const WasmInitExpr& expr) {
123123
case WasmInitExpr::kF64Const:
124124
return kWasmF64;
125125
case WasmInitExpr::kRefFuncConst:
126-
return ValueType::Ref(kHeapFunc, kNonNullable);
126+
return ValueType::Ref(HeapType::kFunc, kNonNullable);
127127
case WasmInitExpr::kRefNullConst:
128128
// It is not possible to retrieve the full {ValueType} of a {WasmInitExpr}
129129
// of kind {kRefNullConst}. As WasmInitExpr of kind {krefNullConst} is

0 commit comments

Comments
 (0)