]> granicus.if.org Git - php/commitdiff
Check if generator object is created by GENERATOR_CREATE when throw exceptions from...
authorDmitry Stogov <dmitry@zend.com>
Mon, 16 May 2016 09:42:13 +0000 (12:42 +0300)
committerDmitry Stogov <dmitry@zend.com>
Mon, 16 May 2016 09:42:13 +0000 (12:42 +0300)
Zend/tests/generators/generator_with_type_check.phpt [new file with mode: 0644]
Zend/tests/generators/generator_with_type_check_2.phpt [new file with mode: 0644]
Zend/zend_compile.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/Zend/tests/generators/generator_with_type_check.phpt b/Zend/tests/generators/generator_with_type_check.phpt
new file mode 100644 (file)
index 0000000..2aa1653
--- /dev/null
@@ -0,0 +1,13 @@
+--TEST--
+Generator wit type check
+--FILE--
+<?php
+function gen(array $a) { yield; }
+gen(42);
+?>
+--EXPECTF--
+Fatal error: Uncaught TypeError: Argument 1 passed to gen() must be of the type array, integer given, called in %sgenerator_with_type_check.php on line 3 and defined in %sgenerator_with_type_check.php:2
+Stack trace:
+#0 %sgenerator_with_type_check.php(3): gen(42)
+#1 {main}
+  thrown in %sgenerator_with_type_check.php on line 2
diff --git a/Zend/tests/generators/generator_with_type_check_2.phpt b/Zend/tests/generators/generator_with_type_check_2.phpt
new file mode 100644 (file)
index 0000000..d8ea4fb
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+Generator wit type check
+--FILE--
+<?php
+function gen(array $a) { yield; }
+try {
+       gen(42);
+} catch (TypeError $e) {
+       echo $e->getMessage()."\n";
+}
+
+try {
+       foreach (gen(42) as $val) {
+               var_dump($val);
+       }
+} catch (TypeError $e) {
+        echo $e->getMessage()."\n";
+}
+?>
+--EXPECTF--
+Argument 1 passed to gen() must be of the type array, integer given, called in %sgenerator_with_type_check_2.php on line 4
+Argument 1 passed to gen() must be of the type array, integer given, called in %sgenerator_with_type_check_2.php on line 10
index 61e537e64aa75200b3abe5c575ed19eb4acbbe29..344293273a23a52b9895ff9dbc9604bad9b824e5 100644 (file)
@@ -472,6 +472,7 @@ struct _zend_execute_data {
 #define ZEND_CALL_CLOSURE            (1 << 5)
 #define ZEND_CALL_RELEASE_THIS       (1 << 6)
 #define ZEND_CALL_ALLOCATED          (1 << 7)
+#define ZEND_CALL_GENERATOR          (1 << 8)
 
 #define ZEND_CALL_INFO_SHIFT         16
 
index 2750d8e60a4e853a2eec856007b64beb670ffcc8..bb430dccd524f87f7c323737b6ed03cfa3b81a86 100644 (file)
@@ -4028,7 +4028,7 @@ ZEND_VM_HANDLER(41, ZEND_GENERATOR_CREATE, ANY, ANY)
                        ZEND_ADD_CALL_FLAG_EX(call_info, ZEND_CALL_RELEASE_THIS);
                        Z_ADDREF(gen_execute_data->This);
                }
-               ZEND_ADD_CALL_FLAG_EX(call_info, (ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED));
+               ZEND_ADD_CALL_FLAG_EX(call_info, (ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED | ZEND_CALL_GENERATOR));
                Z_TYPE_INFO(gen_execute_data->This) = call_info;
                gen_execute_data->prev_execute_data = NULL;
 
@@ -7159,7 +7159,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
                if (catch_op_num) {
                        ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[catch_op_num]);
                        ZEND_VM_CONTINUE();
-               } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+               } else if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) {
                        zend_generator *generator = zend_get_running_generator(execute_data);
                        zend_generator_close(generator, 1);
                        ZEND_VM_RETURN();
@@ -7191,7 +7191,7 @@ ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY)
                case ZEND_USER_OPCODE_CONTINUE:
                        ZEND_VM_CONTINUE();
                case ZEND_USER_OPCODE_RETURN:
-                       if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+                       if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) {
                                zend_generator *generator = zend_get_running_generator(execute_data);
                                zend_generator_close(generator, 1);
                                ZEND_VM_RETURN();
@@ -7581,7 +7581,7 @@ ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, TRY_CATCH, FAST_RET)
                                ZEND_VM_CONTINUE();
                        } else {
                                cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, 0);
-                               if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+                               if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) {
                                        zend_generator *generator = zend_get_running_generator(execute_data);
                                        zend_generator_close(generator, 1);
                                        ZEND_VM_RETURN();
index 5b09255f30c0332636df2895fff5ba94083fd2e3..d729f83ac30309a8f76148fea8045dd1d5e1477b 100644 (file)
@@ -1190,7 +1190,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_CREATE_SPEC_HANDLER(
                        ZEND_ADD_CALL_FLAG_EX(call_info, ZEND_CALL_RELEASE_THIS);
                        Z_ADDREF(gen_execute_data->This);
                }
-               ZEND_ADD_CALL_FLAG_EX(call_info, (ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED));
+               ZEND_ADD_CALL_FLAG_EX(call_info, (ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED | ZEND_CALL_GENERATOR));
                Z_TYPE_INFO(gen_execute_data->This) = call_info;
                gen_execute_data->prev_execute_data = NULL;
 
@@ -1756,7 +1756,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(
                if (catch_op_num) {
                        ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[catch_op_num]);
                        ZEND_VM_CONTINUE();
-               } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+               } else if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) {
                        zend_generator *generator = zend_get_running_generator(execute_data);
                        zend_generator_close(generator, 1);
                        ZEND_VM_RETURN();
@@ -1788,7 +1788,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_
                case ZEND_USER_OPCODE_CONTINUE:
                        ZEND_VM_CONTINUE();
                case ZEND_USER_OPCODE_RETURN:
-                       if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+                       if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) {
                                zend_generator *generator = zend_get_running_generator(execute_data);
                                zend_generator_close(generator, 1);
                                ZEND_VM_RETURN();
@@ -1872,7 +1872,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPC
                                ZEND_VM_CONTINUE();
                        } else {
                                cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, 0);
-                               if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+                               if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) {
                                        zend_generator *generator = zend_get_running_generator(execute_data);
                                        zend_generator_close(generator, 1);
                                        ZEND_VM_RETURN();