|
112 | 112 | import com.oracle.truffle.api.dsl.TypeSystemReference;
|
113 | 113 | import com.oracle.truffle.api.frame.VirtualFrame;
|
114 | 114 | import com.oracle.truffle.api.library.CachedLibrary;
|
| 115 | +import com.oracle.truffle.api.nodes.UnexpectedResultException; |
115 | 116 | import com.oracle.truffle.api.profiles.ConditionProfile;
|
116 | 117 |
|
117 | 118 | @CoreFunctions(extendClasses = PythonBuiltinClassType.PList)
|
@@ -217,36 +218,50 @@ PNone listRange(PList list, PRange range) {
|
217 | 218 | return PNone.NONE;
|
218 | 219 | }
|
219 | 220 |
|
220 |
| - @Specialization(guards = "iterable.isPRangeIterator()") |
| 221 | + @Specialization(guards = "iterable.isPRangeIterator()", rewriteOn = UnexpectedResultException.class) |
221 | 222 | PNone listPGenerator(VirtualFrame frame, PList list, PGenerator iterable,
|
222 | 223 | @Cached GetIteratorNode getIteratorNode,
|
223 | 224 | @Cached SequenceStorageNodes.AppendNode appendNode,
|
224 | 225 | @Cached GetNextNode getNextNode,
|
225 | 226 | @Cached IsBuiltinClassProfile errorProfile,
|
226 | 227 | @Cached("createBinaryProfile()") ConditionProfile stepProfile,
|
227 |
| - @Cached("createBinaryProfile()") ConditionProfile positiveRangeProfile) { |
| 228 | + @Cached("createBinaryProfile()") ConditionProfile positiveRangeProfile) throws UnexpectedResultException { |
228 | 229 | clearStorage(list);
|
229 | 230 | Object iterObj = getIteratorNode.executeWith(frame, iterable);
|
230 | 231 | SequenceStorage storage = EmptySequenceStorage.INSTANCE;
|
231 | 232 |
|
232 | 233 | PRangeIterator range = (PRangeIterator) iterable.getIterator();
|
233 |
| - final int len = range.getLength(stepProfile, positiveRangeProfile); |
234 |
| - if (len > 0) { |
235 |
| - Object value = getNextNode.execute(frame, iterObj); |
236 |
| - storage = SequenceStorageFactory.createStorage(value, len); |
237 |
| - storage = appendNode.execute(storage, value, ListGeneralizationNode.SUPPLIER); |
238 |
| - while (true) { |
239 |
| - try { |
240 |
| - storage = appendNode.execute(storage, getNextNode.execute(frame, iterObj), ListGeneralizationNode.SUPPLIER); |
241 |
| - } catch (PException e) { |
242 |
| - e.expectStopIteration(errorProfile); |
243 |
| - break; |
| 234 | + final int estimatedMaxLen = range.getLength(stepProfile, positiveRangeProfile); |
| 235 | + int realLen = 0; |
| 236 | + if (estimatedMaxLen > 0) { |
| 237 | + Object value = null; |
| 238 | + try { |
| 239 | + value = getNextNode.execute(frame, iterObj); |
| 240 | + realLen++; |
| 241 | + } catch (PException e) { |
| 242 | + e.expectStopIteration(errorProfile); |
| 243 | + } |
| 244 | + if (value != null) { |
| 245 | + storage = SequenceStorageFactory.createStorage(value, estimatedMaxLen); |
| 246 | + storage = appendNode.execute(storage, value, ListGeneralizationNode.SUPPLIER); |
| 247 | + while (true) { |
| 248 | + try { |
| 249 | + storage = appendNode.execute(storage, getNextNode.execute(frame, iterObj), ListGeneralizationNode.SUPPLIER); |
| 250 | + realLen++; |
| 251 | + } catch (PException e) { |
| 252 | + e.expectStopIteration(errorProfile); |
| 253 | + break; |
| 254 | + } |
244 | 255 | }
|
245 | 256 | }
|
246 | 257 | }
|
247 | 258 |
|
248 | 259 | list.setSequenceStorage(storage);
|
249 |
| - return PNone.NONE; |
| 260 | + if (realLen == estimatedMaxLen) { |
| 261 | + return PNone.NONE; |
| 262 | + } else { |
| 263 | + throw new UnexpectedResultException(PNone.NONE); |
| 264 | + } |
250 | 265 | }
|
251 | 266 |
|
252 | 267 | @Specialization(guards = {"!isNoValue(iterable)", "!isString(iterable)"})
|
|
0 commit comments