summaryrefslogtreecommitdiff
path: root/Zend/zend_execute.c
diff options
context:
space:
mode:
authorZeev Suraski <zeev@php.net>2006-06-05 13:58:52 +0000
committerZeev Suraski <zeev@php.net>2006-06-05 13:58:52 +0000
commit51d495850a74177f38207b1e39c3365b77a5a7d6 (patch)
treeb7410f4625f924023eedd812142e797b5591fe3e /Zend/zend_execute.c
parent163f0da75a820a52fa06bad1e420df1cc644bbd3 (diff)
downloadphp-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.c104
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 */