Commit:    68c1e1cfe95b026086cacf40a005ea8f399e9595
Author:    Nikita Popov <ni...@php.net>         Fri, 24 Aug 2012 13:51:39 +0200
Parents:   6517ed021520a608a18da4653cb9c6b414121f6f
Branches:  master

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

Log:
Add dedicated opcode for returns from a generator

Generators don't have a return value, so it doesn't make sense to have
a shared implementation here.

Changed paths:
  M  Zend/zend_opcode.c
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h
  M  Zend/zend_vm_opcodes.h


Diff:
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index 0f39b8a..5c4b20f 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -586,9 +586,8 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
                                                CG(zend_lineno) = 
opline->lineno;
                                                zend_error(E_COMPILE_ERROR, 
"Generators cannot return values using \"return\"");
                                        }
-                                       if (opline->opcode == 
ZEND_RETURN_BY_REF) {
-                                               opline->opcode = ZEND_RETURN;
-                                       }
+
+                                       opline->opcode = ZEND_GENERATOR_RETURN;
                                }
                                break;
                }
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 975a2a7..216cd59 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2931,17 +2931,6 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
        zval *retval_ptr;
        zend_free_op free_op1;
 
-       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();
-       }
-
        SAVE_OPLINE();
        retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
 
@@ -3066,6 +3055,14 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, 
CONST|TMP|VAR|CV, ANY)
        ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
 }
 
+ZEND_VM_HANDLER(162, ZEND_GENERATOR_RETURN, ANY, ANY)
+{
+       if (EX(op_array)->has_finally_block) {
+               ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, 
type, ZEND_RETURN);
+       }
+       ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+}
+
 ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
 {
        USE_OPLINE
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 402442f..ebc0fb9 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -885,6 +885,14 @@ static int ZEND_FASTCALL  
ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER
        return 
zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  
ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       if (EX(op_array)->has_finally_block) {
+               return zend_finally_handler_leaving_SPEC(ZEND_RETURN, 
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+       }
+       return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+}
+
 static int ZEND_FASTCALL  ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -2443,17 +2451,6 @@ static int ZEND_FASTCALL  
ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
        zval *retval_ptr;
 
 
-       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();
-       }
-
        SAVE_OPLINE();
        retval_ptr = opline->op1.zv;
 
@@ -7760,17 +7757,6 @@ static int ZEND_FASTCALL  
ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval *retval_ptr;
        zend_free_op free_op1;
 
-       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();
-       }
-
        SAVE_OPLINE();
        retval_ptr = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 
TSRMLS_CC);
 
@@ -12982,17 +12968,6 @@ static int ZEND_FASTCALL  
ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval *retval_ptr;
        zend_free_op free_op1;
 
-       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();
-       }
-
        SAVE_OPLINE();
        retval_ptr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 
TSRMLS_CC);
 
@@ -30530,17 +30505,6 @@ static int ZEND_FASTCALL  
ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval *retval_ptr;
 
 
-       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();
-       }
-
        SAVE_OPLINE();
        retval_ptr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var 
TSRMLS_CC);
 
@@ -44986,6 +44950,31 @@ void zend_init_opcodes_handlers(void)
        ZEND_DELEGATE_YIELD_SPEC_CV_HANDLER,
        ZEND_DELEGATE_YIELD_SPEC_CV_HANDLER,
        ZEND_DELEGATE_YIELD_SPEC_CV_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+       ZEND_GENERATOR_RETURN_SPEC_HANDLER,
        ZEND_NULL_HANDLER
   };
   zend_opcode_handlers = (opcode_handler_t*)labels;
diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h
index 0a9cf00..0b4903a 100644
--- a/Zend/zend_vm_opcodes.h
+++ b/Zend/zend_vm_opcodes.h
@@ -162,3 +162,4 @@
 #define ZEND_LEAVE                           159
 #define ZEND_YIELD                           160
 #define ZEND_DELEGATE_YIELD                  161
+#define ZEND_GENERATOR_RETURN                162


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to