|
65 | 65 | import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ListGeneralizationNode;
|
66 | 66 | import com.oracle.graal.python.builtins.objects.function.PArguments;
|
67 | 67 | import com.oracle.graal.python.builtins.objects.function.PArguments.ThreadState;
|
| 68 | +import com.oracle.graal.python.builtins.objects.function.PKeyword; |
68 | 69 | import com.oracle.graal.python.builtins.objects.generator.PGenerator;
|
69 | 70 | import com.oracle.graal.python.builtins.objects.ints.PInt;
|
70 | 71 | import com.oracle.graal.python.builtins.objects.iterator.PDoubleSequenceIterator;
|
|
80 | 81 | import com.oracle.graal.python.nodes.ErrorMessages;
|
81 | 82 | import com.oracle.graal.python.nodes.PGuards;
|
82 | 83 | import com.oracle.graal.python.nodes.argument.ReadArgumentNode;
|
| 84 | +import com.oracle.graal.python.nodes.attributes.GetAttributeNode; |
83 | 85 | import com.oracle.graal.python.nodes.builtins.ListNodes;
|
84 | 86 | import com.oracle.graal.python.nodes.builtins.ListNodes.AppendNode;
|
85 | 87 | import com.oracle.graal.python.nodes.builtins.ListNodes.IndexNode;
|
| 88 | +import com.oracle.graal.python.nodes.call.CallNode; |
86 | 89 | import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
|
87 | 90 | import com.oracle.graal.python.nodes.control.GetIteratorExpressionNode.GetIteratorNode;
|
88 | 91 | import com.oracle.graal.python.nodes.control.GetNextNode;
|
|
91 | 94 | import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
|
92 | 95 | import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
|
93 | 96 | import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
|
| 97 | +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; |
94 | 98 | import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
|
95 | 99 | import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
|
96 | 100 | import com.oracle.graal.python.runtime.PythonCore;
|
@@ -840,6 +844,65 @@ public static ListReverseNode create() {
|
840 | 844 | }
|
841 | 845 | }
|
842 | 846 |
|
| 847 | + // list.sort(key=, reverse=) |
| 848 | + @Builtin(name = "sort", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, needsFrame = true) |
| 849 | + @GenerateNodeFactory |
| 850 | + public abstract static class ListSortNode extends PythonVarargsBuiltinNode { |
| 851 | + |
| 852 | + protected static final String SORT = "_sort"; |
| 853 | + protected static final String KEY = "key"; |
| 854 | + |
| 855 | + protected static boolean isSortable(PList list, SequenceStorageNodes.LenNode lenNode) { |
| 856 | + return lenNode.execute(list.getSequenceStorage()) > 1; |
| 857 | + } |
| 858 | + |
| 859 | + protected static boolean maySideEffect(PList list, PKeyword[] keywords) { |
| 860 | + if (PGuards.isObjectStorage(list)) { |
| 861 | + return true; |
| 862 | + } |
| 863 | + if (keywords.length > 0) { |
| 864 | + if (keywords[0].getName().equals(KEY)) { |
| 865 | + return true; |
| 866 | + } |
| 867 | + if (keywords.length > 1 && keywords[1].getName().equals(KEY)) { |
| 868 | + return true; |
| 869 | + } |
| 870 | + } |
| 871 | + return false; |
| 872 | + } |
| 873 | + |
| 874 | + @Specialization(guards = "!isSortable(list, lenNode)") |
| 875 | + @SuppressWarnings("unused") |
| 876 | + Object none(VirtualFrame frame, PList list, Object[] arguments, PKeyword[] keywords, |
| 877 | + @Cached SequenceStorageNodes.LenNode lenNode) { |
| 878 | + return PNone.NONE; |
| 879 | + } |
| 880 | + |
| 881 | + @Specialization(guards = {"isSortable(list, lenNode)", "maySideEffect(list, keywords)"}) |
| 882 | + Object withKey(VirtualFrame frame, PList list, Object[] arguments, PKeyword[] keywords, |
| 883 | + @Cached("create(SORT)") GetAttributeNode sort, |
| 884 | + @Cached CallNode callSort, |
| 885 | + @SuppressWarnings("unused") @Cached SequenceStorageNodes.LenNode lenNode) { |
| 886 | + list.getSequenceStorage().setLock(); |
| 887 | + try { |
| 888 | + defaultSort(frame, list, arguments, keywords, sort, callSort, lenNode); |
| 889 | + } finally { |
| 890 | + list.getSequenceStorage().releaseLock(); |
| 891 | + } |
| 892 | + return PNone.NONE; |
| 893 | + } |
| 894 | + |
| 895 | + @Specialization(guards = {"isSortable(list, lenNode)", "!maySideEffect(list, keywords)"}) |
| 896 | + Object defaultSort(VirtualFrame frame, PList list, Object[] arguments, PKeyword[] keywords, |
| 897 | + @Cached("create(SORT)") GetAttributeNode sort, |
| 898 | + @Cached CallNode callSort, |
| 899 | + @SuppressWarnings("unused") @Cached SequenceStorageNodes.LenNode lenNode) { |
| 900 | + Object sortMethod = sort.executeObject(frame, list); |
| 901 | + callSort.execute(sortMethod, arguments, keywords); |
| 902 | + return PNone.NONE; |
| 903 | + } |
| 904 | + } |
| 905 | + |
843 | 906 | @Builtin(name = __LEN__, minNumOfPositionalArgs = 1)
|
844 | 907 | @GenerateNodeFactory
|
845 | 908 | public abstract static class LenNode extends PythonUnaryBuiltinNode {
|
|
0 commit comments