[*] 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);
{
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}.
TNode<Map> lhs_map = LoadMap(CAST(lhs));
@ -13792,7 +13835,6 @@ TNode<Oddball> CodeStubAssembler::StrictEqual(
BIND(&if_rhsisnotsmi);
{
// Load the instance type of {lhs}.
TNode<Uint16T> lhs_instance_type = LoadMapInstanceType(lhs_map);
// Check if {lhs} is a String.
@ -13829,132 +13871,94 @@ TNode<Oddball> CodeStubAssembler::StrictEqual(
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}.
TNode<Uint16T> rhs_instance_type = LoadInstanceType(CAST(rhs));
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);
// Check if {rhs} is also a BigInt.
Label if_rhsisbigint(this, Label::kDeferred),
if_rhsisnotbigint(this);
Branch(IsBigIntInstanceType(rhs_instance_type), &if_rhsisbigint,
&if_rhsisnotbigint);
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_rhsisbigint);
{
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);
BIND(&if_lhsisreceiver);
{
GotoIf(IsBooleanMap(rhs_map), &if_not_equivalent_types);
OverwriteFeedback(var_type_feedback,
CompareOperationFeedback::kNumberOrOddball);
GotoIf(IsBooleanMap(rhs_map), &if_notequal);
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_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 ==
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);
BIND(&if_lhsisboolean);
{
OverwriteFeedback(
var_type_feedback,
CompareOperationFeedback::kNumberOrOddball);
GotoIf(IsBooleanMap(rhs_map), &if_notequal);
Goto(&if_not_equivalent_types);
}
BIND(&if_rhsisnotheapnumber);
BIND(&if_lhsisnotboolean);
{
OverwriteFeedback(
var_type_feedback,
CompareOperationFeedback::kReceiverOrNullOrUndefined);
Goto(&if_notequal);
Label if_rhsisheapnumber(this), if_rhsisnotheapnumber(this);
static_assert(LAST_PRIMITIVE_HEAP_OBJECT_TYPE ==
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);
{
GotoIfNot(IsSymbolInstanceType(rhs_instance_type),
&if_not_equivalent_types);
OverwriteFeedback(var_type_feedback,
CompareOperationFeedback::kSymbol);
BIND(&if_lhsissymbol);
{
GotoIfNot(IsSymbolInstanceType(rhs_instance_type),
&if_not_equivalent_types);
OverwriteFeedback(var_type_feedback,
CompareOperationFeedback::kSymbol);
Goto(&if_notequal);
}
} else {
Goto(&if_notequal);
}
} else {
Goto(&if_notequal);
}
}
}
@ -13981,30 +13985,71 @@ TNode<Oddball> CodeStubAssembler::StrictEqual(
// Load the map of the {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.
TNode<Float64T> lhs_value = SmiToFloat64(CAST(lhs));
TNode<Float64T> rhs_value = LoadHeapNumberValue(CAST(rhs));
// Load the instance type of {rhs}.
TNode<Uint16T> rhs_instance_type = LoadInstanceType(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}.
Branch(Float64Equal(lhs_value, rhs_value), &if_equal, &if_notequal);
}
BIND(&if_rhsisbigint);
{
if (Is64()) {
Label if_both_bigint(this);
BIND(&if_rhsisnotnumber);
{
TNode<Uint16T> rhs_instance_type = LoadMapInstanceType(rhs_map);
GotoIfNot(IsOddballInstanceType(rhs_instance_type),
&if_not_equivalent_types);
OverwriteFeedback(var_type_feedback,
CompareOperationFeedback::kNumberOrOddball);
Goto(&if_notequal);
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);
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);
{
// 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);
}
}
}
}
}