|
62 | 62 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__INT__;
|
63 | 63 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__ITER__;
|
64 | 64 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__LEN__;
|
| 65 | +import static com.oracle.graal.python.nodes.SpecialMethodNames.__NEXT__; |
65 | 66 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__SETITEM__;
|
66 | 67 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__SET__;
|
67 | 68 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__STR__;
|
|
159 | 160 | import com.oracle.truffle.api.interop.ArityException;
|
160 | 161 | import com.oracle.truffle.api.interop.InteropLibrary;
|
161 | 162 | import com.oracle.truffle.api.interop.InvalidArrayIndexException;
|
| 163 | +import com.oracle.truffle.api.interop.StopIterationException; |
162 | 164 | import com.oracle.truffle.api.interop.TruffleObject;
|
163 | 165 | import com.oracle.truffle.api.interop.UnknownIdentifierException;
|
164 | 166 | import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
|
170 | 172 | import com.oracle.truffle.api.nodes.ExplodeLoop;
|
171 | 173 | import com.oracle.truffle.api.nodes.Node;
|
172 | 174 | import com.oracle.truffle.api.object.DynamicObject;
|
| 175 | +import com.oracle.truffle.api.object.DynamicObjectLibrary; |
| 176 | +import com.oracle.truffle.api.object.HiddenKey; |
173 | 177 | import com.oracle.truffle.api.object.Shape;
|
174 | 178 | import com.oracle.truffle.api.profiles.BranchProfile;
|
175 | 179 | import com.oracle.truffle.api.profiles.ConditionProfile;
|
@@ -2092,4 +2096,64 @@ public static Object getIteratorWithState(PythonAbstractObject self, ThreadState
|
2092 | 2096 | throw raise.raise(PythonErrorType.TypeError, ErrorMessages.OBJ_NOT_ITERABLE, self);
|
2093 | 2097 | }
|
2094 | 2098 | }
|
| 2099 | + |
| 2100 | + @ExportMessage |
| 2101 | + public boolean hasIterator( |
| 2102 | + @CachedLibrary("this") PythonObjectLibrary lib) { |
| 2103 | + return lib.isIterable(this); |
| 2104 | + } |
| 2105 | + |
| 2106 | + @ExportMessage |
| 2107 | + public Object getIterator( |
| 2108 | + @CachedLibrary("this") PythonObjectLibrary lib) throws UnsupportedMessageException { |
| 2109 | + if (lib.isIterable(this)) { |
| 2110 | + return lib.getIterator(this); |
| 2111 | + } else { |
| 2112 | + throw UnsupportedMessageException.create(); |
| 2113 | + } |
| 2114 | + } |
| 2115 | + |
| 2116 | + @ExportMessage |
| 2117 | + public boolean isIterator( |
| 2118 | + @CachedLibrary("this") PythonObjectLibrary lib) { |
| 2119 | + return lib.lookupAttributeOnType(this, __NEXT__) != PNone.NO_VALUE; |
| 2120 | + } |
| 2121 | + |
| 2122 | + private static final HiddenKey NEXT_ELEMENT = new HiddenKey("next_element"); |
| 2123 | + |
| 2124 | + @ExportMessage |
| 2125 | + public boolean hasIteratorNextElement( |
| 2126 | + @CachedLibrary("this") InteropLibrary ilib, |
| 2127 | + @CachedLibrary("this") PythonObjectLibrary plib, |
| 2128 | + @CachedLibrary("this") DynamicObjectLibrary dylib, |
| 2129 | + @Exclusive @Cached IsBuiltinClassProfile exceptionProfile) throws UnsupportedMessageException { |
| 2130 | + if (ilib.isIterator(this)) { |
| 2131 | + Object nextElement = dylib.getOrDefault(this, NEXT_ELEMENT, null); |
| 2132 | + if (nextElement != null) { |
| 2133 | + return true; |
| 2134 | + } |
| 2135 | + try { |
| 2136 | + nextElement = plib.lookupAndCallSpecialMethod(this, null, __NEXT__); |
| 2137 | + dylib.put(this, NEXT_ELEMENT, nextElement); |
| 2138 | + return true; |
| 2139 | + } catch (PException e) { |
| 2140 | + e.expect(PythonBuiltinClassType.StopIteration, exceptionProfile); |
| 2141 | + return false; |
| 2142 | + } |
| 2143 | + } |
| 2144 | + throw UnsupportedMessageException.create(); |
| 2145 | + } |
| 2146 | + |
| 2147 | + @ExportMessage |
| 2148 | + public Object getIteratorNextElement( |
| 2149 | + @CachedLibrary("this") InteropLibrary ilib, |
| 2150 | + @CachedLibrary("this") DynamicObjectLibrary dylib) throws StopIterationException, UnsupportedMessageException { |
| 2151 | + if (ilib.hasIteratorNextElement(this)) { |
| 2152 | + Object nextElement = dylib.getOrDefault(this, NEXT_ELEMENT, null); |
| 2153 | + dylib.put(this, NEXT_ELEMENT, null); |
| 2154 | + return nextElement; |
| 2155 | + } else { |
| 2156 | + throw StopIterationException.create(); |
| 2157 | + } |
| 2158 | + } |
2095 | 2159 | }
|
0 commit comments