]> granicus.if.org Git - php/commitdiff
Remove loop_var_stack
authorNikita Popov <nikic@php.net>
Tue, 7 Jul 2015 17:46:29 +0000 (19:46 +0200)
committerNikita Popov <nikic@php.net>
Tue, 7 Jul 2015 18:55:12 +0000 (20:55 +0200)
Instead add a loop_var member to brk_cont_element. Now that
brk_cont is compile-time the distinction is no longer necessary.

Also drops brk_cont.start, check the loop_var op_type instead.

Zend/zend.c
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_globals.h

index e5fd2e8beeb74a7a8335d2225730825aae336429..e200c05b67270427612a7eb497997d5ff5831a24 100644 (file)
@@ -1045,7 +1045,6 @@ static void zend_error_va_list(int type, const char *format, va_list args)
        zval orig_user_error_handler;
        zend_bool in_compilation;
        zend_class_entry *saved_class_entry;
-       zend_stack loop_var_stack;
        zend_stack delayed_oplines_stack;
        zend_array *symbol_table;
 
@@ -1212,7 +1211,6 @@ static void zend_error_va_list(int type, const char *format, va_list args)
                        if (in_compilation) {
                                saved_class_entry = CG(active_class_entry);
                                CG(active_class_entry) = NULL;
-                               SAVE_STACK(loop_var_stack);
                                SAVE_STACK(delayed_oplines_stack);
                                CG(in_compilation) = 0;
                        }
@@ -1231,7 +1229,6 @@ static void zend_error_va_list(int type, const char *format, va_list args)
 
                        if (in_compilation) {
                                CG(active_class_entry) = saved_class_entry;
-                               RESTORE_STACK(loop_var_stack);
                                RESTORE_STACK(delayed_oplines_stack);
                                CG(in_compilation) = 1;
                        }
