]> granicus.if.org Git - php/commitdiff
Combine foreach copy / switch cond stacks
authorNikita Popov <nikic@php.net>
Fri, 29 Aug 2014 19:47:10 +0000 (21:47 +0200)
committerNikita Popov <nikic@php.net>
Fri, 29 Aug 2014 19:53:09 +0000 (21:53 +0200)
Now one common stack to handle both, which stores znodes instead of
full oplines (foreach copy stack) or switch entries (switch cond
stack).

Also removed EG(start_op) while at it.

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

index 5a3f904f9f5342dd78aa23f72e6a82034cf4816e..590f30257971c62b071ef86ecec211b4e2c9e9a6 100644 (file)
@@ -1019,8 +1019,7 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
        zval orig_user_error_handler;
        zend_bool in_compilation;
        zend_class_entry *saved_class_entry;
-       zend_stack switch_cond_stack;
-       zend_stack foreach_copy_stack;
+       zend_stack loop_var_stack;
        zend_stack delayed_oplines_stack;
        zend_stack context_stack;
        zend_array *symbol_table;
@@ -1184,8 +1183,7 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
                        if (in_compilation) {
                                saved_class_entry = CG(active_class_entry);
                                CG(active_class_entry) = NULL;
-                               SAVE_STACK(switch_cond_stack);
-                               SAVE_STACK(foreach_copy_stack);
+                               SAVE_STACK(loop_var_stack);
                                SAVE_STACK(delayed_oplines_stack);
                                SAVE_STACK(context_stack);
                                CG(in_compilation) = 0;
@@ -1206,8 +1204,7 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
 
                        if (in_compilation) {
                                CG(active_class_entry) = saved_class_entry;
-                               RESTORE_STACK(switch_cond_stack);
-                               RESTORE_STACK(foreach_copy_stack);
+                               RESTORE_STACK(loop_var_stack);
                                RESTORE_STACK(delayed_oplines_stack);
                                RESTORE_STACK(context_stack);
                                CG(in_compilation) = 1;
index 244c15433826d88a9081ae0e26be0d7b29936a9c..5d1fe7fbd8523d1446991a95d28bbb3e4232b58b 100644 (file)
                } \
        } while (0)
 
-#define COPY_NODE(target, src) do { \
-               target ## _type = src ## _type; \
-               target = src; \
-       } while (0)
-
 static inline void zend_alloc_cache_slot(uint32_t literal TSRMLS_DC) {
        zend_op_array *op_array = CG(active_op_array);
        Z_CACHE_SLOT(op_array->literals[literal]) = op_array->last_cache_slot++;
@@ -180,8 +175,7 @@ void zend_init_compiler_context(TSRMLS_D) /* {{{ */
 
 void zend_init_compiler_data_structures(TSRMLS_D) /* {{{ */
 {
-       zend_stack_init(&CG(switch_cond_stack), sizeof(zend_switch_entry));
-       zend_stack_init(&CG(foreach_copy_stack), sizeof(zend_op));
+       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;
@@ -223,8 +217,7 @@ void init_compiler(TSRMLS_D) /* {{{ */
 
 void shutdown_compiler(TSRMLS_D) /* {{{ */
 {
-       zend_stack_destroy(&CG(switch_cond_stack));
-       zend_stack_destroy(&CG(foreach_copy_stack));
+       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));
@@ -881,39 +874,23 @@ void zend_release_labels(int temporary TSRMLS_DC) /* {{{ */
 
 static zend_bool zend_is_call(zend_ast *ast);
 
-static int generate_free_switch_expr(zend_switch_entry *switch_entry TSRMLS_DC) /* {{{ */
+static int generate_free_loop_var(znode *var TSRMLS_DC) /* {{{ */
 {
-       zend_op *opline;
-
-       if (switch_entry->cond.op_type != IS_VAR && switch_entry->cond.op_type != IS_TMP_VAR) {
-               return (switch_entry->cond.op_type == IS_UNUSED);
-       }
-
-       opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-
-       opline->opcode = (switch_entry->cond.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE;
-       SET_NODE(opline->op1, &switch_entry->cond);
-       SET_UNUSED(opline->op2);
-
-       return 0;
-}
-/* }}} */
-
-static int generate_free_foreach_copy(const zend_op *foreach_copy TSRMLS_DC) /* {{{ */
-{
-       zend_op *opline;
+       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) TSRMLS_CC);
 
-       /* If we reach the separator then stop applying the stack */
-       if (foreach_copy->result_type == IS_UNUSED) {
-               return 1;
+                       opline->opcode = var->op_type == IS_TMP_VAR ? ZEND_FREE : ZEND_SWITCH_FREE;
+                       SET_NODE(opline->op1, var);
+                       SET_UNUSED(opline->op2);
+               }
        }
 
