mirror of
https://github.com/php/php-src.git
synced 2024-12-01 05:43:38 +08:00
Fixed wrong GOTO resolution
This commit is contained in:
parent
b0f419540a
commit
74869fa673
29
Zend/tests/jump15.phpt
Normal file
29
Zend/tests/jump15.phpt
Normal file
@ -0,0 +1,29 @@
|
||||
--TEST--
|
||||
jump 15: goto from loop (forward)
|
||||
--FILE--
|
||||
<?php
|
||||
$ar = array("1","2","3");
|
||||
foreach ($ar as $val) {
|
||||
switch ($val) {
|
||||
case "1":
|
||||
echo "1: ok\n";
|
||||
break;
|
||||
case "2":
|
||||
echo "2: ok\n";
|
||||
goto L1;
|
||||
case "3":
|
||||
echo "bug\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
echo "bug\n";
|
||||
L1:
|
||||
try {
|
||||
echo "3: ok\n";
|
||||
} finally {
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
1: ok
|
||||
2: ok
|
||||
3: ok
|
@ -32,6 +32,7 @@
|
||||
#include "zend_multibyte.h"
|
||||
#include "zend_language_scanner.h"
|
||||
#include "zend_inheritance.h"
|
||||
#include "zend_vm.h"
|
||||
|
||||
#define SET_NODE(target, src) do { \
|
||||
target ## _type = (src)->op_type; \
|
||||
@ -3606,7 +3607,7 @@ void zend_resolve_goto_label(zend_op_array *op_array, znode *label_node, zend_op
|
||||
current = CG(context).current_brk_cont;
|
||||
while (current != -1) {
|
||||
if (CG(context).brk_cont_array[current].start >= 0) {
|
||||
zend_emit_op(NULL, ZEND_NOP, NULL, label_node);
|
||||
zend_emit_op(NULL, ZEND_NOP, NULL, NULL);
|
||||
}
|
||||
current = CG(context).brk_cont_array[current].parent;
|
||||
}
|
||||
@ -3658,13 +3659,24 @@ void zend_resolve_goto_label(zend_op_array *op_array, znode *label_node, zend_op
|
||||
if (brk_opline->opcode == ZEND_FREE) {
|
||||
(pass2_opline - free_vars)->opcode = ZEND_FREE;
|
||||
(pass2_opline - free_vars)->op1_type = brk_opline->op1_type;
|
||||
(pass2_opline - free_vars)->op1.var = brk_opline->op1.var;
|
||||
if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) {
|
||||
(pass2_opline - free_vars)->op1.var = brk_opline->op1.var;
|
||||
} else {
|
||||
(pass2_opline - free_vars)->op1.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + brk_opline->op1.var);
|
||||
ZEND_VM_SET_OPCODE_HANDLER(pass2_opline - free_vars);
|
||||
}
|
||||
free_vars--;
|
||||
} else if (brk_opline->opcode == ZEND_FE_FREE) {
|
||||
(pass2_opline - free_vars)->opcode = ZEND_FE_FREE;
|
||||
(pass2_opline - free_vars)->op1_type = brk_opline->op1_type;
|
||||
(pass2_opline - free_vars)->op1.var = brk_opline->op1.var;
|
||||
if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) {
|
||||
(pass2_opline - free_vars)->op1.var = brk_opline->op1.var;
|
||||
} else {
|
||||
(pass2_opline - free_vars)->op1.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + brk_opline->op1.var);
|
||||
ZEND_VM_SET_OPCODE_HANDLER(pass2_opline - free_vars);
|
||||
}
|
||||
free_vars--;
|
||||
}
|
||||
free_vars--;
|
||||
}
|
||||
current = CG(context).brk_cont_array[current].parent;
|
||||
}
|
||||
|
@ -958,6 +958,7 @@ static zend_always_inline int zend_check_arg_send_type(const zend_function *zf,
|
||||
#define ZEND_ARRAY_SIZE_SHIFT 2
|
||||
|
||||
/* Pseudo-opcodes that are used only temporarily during compilation */
|
||||
#define ZEND_GOTO 253
|
||||
#define ZEND_BRK 254
|
||||
#define ZEND_CONT 255
|
||||
|
||||
|
@ -4866,12 +4866,6 @@ ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMPVAR|CV, ANY)
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST)
|
||||
{
|
||||
zend_error_noreturn(E_ERROR, "GOTO must be resolved at compile-time.");
|
||||
ZEND_VM_NEXT_OPCODE(); /* Never reached */
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
|
||||
{
|
||||
USE_OPLINE
|
||||
|
@ -2225,12 +2225,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(Z
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GOTO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_error_noreturn(E_ERROR, "GOTO must be resolved at compile-time.");
|
||||
ZEND_VM_NEXT_OPCODE(); /* Never reached */
|
||||
}
|
||||
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_INTERFACE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
@ -48403,27 +48397,27 @@ void zend_init_opcodes_handlers(void)
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_GOTO_SPEC_CONST_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_GOTO_SPEC_CONST_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_GOTO_SPEC_CONST_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_GOTO_SPEC_CONST_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_GOTO_SPEC_CONST_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
|
@ -122,7 +122,7 @@ const char *zend_vm_opcodes_map[173] = {
|
||||
"ZEND_FETCH_OBJ_UNSET",
|
||||
"ZEND_FETCH_LIST",
|
||||
"ZEND_FETCH_CONSTANT",
|
||||
"ZEND_GOTO",
|
||||
NULL,
|
||||
"ZEND_EXT_STMT",
|
||||
"ZEND_EXT_FCALL_BEGIN",
|
||||
"ZEND_EXT_FCALL_END",
|
||||
|
@ -130,7 +130,6 @@ END_EXTERN_C()
|
||||
#define ZEND_FETCH_OBJ_UNSET 97
|
||||
#define ZEND_FETCH_LIST 98
|
||||
#define ZEND_FETCH_CONSTANT 99
|
||||
#define ZEND_GOTO 100
|
||||
#define ZEND_EXT_STMT 101
|
||||
#define ZEND_EXT_FCALL_BEGIN 102
|
||||
#define ZEND_EXT_FCALL_END 103
|
||||
|
Loading…
Reference in New Issue
Block a user