Commit:    a9a5f7aca61d4bec9ce2cf5dc967bb7c0ed651cd
Author:    Dmitry Stogov <dmi...@zend.com>         Tue, 11 Dec 2012 17:25:32 
+0400
Parents:   8bb106d20c8f36d814772c45d693af2b42b06732
Branches:  PHP-5.5 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=a9a5f7aca61d4bec9ce2cf5dc967bb7c0ed651cd

Log:
- generators API exported for extensions
- improved RETURN sequence to avoid redundant check if op_array is a generator

Changed paths:
  M  Zend/zend_generators.c
  M  Zend/zend_generators.h
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h

diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index dc7ae14..1844be8 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -27,7 +27,7 @@
 ZEND_API zend_class_entry *zend_ce_generator;
 static zend_object_handlers zend_generator_handlers;
 
-void zend_generator_close(zend_generator *generator, zend_bool 
finished_execution TSRMLS_DC) /* {{{ */
+ZEND_API void zend_generator_close(zend_generator *generator, zend_bool 
finished_execution TSRMLS_DC) /* {{{ */
 {
        if (generator->execute_data) {
                zend_execute_data *execute_data = generator->execute_data;
@@ -338,7 +338,7 @@ static zend_object_value 
zend_generator_create(zend_class_entry *class_type TSRM
 
 /* Requires globals EG(scope), EG(current_scope), EG(This),
  * EG(active_symbol_table) and EG(current_execute_data). */
-zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC) /* {{{ */
+ZEND_API zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC) 
/* {{{ */
 {
        zval *return_value;
        zend_generator *generator;
@@ -399,7 +399,7 @@ static zend_function *zend_generator_get_constructor(zval 
*object TSRMLS_DC) /*
 }
 /* }}} */
 
-void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{ */
+ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* 
{{{ */
 {
        if (EG(exception)) {
                return;
diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h
index 90f8160..7e6da13 100644
--- a/Zend/zend_generators.h
+++ b/Zend/zend_generators.h
@@ -62,9 +62,9 @@ static const zend_uchar ZEND_GENERATOR_FORCED_CLOSE      = 
0x2;
 static const zend_uchar ZEND_GENERATOR_AT_FIRST_YIELD    = 0x4;
 
 void zend_register_generator_ce(TSRMLS_D);
-zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC);
-void zend_generator_close(zend_generator *generator, zend_bool 
finished_execution TSRMLS_DC);
-void zend_generator_resume(zend_generator *generator TSRMLS_DC);
+ZEND_API zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC);
+ZEND_API void zend_generator_close(zend_generator *generator, zend_bool 
finished_execution TSRMLS_DC);
+ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC);
 
 #endif
 
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index edbffe1..c5d1748 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -1850,18 +1850,6 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
                /* return from finally block called because of unhandled 
exception */
                zend_exception_restore(TSRMLS_C);               
        }
-       
-       /* Generators go throw a different cleanup process */
-       if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
-               /* The generator object is stored in return_value_ptr_ptr */
-               zend_generator *generator = (zend_generator *) 
EG(return_value_ptr_ptr);
-
-               /* Close the generator to free up resources */
-               zend_generator_close(generator, 1 TSRMLS_CC);
-
-               /* Pass execution back to handling code */
-               ZEND_VM_RETURN();
-       }
 
        EG(current_execute_data) = EX(prev_execute_data);
        EG(opline_ptr) = NULL;
@@ -2969,7 +2957,20 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, 
CONST|TMP|VAR|CV, ANY)
 
 ZEND_VM_HANDLER(161, ZEND_GENERATOR_RETURN, ANY, ANY)
 {
-       ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+       /* The generator object is stored in return_value_ptr_ptr */
+       zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+       if (EXPECTED(EG(exception) == NULL) &&
+           UNEXPECTED(EG(prev_exception) != NULL)) {
+               /* return from finally block called because of unhandled 
exception */
+               zend_exception_restore(TSRMLS_C);               
+       }
+
+       /* Close the generator to free up resources */
+       zend_generator_close(generator, 1 TSRMLS_CC);
+
+       /* Pass execution back to handling code */
+       ZEND_VM_RETURN();
 }
 
 ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
@@ -5124,7 +5125,11 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
                ZEND_VM_CONTINUE();
        } else {
-               ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+               if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 
0)) {
+                       ZEND_VM_DISPATCH_TO_HANDLER(ZEND_GENERATOR_RETURN);
+               } else {
+                       ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+               }
        }
 }
 
