Skip to content

Commit 40e3e23

Browse files
committed
Fix Generator Closure collection
1 parent 1554836 commit 40e3e23

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

Zend/zend_generators.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,6 @@ ZEND_API void zend_generator_close(zend_generator *generator, bool finished_exec
166166
zend_generator_cleanup_unfinished_execution(generator, execute_data, 0);
167167
}
168168

169-
/* Free closure object */
170-
if (EX_CALL_INFO() & ZEND_CALL_CLOSURE) {
171-
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
172-
}
173-
174169
efree(execute_data);
175170
}
176171
}
@@ -330,6 +325,10 @@ static void zend_generator_free_storage(zend_object *object) /* {{{ */
330325

331326
zend_generator_close(generator, 0);
332327

328+
if (generator->func && generator->func->common.fn_flags & ZEND_ACC_CLOSURE) {
329+
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(generator->func));
330+
}
331+
333332
/* we can't immediately free them in zend_generator_close() else yield from won't be able to fetch it */
334333
zval_ptr_dtor(&generator->value);
335334
zval_ptr_dtor(&generator->key);
@@ -354,10 +353,21 @@ static HashTable *zend_generator_get_gc(zend_object *object, zval **table, int *
354353
zend_execute_data *call = NULL;
355354

356355
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+
}
361371
return NULL;
362372
}
363373

0 commit comments

Comments
 (0)