From: Nikita Popov Date: Wed, 18 Nov 2020 11:46:12 +0000 (+0100) Subject: Merge branch 'PHP-7.4' into PHP-8.0 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bbc0dd402aeb68a7b38b89ac75b987271caa6bc7;p=php Merge branch 'PHP-7.4' into PHP-8.0 * PHP-7.4: Short-circuit get_gc for currently running generator --- bbc0dd402aeb68a7b38b89ac75b987271caa6bc7 diff --cc Zend/zend_generators.c index 7746c3de9c,3fbbd49c0a..68c1865c00 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@@ -324,13 -340,30 +324,23 @@@ static HashTable *zend_generator_get_gc return NULL; } + if (generator->flags & ZEND_GENERATOR_CURRENTLY_RUNNING) { + /* If the generator is currently running, we certainly won't be able to GC any values it + * holds on to. The execute_data state might be inconsistent during execution (e.g. because + * GC has been triggered in the middle of a variable reassignment), so we should not try + * to inspect it here. */ + *table = NULL; + *n = 0; + return NULL; + } + op_array = &EX(func)->op_array; - gc_buffer_size = calc_gc_buffer_size(generator); - if (generator->gc_buffer_size < gc_buffer_size) { - generator->gc_buffer = safe_erealloc(generator->gc_buffer, sizeof(zval), gc_buffer_size, 0); - generator->gc_buffer_size = gc_buffer_size; - } - *n = gc_buffer_size; - *table = gc_buffer = generator->gc_buffer; - - ZVAL_COPY_VALUE(gc_buffer++, &generator->value); - ZVAL_COPY_VALUE(gc_buffer++, &generator->key); - ZVAL_COPY_VALUE(gc_buffer++, &generator->retval); - ZVAL_COPY_VALUE(gc_buffer++, &generator->values); + zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); + zend_get_gc_buffer_add_zval(gc_buffer, &generator->value); + zend_get_gc_buffer_add_zval(gc_buffer, &generator->key); + zend_get_gc_buffer_add_zval(gc_buffer, &generator->retval); + zend_get_gc_buffer_add_zval(gc_buffer, &generator->values); if (!(EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE)) { uint32_t i, num_cvs = EX(func)->op_array.last_var;