From 1f6ee19ed3558f3fbc8f5b41cd30264b4a5f16e6 Mon Sep 17 00:00:00 2001 From: Reece Date: Sun, 26 Mar 2023 23:29:53 +0100 Subject: [PATCH] [*] Ensure Token::EQ_STRICT understands all bigints are comparable. Closes #5 Last aurora commit: e9f848d4 --- src/codegen/code-stub-assembler.cc | 293 +++++++++++++++++------------ 1 file changed, 169 insertions(+), 124 deletions(-) diff --git a/src/codegen/code-stub-assembler.cc b/src/codegen/code-stub-assembler.cc index 5ff9a1a31e..05944ec633 100644 --- a/src/codegen/code-stub-assembler.cc +++ b/src/codegen/code-stub-assembler.cc @@ -13728,6 +13728,49 @@ TNode CodeStubAssembler::StrictEqual( BIND(&if_lhsisnotsmi); { + Label if_lhsisbigint(this), if_lhsisnotbigint(this); + + { + // Load the instance type of {lhs}. + TNode 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 lhs_map = LoadMap(CAST(lhs)); @@ -13792,7 +13835,6 @@ TNode CodeStubAssembler::StrictEqual( BIND(&if_rhsisnotsmi); { - // Load the instance type of {lhs}. TNode lhs_instance_type = LoadMapInstanceType(lhs_map); // Check if {lhs} is a String. @@ -13829,132 +13871,94 @@ TNode 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 rhs_instance_type = LoadInstanceType(CAST(rhs)); + if (var_type_feedback != nullptr) { + // Load the instance type of {rhs}. + TNode rhs_map = LoadMap(CAST(rhs)); + TNode 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 rhs_map = LoadMap(CAST(rhs)); - TNode 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 CodeStubAssembler::StrictEqual( // Load the map of the {rhs}. TNode 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 lhs_value = SmiToFloat64(CAST(lhs)); - TNode rhs_value = LoadHeapNumberValue(CAST(rhs)); + // Load the instance type of {rhs}. + TNode 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 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 lhs_value = SmiToFloat64(CAST(lhs)); + TNode 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); + } + } } } }