97
97
import com .oracle .graal .python .nodes .SpecialMethodNames ;
98
98
import com .oracle .graal .python .nodes .control .GetNextNode ;
99
99
import com .oracle .graal .python .nodes .expression .BinaryComparisonNode ;
100
- import com .oracle .graal .python .nodes .expression .BinaryComparisonNode .EqNode ;
101
100
import com .oracle .graal .python .nodes .expression .BinaryComparisonNode .GeNode ;
102
101
import com .oracle .graal .python .nodes .expression .BinaryComparisonNode .GtNode ;
103
102
import com .oracle .graal .python .nodes .expression .BinaryComparisonNode .LeNode ;
112
111
import com .oracle .graal .python .nodes .function .builtins .clinic .ArgumentClinicProvider ;
113
112
import com .oracle .graal .python .nodes .object .IsBuiltinClassProfile ;
114
113
import com .oracle .graal .python .nodes .util .CannotCastException ;
115
- import com .oracle .graal .python .nodes .util .CastToJavaBooleanNode ;
116
114
import com .oracle .graal .python .nodes .util .CastToJavaIntExactNode ;
117
115
import com .oracle .graal .python .nodes .util .CastToJavaStringNode ;
118
116
import com .oracle .graal .python .runtime .PythonContext ;
@@ -904,6 +902,9 @@ Object doGeneric(PDeque self,
904
902
905
903
public abstract static class DequeCompareNode extends PythonBinaryBuiltinNode {
906
904
905
+ @ Child private PythonObjectLibrary selfItemLib ;
906
+ @ Child private PythonObjectLibrary otherItemLib ;
907
+
907
908
@ Specialization (guards = "shortcutIdentityCheck(self, other)" )
908
909
@ SuppressWarnings ("unused" )
909
910
static boolean doSame (PDeque self , PDeque other ) {
@@ -922,10 +923,7 @@ Object doGeneric(VirtualFrame frame, PDeque self, Object other,
922
923
@ CachedLibrary ("other" ) PythonObjectLibrary otherLib ,
923
924
@ Cached GetNextNode selfItNextNode ,
924
925
@ Cached GetNextNode otherItNextNode ,
925
- @ Cached EqNode eqNode ,
926
- @ Cached ("createCmp()" ) BinaryComparisonNode comparisonNode ,
927
- @ Cached IsBuiltinClassProfile profile ,
928
- @ Cached CastToJavaBooleanNode castToJavaBooleanNode ) {
926
+ @ Cached IsBuiltinClassProfile profile ) {
929
927
if (!isPDeque (other )) {
930
928
return PNotImplemented .NOT_IMPLEMENTED ;
931
929
}
@@ -945,12 +943,12 @@ Object doGeneric(VirtualFrame frame, PDeque self, Object other,
945
943
try {
946
944
Object selfItem = selfItNextNode .execute (frame , ait );
947
945
Object otherItem = otherItNextNode .execute (frame , bit );
948
- if (!castToJavaBooleanNode . execute ( eqNode . executeWith ( frame , selfItem , otherItem ) )) {
949
- return castToJavaBooleanNode . execute ( comparisonNode . executeWith ( frame , selfItem , otherItem ) );
946
+ if (!compareEq ( frame , selfItem , otherItem )) {
947
+ return compare ( frame , selfItem , otherItem );
950
948
}
951
949
} catch (PException e ) {
952
950
e .expect (StopIteration , profile );
953
- return comparisonNode . cmp ( self .getSize (), otherDeque .getSize ());
951
+ return compare ( frame , self .getSize (), otherDeque .getSize ());
954
952
}
955
953
}
956
954
}
@@ -969,7 +967,27 @@ boolean shortcutLengthCheck(PDeque self, PDeque other) {
969
967
return true ;
970
968
}
971
969
972
- BinaryComparisonNode createCmp () {
970
+ /**
971
+ * Compares two items using
972
+ * {@link PythonObjectLibrary#equals(Object, Object, PythonObjectLibrary)}. Unfortunately,
973
+ * we cannot use
974
+ * {@link com.oracle.graal.python.nodes.expression.BinaryComparisonNode.EqNode} because
975
+ * CPython uses {@code PyObject_RichCompareBool} which has a special case for identity.
976
+ */
977
+ final boolean compareEq (VirtualFrame frame , Object selfItem , Object otherItem ) {
978
+ if (selfItemLib == null ) {
979
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
980
+ selfItemLib = insert (PythonObjectLibrary .getFactory ().createDispatched (3 ));
981
+ }
982
+ if (otherItemLib == null ) {
983
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
984
+ otherItemLib = insert (PythonObjectLibrary .getFactory ().createDispatched (3 ));
985
+ }
986
+ return selfItemLib .equalsWithFrame (selfItem , otherItem , otherItemLib , frame );
987
+ }
988
+
989
+ @ SuppressWarnings ("unused" )
990
+ boolean compare (VirtualFrame frame , Object selfItem , Object otherItem ) {
973
991
throw CompilerDirectives .shouldNotReachHere ();
974
992
}
975
993
}
@@ -979,7 +997,7 @@ BinaryComparisonNode createCmp() {
979
997
public abstract static class DequeEqNode extends DequeCompareNode {
980
998
@ Specialization (guards = "!shortcutLengthCheck(self, other)" , insertBefore = "doGeneric" )
981
999
@ SuppressWarnings ("unused" )
982
- static boolean doSame (PDeque self , PDeque other ) {
1000
+ static boolean doDifferentLength (PDeque self , PDeque other ) {
983
1001
return false ;
984
1002
}
985
1003
@@ -994,14 +1012,37 @@ boolean shortcutLengthCheck(PDeque self, PDeque other) {
994
1012
}
995
1013
996
1014
@ Override
1015
+ boolean compare (VirtualFrame frame , Object selfItem , Object otherItem ) {
1016
+ return compareEq (frame , selfItem , otherItem );
1017
+ }
1018
+ }
1019
+
1020
+ public abstract static class DequeRelCompareNode extends DequeCompareNode {
1021
+
1022
+ @ Child private BinaryComparisonNode comparisonNode ;
1023
+ @ Child private PythonObjectLibrary lib ;
1024
+
1025
+ @ Override
1026
+ boolean compare (VirtualFrame frame , Object selfItem , Object otherItem ) {
1027
+ if (comparisonNode == null ) {
1028
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
1029
+ comparisonNode = insert (createCmp ());
1030
+ }
1031
+ if (lib == null ) {
1032
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
1033
+ lib = insert (PythonObjectLibrary .getFactory ().createDispatched (3 ));
1034
+ }
1035
+ return lib .isTrue (comparisonNode .executeWith (frame , selfItem , otherItem ), frame );
1036
+ }
1037
+
997
1038
BinaryComparisonNode createCmp () {
998
- return EqNode . create ();
1039
+ throw CompilerDirectives . shouldNotReachHere ();
999
1040
}
1000
1041
}
1001
1042
1002
1043
@ Builtin (name = __LE__ , minNumOfPositionalArgs = 2 )
1003
1044
@ GenerateNodeFactory
1004
- public abstract static class DequeLeNode extends DequeCompareNode {
1045
+ public abstract static class DequeLeNode extends DequeRelCompareNode {
1005
1046
@ Override
1006
1047
boolean shortcutIdentityCheck (Object self , Object other ) {
1007
1048
return self == other ;
@@ -1015,7 +1056,7 @@ BinaryComparisonNode createCmp() {
1015
1056
1016
1057
@ Builtin (name = __LT__ , minNumOfPositionalArgs = 2 )
1017
1058
@ GenerateNodeFactory
1018
- public abstract static class DequeLtNode extends DequeCompareNode {
1059
+ public abstract static class DequeLtNode extends DequeRelCompareNode {
1019
1060
@ Override
1020
1061
BinaryComparisonNode createCmp () {
1021
1062
return LtNode .create ();
@@ -1024,7 +1065,7 @@ BinaryComparisonNode createCmp() {
1024
1065
1025
1066
@ Builtin (name = __GE__ , minNumOfPositionalArgs = 2 )
1026
1067
@ GenerateNodeFactory
1027
- public abstract static class DequeGeNode extends DequeCompareNode {
1068
+ public abstract static class DequeGeNode extends DequeRelCompareNode {
1028
1069
@ Override
1029
1070
boolean shortcutIdentityCheck (Object self , Object other ) {
1030
1071
return self == other ;
@@ -1038,7 +1079,7 @@ BinaryComparisonNode createCmp() {
1038
1079
1039
1080
@ Builtin (name = __GT__ , minNumOfPositionalArgs = 2 )
1040
1081
@ GenerateNodeFactory
1041
- public abstract static class DequeGtNode extends DequeCompareNode {
1082
+ public abstract static class DequeGtNode extends DequeRelCompareNode {
1042
1083
@ Override
1043
1084
BinaryComparisonNode createCmp () {
1044
1085
return GtNode .create ();
0 commit comments