@@ -337,6 +337,31 @@ impl Frame {
337
337
let value = self . pop_value ( ) ;
338
338
Some ( Ok ( ExecutionResult :: Yield ( value) ) )
339
339
}
340
+ bytecode:: Instruction :: YieldFrom => {
341
+ // Value send into iterator:
342
+ self . pop_value ( ) ;
343
+
344
+ let top_of_stack = self . last_value ( ) ;
345
+ let next_obj = objiter:: get_next_object ( vm, & top_of_stack) ;
346
+
347
+ match next_obj {
348
+ Ok ( Some ( value) ) => {
349
+ // Set back program counter:
350
+ self . lasti -= 1 ;
351
+ Some ( Ok ( ExecutionResult :: Yield ( value) ) )
352
+ }
353
+ Ok ( None ) => {
354
+ // Pop iterator from stack:
355
+ self . pop_value ( ) ;
356
+ None
357
+ }
358
+ Err ( next_error) => {
359
+ // Pop iterator from stack:
360
+ self . pop_value ( ) ;
361
+ Some ( Err ( next_error) )
362
+ }
363
+ }
364
+ }
340
365
bytecode:: Instruction :: SetupLoop { start, end } => {
341
366
self . push_block ( Block :: Loop {
342
367
start : * start,
@@ -398,35 +423,31 @@ impl Frame {
398
423
bytecode:: Instruction :: ForIter => {
399
424
// The top of stack contains the iterator, lets push it forward:
400
425
let top_of_stack = self . last_value ( ) ;
401
- let next_obj: PyResult = vm . call_method ( & top_of_stack , "__next__" , vec ! [ ] ) ;
426
+ let next_obj = objiter :: get_next_object ( vm , & top_of_stack ) ;
402
427
403
428
// Check the next object:
404
429
match next_obj {
405
- Ok ( value) => {
430
+ Ok ( Some ( value) ) => {
406
431
self . push_value ( value) ;
407
432
None
408
433
}
409
- Err ( next_error) => {
410
- // Check if we have stopiteration, or something else:
411
- if objtype:: isinstance (
412
- & next_error,
413
- vm. ctx . exceptions . stop_iteration . clone ( ) ,
414
- ) {
415
- // Pop iterator from stack:
416
- self . pop_value ( ) ;
417
-
418
- // End of for loop
419
- let end_label = if let Block :: Loop { start : _, end } = self . last_block ( )
420
- {
421
- * end
422
- } else {
423
- panic ! ( "Wrong block type" )
424
- } ;
425
- self . jump ( end_label) ;
426
- None
434
+ Ok ( None ) => {
435
+ // Pop iterator from stack:
436
+ self . pop_value ( ) ;
437
+
438
+ // End of for loop
439
+ let end_label = if let Block :: Loop { start : _, end } = self . last_block ( ) {
440
+ * end
427
441
} else {
428
- Some ( Err ( next_error) )
429
- }
442
+ panic ! ( "Wrong block type" )
443
+ } ;
444
+ self . jump ( end_label) ;
445
+ None
446
+ }
447
+ Err ( next_error) => {
448
+ // Pop iterator from stack:
449
+ self . pop_value ( ) ;
450
+ Some ( Err ( next_error) )
430
451
}
431
452
}
432
453
}
0 commit comments