diff options
| -rw-r--r-- | Zend/zend.c | 3 | ||||
| -rw-r--r-- | Zend/zend_compile.c | 102 | ||||
| -rw-r--r-- | Zend/zend_compile.h | 2 | ||||
| -rw-r--r-- | Zend/zend_globals.h | 2 | 
4 files changed, 30 insertions, 79 deletions
diff --git a/Zend/zend.c b/Zend/zend.c index e5fd2e8bee..e200c05b67 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -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;  			} diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 69aecc4108..51eb0bc754 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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;  }  /* }}} */ diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 993a19fb6b..3f9c091061 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -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 { diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 28487a2a4a..780007174e 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -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;  | 
