@@ -274,6 +274,25 @@ static uint32_t calc_gc_buffer_size(zend_generator *generator) /* {{{ */
274
274
size += Z_TYPE (execute_data -> This ) == IS_OBJECT ; /* $this */
275
275
size += (EX_CALL_INFO () & ZEND_CALL_CLOSURE ) != 0 ; /* Closure object */
276
276
277
+ /* Live vars */
278
+ if (execute_data -> opline != op_array -> opcodes ) {
279
+ /* -1 required because we want the last run opcode, not the next to-be-run one. */
280
+ uint32_t i , op_num = execute_data -> opline - op_array -> opcodes - 1 ;
281
+ for (i = 0 ; i < op_array -> last_live_range ; i ++ ) {
282
+ const zend_live_range * range = & op_array -> live_range [i ];
283
+ if (range -> start > op_num ) {
284
+ /* Further ranges will not be relevant... */
285
+ break ;
286
+ } else if (op_num < range -> end ) {
287
+ /* LIVE_ROPE and LIVE_SILENCE not relevant for GC */
288
+ uint32_t kind = range -> var & ZEND_LIVE_MASK ;
289
+ if (kind == ZEND_LIVE_TMPVAR || kind == ZEND_LIVE_LOOP ) {
290
+ size ++ ;
291
+ }
292
+ }
293
+ }
294
+ }
295
+
277
296
/* Yield from root references */
278
297
if (generator -> node .children == 0 ) {
279
298
zend_generator * root = generator -> node .ptr .root ;
@@ -340,6 +359,23 @@ static HashTable *zend_generator_get_gc(zval *object, zval **table, int *n) /* {
340
359
ZVAL_OBJ (gc_buffer ++ , (zend_object * ) EX (func )-> common .prototype );
341
360
}
342
361
362
+ if (execute_data -> opline != op_array -> opcodes ) {
363
+ uint32_t i , op_num = execute_data -> opline - op_array -> opcodes - 1 ;
364
+ for (i = 0 ; i < op_array -> last_live_range ; i ++ ) {
365
+ const zend_live_range * range = & op_array -> live_range [i ];
366
+ if (range -> start > op_num ) {
367
+ break ;
368
+ } else if (op_num < range -> end ) {
369
+ uint32_t kind = range -> var & ZEND_LIVE_MASK ;
370
+ uint32_t var_num = range -> var & ~ZEND_LIVE_MASK ;
371
+ zval * var = EX_VAR (var_num );
372
+ if (kind == ZEND_LIVE_TMPVAR || kind == ZEND_LIVE_LOOP ) {
373
+ ZVAL_COPY_VALUE (gc_buffer ++ , var );
374
+ }
375
+ }
376
+ }
377
+ }
378
+
343
379
if (generator -> node .children == 0 ) {
344
380
zend_generator * root = generator -> node .ptr .root ;
345
381
while (root != generator ) {
0 commit comments