summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/tests/generators/generator_returns_generator.phpt16
-rw-r--r--Zend/zend_execute.c1
-rw-r--r--Zend/zend_vm_def.h12
-rw-r--r--Zend/zend_vm_execute.h12
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)