index 69aecc4108129ceee794292d0d8f97ae91b80119..51eb0bc754fc39f7d3ca83c32cb18a6135e8fb49 100644 (file)
@@ -289,7 +289,6 @@ void zend_file_context_end(zend_file_context *prev_context) /* {{{ */
 
 void zend_init_compiler_data_structures(void) /* {{{ */
 {
-       zend_stack_init(&CG(loop_var_stack), sizeof(znode));
        zend_stack_init(&CG(delayed_oplines_stack), sizeof(zend_op));
        CG(active_class_entry) = NULL;
        CG(in_compilation) = 0;
@@ -322,7 +321,6 @@ void init_compiler(void) /* {{{ */
 
 void shutdown_compiler(void) /* {{{ */
 {
-       zend_stack_destroy(&CG(loop_var_stack));
        zend_stack_destroy(&CG(delayed_oplines_stack));
        zend_hash_destroy(&CG(filenames_table));
        zend_hash_destroy(&CG(const_filenames));
@@ -571,14 +569,10 @@ static inline void zend_begin_loop(const znode *loop_var) /* {{{ */
        CG(context).current_brk_cont = CG(context).last_brk_cont;
        brk_cont_element = get_next_brk_cont_element(CG(active_op_array));
        brk_cont_element->parent = parent;
-
-       if (loop_var) {
-               zend_stack_push(&CG(loop_var_stack), loop_var);
-               brk_cont_element->start = get_next_op_number(CG(active_op_array));
+       if (loop_var && (loop_var->op_type & (IS_TMP_VAR|IS_VAR))) {
+               brk_cont_element->loop_var = *loop_var;
        } else {
-               /* The start field is used to free temporary variables in case of exceptions.
-                * We won't try to free something of we don't have loop variable.  */
-               brk_cont_element->start = -1;
+               brk_cont_element->loop_var.op_type = IS_UNUSED;
        }
 }
 /* }}} */
@@ -590,10 +584,6 @@ static inline void zend_end_loop(int cont_addr) /* {{{ */
        brk_cont_element->cont = cont_addr;
        brk_cont_element->brk = get_next_op_number(CG(active_op_array));
        CG(context).current_brk_cont = brk_cont_element->parent;
-
-       if (brk_cont_element->start >= 0) {
-               zend_stack_del_top(&CG(loop_var_stack));
-       }
 }
 /* }}} */
 
@@ -882,24 +872,15 @@ static void str_dtor(zval *zv)  /* {{{ */ {
 
 static zend_bool zend_is_call(zend_ast *ast);
 
-static int generate_free_loop_var(znode *var) /* {{{ */
+static void generate_free_loop_var(znode *var) /* {{{ */
 {
-       switch (var->op_type) {
-               case IS_UNUSED:
-                       /* Stack separator on function boundary, stop applying */
-                       return 1;
-               case IS_VAR:
-               case IS_TMP_VAR:
-               {
-                       zend_op *opline = get_next_op(CG(active_op_array));
+       if (var->op_type != IS_UNUSED) {
+               zend_op *opline = get_next_op(CG(active_op_array));
 
-                       opline->opcode = var->flag ? ZEND_FE_FREE : ZEND_FREE;
-                       SET_NODE(opline->op1, var);
-                       SET_UNUSED(opline->op2);
-               }
+               opline->opcode = var->flag ? ZEND_FE_FREE : ZEND_FREE;
+               SET_NODE(opline->op1, var);
+               SET_UNUSED(opline->op2);
        }
-
-       return 0;
 }
 /* }}} */
 
@@ -3462,7 +3443,12 @@ void zend_compile_unset(zend_ast *ast) /* {{{ */
 
 static void zend_free_foreach_and_switch_variables(void) /* {{{ */
 {
-       zend_stack_apply(&CG(loop_var_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element)) generate_free_loop_var);
+       int array_offset = CG(context).current_brk_cont;
+       while (array_offset != -1) {
+               zend_brk_cont_element *brk_cont = &CG(context).brk_cont_array[array_offset];
+               generate_free_loop_var(&brk_cont->loop_var);
+               array_offset = brk_cont->parent;
+       }
 }
 /* }}} */
 
@@ -3564,7 +3550,6 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */
        } else {
                int array_offset = CG(context).current_brk_cont;
                zend_long nest_level = depth;
-               znode *loop_var = zend_stack_top(&CG(loop_var_stack));
 
                do {
                        if (array_offset == -1) {
@@ -3573,9 +3558,8 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */
                                        depth, depth == 1 ? "" : "s");
                        }
 
-                       if (nest_level > 1 && CG(context).brk_cont_array[array_offset].start >= 0) {
-                               generate_free_loop_var(loop_var);
-                               loop_var--;
+                       if (nest_level > 1) {
+                               generate_free_loop_var(&CG(context).brk_cont_array[array_offset].loop_var);
                        }
 
                        array_offset = CG(context).brk_cont_array[array_offset].parent;
@@ -3592,7 +3576,6 @@ void zend_resolve_goto_label(zend_op_array *op_array, znode *label_node, zend_op
        zend_label *dest;
        int current, distance, free_vars;
        zval *label;
-       znode *loop_var = NULL;
 
        if (pass2_opline) {
                label = RT_CONSTANT(op_array, pass2_opline->op2);
@@ -3613,7 +3596,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) {
+                               if (CG(context).brk_cont_array[current].loop_var.op_type != IS_UNUSED) {
                                        zend_emit_op(NULL, ZEND_NOP, NULL, NULL);
                                }
                                current = CG(context).brk_cont_array[current].parent;
@@ -3633,9 +3616,6 @@ void zend_resolve_goto_label(zend_op_array *op_array, znode *label_node, zend_op
        } else {
                current = CG(context).current_brk_cont;
        }
-       if (!pass2_opline) {
-               loop_var = zend_stack_top(&CG(loop_var_stack));
-       }
        for (distance = 0, free_vars = 0; current != dest->brk_cont; distance++) {
                if (current == -1) {
                        if (pass2_opline) {
@@ -3645,12 +3625,11 @@ void zend_resolve_goto_label(zend_op_array *op_array, znode *label_node, zend_op
                        }
                        zend_error_noreturn(E_COMPILE_ERROR, "'goto' into loop or switch statement is disallowed");
                }
-               if (CG(context).brk_cont_array[current].start >= 0) {
+               if (CG(context).brk_cont_array[current].loop_var.op_type != IS_UNUSED) {
                        if (pass2_opline) {
                                free_vars++;
                        } else {
-                               generate_free_loop_var(loop_var);
-                               loop_var--;
+                               generate_free_loop_var(&CG(context).brk_cont_array[current].loop_var);
                        }
                }
                current = CG(context).brk_cont_array[current].parent;
@@ -3660,30 +3639,18 @@ void zend_resolve_goto_label(zend_op_array *op_array, znode *label_node, zend_op
                if (free_vars) {
                        current = pass2_opline->extended_value;
                        while (current != dest->brk_cont) {
-                               if (CG(context).brk_cont_array[current].start >= 0) {
+                               if (CG(context).brk_cont_array[current].loop_var.op_type != IS_UNUSED) {
                                        zend_op *brk_opline = &op_array->opcodes[CG(context).brk_cont_array[current].brk];
 
-                                       if (brk_opline->opcode == ZEND_FREE) {
-                                               (pass2_opline - free_vars)->opcode = ZEND_FREE;
-                                               (pass2_opline - free_vars)->op1_type = brk_opline->op1_type;
-                                               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;
-                                               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--;
+                                       (pass2_opline - free_vars)->opcode = brk_opline->opcode;
+                                       (pass2_opline - free_vars)->op1_type = brk_opline->op1_type;
+                                       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--;
                                }
                                current = CG(context).brk_cont_array[current].parent;
                        }
@@ -4801,14 +4768,6 @@ void zend_compile_func_decl(znode *result, zend_ast *ast) /* {{{ */
                opline_ext->lineno = decl->start_lineno;
        }
 
-       {
-               /* Push a separator to the loop variable stack */
-               znode dummy_var;
-               dummy_var.op_type = IS_UNUSED;
-
-               zend_stack_push(&CG(loop_var_stack), (void *) &dummy_var);
-       }
-
        zend_compile_params(params_ast, return_type_ast);
        if (uses_ast) {
                zend_compile_closure_uses(uses_ast);
@@ -4826,9 +4785,6 @@ void zend_compile_func_decl(znode *result, zend_ast *ast) /* {{{ */
        pass_two(CG(active_op_array));
        zend_oparray_context_end(&orig_oparray_context);
 
-       /* Pop the loop variable stack separator */
-       zend_stack_del_top(&CG(loop_var_stack));
-
        CG(active_op_array) = orig_op_array;
 }
 /* }}} */
index 993a19fb6b47e2d2fb866abe71b8e4e3b5fe135e..3f9c0910615134026484996f5ae1f9e62a81df10 100644 (file)
@@ -110,10 +110,10 @@ typedef struct _zend_declarables {
 } zend_declarables;
 
 typedef struct _zend_brk_cont_element {
-       int start;
        int cont;
        int brk;
        int parent;
+       znode loop_var;
 } zend_brk_cont_element;
 
 typedef struct _zend_label {
index 28487a2a4a1859894569efc42f9fd9fa0b179650..780007174eae9cc572c9d0f44cf7d80103efcfa4 100644 (file)
@@ -68,8 +68,6 @@ typedef struct _zend_ini_entry zend_ini_entry;
 
 
 struct _zend_compiler_globals {
-       zend_stack loop_var_stack;
-
        zend_class_entry *active_class_entry;
 
        zend_string *compiled_filename;