[wasm-gc] Trap parameter for AssertNotNull
The AssertNotNull operator can be used to represent a trivial type cast. Therefore it needs to take the trap id as a parameter. We also use this operator in one more place in {graph-builder-interface}. Bug: v8:7748 Change-Id: I679c996ef07063c03e1103acac1db91184b15c0e Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4061514 Commit-Queue: Manos Koukoutos <manoskouk@chromium.org> Reviewed-by: Maya Lekova <mslekova@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Cr-Commit-Position: refs/heads/main@{#84543}
This commit is contained in:
parent
a1d477f8d5
commit
7be868e17d
@ -56,7 +56,11 @@ std::ostream& operator<<(std::ostream& os, TrapId trap_id) {
|
||||
|
||||
TrapId TrapIdOf(const Operator* const op) {
|
||||
DCHECK(op->opcode() == IrOpcode::kTrapIf ||
|
||||
op->opcode() == IrOpcode::kTrapUnless);
|
||||
op->opcode() == IrOpcode::kTrapUnless
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
|| op->opcode() == IrOpcode::kAssertNotNull
|
||||
#endif
|
||||
);
|
||||
return OpParameter<TrapId>(op);
|
||||
}
|
||||
|
||||
|
@ -1200,14 +1200,16 @@ struct SimplifiedOperatorGlobalCache final {
|
||||
};
|
||||
NullOperator kNull;
|
||||
|
||||
struct AssertNotNullOperator final : public Operator {
|
||||
AssertNotNullOperator()
|
||||
: Operator(
|
||||
struct AssertNotNullOperator final : public Operator1<TrapId> {
|
||||
explicit AssertNotNullOperator(TrapId trap_id)
|
||||
: Operator1(
|
||||
IrOpcode::kAssertNotNull,
|
||||
Operator::kNoWrite | Operator::kNoThrow | Operator::kIdempotent,
|
||||
"AssertNotNull", 1, 1, 1, 1, 1, 1) {}
|
||||
"AssertNotNull", 1, 1, 1, 1, 1, 1, trap_id) {}
|
||||
};
|
||||
AssertNotNullOperator kAssertNotNull;
|
||||
AssertNotNullOperator kAssertNotNullIllegalCast{TrapId::kTrapIllegalCast};
|
||||
AssertNotNullOperator kAssertNotNullNullDereference{
|
||||
TrapId::kTrapNullDereference};
|
||||
#endif
|
||||
|
||||
#define SPECULATIVE_NUMBER_BINOP(Name) \
|
||||
@ -1404,8 +1406,15 @@ const Operator* SimplifiedOperatorBuilder::RttCanon(int index) {
|
||||
|
||||
const Operator* SimplifiedOperatorBuilder::Null() { return &cache_.kNull; }
|
||||
|
||||
const Operator* SimplifiedOperatorBuilder::AssertNotNull() {
|
||||
return &cache_.kAssertNotNull;
|
||||
const Operator* SimplifiedOperatorBuilder::AssertNotNull(TrapId trap_id) {
|
||||
switch (trap_id) {
|
||||
case TrapId::kTrapNullDereference:
|
||||
return &cache_.kAssertNotNullNullDereference;
|
||||
case TrapId::kTrapIllegalCast:
|
||||
return &cache_.kAssertNotNullIllegalCast;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
const Operator* SimplifiedOperatorBuilder::IsNull() { return &cache_.kIsNull; }
|
||||
|
@ -1086,7 +1086,7 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
|
||||
const Operator* VerifyType();
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
const Operator* AssertNotNull();
|
||||
const Operator* AssertNotNull(TrapId trap_id);
|
||||
const Operator* IsNull();
|
||||
const Operator* IsNotNull();
|
||||
const Operator* Null();
|
||||
|
@ -1142,8 +1142,10 @@ void WasmGraphBuilder::TrapIfFalse(wasm::TrapReason reason, Node* cond,
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::AssertNotNull(Node* object,
|
||||
wasm::WasmCodePosition position) {
|
||||
Node* result = gasm_->AssertNotNull(object);
|
||||
wasm::WasmCodePosition position,
|
||||
wasm::TrapReason reason) {
|
||||
TrapId trap_id = GetTrapIdForTrap(reason);
|
||||
Node* result = gasm_->AssertNotNull(object, trap_id);
|
||||
SetSourcePosition(result, position);
|
||||
return result;
|
||||
}
|
||||
|
@ -255,7 +255,9 @@ class WasmGraphBuilder {
|
||||
Node* EffectPhi(unsigned count, Node** effects_and_control);
|
||||
Node* RefNull();
|
||||
Node* RefFunc(uint32_t function_index);
|
||||
Node* AssertNotNull(Node* object, wasm::WasmCodePosition position);
|
||||
Node* AssertNotNull(
|
||||
Node* object, wasm::WasmCodePosition position,
|
||||
wasm::TrapReason reason = wasm::TrapReason::kTrapNullDereference);
|
||||
Node* TraceInstruction(uint32_t mark_id);
|
||||
Node* Int32Constant(int32_t value);
|
||||
Node* Int64Constant(int64_t value);
|
||||
|
@ -248,7 +248,7 @@ Reduction WasmGCLowering::ReduceAssertNotNull(Node* node) {
|
||||
Node* object = NodeProperties::GetValueInput(node, 0);
|
||||
gasm_.InitializeEffectControl(effect, control);
|
||||
if (!v8_flags.experimental_wasm_skip_null_checks) {
|
||||
gasm_.TrapIf(IsNull(object), TrapId::kTrapNullDereference);
|
||||
gasm_.TrapIf(IsNull(object), TrapIdOf(node->op()));
|
||||
}
|
||||
|
||||
ReplaceWithValue(node, object, gasm_.effect(), gasm_.control());
|
||||
|
@ -266,7 +266,8 @@ Reduction WasmGCOperatorReducer::ReduceWasmTypeCast(Node* node) {
|
||||
} else {
|
||||
gasm_.InitializeEffectControl(effect, control);
|
||||
return Replace(
|
||||
SetType(gasm_.AssertNotNull(object), object_type.type.AsNonNull()));
|
||||
SetType(gasm_.AssertNotNull(object, TrapId::kTrapIllegalCast),
|
||||
object_type.type.AsNonNull()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -366,9 +366,9 @@ Node* WasmGraphAssembler::IsNotNull(Node* object) {
|
||||
return AddNode(graph()->NewNode(simplified_.IsNotNull(), object, control()));
|
||||
}
|
||||
|
||||
Node* WasmGraphAssembler::AssertNotNull(Node* object) {
|
||||
return AddNode(graph()->NewNode(simplified_.AssertNotNull(), object, effect(),
|
||||
control()));
|
||||
Node* WasmGraphAssembler::AssertNotNull(Node* object, TrapId trap_id) {
|
||||
return AddNode(graph()->NewNode(simplified_.AssertNotNull(trap_id), object,
|
||||
effect(), control()));
|
||||
}
|
||||
|
||||
Node* WasmGraphAssembler::WasmExternInternalize(Node* object) {
|
||||
|
@ -249,7 +249,7 @@ class WasmGraphAssembler : public GraphAssembler {
|
||||
|
||||
Node* IsNotNull(Node* object);
|
||||
|
||||
Node* AssertNotNull(Node* object);
|
||||
Node* AssertNotNull(Node* object, TrapId trap_id);
|
||||
|
||||
Node* WasmExternInternalize(Node* object);
|
||||
|
||||
|
@ -2642,8 +2642,8 @@ class LiftoffCompiler {
|
||||
__ AssertUnreachable(AbortReason::kUnexpectedReturnFromWasmTrap);
|
||||
}
|
||||
|
||||
void AssertNullImpl(FullDecoder* decoder, const Value& arg, Value* result,
|
||||
LiftoffCondition cond) {
|
||||
void AssertNullTypecheckImpl(FullDecoder* decoder, const Value& arg,
|
||||
Value* result, LiftoffCondition cond) {
|
||||
LiftoffRegList pinned;
|
||||
LiftoffRegister obj = pinned.set(__ PopToRegister(pinned));
|
||||
Label* trap_label =
|
||||
@ -2658,12 +2658,14 @@ class LiftoffCompiler {
|
||||
__ PushRegister(kRefNull, obj);
|
||||
}
|
||||
|
||||
void AssertNull(FullDecoder* decoder, const Value& arg, Value* result) {
|
||||
AssertNullImpl(decoder, arg, result, kUnequal);
|
||||
void AssertNullTypecheck(FullDecoder* decoder, const Value& arg,
|
||||
Value* result) {
|
||||
AssertNullTypecheckImpl(decoder, arg, result, kUnequal);
|
||||
}
|
||||
|
||||
void AssertNotNull(FullDecoder* decoder, const Value& arg, Value* result) {
|
||||
AssertNullImpl(decoder, arg, result, kEqual);
|
||||
void AssertNotNullTypecheck(FullDecoder* decoder, const Value& arg,
|
||||
Value* result) {
|
||||
AssertNullTypecheckImpl(decoder, arg, result, kEqual);
|
||||
}
|
||||
|
||||
void NopForTestingUnsupportedInLiftoff(FullDecoder* decoder) {
|
||||
@ -6067,7 +6069,7 @@ class LiftoffCompiler {
|
||||
case HeapType::kNoExtern:
|
||||
case HeapType::kNoFunc:
|
||||
DCHECK(null_succeeds);
|
||||
return AssertNull(decoder, obj, result_val);
|
||||
return AssertNullTypecheck(decoder, obj, result_val);
|
||||
case HeapType::kAny:
|
||||
// Any may never need a cast as it is either implicitly convertible or
|
||||
// never convertible for any given type.
|
||||
|
@ -1093,8 +1093,8 @@ struct ControlBase : public PcForErrors<ValidationTag::full_validation> {
|
||||
bool null_succeeds) \
|
||||
F(RefCastAbstract, const Value& obj, HeapType type, Value* result, \
|
||||
bool null_succeeds) \
|
||||
F(AssertNull, const Value& obj, Value* result) \
|
||||
F(AssertNotNull, const Value& obj, Value* result) \
|
||||
F(AssertNullTypecheck, const Value& obj, Value* result) \
|
||||
F(AssertNotNullTypecheck, const Value& obj, Value* result) \
|
||||
F(BrOnCast, const Value& obj, const Value& rtt, Value* result_on_branch, \
|
||||
uint32_t depth) \
|
||||
F(BrOnCastFail, const Value& obj, const Value& rtt, \
|
||||
@ -4892,7 +4892,7 @@ class WasmFullDecoder : public WasmDecoder<ValidationTag, decoding_mode> {
|
||||
CALL_INTERFACE(Drop);
|
||||
}
|
||||
if (obj.type.is_nullable() && !null_succeeds) {
|
||||
CALL_INTERFACE(AssertNotNull, obj, &value);
|
||||
CALL_INTERFACE(AssertNotNullTypecheck, obj, &value);
|
||||
} else {
|
||||
CALL_INTERFACE(Forward, obj, &value);
|
||||
}
|
||||
@ -4905,7 +4905,7 @@ class WasmFullDecoder : public WasmDecoder<ValidationTag, decoding_mode> {
|
||||
// is null.
|
||||
if (obj.type.is_nullable() && null_succeeds) {
|
||||
// Drop rtt from the stack, then assert that obj is null.
|
||||
CALL_INTERFACE(AssertNull, obj, &value);
|
||||
CALL_INTERFACE(AssertNullTypecheck, obj, &value);
|
||||
} else {
|
||||
CALL_INTERFACE(Trap, TrapReason::kTrapIllegalCast);
|
||||
// We know that the following code is not reachable, but according
|
||||
@ -5115,7 +5115,7 @@ class WasmFullDecoder : public WasmDecoder<ValidationTag, decoding_mode> {
|
||||
if (obj.type.is_nullable()) {
|
||||
// Drop rtt from the stack, then assert that obj is null.
|
||||
CALL_INTERFACE(Drop);
|
||||
CALL_INTERFACE(AssertNull, obj, &value);
|
||||
CALL_INTERFACE(AssertNullTypecheck, obj, &value);
|
||||
} else {
|
||||
CALL_INTERFACE(Trap, TrapReason::kTrapIllegalCast);
|
||||
// We know that the following code is not reachable, but according
|
||||
|
@ -469,16 +469,18 @@ class WasmGraphBuildingInterface {
|
||||
builder_->Trap(reason, decoder->position());
|
||||
}
|
||||
|
||||
void AssertNull(FullDecoder* decoder, const Value& obj, Value* result) {
|
||||
void AssertNullTypecheck(FullDecoder* decoder, const Value& obj,
|
||||
Value* result) {
|
||||
builder_->TrapIfFalse(wasm::TrapReason::kTrapIllegalCast,
|
||||
builder_->IsNull(obj.node), decoder->position());
|
||||
Forward(decoder, obj, result);
|
||||
}
|
||||
|
||||
void AssertNotNull(FullDecoder* decoder, const Value& obj, Value* result) {
|
||||
builder_->TrapIfTrue(wasm::TrapReason::kTrapIllegalCast,
|
||||
builder_->IsNull(obj.node), decoder->position());
|
||||
Forward(decoder, obj, result);
|
||||
void AssertNotNullTypecheck(FullDecoder* decoder, const Value& obj,
|
||||
Value* result) {
|
||||
SetAndTypeNode(result,
|
||||
builder_->AssertNotNull(obj.node, decoder->position(),
|
||||
TrapReason::kTrapIllegalCast));
|
||||
}
|
||||
|
||||
void NopForTestingUnsupportedInLiftoff(FullDecoder* decoder) {}
|
||||
|
Loading…
Reference in New Issue
Block a user