Commit 38117eba authored by Manos Koukoutos's avatar Manos Koukoutos Committed by V8 LUCI CQ

[wasm-gc] Implement br_on_array, br_on_non_array

Bug: v8:7748
Change-Id: I5280a22240ef5e920f701e991ed13d8b8881fc6b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3377122Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78584}
parent 93f28d16
......@@ -5914,6 +5914,19 @@ Node* WasmGraphBuilder::RefAsArray(Node* object, bool object_can_be_null,
return object;
}
void WasmGraphBuilder::BrOnArray(Node* object, Node* /*rtt*/,
ObjectReferenceKnowledge config,
Node** match_control, Node** match_effect,
Node** no_match_control,
Node** no_match_effect) {
BrOnCastAbs(match_control, match_effect, no_match_control, no_match_effect,
[=](Callbacks callbacks) -> void {
return ManagedObjectInstanceCheck(object,
config.object_can_be_null,
WASM_ARRAY_TYPE, callbacks);
});
}
Node* WasmGraphBuilder::RefIsI31(Node* object) { return gasm_->IsI31(object); }
Node* WasmGraphBuilder::RefAsI31(Node* object,
......
......@@ -525,6 +525,9 @@ class WasmGraphBuilder {
Node* RefIsArray(Node* object, bool object_can_be_null);
Node* RefAsArray(Node* object, bool object_can_be_null,
wasm::WasmCodePosition position);
void BrOnArray(Node* object, Node* rtt, ObjectReferenceKnowledge config,
Node** match_control, Node** match_effect,
Node** no_match_control, Node** no_match_effect);
Node* RefIsI31(Node* object);
Node* RefAsI31(Node* object, wasm::WasmCodePosition position);
void BrOnI31(Node* object, Node* rtt, ObjectReferenceKnowledge config,
......
......@@ -5773,6 +5773,12 @@ class LiftoffCompiler {
br_depth);
}
void BrOnArray(FullDecoder* decoder, const Value& object,
Value* /* value_on_branch */, uint32_t br_depth) {
return BrOnAbstractType<&LiftoffCompiler::ArrayCheck>(object, decoder,
br_depth);
}
void BrOnNonData(FullDecoder* decoder, const Value& object,
Value* /* value_on_branch */, uint32_t br_depth) {
return BrOnNonAbstractType<&LiftoffCompiler::DataCheck>(object, decoder,
......@@ -5791,6 +5797,12 @@ class LiftoffCompiler {
br_depth);
}
void BrOnNonArray(FullDecoder* decoder, const Value& object,
Value* /* value_on_branch */, uint32_t br_depth) {
return BrOnNonAbstractType<&LiftoffCompiler::ArrayCheck>(object, decoder,
br_depth);
}
void Forward(FullDecoder* decoder, const Value& from, Value* to) {
// Nothing to do here.
}
......
......@@ -945,7 +945,7 @@ struct ControlBase : public PcForErrors<validate> {
WasmRttSubMode mode) \
F(DoReturn, uint32_t drop_values)
#define INTERFACE_NON_CONSTANT_FUNCTIONS(F) \
#define INTERFACE_NON_CONSTANT_FUNCTIONS(F) /* force 80 columns */ \
/* Control: */ \
F(Block, Control* block) \
F(Loop, Control* block) \
......@@ -1080,11 +1080,14 @@ struct ControlBase : public PcForErrors<validate> {
F(BrOnFunc, const Value& object, Value* value_on_branch, uint32_t br_depth) \
F(BrOnData, const Value& object, Value* value_on_branch, uint32_t br_depth) \
F(BrOnI31, const Value& object, Value* value_on_branch, uint32_t br_depth) \
F(BrOnArray, const Value& object, Value* value_on_branch, uint32_t br_depth) \
F(BrOnNonFunc, const Value& object, Value* value_on_fallthrough, \
uint32_t br_depth) \
F(BrOnNonData, const Value& object, Value* value_on_fallthrough, \
uint32_t br_depth) \
F(BrOnNonI31, const Value& object, Value* value_on_fallthrough, \
uint32_t br_depth) \
F(BrOnNonArray, const Value& object, Value* value_on_fallthrough, \
uint32_t br_depth)
// Generic Wasm bytecode decoder with utilities for decoding immediates,
......@@ -4797,6 +4800,7 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
case kExprBrOnData:
case kExprBrOnFunc:
case kExprBrOnArray:
case kExprBrOnI31: {
NON_CONST_ONLY
BranchDepthImmediate<validate> branch_depth(this,
......@@ -4823,7 +4827,10 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
HeapType::Representation heap_type =
opcode == kExprBrOnFunc
? HeapType::kFunc
: opcode == kExprBrOnData ? HeapType::kData : HeapType::kI31;
: opcode == kExprBrOnData
? HeapType::kData
: opcode == kExprBrOnArray ? HeapType::kArray
: HeapType::kI31;
Value result_on_branch =
CreateValue(ValueType::Ref(heap_type, kNonNullable));
Push(result_on_branch);
......@@ -4837,6 +4844,8 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
CALL_INTERFACE(BrOnFunc, obj, value_on_branch, branch_depth.depth);
} else if (opcode == kExprBrOnData) {
CALL_INTERFACE(BrOnData, obj, value_on_branch, branch_depth.depth);
} else if (opcode == kExprBrOnArray) {
CALL_INTERFACE(BrOnArray, obj, value_on_branch, branch_depth.depth);
} else {
CALL_INTERFACE(BrOnI31, obj, value_on_branch, branch_depth.depth);
}
......@@ -4848,6 +4857,7 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
}
case kExprBrOnNonData:
case kExprBrOnNonFunc:
case kExprBrOnNonArray:
case kExprBrOnNonI31: {
NON_CONST_ONLY
BranchDepthImmediate<validate> branch_depth(this,
......@@ -4869,7 +4879,10 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
HeapType::Representation heap_type =
opcode == kExprBrOnNonFunc
? HeapType::kFunc
: opcode == kExprBrOnNonData ? HeapType::kData : HeapType::kI31;
: opcode == kExprBrOnNonData
? HeapType::kData
: opcode == kExprBrOnNonArray ? HeapType::kArray
: HeapType::kI31;
Value value_on_fallthrough =
CreateValue(ValueType::Ref(heap_type, kNonNullable));
......@@ -4880,6 +4893,9 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
} else if (opcode == kExprBrOnNonData) {
CALL_INTERFACE(BrOnNonData, obj, &value_on_fallthrough,
branch_depth.depth);
} else if (opcode == kExprBrOnNonArray) {
CALL_INTERFACE(BrOnNonArray, obj, &value_on_fallthrough,
branch_depth.depth);
} else {
CALL_INTERFACE(BrOnNonI31, obj, &value_on_fallthrough,
branch_depth.depth);
......
......@@ -1257,6 +1257,20 @@ class WasmGraphBuildingInterface {
decoder->position());
}
void BrOnArray(FullDecoder* decoder, const Value& object,
Value* value_on_branch, uint32_t br_depth) {
BrOnCastAbs<&compiler::WasmGraphBuilder::BrOnArray>(
decoder, object, Value{nullptr, kWasmBottom}, value_on_branch, br_depth,
true);
}
void BrOnNonArray(FullDecoder* decoder, const Value& object,
Value* value_on_fallthrough, uint32_t br_depth) {
BrOnCastAbs<&compiler::WasmGraphBuilder::BrOnArray>(
decoder, object, Value{nullptr, kWasmBottom}, value_on_fallthrough,
br_depth, false);
}
void RefIsI31(FullDecoder* decoder, const Value& object, Value* result) {
result->node = builder_->RefIsI31(object.node);
}
......
......@@ -439,9 +439,11 @@ constexpr const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
CASE_OP(BrOnFunc, "br_on_func")
CASE_OP(BrOnData, "br_on_data")
CASE_OP(BrOnI31, "br_on_i31")
CASE_OP(BrOnArray, "br_on_array")
CASE_OP(BrOnNonFunc, "br_on_non_func")
CASE_OP(BrOnNonData, "br_on_non_data")
CASE_OP(BrOnNonI31, "br_on_non_i31")
CASE_OP(BrOnNonArray, "br_on_non_array")
case kNumericPrefix:
case kSimdPrefix:
......
......@@ -707,9 +707,11 @@ bool V8_EXPORT_PRIVATE IsJSCompatibleSignature(const FunctionSig* sig,
V(BrOnFunc, 0xfb60, _) \
V(BrOnData, 0xfb61, _) \
V(BrOnI31, 0xfb62, _) \
V(BrOnArray, 0xfb66, _) /* not standardized - V8 experimental */ \
V(BrOnNonFunc, 0xfb63, _) \
V(BrOnNonData, 0xfb64, _) \
V(BrOnNonI31, 0xfb65, _)
V(BrOnNonI31, 0xfb65, _) \
V(BrOnNonArray, 0xfb67, _) /* not standardized - V8 experimental */
#define FOREACH_ATOMIC_0_OPERAND_OPCODE(V) \
/* AtomicFence does not target a particular linear memory. */ \
......
......@@ -2000,6 +2000,11 @@ WASM_COMPILED_EXEC_TEST(AbstractTypeChecks) {
byte kBrOnDataNotTaken = BR_ON(DATA, Data, WASM_REF_FUNC(function_index));
byte kBrOnFuncTaken = BR_ON(FUNC, Func, WASM_REF_FUNC(function_index));
byte kBrOnFuncNotTaken = BR_ON(FUNC, Func, WASM_I31_NEW(WASM_I32V(42)));
byte kBrOnArrayTaken =
BR_ON(ARRAY, Array,
WASM_ARRAY_NEW_DEFAULT_WITH_RTT(array_index, WASM_I32V(10),
WASM_RTT_CANON(array_index)));
byte kBrOnArrayNotTaken = BR_ON(ARRAY, Array, WASM_I31_NEW(WASM_I32V(42)));
byte kBrOnI31Taken = BR_ON(I31, I31, WASM_I31_NEW(WASM_I32V(42)));
byte kBrOnI31NotTaken =
BR_ON(I31, I31,
......@@ -2026,6 +2031,12 @@ WASM_COMPILED_EXEC_TEST(AbstractTypeChecks) {
byte kBrOnNonFuncNotTaken =
BR_ON_NON(FUNC, Func, WASM_REF_FUNC(function_index));
byte kBrOnNonFuncTaken = BR_ON_NON(FUNC, Func, WASM_I31_NEW(WASM_I32V(42)));
byte kBrOnNonArrayNotTaken =
BR_ON_NON(ARRAY, Array,
WASM_ARRAY_NEW_DEFAULT_WITH_RTT(array_index, WASM_I32V(10),
WASM_RTT_CANON(array_index)));
byte kBrOnNonArrayTaken =
BR_ON_NON(ARRAY, Array, WASM_I31_NEW(WASM_I32V(42)));
byte kBrOnNonI31NotTaken = BR_ON_NON(I31, I31, WASM_I31_NEW(WASM_I32V(42)));
byte kBrOnNonI31Taken =
BR_ON_NON(I31, I31,
......@@ -2069,6 +2080,8 @@ WASM_COMPILED_EXEC_TEST(AbstractTypeChecks) {
tester.CheckResult(kBrOnDataNotTaken, 0);
tester.CheckResult(kBrOnFuncTaken, 1);
tester.CheckResult(kBrOnFuncNotTaken, 0);
tester.CheckResult(kBrOnArrayTaken, 1);
tester.CheckResult(kBrOnArrayNotTaken, 0);
tester.CheckResult(kBrOnI31Taken, 1);
tester.CheckResult(kBrOnI31NotTaken, 0);
......@@ -2076,6 +2089,8 @@ WASM_COMPILED_EXEC_TEST(AbstractTypeChecks) {
tester.CheckResult(kBrOnNonDataNotTaken, 1);
tester.CheckResult(kBrOnNonFuncTaken, 0);
tester.CheckResult(kBrOnNonFuncNotTaken, 1);
tester.CheckResult(kBrOnNonArrayTaken, 0);
tester.CheckResult(kBrOnNonArrayNotTaken, 1);
tester.CheckResult(kBrOnNonI31Taken, 0);
tester.CheckResult(kBrOnNonI31NotTaken, 1);
}
......
......@@ -539,11 +539,15 @@ inline WasmOpcode LoadStoreOpcodeOf(MachineType type, bool store) {
#define WASM_REF_AS_I31(ref) ref, WASM_GC_OP(kExprRefAsI31)
#define WASM_BR_ON_FUNC(depth) \
WASM_GC_OP(kExprBrOnFunc), static_cast<byte>(depth)
#define WASM_BR_ON_ARRAY(depth) \
WASM_GC_OP(kExprBrOnArray), static_cast<byte>(depth)
#define WASM_BR_ON_DATA(depth) \
WASM_GC_OP(kExprBrOnData), static_cast<byte>(depth)
#define WASM_BR_ON_I31(depth) WASM_GC_OP(kExprBrOnI31), static_cast<byte>(depth)
#define WASM_BR_ON_NON_FUNC(depth) \
WASM_GC_OP(kExprBrOnNonFunc), static_cast<byte>(depth)
#define WASM_BR_ON_NON_ARRAY(depth) \
WASM_GC_OP(kExprBrOnNonArray), static_cast<byte>(depth)
#define WASM_BR_ON_NON_DATA(depth) \
WASM_GC_OP(kExprBrOnNonData), static_cast<byte>(depth)
#define WASM_BR_ON_NON_I31(depth) \
......
......@@ -515,6 +515,11 @@ let kExprRefAsArray = 0x5b;
let kExprBrOnFunc = 0x60;
let kExprBrOnData = 0x61;
let kExprBrOnI31 = 0x62;
let kExprBrOnArray = 0x66;
let kExprBrOnNonFunc = 0x63;
let kExprBrOnNonData = 0x64;
let kExprBrOnNonI31 = 0x65;
let kExprBrOnNonArray = 0x67;
// Numeric opcodes.
let kExprI32SConvertSatF32 = 0x00;
......
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