5151import static com .oracle .graal .python .runtime .exception .PythonErrorType .TypeError ;
5252
5353import java .math .BigInteger ;
54+ import java .util .Arrays ;
55+ import java .util .Comparator ;
5456import java .util .List ;
5557
5658import com .oracle .graal .python .PythonLanguage ;
8183import com .oracle .graal .python .builtins .objects .object .PythonObjectLibrary ;
8284import com .oracle .graal .python .builtins .objects .range .PIntRange ;
8385import com .oracle .graal .python .builtins .objects .str .PString ;
86+ import com .oracle .graal .python .builtins .objects .str .StringUtils ;
8487import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
8588import com .oracle .graal .python .nodes .ErrorMessages ;
8689import com .oracle .graal .python .nodes .PGuards ;
105108import com .oracle .graal .python .runtime .exception .PException ;
106109import com .oracle .graal .python .runtime .exception .PythonErrorType ;
107110import 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 ;
108113import com .oracle .graal .python .runtime .sequence .storage .DoubleSequenceStorage ;
109114import com .oracle .graal .python .runtime .sequence .storage .EmptySequenceStorage ;
110115import com .oracle .graal .python .runtime .sequence .storage .IntSequenceStorage ;
111116import com .oracle .graal .python .runtime .sequence .storage .LongSequenceStorage ;
117+ import com .oracle .graal .python .runtime .sequence .storage .ObjectSequenceStorage ;
112118import com .oracle .graal .python .runtime .sequence .storage .SequenceStorage ;
113119import com .oracle .graal .python .runtime .sequence .storage .SequenceStorageFactory ;
114120import com .oracle .graal .python .util .PythonUtils ;
124130import com .oracle .truffle .api .dsl .TypeSystemReference ;
125131import com .oracle .truffle .api .frame .VirtualFrame ;
126132import com .oracle .truffle .api .library .CachedLibrary ;
133+ import com .oracle .truffle .api .nodes .Node ;
127134import com .oracle .truffle .api .nodes .UnexpectedResultException ;
128135import com .oracle .truffle .api .profiles .ConditionProfile ;
129136
@@ -861,6 +868,92 @@ public static ListReverseNode create() {
861868 }
862869 }
863870
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+
864957 // list.sort(key=, reverse=)
865958 @ Builtin (name = SORT , minNumOfPositionalArgs = 1 , takesVarArgs = true , takesVarKeywordArgs = true , needsFrame = true )
866959 @ GenerateNodeFactory
@@ -878,10 +971,10 @@ protected static boolean maySideEffect(PList list, PKeyword[] keywords) {
878971 return true ;
879972 }
880973 if (keywords .length > 0 ) {
881- if (keywords [0 ].getName (). equals ( KEY )) {
974+ if (KEY . equals ( keywords [0 ].getName ())) {
882975 return true ;
883976 }
884- if (keywords .length > 1 && keywords [1 ].getName (). equals ( KEY )) {
977+ if (keywords .length > 1 && KEY . equals ( keywords [1 ].getName ())) {
885978 return true ;
886979 }
887980 }
@@ -901,6 +994,14 @@ Object none(VirtualFrame frame, PList list, Object[] arguments, PKeyword[] keywo
901994 return PNone .NONE ;
902995 }
903996
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+
9041005 @ Specialization (guards = {"isSortable(list, lenNode)" , "maySideEffect(list, keywords)" })
9051006 Object withKey (VirtualFrame frame , PList list , Object [] arguments , PKeyword [] keywords ,
9061007 @ Cached ("create(SORT)" ) GetAttributeNode sort ,
0 commit comments