-       opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-
-       opline->opcode = (foreach_copy->result_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE;
-       COPY_NODE(opline->op1, foreach_copy->result);
-       SET_UNUSED(opline->op2);
-
        return 0;
 }
 /* }}} */
@@ -4708,11 +4685,9 @@ static void zend_free_foreach_and_switch_variables(TSRMLS_D) /* {{{ */
        opnum_start = get_next_op_number(CG(active_op_array));
 
 #ifdef ZTS
-       zend_stack_apply_with_argument(&CG(switch_cond_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element, void *)) generate_free_switch_expr TSRMLS_CC);
-       zend_stack_apply_with_argument(&CG(foreach_copy_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element, void *)) generate_free_foreach_copy TSRMLS_CC);
+       zend_stack_apply_with_argument(&CG(loop_var_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element, void *)) generate_free_loop_var TSRMLS_CC);
 #else
-       zend_stack_apply(&CG(switch_cond_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element)) generate_free_switch_expr);
-       zend_stack_apply(&CG(foreach_copy_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element)) generate_free_foreach_copy);
+       zend_stack_apply(&CG(loop_var_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element)) generate_free_loop_var);
 #endif
 
        opnum_end = get_next_op_number(CG(active_op_array));
@@ -4962,7 +4937,6 @@ void zend_compile_foreach(zend_ast *ast TSRMLS_DC) /* {{{ */
        znode expr_node, reset_node, value_node, key_node, dummy_node;
        zend_op *opline;
        uint32_t opnum_reset, opnum_fetch;
-       zend_op foreach_stack_opline;
 
        if (key_ast) {
                if (key_ast->kind == ZEND_AST_REF) {
@@ -4989,8 +4963,7 @@ void zend_compile_foreach(zend_ast *ast TSRMLS_DC) /* {{{ */
                opline->extended_value = ZEND_FE_RESET_VARIABLE | ZEND_FE_RESET_REFERENCE; // ???
        }
 
-       SET_NODE(foreach_stack_opline.result, &reset_node);
-       zend_stack_push(&CG(foreach_copy_stack), &foreach_stack_opline);
+       zend_stack_push(&CG(loop_var_stack), &reset_node);
 
        opnum_fetch = get_next_op_number(CG(active_op_array));
        opline = zend_emit_op(&value_node, ZEND_FE_FETCH, &reset_node, NULL TSRMLS_CC);
@@ -5042,11 +5015,8 @@ void zend_compile_foreach(zend_ast *ast TSRMLS_DC) /* {{{ */
 
        zend_end_loop(opnum_fetch, 1 TSRMLS_CC);
 
-       {
-               zend_op *container_ptr = zend_stack_top(&CG(foreach_copy_stack));
-               generate_free_foreach_copy(container_ptr TSRMLS_CC);
-               zend_stack_del_top(&CG(foreach_copy_stack));
-       }
+       generate_free_loop_var(&reset_node TSRMLS_CC);
+       zend_stack_del_top(&CG(loop_var_stack));
 }
 /* }}} */
 
@@ -5099,7 +5069,6 @@ void zend_compile_switch(zend_ast *ast TSRMLS_DC) /* {{{ */
 
        uint32_t i;
        zend_bool has_default_case = 0;
-       zend_switch_entry switch_entry;
 
        znode expr_node, case_node;
        zend_op *opline;
@@ -5108,10 +5077,7 @@ void zend_compile_switch(zend_ast *ast TSRMLS_DC) /* {{{ */
 
        zend_compile_expr(&expr_node, expr_ast TSRMLS_CC);
 
