]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.0'
authorBob Weinand <bobwei9@hotmail.com>
Mon, 15 Feb 2016 21:43:58 +0000 (22:43 +0100)
committerBob Weinand <bobwei9@hotmail.com>
Mon, 15 Feb 2016 21:43:58 +0000 (22:43 +0100)
1  2 
Zend/zend_generators.c

index 1c798cc9b4d8392492c83750a3dd473af181fb0b,646e46b6764c2d2d62429e4848358dcffedcc0f7..9633fc4f2dc2550f11e401da8d2924df7ea47428
@@@ -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;
  }
  /* }}} */