diff options
| -rw-r--r-- | Zend/tests/generators/generator_returns_generator.phpt | 16 | ||||
| -rw-r--r-- | Zend/zend_execute.c | 1 | ||||
| -rw-r--r-- | Zend/zend_vm_def.h | 12 | ||||
| -rw-r--r-- | Zend/zend_vm_execute.h | 12 |
4 files changed, 37 insertions, 4 deletions
diff --git a/Zend/tests/generators/generator_returns_generator.phpt b/Zend/tests/generators/generator_returns_generator.phpt new file mode 100644 index 0000000000..a3e2b29468 --- /dev/null +++ b/Zend/tests/generators/generator_returns_generator.phpt @@ -0,0 +1,16 @@ +--TEST-- +A generator function returns a Generator object +--FILE-- +<?php + +function* foo() { + // execution is suspended here, so the following never gets run: + echo "Foo"; +} + +$generator = foo(); +var_dump($generator instanceof Generator); + +?> +--EXPECT-- +bool(true) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index d72fc7369a..d82abfc613 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -35,6 +35,7 @@ #include "zend_exceptions.h" #include "zend_interfaces.h" #include "zend_closures.h" +#include "zend_generators.h" #include "zend_vm.h" #include "zend_dtrace.h" diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 9dc7e0842c..13ae824c48 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -5197,9 +5197,17 @@ ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED) ZEND_VM_HANDLER(159, ZEND_SUSPEND_AND_RETURN_GENERATOR, ANY, ANY) { - /* do nothing for now */ + if (EG(return_value_ptr_ptr)) { + zval *return_value; - ZEND_VM_NEXT_OPCODE(); + ALLOC_INIT_ZVAL(return_value); + object_init_ex(return_value, zend_ce_generator); + + *EG(return_value_ptr_ptr) = return_value; + } + + /* for now we just do a normal return without suspension */ + ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); } ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper) diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index c6c3af65db..12338117f5 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1154,9 +1154,17 @@ static int ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS static int ZEND_FASTCALL ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - /* do nothing for now */ + if (EG(return_value_ptr_ptr)) { + zval *return_value; - ZEND_VM_NEXT_OPCODE(); + ALLOC_INIT_ZVAL(return_value); + object_init_ex(return_value, zend_ce_generator); + + *EG(return_value_ptr_ptr) = return_value; + } + + /* for now we just do a normal return without suspension */ + return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) |
