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