@@ -4422,7 +4422,24 @@ ZEND_API void zend_cleanup_unfinished_execution(zend_execute_data *execute_data,
44224422 cleanup_live_vars (execute_data , op_num , catch_op_num );
44234423}
44244424
4425- ZEND_API HashTable * zend_unfinished_execution_gc (zend_execute_data * execute_data , zend_execute_data * call , zend_get_gc_buffer * gc_buffer )
4425+ ZEND_API ZEND_ATTRIBUTE_DEPRECATED HashTable * zend_unfinished_execution_gc (zend_execute_data * execute_data , zend_execute_data * call , zend_get_gc_buffer * gc_buffer )
4426+ {
4427+ bool suspended_by_yield = false;
4428+
4429+ if (Z_TYPE_INFO (EX (This )) & ZEND_CALL_GENERATOR ) {
4430+ ZEND_ASSERT (EX (return_value ));
4431+
4432+ /* The generator object is stored in EX(return_value) */
4433+ zend_generator * generator = (zend_generator * ) EX (return_value );
4434+ ZEND_ASSERT (execute_data == generator -> execute_data );
4435+
4436+ suspended_by_yield = !(generator -> flags & ZEND_GENERATOR_CURRENTLY_RUNNING );
4437+ }
4438+
4439+ return zend_unfinished_execution_gc_ex (execute_data , call , gc_buffer , suspended_by_yield );
4440+ }
4441+
4442+ ZEND_API HashTable * zend_unfinished_execution_gc_ex (zend_execute_data * execute_data , zend_execute_data * call , zend_get_gc_buffer * gc_buffer , bool suspended_by_yield )
44264443{
44274444 if (!EX (func ) || !ZEND_USER_CODE (EX (func )-> common .type )) {
44284445 return NULL ;
@@ -4458,8 +4475,15 @@ ZEND_API HashTable *zend_unfinished_execution_gc(zend_execute_data *execute_data
44584475 }
44594476
44604477 if (call ) {
4461- /* -1 required because we want the last run opcode, not the next to-be-run one. */
4462- uint32_t op_num = execute_data -> opline - op_array -> opcodes - 1 ;
4478+ uint32_t op_num = execute_data -> opline - op_array -> opcodes ;
4479+ if (suspended_by_yield ) {
4480+ /* When the execution was suspended by yield, EX(opline) points to
4481+ * next opline to execute. Otherwise, it points to the opline that
4482+ * suspended execution. */
4483+ op_num -- ;
4484+ ZEND_ASSERT (EX (func )-> op_array .opcodes [op_num ].opcode == ZEND_YIELD
4485+ || EX (func )-> op_array .opcodes [op_num ].opcode == ZEND_YIELD_FROM );
4486+ }
44634487 zend_unfinished_calls_gc (execute_data , call , op_num , gc_buffer );
44644488 }
44654489
0 commit comments