@@ -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,19 @@ 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
+ zend_get_gc_buffer_add_obj (gc_buffer , ZEND_CLOSURE_OBJECT (generator -> func ));
362
+ zend_get_gc_buffer_use (gc_buffer , table , n );
363
+ } else {
364
+ /* If the non-closure generator has been closed, it can only hold on to three values: The value, key
365
+ * and retval. These three zvals are stored sequentially starting at &generator->value. */
366
+ * table = & generator -> value ;
367
+ * n = 3 ;
368
+ }
361
369
return NULL ;
362
370
}
363
371
@@ -1010,6 +1018,35 @@ ZEND_METHOD(Generator, getReturn)
1010
1018
}
1011
1019
/* }}} */
1012
1020
1021
+ ZEND_METHOD (Generator , __debugInfo )
1022
+ {
1023
+ zend_generator * generator ;
1024
+
1025
+ ZEND_PARSE_PARAMETERS_NONE ();
1026
+
1027
+ generator = (zend_generator * ) Z_OBJ_P (ZEND_THIS );
1028
+
1029
+ array_init (return_value );
1030
+
1031
+ zend_function * func = generator -> func ;
1032
+
1033
+ zval val ;
1034
+ if (func -> common .scope ) {
1035
+ zend_string * class_name = func -> common .scope -> name ;
1036
+ zend_string * func_name = func -> common .function_name ;
1037
+ zend_string * combined = zend_string_concat3 (
1038
+ ZSTR_VAL (class_name ), ZSTR_LEN (class_name ),
1039
+ "::" , strlen ("::" ),
1040
+ ZSTR_VAL (func_name ), ZSTR_LEN (func_name )
1041
+ );
1042
+ ZVAL_NEW_STR (& val , combined );
1043
+ } else {
1044
+ ZVAL_STR_COPY (& val , func -> common .function_name );
1045
+ }
1046
+
1047
+ zend_hash_update (Z_ARR_P (return_value ), ZSTR_KNOWN (ZEND_STR_FUNCTION ), & val );
1048
+ }
1049
+
1013
1050
/* get_iterator implementation */
1014
1051
1015
1052
static void zend_generator_iterator_dtor (zend_object_iterator * iterator ) /* {{{ */
0 commit comments