]> granicus.if.org Git - php/commitdiff
Remove support for cloning generators
authorNikita Popov <nikic@php.net>
Mon, 25 Mar 2013 16:40:58 +0000 (17:40 +0100)
committerNikita Popov <nikic@php.net>
Fri, 29 Mar 2013 10:42:10 +0000 (11:42 +0100)
Zend/tests/generators/clone.phpt
Zend/tests/generators/clone_after_object_call.phpt [deleted file]
Zend/tests/generators/clone_with_foreach.phpt [deleted file]
Zend/tests/generators/clone_with_properties.phpt [deleted file]
Zend/tests/generators/clone_with_stack.phpt [deleted file]
Zend/tests/generators/clone_with_symbol_table.phpt [deleted file]
Zend/tests/generators/clone_with_this.phpt [deleted file]
Zend/tests/generators/nested_method_calls.phpt
Zend/tests/generators/yield_during_method_call.phpt
Zend/zend_generators.c

index 36811dfe6e7441a1be7d28b0cfca6f1cf6427091..22f4428121845b6d0aeaf8164f41bd457d93d092 100644 (file)
@@ -1,32 +1,15 @@
 --TEST--
-Generators can be cloned
+Generators cannot be cloned
 --FILE--
 <?php
 
-function firstN($end) {
-    for ($i = 0; $i < $end; ++$i) {
-        yield $i;
-    }
+function gen() {
+    yield;
 }
 
-$g1 = firstN(5);
-var_dump($g1->current());
-$g1->next();
-
-$g2 = clone $g1;
-var_dump($g2->current());
-$g2->next();
-
-var_dump($g2->current());
-var_dump($g1->current());
-
-$g1->next();
-var_dump($g1->current());
+$gen = gen();
+clone $gen;
 
 ?>
---EXPECT--
-int(0)
-int(1)
-int(2)
-int(1)
-int(2)
+--EXPECTF--
+Fatal error: Trying to clone an uncloneable object of class Generator in %s on line %d
diff --git a/Zend/tests/generators/clone_after_object_call.phpt b/Zend/tests/generators/clone_after_object_call.phpt
deleted file mode 100644 (file)
index 0a42426..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
---TEST--
-Cloning a generator after an object method was called
---FILE--
-<?php
-
-class A { public function b() { } }
-
-function gen() {
-    $a = new A;
-    $a->b();
-    yield;
-}
-
-$g1 = gen();
-$g1->rewind();
-$g2 = clone $g1; 
-
-echo "Done";
---EXPECT--
-Done
diff --git a/Zend/tests/generators/clone_with_foreach.phpt b/Zend/tests/generators/clone_with_foreach.phpt
deleted file mode 100644 (file)
index b05ed07..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
---TEST--
-Cloning a generator with a foreach loop properly adds a ref for the loop var
---FILE--
-<?php
-
-function gen() {
-    foreach ([1, 2, 3] as $i) {
-        yield $i;
-    }
-}
-
-$g1 = gen();
-var_dump($g1->current());
-
-$g2 = clone $g1;
-var_dump($g2->current());
-
-$g1->next();
-$g2->next();
-var_dump($g1->current());
-var_dump($g2->current());
-
-unset($g1);
-$g2->next();
-var_dump($g2->current());
-
-?>
---EXPECT--
-int(1)
-int(1)
-int(2)
-int(2)
-int(3)
diff --git a/Zend/tests/generators/clone_with_properties.phpt b/Zend/tests/generators/clone_with_properties.phpt
deleted file mode 100644 (file)
index 900253c..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
---TEST--
-Tests cloning a generator with properties
---FILE--
-<?php
-
-function gen() { yield; }
-
-$g1 = gen();
-$g1->prop = 'val';
-
-$g2 = clone $g1;
-unset($g1);
-
-var_dump($g2->prop);
-
-?>
---EXPECT--
-string(3) "val"
diff --git a/Zend/tests/generators/clone_with_stack.phpt b/Zend/tests/generators/clone_with_stack.phpt
deleted file mode 100644 (file)
index 5a8e6d8..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
---TEST--
-A generator with an active stack can be cloned
---FILE--
-<?php
-
-function gen() {
-    var_dump(str_repeat("x", yield));
-}
-
-$g1 = gen();
-$g1->rewind();
-$g2 = clone $g1;
-unset($g1);
-$g2->send(10);
-
-?>
---EXPECT--
-string(10) "xxxxxxxxxx"
diff --git a/Zend/tests/generators/clone_with_symbol_table.phpt b/Zend/tests/generators/clone_with_symbol_table.phpt
deleted file mode 100644 (file)
index e1fefeb..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
---TEST--
-A generator using a symbol table can be cloned
---FILE--
-<?php
-
-function gen() {
-    // force compiled variable for $foo
-    $foo = 'foo';
-
-    // force symbol table
-    extract(['foo' => 'bar']);
-
-    // interrupt
-    yield;
-
-    var_dump($foo);
-}
-
-$g1 = gen();
-$g1->rewind();
-$g2 = clone $g1;
-unset($g1);
-$g2->next();
-
-?>
---EXPECT--
-string(3) "bar"
diff --git a/Zend/tests/generators/clone_with_this.phpt b/Zend/tests/generators/clone_with_this.phpt
deleted file mode 100644 (file)
index b242d85..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
---TEST--
-Cloning a generator method (with $this)
---FILE--
-<?php
-
-class Test {
-    protected $foo;
-
-    public function gen() {
-        $this->foo = 'bar';
-        yield; // interrupt
-        var_dump($this->foo);
-    }
-}
-
-$g1 = (new Test)->gen();
-$g1->rewind(); // goto yield
-$g2 = clone $g1;
-unset($g1);
-$g2->next();
-
-?>
---EXPECT--
-string(3) "bar"
index 98aee2e60b09d90b4cb430ecdb67905f523fbdaa..0d640b31c6b892e7fa1194c6fe60b7de23eb8888 100644 (file)
@@ -26,10 +26,7 @@ $g2 = gen(new B);
 $g2->current();
 
 $g1->next();
-
-$g3 = clone $g2;
-unset($g2);
-$g3->next();
+$g2->next();
 
 ?>
 --EXPECT--
index 5fbe84fff559b6cec573e3a45d464dbc1c954324..3a9914d58b7547037af189187f1e9717ce8e80b9 100644 (file)
@@ -22,14 +22,6 @@ $gen = gen();
 $gen->rewind();
 unset($gen);
 
-// test cloning
-$g1 = gen();
-$g1->rewind();
-$g2 = clone $g1;
-unset($g1);
-$g2->send('bar');
-
 ?>
 --EXPECT--
 foo
-bar
index 3f43552f1f08e63df8611faa5574d435b8e9e6a8..d189148f47fcddfeb6d2919b1fed7da27d71dbfa 100644 (file)
@@ -196,175 +196,6 @@ static void zend_generator_free_storage(zend_generator *generator TSRMLS_DC) /*
 }
 /* }}} */
 
-static zend_object_value zend_generator_clone(zval *object TSRMLS_DC) /* {{{ */
-{
-       zend_generator *orig = zend_object_store_get_object(object TSRMLS_CC);
-       zend_object_value clone_val = zend_generator_create(Z_OBJCE_P(object) TSRMLS_CC);
-       zend_generator *clone = zend_object_store_get_object_by_handle(clone_val.handle TSRMLS_CC);
-
-       zend_objects_clone_members(
-               &clone->std, clone_val, &orig->std, Z_OBJ_HANDLE_P(object) TSRMLS_CC
-       );
-
-       clone->execute_data = orig->execute_data;
-       clone->largest_used_integer_key = orig->largest_used_integer_key;
-       clone->flags = orig->flags;
-
-       if (orig->execute_data) {
-               /* Create a few shorter aliases to the old execution data */
-               zend_execute_data *execute_data = orig->execute_data;
-               zend_op_array *op_array = execute_data->op_array;
-               HashTable *symbol_table = execute_data->symbol_table;
-               zend_execute_data *current_execute_data;
-               zend_op **opline_ptr;
-               HashTable *current_symbol_table;
-               zend_vm_stack current_stack;
-               zval *current_this;
-               void **stack_frame, **orig_stack_frame;
-
-               /* Create new execution context. We have to back up and restore
-                * EG(current_execute_data), EG(opline_ptr), EG(active_symbol_table)
-                * and EG(This) here because the function modifies or uses them  */
-               current_execute_data = EG(current_execute_data);
-               EG(current_execute_data) = execute_data->prev_execute_data;
-               opline_ptr = EG(opline_ptr);
-               current_symbol_table = EG(active_symbol_table);
-               EG(active_symbol_table) = execute_data->symbol_table;
-               current_this = EG(This);
-               EG(This) = NULL;
-               current_stack = EG(argument_stack);
-               clone->execute_data = zend_create_execute_data_from_op_array(op_array, 0 TSRMLS_CC);
-               clone->stack = EG(argument_stack);
-               EG(argument_stack) = current_stack;
-               EG(This) = current_this;
-               EG(active_symbol_table) = current_symbol_table;
-               EG(current_execute_data) = current_execute_data;
-               EG(opline_ptr) = opline_ptr;
-
-               /* copy */
-               clone->execute_data->opline = execute_data->opline;
-               clone->execute_data->function_state = execute_data->function_state;
-               clone->execute_data->object = execute_data->object;
-               clone->execute_data->current_scope = execute_data->current_scope;
-               clone->execute_data->current_called_scope = execute_data->current_called_scope;
-               clone->execute_data->fast_ret = execute_data->fast_ret;
-               
-               if (!symbol_table) {
-                       int i;
-
-                       /* Copy compiled variables */
-                       for (i = 0; i < op_array->last_var; i++) {
-                               if (*EX_CV_NUM(execute_data, i)) {
-                                       *EX_CV_NUM(clone->execute_data, i) = (zval **) EX_CV_NUM(clone->execute_data, op_array->last_var + i);
-                                       **EX_CV_NUM(clone->execute_data, i) = *(zval **) EX_CV_NUM(execute_data, op_array->last_var + i);
-                                       Z_ADDREF_PP(*EX_CV_NUM(clone->execute_data, i));
-                               }
-                       }
-               } else {
-                       /* Copy symbol table */
-                       ALLOC_HASHTABLE(clone->execute_data->symbol_table);
-                       zend_hash_init(clone->execute_data->symbol_table, zend_hash_num_elements(symbol_table), NULL, ZVAL_PTR_DTOR, 0);
-                       zend_hash_copy(clone->execute_data->symbol_table, symbol_table, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-
-                       /* Update zval** pointers for compiled variables */
-                       {
-                               int i;
-                               for (i = 0; i < op_array->last_var; i++) {
-                                       if (zend_hash_quick_find(clone->execute_data->symbol_table, op_array->vars[i].name, op_array->vars[i].name_len + 1, op_array->vars[i].hash_value, (void **) EX_CV_NUM(clone->execute_data, i)) == FAILURE) {
-                                               *EX_CV_NUM(clone->execute_data, i) = NULL;
-                                       }
-                               }
-                       }
-               }
-
-               /* Copy nested-calls stack */
-               if (execute_data->call) {
-                       clone->execute_data->call = clone->execute_data->call_slots +
-                               (execute_data->call - execute_data->call_slots);
-               } else {
-                       clone->execute_data->call = NULL;
-               }
-               memcpy(clone->execute_data->call_slots, execute_data->call_slots, ZEND_MM_ALIGNED_SIZE(sizeof(call_slot)) * op_array->nested_calls);
-               if (clone->execute_data->call >= clone->execute_data->call_slots) {
-                       call_slot *call = clone->execute_data->call;
-  
-                       while (call >= clone->execute_data->call_slots) {
-                               if (call->object) {
-                                       Z_ADDREF_P(call->object);
-                               }
-                               call--;
-                       }
-               }
-
-               /* Copy the temporary variables */
-               memcpy(EX_TMP_VAR_NUM(clone->execute_data, op_array->T-1), EX_TMP_VAR_NUM(execute_data, op_array->T-1), ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T);
-
-               /* Copy arguments passed on stack */
-               stack_frame = zend_vm_stack_frame_base(clone->execute_data);
-               orig_stack_frame = zend_vm_stack_frame_base(execute_data);
-               clone->stack->top = stack_frame + (orig->stack->top - orig_stack_frame);
-               if (clone->stack->top != stack_frame) {
-                       memcpy(stack_frame, orig_stack_frame, ZEND_MM_ALIGNED_SIZE(sizeof(zval*)) * (orig->stack->top - orig_stack_frame));
-                       while (clone->stack->top != stack_frame) {
-                               Z_ADDREF_PP((zval**)stack_frame);
-                               stack_frame++;
-                       }
-               }
-
-               /* Add references to loop variables */
-               {
-                       zend_uint op_num = execute_data->opline - op_array->opcodes;
-
-                       int i;
-                       for (i = 0; i < op_array->last_brk_cont; ++i) {
-                               zend_brk_cont_element *brk_cont = op_array->brk_cont_array + i;
-
-                               if (brk_cont->start < 0) {
-                                       continue;
-                               } else if (brk_cont->start > op_num) {
-                                       break;
-                               } else if (brk_cont->brk > op_num) {
-                                       zend_op *brk_opline = op_array->opcodes + brk_cont->brk;
-
-                                       if (brk_opline->opcode == ZEND_SWITCH_FREE) {
-                                               temp_variable *var = EX_TMP_VAR(execute_data, brk_opline->op1.var);
-
-                                               Z_ADDREF_P(var->var.ptr);
-                                       }
-                               }
-                       }
-               }
-
-               /* Update the send_target to use the temporary variable with the same
-                * offset as the original generator, but in our temporary variable
-                * memory segment. */
-               if (orig->send_target) {
-                       size_t offset = (char *) orig->send_target - (char *)execute_data;
-                       clone->send_target = EX_TMP_VAR(clone->execute_data, offset);
-                       zval_copy_ctor(&clone->send_target->tmp_var);
-               }
-
-               if (execute_data->current_this) {
-                       clone->execute_data->current_this = execute_data->current_this;
-                       Z_ADDREF_P(execute_data->current_this);
-               }
-       }
-
-       /* The value and key are known not to be references, so simply add refs */
-       if (orig->value) {
-               clone->value = orig->value;
-               Z_ADDREF_P(orig->value);
-       }
-
-       if (orig->key) {
-               clone->key = orig->key;
-               Z_ADDREF_P(orig->key);
-       }
-
-       return clone_val;
-}
-/* }}} */
-
 static zend_object_value zend_generator_create(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
 {
        zend_generator *generator;
@@ -867,7 +698,7 @@ void zend_register_generator_ce(TSRMLS_D) /* {{{ */
 
        memcpy(&zend_generator_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
        zend_generator_handlers.get_constructor = zend_generator_get_constructor;
-       zend_generator_handlers.clone_obj = zend_generator_clone;
+       zend_generator_handlers.clone_obj = NULL;
 }
 /* }}} */