diff options
author | Zeev Suraski <zeev@php.net> | 2006-06-05 13:58:52 +0000 |
---|---|---|
committer | Zeev Suraski <zeev@php.net> | 2006-06-05 13:58:52 +0000 |
commit | 51d495850a74177f38207b1e39c3365b77a5a7d6 (patch) | |
tree | b7410f4625f924023eedd812142e797b5591fe3e /Zend/zend_execute.c | |
parent | 163f0da75a820a52fa06bad1e420df1cc644bbd3 (diff) | |
download | php-git-51d495850a74177f38207b1e39c3365b77a5a7d6.tar.gz |
Restore ZE1 compatibility mode (Zend Engine part - the modules patches
will follow later today)
Diffstat (limited to 'Zend/zend_execute.c')
-rw-r--r-- | Zend/zend_execute.c | 104 |
1 files changed, 98 insertions, 6 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index f7a19a5845..99fb7ac7ad 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -554,11 +554,30 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode FREE_OP(free_value); return; } - + /* here we are sure we are dealing with an object */ /* separate our value if necessary */ - if (value_op->op_type == IS_TMP_VAR) { + if (EG(ze1_compatibility_mode) && Z_TYPE_P(value) == IS_OBJECT) { + zval *orig_value = value; + char *class_name; + zend_uint class_name_len; + int dup; + + ALLOC_ZVAL(value); + *value = *orig_value; + value->is_ref = 0; + value->refcount = 0; + dup = zend_get_object_classname(orig_value, &class_name, &class_name_len TSRMLS_CC); + if (Z_OBJ_HANDLER_P(value, clone_obj) == NULL) { + zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name); + } + zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name); + value->value.obj = Z_OBJ_HANDLER_P(orig_value, clone_obj)(orig_value TSRMLS_CC); + if(!dup) { + efree(class_name); + } + } else if (value_op->op_type == IS_TMP_VAR) { zval *orig_value = value; ALLOC_ZVAL(value); @@ -701,7 +720,55 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2 goto done_setting_var; } - if (PZVAL_IS_REF(variable_ptr)) { + if (EG(ze1_compatibility_mode) && Z_TYPE_P(value) == IS_OBJECT) { + char *class_name; + zend_uint class_name_len; + int dup; + + dup = zend_get_object_classname(value, &class_name, &class_name_len TSRMLS_CC); + + if (Z_OBJ_HANDLER_P(value, clone_obj) == NULL) { + zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name); + } else if (PZVAL_IS_REF(variable_ptr)) { + if (variable_ptr != value) { + zend_uint refcount = variable_ptr->refcount; + zval garbage; + + if (type != IS_TMP_VAR) { + value->refcount++; + } + garbage = *variable_ptr; + *variable_ptr = *value; + variable_ptr->refcount = refcount; + variable_ptr->is_ref = 1; + zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name); + variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC); + if (type != IS_TMP_VAR) { + value->refcount--; + } + zendi_zval_dtor(garbage); + } + } else { + if (variable_ptr != value) { + value->refcount++; + variable_ptr->refcount--; + if (variable_ptr->refcount == 0) { + zendi_zval_dtor(*variable_ptr); + } else { + ALLOC_ZVAL(variable_ptr); + *variable_ptr_ptr = variable_ptr; + } + *variable_ptr = *value; + INIT_PZVAL(variable_ptr); + zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name); + variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC); + zval_ptr_dtor(&value); + } + } + if (!dup) { + efree(class_name); + } + } else if (PZVAL_IS_REF(variable_ptr)) { if (variable_ptr!=value) { zend_uint refcount = variable_ptr->refcount; zval garbage; @@ -791,9 +858,34 @@ done_setting_var: static inline void zend_receive(zval **variable_ptr_ptr, zval *value TSRMLS_DC) { - (*variable_ptr_ptr)->refcount--; - *variable_ptr_ptr = value; - value->refcount++; + zval *variable_ptr = *variable_ptr_ptr; + + if (EG(ze1_compatibility_mode) && Z_TYPE_P(value) == IS_OBJECT) { + char *class_name; + zend_uint class_name_len; + int dup; + + dup = zend_get_object_classname(value, &class_name, &class_name_len TSRMLS_CC); + + if (Z_OBJ_HANDLER_P(value, clone_obj) == NULL) { + zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name); + } else { + variable_ptr->refcount--; + ALLOC_ZVAL(variable_ptr); + *variable_ptr_ptr = variable_ptr; + *variable_ptr = *value; + INIT_PZVAL(variable_ptr); + zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name); + variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC); + } + if (!dup) { + efree(class_name); + } + } else { + variable_ptr->refcount--; + *variable_ptr_ptr = value; + value->refcount++; + } } /* Utility Functions for Extensions */ |