Commit:    b770b221e0b3036708deb9e22dacf296402787f0
Author:    Nikita Popov <ni...@php.net>         Tue, 29 May 2012 02:31:56 +0200
Parents:   4aab08b64c2318775be6d8e629747ac66a108485
Branches:  master

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

Log:
Make the GOTO and SWITCH VMs work again

Changed paths:
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h
  M  Zend/zend_vm_execute.skl
  M  Zend/zend_vm_gen.php

diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 04b6595..47d5ec4 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -5203,6 +5203,7 @@ ZEND_VM_HANDLER(159, ZEND_SUSPEND_AND_RETURN_GENERATOR, 
ANY, ANY)
                *EG(return_value_ptr_ptr) = return_value;
 
                /* back up some executor globals */
+               SAVE_OPLINE();
                EX(current_this) = EG(This);
                EX(current_scope) = EG(scope);
                EX(current_called_scope) = EG(called_scope);
@@ -5248,6 +5249,8 @@ ZEND_VM_HANDLER(159, ZEND_SUSPEND_AND_RETURN_GENERATOR, 
ANY, ANY)
 
                zend_vm_stack_clear_multiple(TSRMLS_C);
 
+               LOAD_REGS();
+               LOAD_OPLINE();
                ZEND_VM_INC_OPCODE();
                ZEND_VM_LEAVE();
        }
@@ -5293,6 +5296,10 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV, ANY)
                FREE_OP1_IF_VAR();
        }
 
+       /* The GOTO VM uses a local opline variable. We need to set the opline
+        * variable in execute_data so we don't resume at an old position. */
+       SAVE_OPLINE();
+
        ZEND_VM_RETURN();
 }
 
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index c195148..bd22768 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -393,10 +393,10 @@ static zend_execute_data 
*zend_create_execute_data_from_op_array(zend_op_array *
        if (op_array->this_var != -1 && EG(This)) {
                Z_ADDREF_P(EG(This)); /* For $this pointer */
                if (!EG(active_symbol_table)) {
-                       EX_CV(op_array->this_var) = (zval**)EX_CVs() + 
(op_array->last_var + op_array->this_var);
-                       *EX_CV(op_array->this_var) = EG(This);
+                       EX(CVs)[op_array->this_var] = (zval **) EX(CVs) + 
op_array->last_var + op_array->this_var;
+                       *EX(CVs)[op_array->this_var] = EG(This);
                } else {
-                       if (zend_hash_add(EG(active_symbol_table), "this", 
sizeof("this"), &EG(This), sizeof(zval *), 
(void**)&EX_CV(op_array->this_var))==FAILURE) {
+                       if (zend_hash_add(EG(active_symbol_table), "this", 
sizeof("this"), &EG(This), sizeof(zval *), (void **) 
&EX(CVs)[op_array->this_var])==FAILURE) {
                                Z_DELREF_P(EG(This));
                        }
                }
@@ -425,7 +425,6 @@ ZEND_API void execute_ex(zend_execute_data *execute_data 
TSRMLS_DC)
 
        EG(in_execution) = 1;
 
-zend_vm_enter:
        LOAD_REGS();
        LOAD_OPLINE();
 
@@ -444,8 +443,10 @@ zend_vm_enter:
                                        return;
                                case 2:
                                        execute_data = 
zend_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC);
+                                       break;
                                case 3:
                                        execute_data = EG(current_execute_data);
+                                       break;
                                default:
                                        break;
                        }
@@ -1185,6 +1186,7 @@ static int ZEND_FASTCALL  
ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER(ZEND_OP
                *EG(return_value_ptr_ptr) = return_value;
 
                /* back up some executor globals */
+               SAVE_OPLINE();
                EX(current_this) = EG(This);
                EX(current_scope) = EG(scope);
                EX(current_called_scope) = EG(called_scope);
@@ -1230,6 +1232,8 @@ static int ZEND_FASTCALL  
ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER(ZEND_OP
 
                zend_vm_stack_clear_multiple(TSRMLS_C);
 
+               LOAD_REGS();
+               LOAD_OPLINE();
                ZEND_VM_INC_OPCODE();
                ZEND_VM_LEAVE();
        }
@@ -3067,6 +3071,10 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
 
        }
 
+       /* The GOTO VM uses a local opline variable. We need to set the opline
+        * variable in execute_data so we don't resume at an old position. */
+       SAVE_OPLINE();
+
        ZEND_VM_RETURN();
 }
 
@@ -7704,6 +7712,10 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        }
 
+       /* The GOTO VM uses a local opline variable. We need to set the opline
+        * variable in execute_data so we don't resume at an old position. */
+       SAVE_OPLINE();
+
        ZEND_VM_RETURN();
 }
 
@@ -12419,6 +12431,10 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        }
 
+       /* The GOTO VM uses a local opline variable. We need to set the opline
+        * variable in execute_data so we don't resume at an old position. */
+       SAVE_OPLINE();
+
        ZEND_VM_RETURN();
 }
 
@@ -28304,6 +28320,10 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        }
 
+       /* The GOTO VM uses a local opline variable. We need to set the opline
+        * variable in execute_data so we don't resume at an old position. */
+       SAVE_OPLINE();
+
        ZEND_VM_RETURN();
 }
 
