cvs: ZendEngine2 / zend_compile.c zend_compile.h zend_execute.c zend_execute.h

From: Date: Sun, 14 Dec 2003 16:09:08 +0000
Subject: cvs: ZendEngine2 / zend_compile.c zend_compile.h zend_execute.c zend_execute.h
Groups: php.zend-engine.cvs 
Request: Send a blank email to php-zend-engine-cvs+get-2115@lists.php.net to get a copy of this message
zeev Sun Dec 14 11:09:08 2003 EDT Modified files: /ZendEngine2 zend_compile.c zend_compile.h zend_execute.c zend_execute.h Log: Fix behavior of return-by-reference functions. Remove erroneous warnings, add E_STRICT warnings in case you return something by reference that you're not supposed to (anything that's not a variable, or a return-value of a function that returned by reference). Index: ZendEngine2/zend_compile.c diff -u ZendEngine2/zend_compile.c:1.501 ZendEngine2/zend_compile.c:1.502 --- ZendEngine2/zend_compile.c:1.501 Sat Dec 6 14:02:12 2003 +++ ZendEngine2/zend_compile.c Sun Dec 14 11:09:07 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_compile.c,v 1.501 2003/12/06 19:02:12 helly Exp $ */ +/* $Id: zend_compile.c,v 1.502 2003/12/14 16:09:07 zeev Exp $ */ #include "zend_language_parser.h" #include "zend.h" @@ -739,7 +739,7 @@ } } -zend_bool zend_is_function_or_method_call(znode *variable) +static inline zend_bool zend_is_function_or_method_call(znode *variable) { zend_uint type = variable->u.EA.type; @@ -1475,10 +1475,6 @@ } else { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); } -#if 0 - } else if (expr && CG(active_op_array)->return_reference) { - zend_error(E_COMPILE_ERROR, "Only variables may be returned by reference"); -#endif } #ifdef ZTS @@ -1499,6 +1495,15 @@ opline->op1.op_type = IS_CONST; INIT_ZVAL(opline->op1.u.constant); } + + if (do_end_vparse) { + if (zend_is_function_or_method_call(expr)) { + opline->extended_value = ZEND_RETURNS_FUNCTION; + } else { + opline->extended_value = 0; + } + } + SET_UNUSED(opline->op2); } Index: ZendEngine2/zend_compile.h diff -u ZendEngine2/zend_compile.h:1.263 ZendEngine2/zend_compile.h:1.264 --- ZendEngine2/zend_compile.h:1.263 Mon Nov 24 13:13:29 2003 +++ ZendEngine2/zend_compile.h Sun Dec 14 11:09:07 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_compile.h,v 1.263 2003/11/24 18:13:29 andi Exp $ */ +/* $Id: zend_compile.h,v 1.264 2003/12/14 16:09:07 zeev Exp $ */ #ifndef ZEND_COMPILE_H #define ZEND_COMPILE_H @@ -790,6 +790,9 @@ #define ZEND_RETURN_VAL 0 #define ZEND_RETURN_REF 1 + +#define ZEND_RETURNS_FUNCTION 1<<0 + END_EXTERN_C() #define ZEND_CLONE_FUNC_NAME "__clone" Index: ZendEngine2/zend_execute.c diff -u ZendEngine2/zend_execute.c:1.564 ZendEngine2/zend_execute.c:1.565 --- ZendEngine2/zend_execute.c:1.564 Sun Dec 14 07:32:02 2003 +++ ZendEngine2/zend_execute.c Sun Dec 14 11:09:07 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_execute.c,v 1.564 2003/12/14 12:32:02 zeev Exp $ */ +/* $Id: zend_execute.c,v 1.565 2003/12/14 16:09:07 zeev Exp $ */ #define ZEND_INTENSIVE_DEBUGGING 0 @@ -2512,6 +2512,8 @@ should_change_scope = 0; } + EX_T(EX(opline)->result.u.var).var.fcall_returned_reference = 0; + if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { ALLOC_ZVAL(EX_T(EX(opline)->result.u.var).var.ptr); INIT_ZVAL(*(EX_T(EX(opline)->result.u.var).var.ptr)); @@ -2561,6 +2563,7 @@ EG(active_op_array) = (zend_op_array *) EX(function_state).function; zend_execute(EG(active_op_array) TSRMLS_CC); + EX_T(EX(opline)->result.u.var).var.fcall_returned_reference = EG(active_op_array)->return_reference; if (return_value_used && !EX_T(EX(opline)->result.u.var).var.ptr) { if (!EG(exception)) { @@ -2685,20 +2688,28 @@ { zval *retval_ptr; zval **retval_ptr_ptr; - - if ((EG(active_op_array)->return_reference == ZEND_RETURN_REF) && - (EX(opline)->op1.op_type != IS_CONST) && - (EX(opline)->op1.op_type != IS_TMP_VAR)) { - + + if (EG(active_op_array)->return_reference == ZEND_RETURN_REF) { + if (EX(opline)->op1.op_type == IS_CONST || EX(opline)->op1.op_type == IS_TMP_VAR) { + /* Not supposed to happen, but we'll allow it */ + zend_error(E_STRICT, "Only variable references should be returned by reference"); + goto return_by_value; + } + retval_ptr_ptr = get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), BP_VAR_W); if (!retval_ptr_ptr) { - zend_error(E_ERROR, "Cannot return overloaded elements or string offsets by reference"); + zend_error(E_ERROR, "Cannot return string offsets by reference"); } if (!(*retval_ptr_ptr)->is_ref - && EX_T(EX(opline)->op1.u.var).var.ptr_ptr == &EX_T(EX(opline)->op1.u.var).var.ptr) { - zend_error(E_ERROR, "Only variables or references can be returned by reference"); + /*&& EX_T(EX(opline)->op1.u.var).var.ptr_ptr == &EX_T(EX(opline)->op1.u.var).var.ptr*/) { + if (EX(opline)->extended_value == ZEND_RETURNS_FUNCTION + && !EX_T(EX(opline)->op1.u.var).var.fcall_returned_reference) { + zend_error(E_STRICT, "Only variable references should be returned by reference"); + PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */ + goto return_by_value; + } } SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr); @@ -2706,6 +2717,7 @@ (*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr); } else { +return_by_value: retval_ptr = get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R); if (!EG(free_op1)) { /* Not a temp var */ Index: ZendEngine2/zend_execute.h diff -u ZendEngine2/zend_execute.h:1.59 ZendEngine2/zend_execute.h:1.60 --- ZendEngine2/zend_execute.h:1.59 Sun Dec 14 07:32:02 2003 +++ ZendEngine2/zend_execute.h Sun Dec 14 11:09:07 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_execute.h,v 1.59 2003/12/14 12:32:02 zeev Exp $ */ +/* $Id: zend_execute.h,v 1.60 2003/12/14 16:09:07 zeev Exp $ */ #ifndef ZEND_EXECUTE_H #define ZEND_EXECUTE_H @@ -36,6 +36,7 @@ zval *str; zend_uint offset; } str_offset; + zend_bool fcall_returned_reference; } var; zend_class_entry *class_entry; } temp_variable;

« previous php.zend-engine.cvs (#2115) next »