From: Bob Weinand Date: Mon, 15 Feb 2016 21:43:58 +0000 (+0100) Subject: Merge branch 'PHP-7.0' X-Git-Tag: php-7.1.0alpha1~617^2~5 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=77ca527c91a253c00850ea4bab242af25fd71df5;p=php Merge branch 'PHP-7.0' --- 77ca527c91a253c00850ea4bab242af25fd71df5 diff --cc Zend/zend_generators.c index 1c798cc9b4,646e46b676..9633fc4f2d --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@@ -228,65 -193,9 +230,65 @@@ static uint32_t calc_gc_buffer_size(zen static HashTable *zend_generator_get_gc(zval *object, zval **table, int *n) /* {{{ */ { zend_generator *generator = (zend_generator*) Z_OBJ_P(object); - *table = &generator->value; - *n = 3; - return NULL; + zend_execute_data *execute_data = generator->execute_data; + zend_op_array *op_array; + zval *gc_buffer; + uint32_t gc_buffer_size; + + if (!execute_data) { + /* If the generator has been closed, it can only hold on to three values: The value, key + * and retval. These three zvals are stored sequentially starting at &generator->value. */ + *table = &generator->value; + *n = 3; + 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); + + if (!execute_data->symbol_table) { + uint32_t i, num_cvs = EX(func)->op_array.last_var; + for (i = 0; i < num_cvs; i++) { + ZVAL_COPY_VALUE(gc_buffer++, EX_VAR_NUM(i)); + } + } + + if (EX_CALL_INFO() & ZEND_CALL_FREE_EXTRA_ARGS) { + zval *zv = EX_VAR_NUM(op_array->last_var + op_array->T); + zval *end = zv + (EX_NUM_ARGS() - op_array->num_args); + while (zv != end) { + ZVAL_COPY_VALUE(gc_buffer++, zv++); + } + } + + if (Z_OBJ(execute_data->This)) { + ZVAL_OBJ(gc_buffer++, Z_OBJ(execute_data->This)); + } + if (EX_CALL_INFO() & ZEND_CALL_CLOSURE) { + ZVAL_OBJ(gc_buffer++, (zend_object *) EX(func)->common.prototype); + } + + if (generator->node.children == 0) { - zend_generator *root = generator->node.ptr.root; - while (root != generator) { - ZVAL_OBJ(gc_buffer++, &root->std); - root = zend_generator_get_child(&root->node, generator); ++ zend_generator *child = generator, *root = generator->node.ptr.root; ++ while (root != child) { ++ ZVAL_OBJ(gc_buffer++, &child->std); ++ child = child->node.parent; + } + } + + return execute_data->symbol_table; } /* }}} */