diff --git a/Zend/zend_vm_execute.skl b/Zend/zend_vm_execute.skl
index d251e55..e77c7cb 100644
--- a/Zend/zend_vm_execute.skl
+++ b/Zend/zend_vm_execute.skl
@@ -54,10 +54,10 @@ static zend_execute_data 
*zend_create_execute_data_from_op_array(zend_op_array *
        if (op_array->this_var != -1 && EG(This)) {
                Z_ADDREF_P(EG(This)); /* For $this pointer */
                if (!EG(active_symbol_table)) {
-                       EX_CV(op_array->this_var) = (zval**)EX_CVs() + 
(op_array->last_var + op_array->this_var);
-                       *EX_CV(op_array->this_var) = EG(This);
+                       EX(CVs)[op_array->this_var] = (zval **) EX(CVs) + 
op_array->last_var + op_array->this_var;
+                       *EX(CVs)[op_array->this_var] = EG(This);
                } else {
-                       if (zend_hash_add(EG(active_symbol_table), "this", 
sizeof("this"), &EG(This), sizeof(zval *), 
(void**)&EX_CV(op_array->this_var))==FAILURE) {
+                       if (zend_hash_add(EG(active_symbol_table), "this", 
sizeof("this"), &EG(This), sizeof(zval *), (void **) 
&EX(CVs)[op_array->this_var])==FAILURE) {
                                Z_DELREF_P(EG(This));
                        }
                }
@@ -88,7 +88,6 @@ ZEND_API void {%EXECUTOR_NAME%}_ex(zend_execute_data 
*execute_data TSRMLS_DC)
 
        EG(in_execution) = 1;
 
-zend_vm_enter:
        LOAD_REGS();
        LOAD_OPLINE();
 
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index b7fd874..ee2b0b2 100644
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -856,7 +856,7 @@ function gen_executor($f, $skl, $spec, $kind, 
$executor_name, $initializer_name,
                                                        out($f,"#define 
LOAD_REGS()                do {Ts = EX(Ts); CVs = EX(CVs);} while (0)\n");
                                                        out($f,"#define 
ZEND_VM_CONTINUE() goto zend_vm_continue\n");
                                                        out($f,"#define 
ZEND_VM_RETURN()   EG(in_execution) = original_in_execution; return\n");
-                                                       out($f,"#define 
ZEND_VM_ENTER()    op_array = EG(active_op_array); goto zend_vm_enter\n");
+                                                       out($f,"#define 
ZEND_VM_ENTER()    execute_data = 
zend_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC); 
LOAD_REGS(); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
                                                        out($f,"#define 
ZEND_VM_LEAVE()    ZEND_VM_CONTINUE()\n");
                                                        out($f,"#define 
ZEND_VM_DISPATCH(opcode, opline) dispatch_handler = 
zend_vm_get_opcode_handler(opcode, opline); goto zend_vm_dispatch;\n\n");
                                                        out($f,"#define 
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC\n");
@@ -892,7 +892,7 @@ function gen_executor($f, $skl, $spec, $kind, 
$executor_name, $initializer_name,
                                                        out($f,"#define 
LOAD_REGS()                do {Ts = EX(Ts); CVs = EX(CVs);} while (0)\n");
                                                        out($f,"#define 
ZEND_VM_CONTINUE() goto *(void**)(OPLINE->handler)\n");
                                                        out($f,"#define 
ZEND_VM_RETURN()   EG(in_execution) = original_in_execution; return\n");
-                                                       out($f,"#define 
ZEND_VM_ENTER()    op_array = EG(active_op_array); goto zend_vm_enter\n");
+                                                       out($f,"#define 
ZEND_VM_ENTER()    execute_data = 
zend_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC); 
LOAD_REGS(); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
                                                        out($f,"#define 
ZEND_VM_LEAVE()    ZEND_VM_CONTINUE()\n");
                                                        out($f,"#define 
ZEND_VM_DISPATCH(opcode, opline) goto 
*(void**)(zend_vm_get_opcode_handler(opcode, opline));\n\n");
                                                        out($f,"#define 
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC\n");
@@ -932,7 +932,7 @@ function gen_executor($f, $skl, $spec, $kind, 
$executor_name, $initializer_name,
                                          // Emit array of labels of opcode 
handlers and code for
                                          // zend_opcode_handlers initialization
                                                $prolog = $m[1];
-                                               out($f,$prolog."if (op_array == 
NULL) {\n");
+                                               out($f,$prolog."if 
(execute_data == NULL) {\n");
                                                out($f,$prolog."\tstatic const 
opcode_handler_t labels[] = {\n");
                                                gen_labels($f, $spec, $kind, 
$prolog."\t\t");
                                                out($f,$prolog."\t};\n");
@@ -977,8 +977,10 @@ function gen_executor($f, $skl, $spec, $kind, 
$executor_name, $initializer_name,
                                                        $m[1]."\t\treturn;\n".
                                                        $m[1]."\tcase 2:\n" . 
                                                        $m[1]."\t\texecute_data 
= zend_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC);\n".
+                                                       $m[1]."\t\tbreak;\n" .
                                                        $m[1]."\tcase 3:\n" . 
                                                        $m[1]."\t\texecute_data 
= EG(current_execute_data);\n".
+                                                       $m[1]."\t\tbreak;\n" .
                                                        $m[1]."\tdefault:\n".
                                                        $m[1]."\t\tbreak;\n".
                                                        $m[1]."}".$m[3]."\n");
@@ -1005,9 +1007,9 @@ function gen_executor($f, $skl, $spec, $kind, 
$executor_name, $initializer_name,
                                        $prolog = $m[1];
                                        if ($kind == ZEND_VM_KIND_GOTO) {
                                          // Labels are defined in the executor 
itself, so we call it
-                                         // with op_array NULL and it sets 
zend_opcode_handlers array
+                                         // with execute_data NULL and it sets 
zend_opcode_handlers array
                                                
out($f,$prolog."TSRMLS_FETCH();\n");
-                                               
out($f,$prolog."zend_execute(NULL TSRMLS_CC);\n");
+                                               
out($f,$prolog.$executor_name."_ex(NULL TSRMLS_CC);\n");
                                        } else {
                                                if ($old) {
                                                  // Reserving space for 
user-defined opcodes
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to