|
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