Commit:    ae716939eb500f962336d37b96069cb7452c25df
Author:    Nikita Popov <ni...@php.net>         Mon, 13 Aug 2012 17:17:18 +0200
Parents:   f4ce3646285fbdd3354ca86ae67857b6ee8f7e3a
Branches:  master

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

Log:
Support trivial finally in generators (no yield, no return)

The finally clause is now properly run when an exception is thrown in the
try-block. It is not yet run on `return` and also not run when the generator
is claused within a try block.

I'll add those two things as soon as laruence refactored the finally code.

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


Diff:
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 83ae5c5..49ee314 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2513,6 +2513,18 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
        zend_bool nested;
        zend_op_array *op_array = EX(op_array);
 
+       /* Generators go throw a different cleanup process */
+       if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
+               /* 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)) {
@@ -5213,18 +5225,6 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
         ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
         ZEND_VM_CONTINUE();
     } else {
-               /* For generators skip the leave handler and return directly */
-               if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
-                       /* 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();
-               }
-
         ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
     }
 }
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 495b520..94c2a7c 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -496,6 +496,18 @@ static int ZEND_FASTCALL 
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
        zend_bool nested;
        zend_op_array *op_array = EX(op_array);
 
+       /* Generators go throw a different cleanup process */
+       if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
+               /* 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)) {
@@ -1177,18 +1189,6 @@ static int ZEND_FASTCALL  
ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
         ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
         ZEND_VM_CONTINUE();
     } else {
-               /* For generators skip the leave handler and return directly */
-               if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
-                       /* 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();
-               }
-
         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