diff options
Diffstat (limited to 'Zend/zend_execute.c')
| -rw-r--r-- | Zend/zend_execute.c | 53 |
1 files changed, 28 insertions, 25 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 3b27bcefb..4b3631cd7 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) 1998-2006 Zend Technologies Ltd. (http://www.zend.com) | + | Copyright (c) 1998-2007 Zend Technologies Ltd. (http://www.zend.com) | +----------------------------------------------------------------------+ | This source file is subject to version 2.00 of the Zend license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_execute.c,v 1.716.2.12.2.12 2006/10/02 11:09:52 tony2001 Exp $ */ +/* $Id: zend_execute.c,v 1.716.2.12.2.19 2007/04/16 08:09:54 dmitry Exp $ */ #define ZEND_INTENSIVE_DEBUGGING 0 @@ -64,7 +64,7 @@ static void zend_extension_fcall_end_handler(zend_extension *extension, zend_op_ #define TEMP_VAR_STACK_LIMIT 2000 -static inline void zend_pzval_unlock_func(zval *z, zend_free_op *should_free) +static inline void zend_pzval_unlock_func(zval *z, zend_free_op *should_free, int unref) { if (!--z->refcount) { z->refcount = 1; @@ -73,7 +73,7 @@ static inline void zend_pzval_unlock_func(zval *z, zend_free_op *should_free) /* should_free->is_var = 1; */ } else { should_free->var = 0; - if (z->is_ref && z->refcount == 1) { + if (unref && z->is_ref && z->refcount == 1) { z->is_ref = 0; } } @@ -87,7 +87,8 @@ static inline void zend_pzval_unlock_free_func(zval *z) } } -#define PZVAL_UNLOCK(z, f) zend_pzval_unlock_func(z, f) +#define PZVAL_UNLOCK(z, f) zend_pzval_unlock_func(z, f, 1) +#define PZVAL_UNLOCK_EX(z, f, u) zend_pzval_unlock_func(z, f, u) #define PZVAL_UNLOCK_FREE(z) zend_pzval_unlock_free_func(z) #define PZVAL_LOCK(z) (z)->refcount++ #define RETURN_VALUE_UNUSED(pzn) (((pzn)->u.EA.type & EXT_TYPE_UNUSED)) @@ -103,15 +104,15 @@ static inline void zend_pzval_unlock_free_func(zval *z) #define FREE_OP(should_free) \ if (should_free.var) { \ - if ((long)should_free.var & 1L) { \ - zval_dtor((zval*)((long)should_free.var & ~1L)); \ + if ((zend_uintptr_t)should_free.var & 1L) { \ + zval_dtor((zval*)((zend_uintptr_t)should_free.var & ~1L)); \ } else { \ zval_ptr_dtor(&should_free.var); \ } \ } #define FREE_OP_IF_VAR(should_free) \ - if (should_free.var != NULL && (((long)should_free.var & 1L) == 0)) { \ + if (should_free.var != NULL && (((zend_uintptr_t)should_free.var & 1L) == 0)) { \ zval_ptr_dtor(&should_free.var); \ } @@ -120,9 +121,9 @@ static inline void zend_pzval_unlock_free_func(zval *z) zval_ptr_dtor(&should_free.var); \ } -#define TMP_FREE(z) (zval*)(((long)(z)) | 1L) +#define TMP_FREE(z) (zval*)(((zend_uintptr_t)(z)) | 1L) -#define IS_TMP_FREE(should_free) ((long)should_free.var & 1L) +#define IS_TMP_FREE(should_free) ((zend_uintptr_t)should_free.var & 1L) #define INIT_PZVAL_COPY(z,v) \ (z)->value = (v)->value; \ @@ -411,11 +412,7 @@ static void zend_assign_to_variable_reference(zval **variable_ptr_ptr, zval **va *variable_ptr_ptr = value_ptr; value_ptr->refcount++; - variable_ptr->refcount--; - if (variable_ptr->refcount==0) { - zendi_zval_dtor(*variable_ptr); - FREE_ZVAL(variable_ptr); - } + zval_ptr_dtor(&variable_ptr); } else if (!variable_ptr->is_ref) { if (variable_ptr_ptr == value_ptr_ptr) { SEPARATE_ZVAL(variable_ptr_ptr); @@ -614,7 +611,7 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode Z_OBJ_HT_P(object)->write_dimension(object, property_name, value TSRMLS_CC); } - if (result && !RETURN_VALUE_UNUSED(result)) { + if (result && !RETURN_VALUE_UNUSED(result) && !EG(exception)) { T(result->u.var).var.ptr = value; T(result->u.var).var.ptr_ptr = &T(result->u.var).var.ptr; /* this is so that we could use it in FETCH_DIM_R, etc. - see bug #27876 */ PZVAL_LOCK(value); @@ -1166,16 +1163,22 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC); if (overloaded_result) { - switch (type) { - case BP_VAR_RW: - case BP_VAR_W: - if (Z_TYPE_P(overloaded_result) != IS_OBJECT - && !overloaded_result->is_ref) { - zend_error_noreturn(E_ERROR, "Objects used as arrays in post/pre increment/decrement must return values by reference"); - } - break; + if (!overloaded_result->is_ref && + (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)) { + if (overloaded_result->refcount > 0) { + zval *tmp = overloaded_result; + + ALLOC_ZVAL(overloaded_result); + *overloaded_result = *tmp; + zval_copy_ctor(overloaded_result); + overloaded_result->is_ref = 0; + overloaded_result->refcount = 0; + } + if (Z_TYPE_P(overloaded_result) != IS_OBJECT) { + zend_class_entry *ce = Z_OBJCE_P(container); + zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name); + } } - retval = &overloaded_result; } else { retval = &EG(error_zval_ptr); |
