cvs: ZendEngine2(PHP_5_3) / zend_compile.c zend_compile.h zend_execute.c zend_vm_def.h zend_vm_execute.h /tests bug44913.phpt php-src NEWS
| From: | Dmitry Stogov | Date: | Mon, 05 May 2008 11:03:38 +0000 |
| Subject: | cvs: ZendEngine2(PHP_5_3) / zend_compile.c zend_compile.h zend_execute.c zend_vm_def.h zend_vm_execute.h /tests bug44913.phpt php-src NEWS | ||
| Groups: | php.zend-engine.cvs | ||
| Request: | Send a blank email to php-zend-engine-cvs+get-6661@lists.php.net to get a copy of this message | ||
dmitry Mon May 5 11:03:38 2008 UTC
Added files: (Branch: PHP_5_3)
/ZendEngine2/tests bug44913.phpt
Modified files:
/php-src NEWS
/ZendEngine2 zend_compile.c zend_compile.h zend_execute.c
zend_vm_def.h zend_vm_execute.h
Log:
- Use ZEND_FREE() opcode instead of ZEND_SWITCH_FREE(IS_TMP_VAR)
- Fixed bug #44913 (Segfault when using return in combination with nested loops
and continue 2)
http://cvs.php.net/viewvc.cgi/php-src/NEWS?r1=1.2027.2.547.2.965.2.174&r2=1.2027.2.547.2.965.2.175&diff_format=u Index: php-src/NEWS diff -u php-src/NEWS:1.2027.2.547.2.965.2.174 php-src/NEWS:1.2027.2.547.2.965.2.175 --- php-src/NEWS:1.2027.2.547.2.965.2.174 Mon May 5 07:29:41 2008 +++ php-src/NEWS Mon May 5 11:03:32 2008 @@ -109,6 +109,7 @@ - Added Windows support for asinh(), acosh(), atanh(), log1p() and expm1() (Kalle) - Improved PHP runtime speed and memory usage: + . Use ZEND_FREE() opcode instead of ZEND_SWITCH_FREE(IS_TMP_VAR). (Dmitry) . Lazy EG(active_symbol_table) initialization. (Dmitry) . Optimized ZEND_RETURN opcode to not allocate and copy return value if it is not used. (Dmitry) @@ -169,6 +170,8 @@ - Fixed an issue in date() where a : was printed for the O modifier after a P modifier was used. (Derick) +- Fixed bug #44913 (Segfault when using return in combination with nested loops + and continue 2). (Dmitry) - Fixed bug #44899 (__isset usage changes behavior of empty()) (Etienne) - Fixed bug #44805 (rename() function is not portable to Windows). (Pierre) - Fixed bug #44742 (timezone_offset_get() causes segmentation faults). (Derick) http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_compile.c?r1=1.647.2.27.2.41.2.61&r2=1.647.2.27.2.41.2.62&diff_format=u Index: ZendEngine2/zend_compile.c diff -u ZendEngine2/zend_compile.c:1.647.2.27.2.41.2.61 ZendEngine2/zend_compile.c:1.647.2.27.2.41.2.62 --- ZendEngine2/zend_compile.c:1.647.2.27.2.41.2.61 Mon May 5 09:44:39 2008 +++ ZendEngine2/zend_compile.c Mon May 5 11:03:32 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_compile.c,v 1.647.2.27.2.41.2.61 2008/05/05 09:44:39 dmitry Exp $ */ +/* $Id: zend_compile.c,v 1.647.2.27.2.41.2.62 2008/05/05 11:03:32 dmitry Exp $ */ #include <zend_language_parser.h> #include "zend.h" @@ -2024,7 +2024,7 @@ opline = get_next_op(CG(active_op_array) TSRMLS_CC); - opline->opcode = ZEND_SWITCH_FREE; + opline->opcode = (switch_entry->cond.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE; opline->op1 = switch_entry->cond; SET_UNUSED(opline->op2); opline->extended_value = 0; @@ -2042,7 +2042,7 @@ opline = get_next_op(CG(active_op_array) TSRMLS_CC); - opline->opcode = ZEND_SWITCH_FREE; + opline->opcode = (foreach_copy->result.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE; opline->op1 = foreach_copy->result; SET_UNUSED(opline->op2); opline->extended_value = 1; @@ -2050,7 +2050,7 @@ if (foreach_copy->op1.op_type != IS_UNUSED) { opline = get_next_op(CG(active_op_array) TSRMLS_CC); - opline->opcode = ZEND_SWITCH_FREE; + opline->opcode = (foreach_copy->op1.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE; opline->op1 = foreach_copy->op1; SET_UNUSED(opline->op2); opline->extended_value = 0; @@ -2062,6 +2062,7 @@ void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) { zend_op *opline; + int start_op_number, end_op_number; if (do_end_vparse) { if (CG(active_op_array)->return_reference && !zend_is_function_or_method_call(expr)) { @@ -2071,6 +2072,8 @@ } } + start_op_number = 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); @@ -2079,6 +2082,12 @@ zend_stack_apply(&CG(foreach_copy_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element)) generate_free_foreach_copy); #endif + end_op_number = get_next_op_number(CG(active_op_array)); + while (start_op_number < end_op_number) { + CG(active_op_array)->opcodes[start_op_number].op1.u.EA.type = EXT_TYPE_FREE_ON_RETURN; + start_op_number++; + } + opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_RETURN; @@ -3075,7 +3084,7 @@ if (switch_entry_ptr->cond.op_type==IS_VAR || switch_entry_ptr->cond.op_type==IS_TMP_VAR) { /* emit free for the switch condition*/ opline = get_next_op(CG(active_op_array) TSRMLS_CC); - opline->opcode = ZEND_SWITCH_FREE; + opline->opcode = (switch_entry_ptr->cond.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE; opline->op1 = switch_entry_ptr->cond; SET_UNUSED(opline->op2); } http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_compile.h?r1=1.316.2.8.2.12.2.21&r2=1.316.2.8.2.12.2.22&diff_format=u Index: ZendEngine2/zend_compile.h diff -u ZendEngine2/zend_compile.h:1.316.2.8.2.12.2.21 ZendEngine2/zend_compile.h:1.316.2.8.2.12.2.22 --- ZendEngine2/zend_compile.h:1.316.2.8.2.12.2.21 Sat Mar 29 11:52:10 2008 +++ ZendEngine2/zend_compile.h Mon May 5 11:03:32 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_compile.h,v 1.316.2.8.2.12.2.21 2008/03/29 11:52:10 felipe Exp $ */ +/* $Id: zend_compile.h,v 1.316.2.8.2.12.2.22 2008/05/05 11:03:32 dmitry Exp $ */ #ifndef ZEND_COMPILE_H #define ZEND_COMPILE_H @@ -323,7 +323,8 @@ #define IS_UNUSED (1<<3) /* Unused variable */ #define IS_CV (1<<4) /* Compiled variable */ -#define EXT_TYPE_UNUSED (1<<0) +#define EXT_TYPE_UNUSED (1<<0) +#define EXT_TYPE_FREE_ON_RETURN (2<<0) #include "zend_globals.h" http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_execute.c?r1=1.716.2.12.2.24.2.26&r2=1.716.2.12.2.24.2.27&diff_format=u Index: ZendEngine2/zend_execute.c diff -u ZendEngine2/zend_execute.c:1.716.2.12.2.24.2.26 ZendEngine2/zend_execute.c:1.716.2.12.2.24.2.27 --- ZendEngine2/zend_execute.c:1.716.2.12.2.24.2.26 Tue Apr 29 08:15:16 2008 +++ ZendEngine2/zend_execute.c Mon May 5 11:03:32 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_execute.c,v 1.716.2.12.2.24.2.26 2008/04/29 08:15:16 dmitry Exp $ */ +/* $Id: zend_execute.c,v 1.716.2.12.2.24.2.27 2008/05/05 11:03:32 dmitry Exp $ */ #define ZEND_INTENSIVE_DEBUGGING 0 @@ -377,22 +377,18 @@ return get_zval_ptr(op, Ts, should_free, type); } -static inline void zend_switch_free(temp_variable *T, int type, int extended_value TSRMLS_DC) +static inline void zend_switch_free(temp_variable *T, int extended_value TSRMLS_DC) { - if (type == IS_VAR) { - if (T->var.ptr) { - if (extended_value & ZEND_FE_RESET_VARIABLE) { /* foreach() free */ - Z_DELREF_P(T->var.ptr); - } - zval_ptr_dtor(&T->var.ptr); - } else if (!T->var.ptr_ptr) { - /* perform the equivalent of equivalent of a - * quick & silent get_zval_ptr, and FREE_OP - */ - PZVAL_UNLOCK_FREE(T->str_offset.str); - } - } else { /* IS_TMP_VAR */ - zendi_zval_dtor(T->tmp_var); + if (T->var.ptr) { + if (extended_value & ZEND_FE_RESET_VARIABLE) { /* foreach() free */ + Z_DELREF_P(T->var.ptr); + } + zval_ptr_dtor(&T->var.ptr); + } else if (!T->var.ptr_ptr) { + /* perform the equivalent of equivalent of a + * quick & silent get_zval_ptr, and FREE_OP + */ + PZVAL_UNLOCK_FREE(T->str_offset.str); } } @@ -1241,10 +1237,14 @@ switch (brk_opline->opcode) { case ZEND_SWITCH_FREE: - zend_switch_free(&T(brk_opline->op1.u.var), brk_opline->op1.op_type, brk_opline->extended_value TSRMLS_CC); + if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) { + zend_switch_free(&T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC); + } break; case ZEND_FREE: - zendi_zval_dtor(T(brk_opline->op1.u.var).tmp_var); + if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) { + zendi_zval_dtor(T(brk_opline->op1.u.var).tmp_var); + } break; } } http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_def.h?r1=1.59.2.29.2.48.2.51&r2=1.59.2.29.2.48.2.52&diff_format=u Index: ZendEngine2/zend_vm_def.h diff -u ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.51 ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.52 --- ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.51 Wed Apr 30 10:44:08 2008 +++ ZendEngine2/zend_vm_def.h Mon May 5 11:03:32 2008 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_vm_def.h,v 1.59.2.29.2.48.2.51 2008/04/30 10:44:08 dmitry Exp $ */ +/* $Id: zend_vm_def.h,v 1.59.2.29.2.48.2.52 2008/05/05 11:03:32 dmitry Exp $ */ /* If you change this file, please regenerate the zend_vm_execute.h and * zend_vm_opcodes.h files by running: @@ -2642,10 +2642,14 @@ switch (brk_opline->opcode) { case ZEND_SWITCH_FREE: - zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->op1.op_type, brk_opline->extended_value TSRMLS_CC); + if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) { + zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC); + } break; case ZEND_FREE: - zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var); + if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) { + zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var); + } break; } ZEND_VM_JMP(opline->op1.u.jmp_addr); @@ -2683,11 +2687,11 @@ ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(49, ZEND_SWITCH_FREE, TMP|VAR, ANY) +ZEND_VM_HANDLER(49, ZEND_SWITCH_FREE, VAR, ANY) { zend_op *opline = EX(opline); - zend_switch_free(&EX_T(opline->op1.u.var), OP1_TYPE, opline->extended_value TSRMLS_CC); + zend_switch_free(&EX_T(opline->op1.u.var), opline->extended_value TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); } @@ -4123,10 +4127,14 @@ switch (brk_opline->opcode) { case ZEND_SWITCH_FREE: - zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->op1.op_type, brk_opline->extended_value TSRMLS_CC); + if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) { + zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC); + } break; case ZEND_FREE: - zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var); + if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) { + zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var); + } break; } } http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_execute.h?r1=1.62.2.30.2.49.2.50&r2=1.62.2.30.2.49.2.51&diff_format=u Index: ZendEngine2/zend_vm_execute.h diff -u ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.50 ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.51 --- ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.50 Wed Apr 30 10:44:08 2008 +++ ZendEngine2/zend_vm_execute.h Mon May 5 11:03:33 2008 @@ -515,7 +515,7 @@ switch (brk_opline->opcode) { case ZEND_SWITCH_FREE: - zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->op1.op_type, brk_opline->extended_value TSRMLS_CC); + zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC); break; case ZEND_FREE: zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var); @@ -724,7 +724,7 @@ switch (brk_opline->opcode) { case ZEND_SWITCH_FREE: - zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->op1.op_type, brk_opline->extended_value TSRMLS_CC); + zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC); break; case ZEND_FREE: zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var); @@ -4735,14 +4735,6 @@ ZEND_VM_NEXT_OPCODE(); } -static int ZEND_SWITCH_FREE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zend_op *opline = EX(opline); - - zend_switch_free(&EX_T(opline->op1.u.var), IS_TMP_VAR, opline->extended_value TSRMLS_CC); - ZEND_VM_NEXT_OPCODE(); -} - static int ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); @@ -7990,7 +7982,7 @@ { zend_op *opline = EX(opline); - zend_switch_free(&EX_T(opline->op1.u.var), IS_VAR, opline->extended_value TSRMLS_CC); + zend_switch_free(&EX_T(opline->op1.u.var), opline->extended_value TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); } @@ -30747,11 +30739,11 @@ ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_SWITCH_FREE_SPEC_TMP_HANDLER, - ZEND_SWITCH_FREE_SPEC_TMP_HANDLER, - ZEND_SWITCH_FREE_SPEC_TMP_HANDLER, - ZEND_SWITCH_FREE_SPEC_TMP_HANDLER, - ZEND_SWITCH_FREE_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_SWITCH_FREE_SPEC_VAR_HANDLER, ZEND_SWITCH_FREE_SPEC_VAR_HANDLER, ZEND_SWITCH_FREE_SPEC_VAR_HANDLER, http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/bug44913.phpt?view=markup&rev=1.1 Index: ZendEngine2/tests/bug44913.phpt +++ ZendEngine2/tests/bug44913.phpt --TEST-- Bug #44913 (Segfault when using return in combination with nested loops and continue 2) --FILE-- <?php function something() { foreach(array(1, 2) as $value) { for($i = 0; $i < 1; $i++) { continue 2; } return; } } something(); echo "ok\n"; ?> --EXPECT-- ok
http://cvs.php.net/viewvc.cgi/php-src/NEWS?r1=1.2027.2.547.2.965.2.174&r2=1.2027.2.547.2.965.2.175&diff_format=u Index: php-src/NEWS diff -u php-src/NEWS:1.2027.2.547.2.965.2.174 php-src/NEWS:1.2027.2.547.2.965.2.175 --- php-src/NEWS:1.2027.2.547.2.965.2.174 Mon May 5 07:29:41 2008 +++ php-src/NEWS Mon May 5 11:03:32 2008 @@ -109,6 +109,7 @@ - Added Windows support for asinh(), acosh(), atanh(), log1p() and expm1() (Kalle) - Improved PHP runtime speed and memory usage: + . Use ZEND_FREE() opcode instead of ZEND_SWITCH_FREE(IS_TMP_VAR). (Dmitry) . Lazy EG(active_symbol_table) initialization. (Dmitry) . Optimized ZEND_RETURN opcode to not allocate and copy return value if it is not used. (Dmitry) @@ -169,6 +170,8 @@ - Fixed an issue in date() where a : was printed for the O modifier after a P modifier was used. (Derick) +- Fixed bug #44913 (Segfault when using return in combination with nested loops + and continue 2). (Dmitry) - Fixed bug #44899 (__isset usage changes behavior of empty()) (Etienne) - Fixed bug #44805 (rename() function is not portable to Windows). (Pierre) - Fixed bug #44742 (timezone_offset_get() causes segmentation faults). (Derick) http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_compile.c?r1=1.647.2.27.2.41.2.61&r2=1.647.2.27.2.41.2.62&diff_format=u Index: ZendEngine2/zend_compile.c diff -u ZendEngine2/zend_compile.c:1.647.2.27.2.41.2.61 ZendEngine2/zend_compile.c:1.647.2.27.2.41.2.62 --- ZendEngine2/zend_compile.c:1.647.2.27.2.41.2.61 Mon May 5 09:44:39 2008 +++ ZendEngine2/zend_compile.c Mon May 5 11:03:32 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_compile.c,v 1.647.2.27.2.41.2.61 2008/05/05 09:44:39 dmitry Exp $ */ +/* $Id: zend_compile.c,v 1.647.2.27.2.41.2.62 2008/05/05 11:03:32 dmitry Exp $ */ #include <zend_language_parser.h> #include "zend.h" @@ -2024,7 +2024,7 @@ opline = get_next_op(CG(active_op_array) TSRMLS_CC); - opline->opcode = ZEND_SWITCH_FREE; + opline->opcode = (switch_entry->cond.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE; opline->op1 = switch_entry->cond; SET_UNUSED(opline->op2); opline->extended_value = 0; @@ -2042,7 +2042,7 @@ opline = get_next_op(CG(active_op_array) TSRMLS_CC); - opline->opcode = ZEND_SWITCH_FREE; + opline->opcode = (foreach_copy->result.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE; opline->op1 = foreach_copy->result; SET_UNUSED(opline->op2); opline->extended_value = 1; @@ -2050,7 +2050,7 @@ if (foreach_copy->op1.op_type != IS_UNUSED) { opline = get_next_op(CG(active_op_array) TSRMLS_CC); - opline->opcode = ZEND_SWITCH_FREE; + opline->opcode = (foreach_copy->op1.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE; opline->op1 = foreach_copy->op1; SET_UNUSED(opline->op2); opline->extended_value = 0; @@ -2062,6 +2062,7 @@ void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) { zend_op *opline; + int start_op_number, end_op_number; if (do_end_vparse) { if (CG(active_op_array)->return_reference && !zend_is_function_or_method_call(expr)) { @@ -2071,6 +2072,8 @@ } } + start_op_number = 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); @@ -2079,6 +2082,12 @@ zend_stack_apply(&CG(foreach_copy_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element)) generate_free_foreach_copy); #endif + end_op_number = get_next_op_number(CG(active_op_array)); + while (start_op_number < end_op_number) { + CG(active_op_array)->opcodes[start_op_number].op1.u.EA.type = EXT_TYPE_FREE_ON_RETURN; + start_op_number++; + } + opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_RETURN; @@ -3075,7 +3084,7 @@ if (switch_entry_ptr->cond.op_type==IS_VAR || switch_entry_ptr->cond.op_type==IS_TMP_VAR) { /* emit free for the switch condition*/ opline = get_next_op(CG(active_op_array) TSRMLS_CC); - opline->opcode = ZEND_SWITCH_FREE; + opline->opcode = (switch_entry_ptr->cond.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE; opline->op1 = switch_entry_ptr->cond; SET_UNUSED(opline->op2); } http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_compile.h?r1=1.316.2.8.2.12.2.21&r2=1.316.2.8.2.12.2.22&diff_format=u Index: ZendEngine2/zend_compile.h diff -u ZendEngine2/zend_compile.h:1.316.2.8.2.12.2.21 ZendEngine2/zend_compile.h:1.316.2.8.2.12.2.22 --- ZendEngine2/zend_compile.h:1.316.2.8.2.12.2.21 Sat Mar 29 11:52:10 2008 +++ ZendEngine2/zend_compile.h Mon May 5 11:03:32 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_compile.h,v 1.316.2.8.2.12.2.21 2008/03/29 11:52:10 felipe Exp $ */ +/* $Id: zend_compile.h,v 1.316.2.8.2.12.2.22 2008/05/05 11:03:32 dmitry Exp $ */ #ifndef ZEND_COMPILE_H #define ZEND_COMPILE_H @@ -323,7 +323,8 @@ #define IS_UNUSED (1<<3) /* Unused variable */ #define IS_CV (1<<4) /* Compiled variable */ -#define EXT_TYPE_UNUSED (1<<0) +#define EXT_TYPE_UNUSED (1<<0) +#define EXT_TYPE_FREE_ON_RETURN (2<<0) #include "zend_globals.h" http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_execute.c?r1=1.716.2.12.2.24.2.26&r2=1.716.2.12.2.24.2.27&diff_format=u Index: ZendEngine2/zend_execute.c diff -u ZendEngine2/zend_execute.c:1.716.2.12.2.24.2.26 ZendEngine2/zend_execute.c:1.716.2.12.2.24.2.27 --- ZendEngine2/zend_execute.c:1.716.2.12.2.24.2.26 Tue Apr 29 08:15:16 2008 +++ ZendEngine2/zend_execute.c Mon May 5 11:03:32 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_execute.c,v 1.716.2.12.2.24.2.26 2008/04/29 08:15:16 dmitry Exp $ */ +/* $Id: zend_execute.c,v 1.716.2.12.2.24.2.27 2008/05/05 11:03:32 dmitry Exp $ */ #define ZEND_INTENSIVE_DEBUGGING 0 @@ -377,22 +377,18 @@ return get_zval_ptr(op, Ts, should_free, type); } -static inline void zend_switch_free(temp_variable *T, int type, int extended_value TSRMLS_DC) +static inline void zend_switch_free(temp_variable *T, int extended_value TSRMLS_DC) { - if (type == IS_VAR) { - if (T->var.ptr) { - if (extended_value & ZEND_FE_RESET_VARIABLE) { /* foreach() free */ - Z_DELREF_P(T->var.ptr); - } - zval_ptr_dtor(&T->var.ptr); - } else if (!T->var.ptr_ptr) { - /* perform the equivalent of equivalent of a - * quick & silent get_zval_ptr, and FREE_OP - */ - PZVAL_UNLOCK_FREE(T->str_offset.str); - } - } else { /* IS_TMP_VAR */ - zendi_zval_dtor(T->tmp_var); + if (T->var.ptr) { + if (extended_value & ZEND_FE_RESET_VARIABLE) { /* foreach() free */ + Z_DELREF_P(T->var.ptr); + } + zval_ptr_dtor(&T->var.ptr); + } else if (!T->var.ptr_ptr) { + /* perform the equivalent of equivalent of a + * quick & silent get_zval_ptr, and FREE_OP + */ + PZVAL_UNLOCK_FREE(T->str_offset.str); } } @@ -1241,10 +1237,14 @@ switch (brk_opline->opcode) { case ZEND_SWITCH_FREE: - zend_switch_free(&T(brk_opline->op1.u.var), brk_opline->op1.op_type, brk_opline->extended_value TSRMLS_CC); + if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) { + zend_switch_free(&T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC); + } break; case ZEND_FREE: - zendi_zval_dtor(T(brk_opline->op1.u.var).tmp_var); + if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) { + zendi_zval_dtor(T(brk_opline->op1.u.var).tmp_var); + } break; } } http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_def.h?r1=1.59.2.29.2.48.2.51&r2=1.59.2.29.2.48.2.52&diff_format=u Index: ZendEngine2/zend_vm_def.h diff -u ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.51 ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.52 --- ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.51 Wed Apr 30 10:44:08 2008 +++ ZendEngine2/zend_vm_def.h Mon May 5 11:03:32 2008 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_vm_def.h,v 1.59.2.29.2.48.2.51 2008/04/30 10:44:08 dmitry Exp $ */ +/* $Id: zend_vm_def.h,v 1.59.2.29.2.48.2.52 2008/05/05 11:03:32 dmitry Exp $ */ /* If you change this file, please regenerate the zend_vm_execute.h and * zend_vm_opcodes.h files by running: @@ -2642,10 +2642,14 @@ switch (brk_opline->opcode) { case ZEND_SWITCH_FREE: - zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->op1.op_type, brk_opline->extended_value TSRMLS_CC); + if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) { + zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC); + } break; case ZEND_FREE: - zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var); + if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) { + zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var); + } break; } ZEND_VM_JMP(opline->op1.u.jmp_addr); @@ -2683,11 +2687,11 @@ ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(49, ZEND_SWITCH_FREE, TMP|VAR, ANY) +ZEND_VM_HANDLER(49, ZEND_SWITCH_FREE, VAR, ANY) { zend_op *opline = EX(opline); - zend_switch_free(&EX_T(opline->op1.u.var), OP1_TYPE, opline->extended_value TSRMLS_CC); + zend_switch_free(&EX_T(opline->op1.u.var), opline->extended_value TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); } @@ -4123,10 +4127,14 @@ switch (brk_opline->opcode) { case ZEND_SWITCH_FREE: - zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->op1.op_type, brk_opline->extended_value TSRMLS_CC); + if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) { + zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC); + } break; case ZEND_FREE: - zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var); + if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) { + zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var); + } break; } } http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_execute.h?r1=1.62.2.30.2.49.2.50&r2=1.62.2.30.2.49.2.51&diff_format=u Index: ZendEngine2/zend_vm_execute.h diff -u ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.50 ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.51 --- ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.50 Wed Apr 30 10:44:08 2008 +++ ZendEngine2/zend_vm_execute.h Mon May 5 11:03:33 2008 @@ -515,7 +515,7 @@ switch (brk_opline->opcode) { case ZEND_SWITCH_FREE: - zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->op1.op_type, brk_opline->extended_value TSRMLS_CC); + zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC); break; case ZEND_FREE: zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var); @@ -724,7 +724,7 @@ switch (brk_opline->opcode) { case ZEND_SWITCH_FREE: - zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->op1.op_type, brk_opline->extended_value TSRMLS_CC); + zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC); break; case ZEND_FREE: zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var); @@ -4735,14 +4735,6 @@ ZEND_VM_NEXT_OPCODE(); } -static int ZEND_SWITCH_FREE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zend_op *opline = EX(opline); - - zend_switch_free(&EX_T(opline->op1.u.var), IS_TMP_VAR, opline->extended_value TSRMLS_CC); - ZEND_VM_NEXT_OPCODE(); -} - static int ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); @@ -7990,7 +7982,7 @@ { zend_op *opline = EX(opline); - zend_switch_free(&EX_T(opline->op1.u.var), IS_VAR, opline->extended_value TSRMLS_CC); + zend_switch_free(&EX_T(opline->op1.u.var), opline->extended_value TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); } @@ -30747,11 +30739,11 @@ ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_SWITCH_FREE_SPEC_TMP_HANDLER, - ZEND_SWITCH_FREE_SPEC_TMP_HANDLER, - ZEND_SWITCH_FREE_SPEC_TMP_HANDLER, - ZEND_SWITCH_FREE_SPEC_TMP_HANDLER, - ZEND_SWITCH_FREE_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_SWITCH_FREE_SPEC_VAR_HANDLER, ZEND_SWITCH_FREE_SPEC_VAR_HANDLER, ZEND_SWITCH_FREE_SPEC_VAR_HANDLER, http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/bug44913.phpt?view=markup&rev=1.1 Index: ZendEngine2/tests/bug44913.phpt +++ ZendEngine2/tests/bug44913.phpt --TEST-- Bug #44913 (Segfault when using return in combination with nested loops and continue 2) --FILE-- <?php function something() { foreach(array(1, 2) as $value) { for($i = 0; $i < 1; $i++) { continue 2; } return; } } something(); echo "ok\n"; ?> --EXPECT-- ok