[*] Ensure Token::EQ_STRICT understands all bigints are comparable.

Closes #5

Last aurora commit: e9f848d4
This commit is contained in:
Reece Wilson 2023-03-26 23:29:53 +01:00
parent e9f848d445
commit 1f6ee19ed3

View File

@ -13728,6 +13728,49 @@ TNode<Oddball> CodeStubAssembler::StrictEqual(
BIND(&if_lhsisnotsmi); BIND(&if_lhsisnotsmi);
{ {
Label if_lhsisbigint(this), if_lhsisnotbigint(this);
{
// Load the instance type of {lhs}.
TNode<Uint16T> lhs_instance_type = LoadInstanceType(CAST(lhs));
// Check if either {rhs} or {lhs} is a BigInt.
GotoIf(IsBigIntInstanceType(lhs_instance_type), &if_lhsisbigint);
GotoIf(TaggedIsSmi(rhs), &if_lhsisnotbigint);
GotoIf(IsBigIntInstanceType(LoadInstanceType(CAST(rhs))), &if_lhsisbigint);
Goto(&if_lhsisnotbigint);
BIND(&if_lhsisbigint);
{
if (Is64()) {
Label if_both_bigint(this);
GotoIf(TaggedIsSmi(lhs), &if_both_bigint);
GotoIf(IsHeapNumber(CAST(lhs)), &if_both_bigint);
GotoIfLargeBigInt(CAST(lhs), &if_both_bigint);
GotoIf(TaggedIsSmi(rhs), &if_both_bigint);
GotoIf(IsHeapNumber(CAST(rhs)), &if_both_bigint);
GotoIfLargeBigInt(CAST(rhs), &if_both_bigint);
OverwriteFeedback(var_type_feedback,
CompareOperationFeedback::kBigInt64);
BigInt64Comparison(Operation::kStrictEqual, lhs, rhs, &if_equal,
&if_notequal);
BIND(&if_both_bigint);
}
CombineFeedback(var_type_feedback, CompareOperationFeedback::kBigInt);
result = CAST(CallBuiltin(Builtin::kBigIntEqual, NoContextConstant(),
lhs, rhs));
Goto(&end);
}
}
BIND(&if_lhsisnotbigint);
// Load the map of {lhs}. // Load the map of {lhs}.
TNode<Map> lhs_map = LoadMap(CAST(lhs)); TNode<Map> lhs_map = LoadMap(CAST(lhs));
@ -13792,7 +13835,6 @@ TNode<Oddball> CodeStubAssembler::StrictEqual(
BIND(&if_rhsisnotsmi); BIND(&if_rhsisnotsmi);
{ {
// Load the instance type of {lhs}.
TNode<Uint16T> lhs_instance_type = LoadMapInstanceType(lhs_map); TNode<Uint16T> lhs_instance_type = LoadMapInstanceType(lhs_map);
// Check if {lhs} is a String. // Check if {lhs} is a String.
@ -13829,132 +13871,94 @@ TNode<Oddball> CodeStubAssembler::StrictEqual(
BIND(&if_lhsisnotstring); BIND(&if_lhsisnotstring);
{ {
// Check if {lhs} is a BigInt.
Label if_lhsisbigint(this), if_lhsisnotbigint(this);
Branch(IsBigIntInstanceType(lhs_instance_type), &if_lhsisbigint,
&if_lhsisnotbigint);
BIND(&if_lhsisbigint);
{ {
// Load the instance type of {rhs}. if (var_type_feedback != nullptr) {
TNode<Uint16T> rhs_instance_type = LoadInstanceType(CAST(rhs)); // Load the instance type of {rhs}.
TNode<Map> rhs_map = LoadMap(CAST(rhs));
TNode<Uint16T> rhs_instance_type = LoadMapInstanceType(rhs_map);
// Check if {rhs} is also a BigInt. Label if_lhsissymbol(this), if_lhsisreceiver(this),
Label if_rhsisbigint(this, Label::kDeferred), if_lhsisoddball(this);
if_rhsisnotbigint(this); GotoIf(IsJSReceiverInstanceType(lhs_instance_type),
Branch(IsBigIntInstanceType(rhs_instance_type), &if_rhsisbigint, &if_lhsisreceiver);
&if_rhsisnotbigint); GotoIf(IsBooleanMap(lhs_map), &if_not_equivalent_types);
GotoIf(IsOddballInstanceType(lhs_instance_type),
&if_lhsisoddball);
Branch(IsSymbolInstanceType(lhs_instance_type), &if_lhsissymbol,
&if_not_equivalent_types);
BIND(&if_rhsisbigint); BIND(&if_lhsisreceiver);
{
if (Is64()) {
Label if_both_bigint(this);
GotoIfLargeBigInt(CAST(lhs), &if_both_bigint);
GotoIfLargeBigInt(CAST(rhs), &if_both_bigint);
OverwriteFeedback(var_type_feedback,
CompareOperationFeedback::kBigInt64);
BigInt64Comparison(Operation::kStrictEqual, lhs, rhs,
&if_equal, &if_notequal);
BIND(&if_both_bigint);
}
CombineFeedback(var_type_feedback,
CompareOperationFeedback::kBigInt);
result = CAST(CallBuiltin(Builtin::kBigIntEqual,
NoContextConstant(), lhs, rhs));
Goto(&end);
}
BIND(&if_rhsisnotbigint);
Goto(&if_not_equivalent_types);
}
BIND(&if_lhsisnotbigint);
if (var_type_feedback != nullptr) {
// Load the instance type of {rhs}.
TNode<Map> rhs_map = LoadMap(CAST(rhs));
TNode<Uint16T> rhs_instance_type = LoadMapInstanceType(rhs_map);
Label if_lhsissymbol(this), if_lhsisreceiver(this),
if_lhsisoddball(this);
GotoIf(IsJSReceiverInstanceType(lhs_instance_type),
&if_lhsisreceiver);
GotoIf(IsBooleanMap(lhs_map), &if_not_equivalent_types);
GotoIf(IsOddballInstanceType(lhs_instance_type),
&if_lhsisoddball);
Branch(IsSymbolInstanceType(lhs_instance_type), &if_lhsissymbol,
&if_not_equivalent_types);
BIND(&if_lhsisreceiver);
{
GotoIf(IsBooleanMap(rhs_map), &if_not_equivalent_types);
OverwriteFeedback(var_type_feedback,
CompareOperationFeedback::kReceiver);
GotoIf(IsJSReceiverInstanceType(rhs_instance_type),
&if_notequal);
OverwriteFeedback(
var_type_feedback,
CompareOperationFeedback::kReceiverOrNullOrUndefined);
GotoIf(IsOddballInstanceType(rhs_instance_type), &if_notequal);
Goto(&if_not_equivalent_types);
}
BIND(&if_lhsisoddball);
{
Label if_lhsisboolean(this), if_lhsisnotboolean(this);
Branch(IsBooleanMap(lhs_map), &if_lhsisboolean,
&if_lhsisnotboolean);
BIND(&if_lhsisboolean);
{ {
GotoIf(IsBooleanMap(rhs_map), &if_not_equivalent_types);
OverwriteFeedback(var_type_feedback, OverwriteFeedback(var_type_feedback,
CompareOperationFeedback::kNumberOrOddball); CompareOperationFeedback::kReceiver);
GotoIf(IsBooleanMap(rhs_map), &if_notequal); GotoIf(IsJSReceiverInstanceType(rhs_instance_type),
&if_notequal);
OverwriteFeedback(
var_type_feedback,
CompareOperationFeedback::kReceiverOrNullOrUndefined);
GotoIf(IsOddballInstanceType(rhs_instance_type),
&if_notequal);
Goto(&if_not_equivalent_types); Goto(&if_not_equivalent_types);
} }
BIND(&if_lhsisnotboolean); BIND(&if_lhsisoddball);
{ {
Label if_rhsisheapnumber(this), if_rhsisnotheapnumber(this); Label if_lhsisboolean(this), if_lhsisnotboolean(this);
Branch(IsBooleanMap(lhs_map), &if_lhsisboolean,
&if_lhsisnotboolean);
static_assert(LAST_PRIMITIVE_HEAP_OBJECT_TYPE == BIND(&if_lhsisboolean);
ODDBALL_TYPE);
GotoIf(Int32LessThan(rhs_instance_type,
Int32Constant(ODDBALL_TYPE)),
&if_not_equivalent_types);
Branch(IsHeapNumberMap(rhs_map), &if_rhsisheapnumber,
&if_rhsisnotheapnumber);
BIND(&if_rhsisheapnumber);
{ {
OverwriteFeedback( OverwriteFeedback(
var_type_feedback, var_type_feedback,
CompareOperationFeedback::kNumberOrOddball); CompareOperationFeedback::kNumberOrOddball);
GotoIf(IsBooleanMap(rhs_map), &if_notequal);
Goto(&if_not_equivalent_types); Goto(&if_not_equivalent_types);
} }
BIND(&if_rhsisnotheapnumber); BIND(&if_lhsisnotboolean);
{ {
OverwriteFeedback( Label if_rhsisheapnumber(this), if_rhsisnotheapnumber(this);
var_type_feedback,
CompareOperationFeedback::kReceiverOrNullOrUndefined); static_assert(LAST_PRIMITIVE_HEAP_OBJECT_TYPE ==
Goto(&if_notequal); ODDBALL_TYPE);
GotoIf(Int32LessThan(rhs_instance_type,
Int32Constant(ODDBALL_TYPE)),
&if_not_equivalent_types);
Branch(IsHeapNumberMap(rhs_map), &if_rhsisheapnumber,
&if_rhsisnotheapnumber);
BIND(&if_rhsisheapnumber);
{
OverwriteFeedback(
var_type_feedback,
CompareOperationFeedback::kNumberOrOddball);
Goto(&if_not_equivalent_types);
}
BIND(&if_rhsisnotheapnumber);
{
OverwriteFeedback(
var_type_feedback,
CompareOperationFeedback::kReceiverOrNullOrUndefined);
Goto(&if_notequal);
}
} }
} }
}
BIND(&if_lhsissymbol); BIND(&if_lhsissymbol);
{ {
GotoIfNot(IsSymbolInstanceType(rhs_instance_type), GotoIfNot(IsSymbolInstanceType(rhs_instance_type),
&if_not_equivalent_types); &if_not_equivalent_types);
OverwriteFeedback(var_type_feedback, OverwriteFeedback(var_type_feedback,
CompareOperationFeedback::kSymbol); CompareOperationFeedback::kSymbol);
Goto(&if_notequal);
}
} else {
Goto(&if_notequal); Goto(&if_notequal);
} }
} else {
Goto(&if_notequal);
} }
} }
} }
@ -13981,30 +13985,71 @@ TNode<Oddball> CodeStubAssembler::StrictEqual(
// Load the map of the {rhs}. // Load the map of the {rhs}.
TNode<Map> rhs_map = LoadMap(CAST(rhs)); TNode<Map> rhs_map = LoadMap(CAST(rhs));
// The {rhs} could be a HeapNumber with the same value as {lhs}.
Label if_rhsisnumber(this), if_rhsisnotnumber(this);
Branch(IsHeapNumberMap(rhs_map), &if_rhsisnumber, &if_rhsisnotnumber);
BIND(&if_rhsisnumber);
{ {
// Convert {lhs} and {rhs} to floating point values. // Load the instance type of {rhs}.
TNode<Float64T> lhs_value = SmiToFloat64(CAST(lhs)); TNode<Uint16T> rhs_instance_type = LoadInstanceType(CAST(rhs));
TNode<Float64T> rhs_value = LoadHeapNumberValue(CAST(rhs));
CombineFeedback(var_type_feedback, CompareOperationFeedback::kNumber); Label if_rhsisbigint(this), if_rhsisnotbigint(this);
Branch(IsBigIntInstanceType(rhs_instance_type), &if_rhsisbigint,
&if_rhsisnotbigint);
// Perform a floating point comparison of {lhs} and {rhs}. BIND(&if_rhsisbigint);
Branch(Float64Equal(lhs_value, rhs_value), &if_equal, &if_notequal); {
} if (Is64()) {
Label if_both_bigint(this);
BIND(&if_rhsisnotnumber); GotoIf(TaggedIsSmi(lhs), &if_both_bigint);
{ GotoIf(IsHeapNumber(CAST(lhs)), &if_both_bigint);
TNode<Uint16T> rhs_instance_type = LoadMapInstanceType(rhs_map); GotoIfLargeBigInt(CAST(lhs), &if_both_bigint);
GotoIfNot(IsOddballInstanceType(rhs_instance_type),
&if_not_equivalent_types); //GotoIf(TaggedIsSmi(rhs), &if_both_bigint);
OverwriteFeedback(var_type_feedback, GotoIfLargeBigInt(CAST(rhs), &if_both_bigint);
CompareOperationFeedback::kNumberOrOddball);
Goto(&if_notequal); OverwriteFeedback(var_type_feedback,
CompareOperationFeedback::kBigInt64);
BigInt64Comparison(Operation::kStrictEqual, lhs, rhs, &if_equal,
&if_notequal);
BIND(&if_both_bigint);
}
CombineFeedback(var_type_feedback,
CompareOperationFeedback::kBigInt);
result = CAST(CallBuiltin(Builtin::kBigIntEqual,
NoContextConstant(), lhs, rhs));
Goto(&end);
}
BIND(&if_rhsisnotbigint);
{
// The {rhs} could be a HeapNumber with the same value as {lhs}.
Label if_rhsisnumber(this), if_rhsisnotnumber(this);
Branch(IsHeapNumberMap(rhs_map), &if_rhsisnumber,
&if_rhsisnotnumber);
BIND(&if_rhsisnumber);
{
// Convert {lhs} and {rhs} to floating point values.
TNode<Float64T> lhs_value = SmiToFloat64(CAST(lhs));
TNode<Float64T> rhs_value = LoadHeapNumberValue(CAST(rhs));
CombineFeedback(var_type_feedback,
CompareOperationFeedback::kNumber);
// Perform a floating point comparison of {lhs} and {rhs}.
Branch(Float64Equal(lhs_value, rhs_value), &if_equal,
&if_notequal);
}
BIND(&if_rhsisnotnumber);
{
GotoIfNot(IsOddballInstanceType(rhs_instance_type),
&if_not_equivalent_types);
OverwriteFeedback(var_type_feedback,
CompareOperationFeedback::kNumberOrOddball);
Goto(&if_notequal);
}
}
} }
} }
} }