|
40 | 40 | */
|
41 | 41 | package com.oracle.graal.python.nodes.argument.positional;
|
42 | 42 |
|
| 43 | +import java.util.ArrayList; |
43 | 44 | import java.util.Iterator;
|
| 45 | +import java.util.List; |
44 | 46 |
|
45 | 47 | import com.oracle.graal.python.builtins.objects.PNone;
|
46 | 48 | import com.oracle.graal.python.builtins.objects.dict.PDict;
|
47 | 49 | import com.oracle.graal.python.builtins.objects.list.PList;
|
48 | 50 | import com.oracle.graal.python.builtins.objects.set.PSet;
|
49 | 51 | import com.oracle.graal.python.builtins.objects.tuple.PTuple;
|
50 | 52 | import com.oracle.graal.python.nodes.PNode;
|
| 53 | +import com.oracle.graal.python.nodes.control.GetIteratorNode; |
| 54 | +import com.oracle.graal.python.nodes.control.GetNextNode; |
| 55 | +import com.oracle.graal.python.runtime.exception.PException; |
| 56 | +import com.oracle.graal.python.runtime.exception.PythonErrorType; |
| 57 | +import com.oracle.truffle.api.dsl.Cached; |
51 | 58 | import com.oracle.truffle.api.dsl.NodeChild;
|
52 | 59 | import com.oracle.truffle.api.dsl.NodeChildren;
|
53 | 60 | import com.oracle.truffle.api.dsl.Specialization;
|
54 | 61 | import com.oracle.truffle.api.frame.VirtualFrame;
|
55 |
| -import com.oracle.truffle.api.nodes.Node; |
| 62 | +import com.oracle.truffle.api.profiles.ConditionProfile; |
56 | 63 |
|
57 | 64 | @NodeChildren({@NodeChild(value = "splat", type = PNode.class)})
|
58 |
| -public abstract class ExecutePositionalStarargsNode extends Node { |
| 65 | +public abstract class ExecutePositionalStarargsNode extends PNode { |
59 | 66 | public abstract Object[] execute(VirtualFrame frame);
|
60 | 67 |
|
61 | 68 | public abstract Object[] executeWith(Object starargs);
|
@@ -110,6 +117,26 @@ Object[] starargs(PNone none) {
|
110 | 117 | return new Object[0];
|
111 | 118 | }
|
112 | 119 |
|
| 120 | + @Specialization |
| 121 | + Object[] starargs(Object object, |
| 122 | + @Cached("create()") GetIteratorNode getIterator, |
| 123 | + @Cached("create()") GetNextNode next, |
| 124 | + @Cached("createBinaryProfile()") ConditionProfile errorProfile) { |
| 125 | + Object iterator = getIterator.executeWith(object); |
| 126 | + if (iterator != PNone.NO_VALUE && iterator != PNone.NONE) { |
| 127 | + List<Object> internalStorage = new ArrayList<>(); |
| 128 | + while (true) { |
| 129 | + try { |
| 130 | + internalStorage.add(next.execute(iterator)); |
| 131 | + } catch (PException e) { |
| 132 | + e.expectStopIteration(getCore(), errorProfile); |
| 133 | + return internalStorage.toArray(); |
| 134 | + } |
| 135 | + } |
| 136 | + } |
| 137 | + throw raise(PythonErrorType.TypeError, "argument after * must be an iterable, not %p", object); |
| 138 | + } |
| 139 | + |
113 | 140 | public static ExecutePositionalStarargsNode create() {
|
114 | 141 | return ExecutePositionalStarargsNodeGen.create(null);
|
115 | 142 | }
|
|
0 commit comments