cvs: ZendEngine2 / zend_compile.c zend_compile.h zend_execute.c zend_vm_def.h zend_vm_execute.h /tests bug44913.phpt
[email protected] ("Dmitry Stogov")
| Newsgroups | php.zend-engine.cvs |
|---|---|
| Message-ID | <cvsdmitry1209985366@cvsserver> |
dmitry Mon May 5 11:02:46 2008 UTC
Added files:
/ZendEngine2/tests bug44913.phpt
Modified files:
/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)
dmitry-20080505110246.txt
(text/plain, 11.6 KB)
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_compile.c?r1=1.821&r2=1.822&diff_format=u
Index: ZendEngine2/zend_compile.c
diff -u ZendEngine2/zend_compile.c:1.821 ZendEngine2/zend_compile.c:1.822
--- ZendEngine2/zend_compile.c:1.821 Mon May 5 09:44:07 2008
+++ ZendEngine2/zend_compile.c Mon May 5 11:02:45 2008
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_compile.c,v 1.821 2008/05/05 09:44:07 dmitry Exp $ */
+/* $Id: zend_compile.c,v 1.822 2008/05/05 11:02:45 dmitry Exp $ */
#include <zend_language_parser.h>
#include "zend.h"
@@ -2129,7 +2129,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;
@@ -2148,7 +2148,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;
@@ -2156,7 +2156,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;
@@ -2169,6 +2169,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)) {
@@ -2178,6 +2179,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);
@@ -2186,6 +2189,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;
@@ -3225,7 +3234,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.378&r2=1.379&diff_format=u
Index: ZendEngine2/zend_compile.h
diff -u ZendEngine2/zend_compile.h:1.378 ZendEngine2/zend_compile.h:1.379
--- ZendEngine2/zend_compile.h:1.378 Wed Mar 26 14:23:01 2008
+++ ZendEngine2/zend_compile.h Mon May 5 11:02:45 2008
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_compile.h,v 1.378 2008/03/26 14:23:01 scottmac Exp $ */
+/* $Id: zend_compile.h,v 1.379 2008/05/05 11:02:45 dmitry Exp $ */
#ifndef ZEND_COMPILE_H
#define ZEND_COMPILE_H
@@ -324,7 +324,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.794&r2=1.795&diff_format=u
Index: ZendEngine2/zend_execute.c
diff -u ZendEngine2/zend_execute.c:1.794 ZendEngine2/zend_execute.c:1.795
--- ZendEngine2/zend_execute.c:1.794 Tue Apr 29 08:15:48 2008
+++ ZendEngine2/zend_execute.c Mon May 5 11:02:45 2008
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_execute.c,v 1.794 2008/04/29 08:15:48 dmitry Exp $ */
+/* $Id: zend_execute.c,v 1.795 2008/05/05 11:02:45 dmitry Exp $ */
#define ZEND_INTENSIVE_DEBUGGING 0
@@ -412,22 +412,18 @@
}
/* }}} */
-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);
}
}
/* }}} */
@@ -1347,10 +1343,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.227&r2=1.228&diff_format=u
Index: ZendEngine2/zend_vm_def.h
diff -u ZendEngine2/zend_vm_def.h:1.227 ZendEngine2/zend_vm_def.h:1.228
--- ZendEngine2/zend_vm_def.h:1.227 Wed Apr 30 10:44:24 2008
+++ ZendEngine2/zend_vm_def.h Mon May 5 11:02:45 2008
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_vm_def.h,v 1.227 2008/04/30 10:44:24 dmitry Exp $ */
+/* $Id: zend_vm_def.h,v 1.228 2008/05/05 11:02:45 dmitry Exp $ */
/* If you change this file, please regenerate the zend_vm_execute.h and
* zend_vm_opcodes.h files by running:
@@ -2702,10 +2702,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);
@@ -2743,11 +2747,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();
}
@@ -4287,10 +4291,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.231&r2=1.232&diff_format=u
Index: ZendEngine2/zend_vm_execute.h
diff -u ZendEngine2/zend_vm_execute.h:1.231 ZendEngine2/zend_vm_execute.h:1.232
--- ZendEngine2/zend_vm_execute.h:1.231 Wed Apr 30 10:44:24 2008
+++ ZendEngine2/zend_vm_execute.h Mon May 5 11:02:45 2008
@@ -523,10 +523,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;
}
}
@@ -733,10 +737,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);
@@ -4868,14 +4876,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);
@@ -8266,7 +8266,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();
}
@@ -31948,11 +31948,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