mirror of
https://github.com/php/php-src.git
synced 2024-11-27 20:03:40 +08:00
Make the GOTO and SWITCH VMs work again
This commit is contained in:
parent
4aab08b64c
commit
b770b221e0
@ -5203,6 +5203,7 @@ ZEND_VM_HANDLER(159, ZEND_SUSPEND_AND_RETURN_GENERATOR, ANY, ANY)
|
|||||||
*EG(return_value_ptr_ptr) = return_value;
|
*EG(return_value_ptr_ptr) = return_value;
|
||||||
|
|
||||||
/* back up some executor globals */
|
/* back up some executor globals */
|
||||||
|
SAVE_OPLINE();
|
||||||
EX(current_this) = EG(This);
|
EX(current_this) = EG(This);
|
||||||
EX(current_scope) = EG(scope);
|
EX(current_scope) = EG(scope);
|
||||||
EX(current_called_scope) = EG(called_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);
|
zend_vm_stack_clear_multiple(TSRMLS_C);
|
||||||
|
|
||||||
|
LOAD_REGS();
|
||||||
|
LOAD_OPLINE();
|
||||||
ZEND_VM_INC_OPCODE();
|
ZEND_VM_INC_OPCODE();
|
||||||
ZEND_VM_LEAVE();
|
ZEND_VM_LEAVE();
|
||||||
}
|
}
|
||||||
@ -5293,6 +5296,10 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV, ANY)
|
|||||||
FREE_OP1_IF_VAR();
|
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();
|
ZEND_VM_RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)) {
|
if (op_array->this_var != -1 && EG(This)) {
|
||||||
Z_ADDREF_P(EG(This)); /* For $this pointer */
|
Z_ADDREF_P(EG(This)); /* For $this pointer */
|
||||||
if (!EG(active_symbol_table)) {
|
if (!EG(active_symbol_table)) {
|
||||||
EX_CV(op_array->this_var) = (zval**)EX_CVs() + (op_array->last_var + op_array->this_var);
|
EX(CVs)[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] = EG(This);
|
||||||
} else {
|
} 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));
|
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;
|
EG(in_execution) = 1;
|
||||||
|
|
||||||
zend_vm_enter:
|
|
||||||
LOAD_REGS();
|
LOAD_REGS();
|
||||||
LOAD_OPLINE();
|
LOAD_OPLINE();
|
||||||
|
|
||||||
@ -444,8 +443,10 @@ zend_vm_enter:
|
|||||||
return;
|
return;
|
||||||
case 2:
|
case 2:
|
||||||
execute_data = zend_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC);
|
execute_data = zend_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC);
|
||||||
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
execute_data = EG(current_execute_data);
|
execute_data = EG(current_execute_data);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
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;
|
*EG(return_value_ptr_ptr) = return_value;
|
||||||
|
|
||||||
/* back up some executor globals */
|
/* back up some executor globals */
|
||||||
|
SAVE_OPLINE();
|
||||||
EX(current_this) = EG(This);
|
EX(current_this) = EG(This);
|
||||||
EX(current_scope) = EG(scope);
|
EX(current_scope) = EG(scope);
|
||||||
EX(current_called_scope) = EG(called_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);
|
zend_vm_stack_clear_multiple(TSRMLS_C);
|
||||||
|
|
||||||
|
LOAD_REGS();
|
||||||
|
LOAD_OPLINE();
|
||||||
ZEND_VM_INC_OPCODE();
|
ZEND_VM_INC_OPCODE();
|
||||||
ZEND_VM_LEAVE();
|
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();
|
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();
|
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);};
|
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();
|
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();
|
ZEND_VM_RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)) {
|
if (op_array->this_var != -1 && EG(This)) {
|
||||||
Z_ADDREF_P(EG(This)); /* For $this pointer */
|
Z_ADDREF_P(EG(This)); /* For $this pointer */
|
||||||
if (!EG(active_symbol_table)) {
|
if (!EG(active_symbol_table)) {
|
||||||
EX_CV(op_array->this_var) = (zval**)EX_CVs() + (op_array->last_var + op_array->this_var);
|
EX(CVs)[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] = EG(This);
|
||||||
} else {
|
} 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));
|
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;
|
EG(in_execution) = 1;
|
||||||
|
|
||||||
zend_vm_enter:
|
|
||||||
LOAD_REGS();
|
LOAD_REGS();
|
||||||
LOAD_OPLINE();
|
LOAD_OPLINE();
|
||||||
|
|
||||||
|
@ -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 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_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_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_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_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");
|
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 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_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_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_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_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");
|
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
|
// Emit array of labels of opcode handlers and code for
|
||||||
// zend_opcode_handlers initialization
|
// zend_opcode_handlers initialization
|
||||||
$prolog = $m[1];
|
$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");
|
out($f,$prolog."\tstatic const opcode_handler_t labels[] = {\n");
|
||||||
gen_labels($f, $spec, $kind, $prolog."\t\t");
|
gen_labels($f, $spec, $kind, $prolog."\t\t");
|
||||||
out($f,$prolog."\t};\n");
|
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]."\t\treturn;\n".
|
||||||
$m[1]."\tcase 2:\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\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]."\tcase 3:\n" .
|
||||||
$m[1]."\t\texecute_data = EG(current_execute_data);\n".
|
$m[1]."\t\texecute_data = EG(current_execute_data);\n".
|
||||||
|
$m[1]."\t\tbreak;\n" .
|
||||||
$m[1]."\tdefault:\n".
|
$m[1]."\tdefault:\n".
|
||||||
$m[1]."\t\tbreak;\n".
|
$m[1]."\t\tbreak;\n".
|
||||||
$m[1]."}".$m[3]."\n");
|
$m[1]."}".$m[3]."\n");
|
||||||
@ -1005,9 +1007,9 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
|
|||||||
$prolog = $m[1];
|
$prolog = $m[1];
|
||||||
if ($kind == ZEND_VM_KIND_GOTO) {
|
if ($kind == ZEND_VM_KIND_GOTO) {
|
||||||
// Labels are defined in the executor itself, so we call it
|
// 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."TSRMLS_FETCH();\n");
|
||||||
out($f,$prolog."zend_execute(NULL TSRMLS_CC);\n");
|
out($f,$prolog.$executor_name."_ex(NULL TSRMLS_CC);\n");
|
||||||
} else {
|
} else {
|
||||||
if ($old) {
|
if ($old) {
|
||||||
// Reserving space for user-defined opcodes
|
// Reserving space for user-defined opcodes
|
||||||
|
Loading…
Reference in New Issue
Block a user