51
51
import static com .oracle .graal .python .runtime .exception .PythonErrorType .TypeError ;
52
52
53
53
import java .math .BigInteger ;
54
+ import java .util .Arrays ;
55
+ import java .util .Comparator ;
54
56
import java .util .List ;
55
57
56
58
import com .oracle .graal .python .PythonLanguage ;
81
83
import com .oracle .graal .python .builtins .objects .object .PythonObjectLibrary ;
82
84
import com .oracle .graal .python .builtins .objects .range .PIntRange ;
83
85
import com .oracle .graal .python .builtins .objects .str .PString ;
86
+ import com .oracle .graal .python .builtins .objects .str .StringUtils ;
84
87
import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
85
88
import com .oracle .graal .python .nodes .ErrorMessages ;
86
89
import com .oracle .graal .python .nodes .PGuards ;
105
108
import com .oracle .graal .python .runtime .exception .PException ;
106
109
import com .oracle .graal .python .runtime .exception .PythonErrorType ;
107
110
import com .oracle .graal .python .runtime .sequence .PSequence ;
111
+ import com .oracle .graal .python .runtime .sequence .storage .BoolSequenceStorage ;
112
+ import com .oracle .graal .python .runtime .sequence .storage .ByteSequenceStorage ;
108
113
import com .oracle .graal .python .runtime .sequence .storage .DoubleSequenceStorage ;
109
114
import com .oracle .graal .python .runtime .sequence .storage .EmptySequenceStorage ;
110
115
import com .oracle .graal .python .runtime .sequence .storage .IntSequenceStorage ;
111
116
import com .oracle .graal .python .runtime .sequence .storage .LongSequenceStorage ;
117
+ import com .oracle .graal .python .runtime .sequence .storage .ObjectSequenceStorage ;
112
118
import com .oracle .graal .python .runtime .sequence .storage .SequenceStorage ;
113
119
import com .oracle .graal .python .runtime .sequence .storage .SequenceStorageFactory ;
114
120
import com .oracle .graal .python .util .PythonUtils ;
124
130
import com .oracle .truffle .api .dsl .TypeSystemReference ;
125
131
import com .oracle .truffle .api .frame .VirtualFrame ;
126
132
import com .oracle .truffle .api .library .CachedLibrary ;
133
+ import com .oracle .truffle .api .nodes .Node ;
127
134
import com .oracle .truffle .api .nodes .UnexpectedResultException ;
128
135
import com .oracle .truffle .api .profiles .ConditionProfile ;
129
136
@@ -861,6 +868,92 @@ public static ListReverseNode create() {
861
868
}
862
869
}
863
870
871
+ abstract static class SimpleSortNode extends Node {
872
+
873
+ protected static final String SORT = "_sort" ;
874
+
875
+ protected abstract void execute (VirtualFrame frame , PList list , SequenceStorage storage );
876
+
877
+ @ Specialization
878
+ @ TruffleBoundary
879
+ void sort (@ SuppressWarnings ("unused" ) PList list , BoolSequenceStorage storage ) {
880
+ int length = storage .length ();
881
+ int trueValues = 0 ;
882
+ boolean [] array = storage .getInternalBoolArray ();
883
+ for (int i = 0 ; i < length ; i ++) {
884
+ if (array [i ]) {
885
+ trueValues ++;
886
+ }
887
+ }
888
+ Arrays .fill (array , 0 , length - trueValues , false );
889
+ Arrays .fill (array , length - trueValues , length , true );
890
+ }
891
+
892
+ @ Specialization
893
+ @ TruffleBoundary
894
+ void sort (@ SuppressWarnings ("unused" ) PList list , ByteSequenceStorage storage ) {
895
+ Arrays .sort (storage .getInternalByteArray (), 0 , storage .length ());
896
+ }
897
+
898
+ @ Specialization
899
+ @ TruffleBoundary
900
+ void sort (@ SuppressWarnings ("unused" ) PList list , IntSequenceStorage storage ) {
901
+ Arrays .sort (storage .getInternalIntArray (), 0 , storage .length ());
902
+ }
903
+
904
+ @ Specialization
905
+ @ TruffleBoundary
906
+ void sort (@ SuppressWarnings ("unused" ) PList list , LongSequenceStorage storage ) {
907
+ Arrays .sort (storage .getInternalLongArray (), 0 , storage .length ());
908
+ }
909
+
910
+ @ Specialization
911
+ @ TruffleBoundary
912
+ void sort (@ SuppressWarnings ("unused" ) PList list , DoubleSequenceStorage storage ) {
913
+ Arrays .sort (storage .getInternalDoubleArray (), 0 , storage .length ());
914
+ }
915
+
916
+ private static final class StringComparator implements Comparator <Object > {
917
+ public int compare (Object o1 , Object o2 ) {
918
+ return StringUtils .compareToUnicodeAware ((String ) o1 , (String ) o2 );
919
+ }
920
+ }
921
+
922
+ private static final StringComparator COMPARATOR = new StringComparator ();
923
+
924
+ @ Specialization (guards = "isStringOnly(storage)" )
925
+ @ TruffleBoundary
926
+ void sort (@ SuppressWarnings ("unused" ) PList list , ObjectSequenceStorage storage ) {
927
+ Arrays .sort (storage .getInternalArray (), 0 , storage .length (), COMPARATOR );
928
+ }
929
+
930
+ @ TruffleBoundary
931
+ protected static boolean isStringOnly (ObjectSequenceStorage storage ) {
932
+ int length = storage .length ();
933
+ Object [] array = storage .getInternalArray ();
934
+ for (int i = 0 ; i < length ; i ++) {
935
+ Object value = array [i ];
936
+ if (!(value instanceof String )) {
937
+ return false ;
938
+ }
939
+ }
940
+ return true ;
941
+ }
942
+
943
+ protected static boolean isSimpleType (SequenceStorage storage ) {
944
+ return storage instanceof BoolSequenceStorage || storage instanceof ByteSequenceStorage || storage instanceof IntSequenceStorage || storage instanceof LongSequenceStorage ||
945
+ storage instanceof DoubleSequenceStorage || (storage instanceof ObjectSequenceStorage && isStringOnly ((ObjectSequenceStorage ) storage ));
946
+ }
947
+
948
+ @ Specialization (guards = "!isSimpleType(storage)" )
949
+ void defaultSort (VirtualFrame frame , PList list , @ SuppressWarnings ("unused" ) SequenceStorage storage ,
950
+ @ Cached ("create(SORT)" ) GetAttributeNode sort ,
951
+ @ Cached CallNode callSort ) {
952
+ Object sortMethod = sort .executeObject (frame , list );
953
+ callSort .execute (frame , sortMethod , PythonUtils .EMPTY_OBJECT_ARRAY , PKeyword .EMPTY_KEYWORDS );
954
+ }
955
+ }
956
+
864
957
// list.sort(key=, reverse=)
865
958
@ Builtin (name = SORT , minNumOfPositionalArgs = 1 , takesVarArgs = true , takesVarKeywordArgs = true , needsFrame = true )
866
959
@ GenerateNodeFactory
@@ -878,10 +971,10 @@ protected static boolean maySideEffect(PList list, PKeyword[] keywords) {
878
971
return true ;
879
972
}
880
973
if (keywords .length > 0 ) {
881
- if (keywords [0 ].getName (). equals ( KEY )) {
974
+ if (KEY . equals ( keywords [0 ].getName ())) {
882
975
return true ;
883
976
}
884
- if (keywords .length > 1 && keywords [1 ].getName (). equals ( KEY )) {
977
+ if (keywords .length > 1 && KEY . equals ( keywords [1 ].getName ())) {
885
978
return true ;
886
979
}
887
980
}
@@ -901,6 +994,14 @@ Object none(VirtualFrame frame, PList list, Object[] arguments, PKeyword[] keywo
901
994
return PNone .NONE ;
902
995
}
903
996
997
+ @ Specialization (guards = {"isSortable(list, lenNode)" , "arguments.length == 0" , "keywords.length == 0" , "!maySideEffect(list, keywords)" })
998
+ Object simple (VirtualFrame frame , PList list , @ SuppressWarnings ("unused" ) Object [] arguments , @ SuppressWarnings ("unused" ) PKeyword [] keywords ,
999
+ @ Cached SimpleSortNode simpleSort ,
1000
+ @ SuppressWarnings ("unused" ) @ Cached SequenceStorageNodes .LenNode lenNode ) {
1001
+ simpleSort .execute (frame , list , list .getSequenceStorage ());
1002
+ return PNone .NONE ;
1003
+ }
1004
+
904
1005
@ Specialization (guards = {"isSortable(list, lenNode)" , "maySideEffect(list, keywords)" })
905
1006
Object withKey (VirtualFrame frame , PList list , Object [] arguments , PKeyword [] keywords ,
906
1007
@ Cached ("create(SORT)" ) GetAttributeNode sort ,
@@ -921,7 +1022,7 @@ Object defaultSort(VirtualFrame frame, PList list, Object[] arguments, PKeyword[
921
1022
@ Cached CallNode callSort ,
922
1023
@ SuppressWarnings ("unused" ) @ Cached SequenceStorageNodes .LenNode lenNode ) {
923
1024
Object sortMethod = sort .executeObject (frame , list );
924
- callSort .execute (sortMethod , arguments , keywords );
1025
+ callSort .execute (frame , sortMethod , arguments , keywords );
925
1026
return PNone .NONE ;
926
1027
}
927
1028
0 commit comments