@@ -5151,7 +5156,11 @@ ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY)
                case ZEND_USER_OPCODE_CONTINUE:
                        ZEND_VM_CONTINUE();
                case ZEND_USER_OPCODE_RETURN:
-                       ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+                       if (UNEXPECTED((EX(op_array)->fn_flags & 
ZEND_ACC_GENERATOR) != 0)) {
+                               
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_GENERATOR_RETURN);
+                       } else {
+                               ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+                       }
                case ZEND_USER_OPCODE_ENTER:
                        ZEND_VM_ENTER();
                case ZEND_USER_OPCODE_LEAVE:
@@ -5444,6 +5453,9 @@ ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, ANY)
                        zend_exception_restore(TSRMLS_C);
                        
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
                        ZEND_VM_CONTINUE();
+               } else if (UNEXPECTED((EX(op_array)->fn_flags & 
ZEND_ACC_GENERATOR) != 0)) {
+                       zend_exception_restore(TSRMLS_C);
+                       ZEND_VM_DISPATCH_TO_HANDLER(ZEND_GENERATOR_RETURN);
                } else {
                        zend_exception_restore(TSRMLS_C);
                        ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 80967bd..7c11016 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -392,18 +392,6 @@ static int ZEND_FASTCALL 
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
                zend_exception_restore(TSRMLS_C);
        }
 
-       /* Generators go throw a different cleanup process */
-       if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
-               /* The generator object is stored in return_value_ptr_ptr */
-               zend_generator *generator = (zend_generator *) 
EG(return_value_ptr_ptr);
-
-               /* Close the generator to free up resources */
-               zend_generator_close(generator, 1 TSRMLS_CC);
-
-               /* Pass execution back to handling code */
-               ZEND_VM_RETURN();
-       }
-
        EG(current_execute_data) = EX(prev_execute_data);
        EG(opline_ptr) = NULL;
        if (!EG(active_symbol_table)) {
@@ -705,7 +693,20 @@ static int ZEND_FASTCALL  
ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER
 
 static int ZEND_FASTCALL  
ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-       return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+       /* The generator object is stored in return_value_ptr_ptr */
+       zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+       if (EXPECTED(EG(exception) == NULL) &&
+           UNEXPECTED(EG(prev_exception) != NULL)) {
+               /* return from finally block called because of unhandled 
exception */
+               zend_exception_restore(TSRMLS_C);
+       }
+
+       /* Close the generator to free up resources */
+       zend_generator_close(generator, 1 TSRMLS_CC);
+
+       /* Pass execution back to handling code */
+       ZEND_VM_RETURN();
 }
 
 static int ZEND_FASTCALL  ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -1086,7 +1087,11 @@ static int ZEND_FASTCALL  
ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
                ZEND_VM_CONTINUE();
        } else {
-               return 
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+               if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 
0)) {
+                       return 
ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+               } else {
+                       return 
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+               }
        }
 }
 
@@ -1113,7 +1118,11 @@ static int ZEND_FASTCALL  
ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS
                case ZEND_USER_OPCODE_CONTINUE:
                        ZEND_VM_CONTINUE();
                case ZEND_USER_OPCODE_RETURN:
-                       return 
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+                       if (UNEXPECTED((EX(op_array)->fn_flags & 
ZEND_ACC_GENERATOR) != 0)) {
+                               return 
ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+                       } else {
+                               return 
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+                       }
                case ZEND_USER_OPCODE_ENTER:
                        ZEND_VM_ENTER();
                case ZEND_USER_OPCODE_LEAVE:
@@ -1169,6 +1178,9 @@ static int ZEND_FASTCALL  
ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        zend_exception_restore(TSRMLS_C);
                        
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
                        ZEND_VM_CONTINUE();
+               } else if (UNEXPECTED((EX(op_array)->fn_flags & 
ZEND_ACC_GENERATOR) != 0)) {
+                       zend_exception_restore(TSRMLS_C);
+                       return 
ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
                } else {
                        zend_exception_restore(TSRMLS_C);
                        return 
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to