@@ -4494,7 +4494,24 @@ ZEND_API void zend_cleanup_unfinished_execution(zend_execute_data *execute_data,
4494
4494
cleanup_live_vars (execute_data , op_num , catch_op_num );
4495
4495
}
4496
4496
4497
- ZEND_API HashTable * zend_unfinished_execution_gc (zend_execute_data * execute_data , zend_execute_data * call , zend_get_gc_buffer * gc_buffer )
4497
+ 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 )
4498
+ {
4499
+ bool suspended_by_yield = false;
4500
+
4501
+ if (Z_TYPE_INFO (EX (This )) & ZEND_CALL_GENERATOR ) {
4502
+ ZEND_ASSERT (EX (return_value ));
4503
+
4504
+ /* The generator object is stored in EX(return_value) */
4505
+ zend_generator * generator = (zend_generator * ) EX (return_value );
4506
+ ZEND_ASSERT (execute_data == generator -> execute_data );
4507
+
4508
+ suspended_by_yield = !(generator -> flags & ZEND_GENERATOR_CURRENTLY_RUNNING );
4509
+ }
4510
+
4511
+ return zend_unfinished_execution_gc_ex (execute_data , call , gc_buffer , suspended_by_yield );
4512
+ }
4513
+
4514
+ 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 )
4498
4515
{
4499
4516
if (!EX (func ) || !ZEND_USER_CODE (EX (func )-> common .type )) {
4500
4517
return NULL ;
@@ -4530,8 +4547,15 @@ ZEND_API HashTable *zend_unfinished_execution_gc(zend_execute_data *execute_data
4530
4547
}
4531
4548
4532
4549
if (call ) {
4533
- /* -1 required because we want the last run opcode, not the next to-be-run one. */
4534
- uint32_t op_num = execute_data -> opline - op_array -> opcodes - 1 ;
4550
+ uint32_t op_num = execute_data -> opline - op_array -> opcodes ;
4551
+ if (suspended_by_yield ) {
4552
+ /* When the execution was suspended by yield, EX(opline) points to
4553
+ * next opline to execute. Otherwise, it points to the opline that
4554
+ * suspended execution. */
4555
+ op_num -- ;
4556
+ ZEND_ASSERT (EX (func )-> op_array .opcodes [op_num ].opcode == ZEND_YIELD
4557
+ || EX (func )-> op_array .opcodes [op_num ].opcode == ZEND_YIELD_FROM );
4558
+ }
4535
4559
zend_unfinished_calls_gc (execute_data , call , op_num , gc_buffer );
4536
4560
}
4537
4561
0 commit comments