@@ -166,11 +166,6 @@ ZEND_API void zend_generator_close(zend_generator *generator, bool finished_exec
166
166
zend_generator_cleanup_unfinished_execution (generator , execute_data , 0 );
167
167
}
168
168
169
- /* Free closure object */
170
- if (EX_CALL_INFO () & ZEND_CALL_CLOSURE ) {
171
- OBJ_RELEASE (ZEND_CLOSURE_OBJECT (EX (func )));
172
- }
173
-
174
169
efree (execute_data );
175
170
}
176
171
}
@@ -330,6 +325,10 @@ static void zend_generator_free_storage(zend_object *object) /* {{{ */
330
325
331
326
zend_generator_close (generator , 0 );
332
327
328
+ if (generator -> func && generator -> func -> common .fn_flags & ZEND_ACC_CLOSURE ) {
329
+ OBJ_RELEASE (ZEND_CLOSURE_OBJECT (generator -> func ));
330
+ }
331
+
333
332
/* we can't immediately free them in zend_generator_close() else yield from won't be able to fetch it */
334
333
zval_ptr_dtor (& generator -> value );
335
334
zval_ptr_dtor (& generator -> key );
@@ -354,10 +353,21 @@ static HashTable *zend_generator_get_gc(zend_object *object, zval **table, int *
354
353
zend_execute_data * call = NULL ;
355
354
356
355
if (!execute_data ) {
357
- /* If the generator has been closed, it can only hold on to three values: The value, key
358
- * and retval. These three zvals are stored sequentially starting at &generator->value. */
359
- * table = & generator -> value ;
360
- * n = 3 ;
356
+ if (UNEXPECTED (generator -> func -> common .fn_flags & ZEND_ACC_CLOSURE )) {
357
+ zend_get_gc_buffer * gc_buffer = zend_get_gc_buffer_create ();
358
+ zend_get_gc_buffer_add_zval (gc_buffer , & generator -> value );
359
+ zend_get_gc_buffer_add_zval (gc_buffer , & generator -> key );
360
+ zend_get_gc_buffer_add_zval (gc_buffer , & generator -> retval );
361
+ if (generator -> func && generator -> func -> common .fn_flags & ZEND_ACC_CLOSURE ) {
362
+ zend_get_gc_buffer_add_obj (gc_buffer , ZEND_CLOSURE_OBJECT (generator -> func ));
363
+ }
364
+ zend_get_gc_buffer_use (gc_buffer , table , n );
365
+ } else {
366
+ /* If the non-closure generator has been closed, it can only hold on to three values: The value, key
367
+ * and retval. These three zvals are stored sequentially starting at &generator->value. */
368
+ * table = & generator -> value ;
369
+ * n = 3 ;
370
+ }
361
371
return NULL ;
362
372
}
363
373
0 commit comments