@@ -337,6 +337,31 @@ impl Frame {
337337 let value = self . pop_value ( ) ;
338338 Some ( Ok ( ExecutionResult :: Yield ( value) ) )
339339 }
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+ }
340365 bytecode:: Instruction :: SetupLoop { start, end } => {
341366 self . push_block ( Block :: Loop {
342367 start : * start,
@@ -398,35 +423,31 @@ impl Frame {
398423 bytecode:: Instruction :: ForIter => {
399424 // The top of stack contains the iterator, lets push it forward:
400425 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 ) ;
402427
403428 // Check the next object:
404429 match next_obj {
405- Ok ( value) => {
430+ Ok ( Some ( value) ) => {
406431 self . push_value ( value) ;
407432 None
408433 }
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
427441 } 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) )
430451 }
431452 }
432453 }
0 commit comments