From: Nikita Popov Date: Fri, 29 Aug 2014 19:47:10 +0000 (+0200) Subject: Combine foreach copy / switch cond stacks X-Git-Tag: PRE_PHP7_REMOVALS~188 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b73bea9cc86468f82b6619d05e2f105d2712809e;p=php Combine foreach copy / switch cond stacks 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. --- diff --git a/Zend/zend.c b/Zend/zend.c index 5a3f904f9f..590f302579 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -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; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 244c154338..5d1fe7fbd8 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -55,11 +55,6 @@ } \ } 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; } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index b8e8ae1083..71a622f417 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -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 */ diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 37352c9106..5984e2dc82 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -190,7 +190,6 @@ void init_executor(TSRMLS_D) /* {{{ */ ZVAL_OBJ(&EG(This), NULL); EG(active) = 1; - EG(start_op) = NULL; } /* }}} */ diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 266941c320..c757f1fa2f 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -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;