-       switch_entry.cond = expr_node;
-       switch_entry.default_case = -1;
-       switch_entry.control_var = -1;
-       zend_stack_push(&CG(switch_cond_stack), (void *) &switch_entry);
+       zend_stack_push(&CG(loop_var_stack), &expr_node);
 
        zend_begin_loop(TSRMLS_C);
 
@@ -5168,7 +5134,7 @@ void zend_compile_switch(zend_ast *ast TSRMLS_DC) /* {{{ */
                zval_dtor(&expr_node.u.constant);
        }
 
-       zend_stack_del_top(&CG(switch_cond_stack));
+       zend_stack_del_top(&CG(loop_var_stack));
        efree(jmpnz_opnums);
 }
 /* }}} */
@@ -5800,23 +5766,11 @@ void zend_compile_func_decl(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
        }
 
        {
-               /* Push a separator to the switch stack */
-               zend_switch_entry switch_entry;
-
-               switch_entry.cond.op_type = IS_UNUSED;
-               switch_entry.default_case = 0;
-               switch_entry.control_var = 0;
-
-               zend_stack_push(&CG(switch_cond_stack), (void *) &switch_entry);
-       }
-
-       {
-               /* Push a separator to the foreach stack */
-               zend_op dummy_opline;
-
-               dummy_opline.result_type = IS_UNUSED;
+               /* Push a separator to the loop variable stack */
+               znode dummy_var;
+               dummy_var.op_type = IS_UNUSED;
 
-               zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline);
+               zend_stack_push(&CG(loop_var_stack), (void *) &dummy_var);
        }
 
        zend_compile_params(params_ast TSRMLS_CC);
@@ -5836,9 +5790,8 @@ void zend_compile_func_decl(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
        pass_two(CG(active_op_array) TSRMLS_CC);
        zend_release_labels(0 TSRMLS_CC);
 
-       /* Pop the switch and foreach separators */
-       zend_stack_del_top(&CG(switch_cond_stack));
-       zend_stack_del_top(&CG(foreach_copy_stack));
+       /* Pop the loop variable stack separator */
+       zend_stack_del_top(&CG(loop_var_stack));
 
        CG(active_op_array) = orig_op_array;
 }
index b8e8ae108333f354554de432819ea659ae96c5e6..71a622f4173ecb2d1be851e563b02f14f68e0bf7 100644 (file)
@@ -347,12 +347,6 @@ union _zend_function {
        zend_internal_function internal_function;
 };
 
-typedef struct _zend_switch_entry {
-       znode cond;
-       int default_case;
-       int control_var;
-} zend_switch_entry;
-
 typedef enum _vm_frame_kind {
        VM_FRAME_NESTED_FUNCTION,       /* stackless VM call to function */
        VM_FRAME_NESTED_CODE,           /* stackless VM call to include/require/eval */
index 37352c9106e17c09f7fe732eec1aaee56c1e63ab..5984e2dc829b69ab72309545f3460d8735d2ecd9 100644 (file)
@@ -190,7 +190,6 @@ void init_executor(TSRMLS_D) /* {{{ */
        ZVAL_OBJ(&EG(This), NULL);
 
        EG(active) = 1;
-       EG(start_op) = NULL;
 }
 /* }}} */
 
index 266941c3202c49311ed91176971fb914ab5a815e..c757f1fa2f8b1d5ecd611686eee1084074de260c 100644 (file)
@@ -71,8 +71,7 @@ typedef struct _zend_ini_entry zend_ini_entry;
 
 
 struct _zend_compiler_globals {
-       zend_stack switch_cond_stack;
-       zend_stack foreach_copy_stack;
+       zend_stack loop_var_stack;
 
        zend_class_entry *active_class_entry;
 
@@ -231,8 +230,6 @@ struct _zend_executor_globals {
        zend_bool active;
        zend_bool valid_symbol_table;
 
-       zend_op *start_op;
-
        void *saved_fpu_cw_ptr;
 #if XPFPA_HAVE_CW
        XPFPA_CW_DATATYPE saved_fpu_cw;