]> granicus.if.org Git - php/commitdiff
Support trivial finally in generators (no yield, no return)
authorNikita Popov <nikic@php.net>
Mon, 13 Aug 2012 15:17:18 +0000 (17:17 +0200)
committerNikita Popov <nikic@php.net>
Mon, 13 Aug 2012 15:22:21 +0000 (17:22 +0200)
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.

Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 83ae5c5ba43f90424574bc92a47fd7f6d8e49eb7..49ee3148e3d039b7d542d1e520e92e1744dd7d4e 100644 (file)
@@ -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);
     }
 }
index 495b520ecb22f33f88b8a8850da7bc2755062ee8..94c2a7cf166b43c7825f9f69e2c58852f86d4bd2 100644 (file)
@@ -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);
     }
 }