From: Nikita Popov Date: Fri, 22 May 2015 20:08:44 +0000 (+0200) Subject: Embed break/continue depth into opline X-Git-Tag: PRE_PHP7_NSAPI_REMOVAL~36^2~9 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9325ada7253efb330e4fd79579d6e6fc0334d7b2;p=php Embed break/continue depth into opline Previously a separate lval literal was used - this is probably a leftover from the time where the break level could still be specified dynamically. --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index fb75643681..2ea4451b09 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3528,26 +3528,27 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */ { zend_ast *depth_ast = ast->child[0]; - znode depth_node; zend_op *opline; + int depth; ZEND_ASSERT(ast->kind == ZEND_AST_BREAK || ast->kind == ZEND_AST_CONTINUE); if (depth_ast) { + zval *depth_zv; if (depth_ast->kind != ZEND_AST_ZVAL) { zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator with non-constant operand " "is no longer supported", ast->kind == ZEND_AST_BREAK ? "break" : "continue"); } - zend_compile_expr(&depth_node, depth_ast); - - if (Z_TYPE(depth_node.u.constant) != IS_LONG || Z_LVAL(depth_node.u.constant) < 1) { + depth_zv = zend_ast_get_zval(depth_ast); + if (Z_TYPE_P(depth_zv) != IS_LONG || Z_LVAL_P(depth_zv) < 1) { zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator accepts only positive numbers", ast->kind == ZEND_AST_BREAK ? "break" : "continue"); } + + depth = Z_LVAL_P(depth_zv); } else { - depth_node.op_type = IS_CONST; - ZVAL_LONG(&depth_node.u.constant, 1); + depth = 1; } if (CG(context).current_brk_cont == -1) { @@ -3555,20 +3556,20 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */ ast->kind == ZEND_AST_BREAK ? "break" : "continue"); } else { int array_offset = CG(context).current_brk_cont; - zend_long nest_level = Z_LVAL(depth_node.u.constant); + zend_long nest_level = depth; do { if (array_offset == -1) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot '%s' %d level%s", ast->kind == ZEND_AST_BREAK ? "break" : "continue", - Z_LVAL(depth_node.u.constant), (Z_LVAL(depth_node.u.constant) == 1) ? "" : "s"); + depth, depth == 1 ? "" : "s"); } array_offset = CG(active_op_array)->brk_cont_array[array_offset].parent; } while (--nest_level > 0); } - opline = zend_emit_op(NULL, ast->kind == ZEND_AST_BREAK ? ZEND_BRK : ZEND_CONT, - NULL, &depth_node); - opline->op1.opline_num = CG(context).current_brk_cont; + opline = zend_emit_op(NULL, ast->kind == ZEND_AST_BREAK ? ZEND_BRK : ZEND_CONT, NULL, NULL); + opline->op1.num = CG(context).current_brk_cont; + opline->op2.num = depth; } /* }}} */ diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index f24fc9f193..933c75a706 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -682,11 +682,11 @@ static void zend_resolve_finally_calls(zend_op_array *op_array) case ZEND_BRK: case ZEND_CONT: { - int nest_levels, array_offset; + int nest_levels = opline->op2.num; + int array_offset = opline->op1.num; zend_brk_cont_element *jmp_to; - nest_levels = Z_LVAL(op_array->literals[opline->op2.constant]); - if ((array_offset = opline->op1.opline_num) != -1) { + if (array_offset != -1) { do { jmp_to = &op_array->brk_cont_array[array_offset]; if (nest_levels > 1) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index d3e7dfece1..f63a41e515 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4816,24 +4816,24 @@ ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMPVAR|CV, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(50, ZEND_BRK, ANY, CONST) +ZEND_VM_HANDLER(50, ZEND_BRK, ANY, ANY) { USE_OPLINE zend_brk_cont_element *el; SAVE_OPLINE(); - el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->op1.opline_num, + el = zend_brk_cont(opline->op2.num, opline->op1.num, &EX(func)->op_array, execute_data); ZEND_VM_JMP(EX(func)->op_array.opcodes + el->brk); } -ZEND_VM_HANDLER(51, ZEND_CONT, ANY, CONST) +ZEND_VM_HANDLER(51, ZEND_CONT, ANY, ANY) { USE_OPLINE zend_brk_cont_element *el; SAVE_OPLINE(); - el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->op1.opline_num, + el = zend_brk_cont(opline->op2.num, opline->op1.num, &EX(func)->op_array, execute_data); ZEND_VM_JMP(EX(func)->op_array.opcodes + el->cont); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 2fa1079f27..aa3b7f3658 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1248,6 +1248,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEN ZEND_VM_NEXT_OPCODE(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BRK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_brk_cont_element *el; + + SAVE_OPLINE(); + el = zend_brk_cont(opline->op2.num, opline->op1.num, + &EX(func)->op_array, execute_data); + ZEND_VM_JMP(EX(func)->op_array.opcodes + el->brk); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONT_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_brk_cont_element *el; + + SAVE_OPLINE(); + el = zend_brk_cont(opline->op2.num, opline->op1.num, + &EX(func)->op_array, execute_data); + ZEND_VM_JMP(EX(func)->op_array.opcodes + el->cont); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -2348,28 +2370,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_BRK_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_brk_cont_element *el; - - SAVE_OPLINE(); - el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->op1.opline_num, - &EX(func)->op_array, execute_data); - ZEND_VM_JMP(EX(func)->op_array.opcodes + el->brk); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_brk_cont_element *el; - - SAVE_OPLINE(); - el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->op1.opline_num, - &EX(func)->op_array, execute_data); - ZEND_VM_JMP(EX(func)->op_array.opcodes + el->cont); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GOTO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -46678,56 +46678,56 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_BRK_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_BRK_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_BRK_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_BRK_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_BRK_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CONT_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CONT_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CONT_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CONT_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CONT_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_BRK_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, + ZEND_CONT_SPEC_HANDLER, ZEND_BOOL_SPEC_CONST_HANDLER, ZEND_BOOL_SPEC_CONST_HANDLER, ZEND_BOOL_SPEC_CONST_HANDLER, diff --git a/ext/opcache/Optimizer/pass2.c b/ext/opcache/Optimizer/pass2.c index c0832a1cbf..3991a41e0f 100644 --- a/ext/opcache/Optimizer/pass2.c +++ b/ext/opcache/Optimizer/pass2.c @@ -186,16 +186,10 @@ void zend_optimizer_pass2(zend_op_array *op_array) case ZEND_CONT: { zend_brk_cont_element *jmp_to; - int array_offset; - int nest_levels; + int array_offset = ZEND_OP1(opline).num; + int nest_levels = ZEND_OP2(opline).num; int dont_optimize = 0; - ZEND_ASSERT(ZEND_OP2_TYPE(opline) == IS_CONST); - ZEND_ASSERT(Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_LONG); - - nest_levels = Z_LVAL(ZEND_OP2_LITERAL(opline)); - - array_offset = ZEND_OP1(opline).opline_num; while (1) { if (array_offset == -1) { dont_optimize = 1; /* don't optimize this bogus break/continue, let the executor shout */