]> granicus.if.org Git - php/commitdiff
Embed break/continue depth into opline
authorNikita Popov <nikic@php.net>
Fri, 22 May 2015 20:08:44 +0000 (22:08 +0200)
committerNikita Popov <nikic@php.net>
Sat, 23 May 2015 08:51:33 +0000 (10:51 +0200)
Previously a separate lval literal was used - this is probably a
leftover from the time where the break level could still be
specified dynamically.

Zend/zend_compile.c
Zend/zend_opcode.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/opcache/Optimizer/pass2.c

index fb7564368115e66ee0c14e6fbeed05109dddb7e4..2ea4451b09b9411a4775f5ac2cdfd959fa80d13a 100644 (file)
@@ -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;
 }
 /* }}} */
 
index f24fc9f1932657b5211f983f154b7c8b1bfbc877..933c75a706d445f0cf9be35eddf0981cd16cd6de 100644 (file)
@@ -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) {
index d3e7dfece1ed4733475b5c56469248a1d2e62fec..f63a41e51514772213b3a5311aeb03dcba5e5eee 100644 (file)
@@ -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);
 }
index 2fa1079f27360c2f9266bc350baf69979b4fef28..aa3b7f3658030f263bddf93cd022de26b2b1f7ff 100644 (file)
@@ -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,
index c0832a1cbff22f647152ffd8d2ed77fe48872563..3991a41e0f2fbc5d18882afe5fe341247ef99b66 100644 (file)
@@ -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 */