From: Dmitry Stogov Date: Thu, 27 Feb 2014 11:40:13 +0000 (+0400) Subject: Refactored read_property() and read_dimension() handlers X-Git-Tag: POST_PHPNG_MERGE~412^2~505 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1c3ba95bb547f8d9b0bd0496238a76ef6a706b07;p=php Refactored read_property() and read_dimension() handlers --- diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 417ae1032e..32f60dc232 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3858,6 +3858,7 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const c { zval property, *value; zend_class_entry *old_scope = EG(scope); + zval rv; EG(scope) = scope; @@ -3867,7 +3868,7 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const c } ZVAL_STRINGL(&property, name, name_length); - value = Z_OBJ_HT_P(object)->read_property(object, &property, silent?BP_VAR_IS:BP_VAR_R, 0 TSRMLS_CC); + value = Z_OBJ_HT_P(object)->read_property(object, &property, silent?BP_VAR_IS:BP_VAR_R, 0, &rv TSRMLS_CC); zval_ptr_dtor(&property); EG(scope) = old_scope; diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index e2bffd8dbf..ca2761ef51 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1154,6 +1154,7 @@ fetch_from_array: retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC); } //??? ZVAL_COPY(result, retval); + if (Z_REFCOUNTED_P(retval)) Z_ADDREF_P(retval); ZVAL_INDIRECT(result, retval); return; break; @@ -1241,7 +1242,7 @@ convert_to_array: //??? MAKE_REAL_ZVAL_PTR(dim); //??? ZVAL_NULL(orig); //??? } - overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC); + overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result TSRMLS_CC); if (overloaded_result) { //??? if (!Z_ISREF_P(overloaded_result)) { @@ -1261,7 +1262,10 @@ convert_to_array: //??? AI_SET_PTR(result, overloaded_result); //??? PZVAL_LOCK(overloaded_result); //??? ZVAL_COPY(result, overloaded_result); - ZVAL_INDIRECT(result, overloaded_result); + if (result != overloaded_result) { + if (Z_REFCOUNTED_P(overloaded_result)) Z_ADDREF_P(overloaded_result); + ZVAL_INDIRECT(result, overloaded_result); + } } else { result = &EG(error_zval); } @@ -1364,11 +1368,13 @@ static void zend_fetch_dimension_address_read(zval *result, zval *container, zva //??? MAKE_REAL_ZVAL_PTR(dim); //??? ZVAL_NULL(orig); //??? } - overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC); + overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result TSRMLS_CC); if (result) { if (overloaded_result) { - ZVAL_COPY(result, overloaded_result); + if (result != overloaded_result) { + ZVAL_COPY(result, overloaded_result); + } } else { ZVAL_NULL(result); } @@ -1413,20 +1419,27 @@ static void zend_fetch_property_address(zval *result, zval *container, zval *pro zval *ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, key TSRMLS_CC); if (NULL == ptr) { if (Z_OBJ_HT_P(container)->read_property && - (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, key TSRMLS_CC)) != NULL) { + (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, key, result TSRMLS_CC)) != NULL) { + if (ptr != result) { //??? ZVAL_COPY(result, ptr); - ZVAL_INDIRECT(result, ptr); + if (Z_REFCOUNTED_P(ptr)) Z_ADDREF_P(ptr); + ZVAL_INDIRECT(result, ptr); + } } else { zend_error_noreturn(E_ERROR, "Cannot access undefined property for object with overloaded property access"); } } else { //??? ZVAL_COPY(result, ptr); + if (Z_REFCOUNTED_P(ptr)) Z_ADDREF_P(ptr); ZVAL_INDIRECT(result, ptr); } } else if (Z_OBJ_HT_P(container)->read_property) { - zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, key TSRMLS_CC); + zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, key, result TSRMLS_CC); + if (ptr != result) { //??? ZVAL_COPY(result, ptr); - ZVAL_INDIRECT(result, ptr); + if (Z_REFCOUNTED_P(ptr)) Z_ADDREF_P(ptr); + ZVAL_INDIRECT(result, ptr); + } } else { zend_error(E_WARNING, "This object doesn't support property references"); ZVAL_INDIRECT(result, &EG(error_zval)); diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 5195d15cd2..81efca6c83 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -86,7 +86,7 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */ prop_info->offset >= 0 && Z_TYPE(zobj->properties_table[prop_info->offset]) != IS_UNDEF) { zval *zv = zend_hash_add(zobj->properties, prop_info->name, &zobj->properties_table[prop_info->offset]); - if (EXPECTED(zv)) { + if (EXPECTED(zv != NULL)) { ZVAL_INDIRECT(&zobj->properties_table[prop_info->offset], zv); } } @@ -419,12 +419,12 @@ static long *zend_get_property_guard(zend_object *zobj, zend_property_info *prop } /* }}} */ -zval *zend_std_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */ +zval *zend_std_read_property(zval *object, zval *member, int type, const zend_literal *key, zval *rv TSRMLS_DC) /* {{{ */ { zend_object *zobj; zval tmp_member; zval *retval; - zval rv; +//??? zval rv; zend_property_info *property_info; int silent; @@ -471,13 +471,13 @@ zval *zend_std_read_property(zval *object, zval *member, int type, const zend_li SEPARATE_ZVAL(object); } *guard |= IN_GET; /* prevent circular getting */ - zend_std_call_getter(object, member, &rv TSRMLS_CC); + zend_std_call_getter(object, member, rv TSRMLS_CC); *guard &= ~IN_GET; + if (Z_TYPE_P(rv) != IS_UNDEF) { + retval = rv; //??? #if 0 - if (rv) { - retval = rv; if (!Z_ISREF_P(rv) && (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)) { if (Z_REFCOUNT_P(rv) > 0) { @@ -492,15 +492,15 @@ zval *zend_std_read_property(zval *object, zval *member, int type, const zend_li zend_error(E_NOTICE, "Indirect modification of overloaded property %s::$%s has no effect", zobj->ce->name->val, Z_STRVAL_P(member)); } } +#endif } else { - retval = &EG(uninitialized_zval_ptr); + retval = &EG(uninitialized_zval); } - if (EXPECTED(*retval != object)) { - zval_ptr_dtor(&object); + if (EXPECTED(retval != object)) { + zval_ptr_dtor(object); } else { Z_DELREF_P(object); } -#endif } else { if (Z_STRVAL_P(member)[0] == '\0') { if (Z_STRLEN_P(member) == 0) { @@ -648,10 +648,10 @@ found: } /* }}} */ -zval *zend_std_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) /* {{{ */ +zval *zend_std_read_dimension(zval *object, zval *offset, int type, zval *rv TSRMLS_DC) /* {{{ */ { zend_class_entry *ce = Z_OBJCE_P(object); - zval retval, tmp; + zval tmp; if (EXPECTED(instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC) != 0)) { if(offset == NULL) { @@ -661,11 +661,11 @@ zval *zend_std_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) /* } else { SEPARATE_ARG_IF_REF(offset); } - zend_call_method_with_1_params(object, ce, NULL, "offsetget", &retval, offset); + zend_call_method_with_1_params(object, ce, NULL, "offsetget", rv, offset); zval_ptr_dtor(offset); - if (UNEXPECTED(Z_TYPE(retval) == IS_UNDEF)) { + if (UNEXPECTED(Z_TYPE_P(rv) == IS_UNDEF)) { if (UNEXPECTED(!EG(exception))) { zend_error_noreturn(E_ERROR, "Undefined offset for object of type %s used as array", ce->name->val); } @@ -673,11 +673,9 @@ zval *zend_std_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) /* } /* Undo PZVAL_LOCK() */ - if (Z_REFCOUNTED(retval)) Z_DELREF(retval); + if (Z_REFCOUNTED_P(rv)) Z_DELREF_P(rv); - // TODO: FIXME??? - //???return &retval; - return NULL; + return rv; } else { zend_error_noreturn(E_ERROR, "Cannot use object of type %s as array", ce->name->val); return NULL; diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 34e0172f90..64225cebd2 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -31,10 +31,10 @@ struct _zend_literal; symbol table, its reference count should be 0. */ /* Used to fetch property from the object, read-only */ -typedef zval *(*zend_object_read_property_t)(zval *object, zval *member, int type, const struct _zend_literal *key TSRMLS_DC); +typedef zval *(*zend_object_read_property_t)(zval *object, zval *member, int type, const struct _zend_literal *key, zval *rv TSRMLS_DC); /* Used to fetch dimension from the object, read-only */ -typedef zval *(*zend_object_read_dimension_t)(zval *object, zval *offset, int type TSRMLS_DC); +typedef zval *(*zend_object_read_dimension_t)(zval *object, zval *offset, int type, zval *rv TSRMLS_DC); /* The following rule applies to write_property() and write_dimension() implementations: diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c index 6f80771ce6..a4a5055b70 100644 --- a/Zend/zend_objects_API.c +++ b/Zend/zend_objects_API.c @@ -279,7 +279,7 @@ ZEND_API zval* zend_object_proxy_get(zval *property TSRMLS_DC) zend_proxy_object *probj = (zend_proxy_object*)Z_OBJ_P(property); if (Z_OBJ_HT(probj->object) && Z_OBJ_HT(probj->object)->read_property) { - return Z_OBJ_HT(probj->object)->read_property(&probj->object, &probj->property, BP_VAR_R, 0 TSRMLS_CC); + return Z_OBJ_HT(probj->object)->read_property(&probj->object, &probj->property, BP_VAR_R, 0, NULL TSRMLS_CC); } else { zend_error(E_WARNING, "Cannot read property of object - no read handler defined"); } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index b459bbce7f..e8657ea510 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -373,14 +373,15 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR if (!have_get_ptr) { zval *z = NULL; + zval rv; if (opline->extended_value == ZEND_ASSIGN_OBJ) { if (Z_OBJ_HT_P(object)->read_property) { - z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); } } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { if (Z_OBJ_HT_P(object)->read_dimension) { - z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC); } } if (z) { @@ -628,8 +629,10 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR| } if (!have_get_ptr) { + zval rv; + if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); @@ -725,7 +728,8 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR if (!have_get_ptr) { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval rv; + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -1115,6 +1119,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST| } /* break missing intentionally */ default: +//??? if (Z_REFCOUNTED_P(retval)) Z_ADDREF_P(retval); ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); break; } @@ -1359,9 +1364,11 @@ ZEND_VM_HELPER(zend_fetch_property_address_read_helper, VAR|UNUSED|CV, CONST|TMP } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (IS_OP2_TMP_FREE()) { zval_ptr_dtor(offset); @@ -1486,9 +1493,11 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, VAR|UNUSED|CV, CONST|TMP|VAR|CV) } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (IS_OP2_TMP_FREE()) { zval_ptr_dtor(offset); @@ -1805,7 +1814,7 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV) } //??? FREE_OP1_VAR_PTR(); -//??? FREE_OP2_VAR_PTR(); + FREE_OP2_VAR_PTR(); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -3693,7 +3702,7 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUS Z_ADDREF_P(expr_ptr); } } else { - expr_ptr=GET_OP1_ZVAL_PTR(BP_VAR_R); + expr_ptr=GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R); if (IS_OP1_TMP_FREE()) { /* temporary variable */ zval new_expr; diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 7151013967..959d028ada 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3633,6 +3633,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type } /* break missing intentionally */ default: +//??? if (Z_REFCOUNTED_P(retval)) Z_ADDREF_P(retval); ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); break; } @@ -5408,6 +5409,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type, } /* break missing intentionally */ default: +//??? if (Z_REFCOUNTED_P(retval)) Z_ADDREF_P(retval); ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); break; } @@ -6114,6 +6116,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ } /* break missing intentionally */ default: +//??? if (Z_REFCOUNTED_P(retval)) Z_ADDREF_P(retval); ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); break; } @@ -8756,6 +8759,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type, } /* break missing intentionally */ default: +//??? if (Z_REFCOUNTED_P(retval)) Z_ADDREF_P(retval); ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); break; } @@ -10412,6 +10416,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE } /* break missing intentionally */ default: +//??? if (Z_REFCOUNTED_P(retval)) Z_ADDREF_P(retval); ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); break; } @@ -11126,6 +11131,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type, } /* break missing intentionally */ default: +//??? if (Z_REFCOUNTED_P(retval)) Z_ADDREF_P(retval); ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); break; } @@ -13905,14 +13911,15 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b if (!have_get_ptr) { zval *z = NULL; + zval rv; if (opline->extended_value == ZEND_ASSIGN_OBJ) { if (Z_OBJ_HT_P(object)->read_property) { - z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); } } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { if (Z_OBJ_HT_P(object)->read_dimension) { - z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC); } } if (z) { @@ -14159,8 +14166,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t } if (!have_get_ptr) { + zval rv; + if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); @@ -14256,7 +14265,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ if (!have_get_ptr) { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval rv; + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -14422,6 +14432,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, } /* break missing intentionally */ default: +//??? if (Z_REFCOUNTED_P(retval)) Z_ADDREF_P(retval); ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); break; } @@ -14665,9 +14676,11 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_CONST( } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -14792,9 +14805,11 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -15343,7 +15358,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC Z_ADDREF_P(expr_ptr); } } else { - expr_ptr=_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr=_get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (0) { /* temporary variable */ zval new_expr; @@ -16331,14 +16346,15 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin if (!have_get_ptr) { zval *z = NULL; + zval rv; if (opline->extended_value == ZEND_ASSIGN_OBJ) { if (Z_OBJ_HT_P(object)->read_property) { - z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); } } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { if (Z_OBJ_HT_P(object)->read_dimension) { - z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC); } } if (z) { @@ -16586,8 +16602,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i } if (!have_get_ptr) { + zval rv; + if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); @@ -16683,7 +16701,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t if (!have_get_ptr) { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval rv; + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -16931,9 +16950,11 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_TMP(ZE } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (1) { zval_ptr_dtor(offset); @@ -17058,9 +17079,11 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (1) { zval_ptr_dtor(offset); @@ -17519,7 +17542,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD Z_ADDREF_P(expr_ptr); } } else { - expr_ptr=_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr=_get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (0) { /* temporary variable */ zval new_expr; @@ -18334,14 +18357,15 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin if (!have_get_ptr) { zval *z = NULL; + zval rv; if (opline->extended_value == ZEND_ASSIGN_OBJ) { if (Z_OBJ_HT_P(object)->read_property) { - z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); } } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { if (Z_OBJ_HT_P(object)->read_dimension) { - z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC); } } if (z) { @@ -18589,8 +18613,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i } if (!have_get_ptr) { + zval rv; + if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); @@ -18686,7 +18712,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t if (!have_get_ptr) { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval rv; + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -18852,6 +18879,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE } /* break missing intentionally */ default: +//??? if (Z_REFCOUNTED_P(retval)) Z_ADDREF_P(retval); ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); break; } @@ -19095,9 +19123,11 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_VAR(ZE } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -19222,9 +19252,11 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -19519,7 +19551,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL } //??? if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; -//??? if (free_op2.var) {zval_ptr_dtor_nogc(free_op2.var);}; + if (free_op2.var) {zval_ptr_dtor_nogc(free_op2.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -19742,7 +19774,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD Z_ADDREF_P(expr_ptr); } } else { - expr_ptr=_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr=_get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (0) { /* temporary variable */ zval new_expr; @@ -20455,14 +20487,15 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (* if (!have_get_ptr) { zval *z = NULL; + zval rv; if (opline->extended_value == ZEND_ASSIGN_OBJ) { if (Z_OBJ_HT_P(object)->read_property) { - z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); } } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { if (Z_OBJ_HT_P(object)->read_dimension) { - z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC); } } if (z) { @@ -20779,6 +20812,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, } /* break missing intentionally */ default: +//??? if (Z_REFCOUNTED_P(retval)) Z_ADDREF_P(retval); ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); break; } @@ -21124,7 +21158,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP Z_ADDREF_P(expr_ptr); } } else { - expr_ptr=_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr=_get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (0) { /* temporary variable */ zval new_expr; @@ -21849,14 +21883,15 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina if (!have_get_ptr) { zval *z = NULL; + zval rv; if (opline->extended_value == ZEND_ASSIGN_OBJ) { if (Z_OBJ_HT_P(object)->read_property) { - z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); } } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { if (Z_OBJ_HT_P(object)->read_dimension) { - z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC); } } if (z) { @@ -22103,8 +22138,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in } if (!have_get_ptr) { + zval rv; + if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); @@ -22200,7 +22237,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i if (!have_get_ptr) { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval rv; + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -22448,9 +22486,11 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_CV(ZEN } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -22575,9 +22615,11 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -22870,7 +22912,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE } //??? if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; -//??? ; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -23091,7 +23132,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE Z_ADDREF_P(expr_ptr); } } else { - expr_ptr=_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr=_get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (0) { /* temporary variable */ zval new_expr; @@ -23711,14 +23752,15 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int if (!have_get_ptr) { zval *z = NULL; + zval rv; if (opline->extended_value == ZEND_ASSIGN_OBJ) { if (Z_OBJ_HT_P(object)->read_property) { - z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); } } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { if (Z_OBJ_HT_P(object)->read_dimension) { - z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC); } } if (z) { @@ -23964,8 +24006,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde } if (!have_get_ptr) { + zval rv; + if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); @@ -24061,7 +24105,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd if (!have_get_ptr) { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval rv; + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -24135,9 +24180,11 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_CON } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -24260,9 +24307,11 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -25060,14 +25109,15 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (* if (!have_get_ptr) { zval *z = NULL; + zval rv; if (opline->extended_value == ZEND_ASSIGN_OBJ) { if (Z_OBJ_HT_P(object)->read_property) { - z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); } } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { if (Z_OBJ_HT_P(object)->read_dimension) { - z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC); } } if (z) { @@ -25314,8 +25364,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_ } if (!have_get_ptr) { + zval rv; + if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); @@ -25411,7 +25463,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec if (!have_get_ptr) { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval rv; + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -25485,9 +25538,11 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_TMP } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (1) { zval_ptr_dtor(offset); @@ -25610,9 +25665,11 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_ } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (1) { zval_ptr_dtor(offset); @@ -26326,14 +26383,15 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (* if (!have_get_ptr) { zval *z = NULL; + zval rv; if (opline->extended_value == ZEND_ASSIGN_OBJ) { if (Z_OBJ_HT_P(object)->read_property) { - z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); } } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { if (Z_OBJ_HT_P(object)->read_dimension) { - z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC); } } if (z) { @@ -26580,8 +26638,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_ } if (!have_get_ptr) { + zval rv; + if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); @@ -26677,7 +26737,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec if (!have_get_ptr) { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval rv; + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -26751,9 +26812,11 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_VAR } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -26876,9 +26939,11 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -27593,14 +27658,15 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int if (!have_get_ptr) { zval *z = NULL; + zval rv; if (opline->extended_value == ZEND_ASSIGN_OBJ) { if (Z_OBJ_HT_P(object)->read_property) { - z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); } } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { if (Z_OBJ_HT_P(object)->read_dimension) { - z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC); } } if (z) { @@ -27994,14 +28060,15 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b if (!have_get_ptr) { zval *z = NULL; + zval rv; if (opline->extended_value == ZEND_ASSIGN_OBJ) { if (Z_OBJ_HT_P(object)->read_property) { - z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); } } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { if (Z_OBJ_HT_P(object)->read_dimension) { - z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC); } } if (z) { @@ -28247,8 +28314,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t } if (!have_get_ptr) { + zval rv; + if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); @@ -28344,7 +28413,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_ if (!have_get_ptr) { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval rv; + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -28418,9 +28488,11 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_CV( } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -28543,9 +28615,11 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -30737,14 +30811,15 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi if (!have_get_ptr) { zval *z = NULL; + zval rv; if (opline->extended_value == ZEND_ASSIGN_OBJ) { if (Z_OBJ_HT_P(object)->read_property) { - z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); } } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { if (Z_OBJ_HT_P(object)->read_dimension) { - z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC); } } if (z) { @@ -30990,8 +31065,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t } if (!have_get_ptr) { + zval rv; + if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); @@ -31087,7 +31164,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t if (!have_get_ptr) { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval rv; + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -31253,6 +31331,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z } /* break missing intentionally */ default: +//??? if (Z_REFCOUNTED_P(retval)) Z_ADDREF_P(retval); ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); break; } @@ -31496,9 +31575,11 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_CONST(Z } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -31621,9 +31702,11 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -31963,7 +32046,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO Z_ADDREF_P(expr_ptr); } } else { - expr_ptr=_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + expr_ptr=_get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); if (0) { /* temporary variable */ zval new_expr; @@ -32945,14 +33028,15 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina if (!have_get_ptr) { zval *z = NULL; + zval rv; if (opline->extended_value == ZEND_ASSIGN_OBJ) { if (Z_OBJ_HT_P(object)->read_property) { - z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); } } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { if (Z_OBJ_HT_P(object)->read_dimension) { - z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC); } } if (z) { @@ -33199,8 +33283,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in } if (!have_get_ptr) { + zval rv; + if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); @@ -33296,7 +33382,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i if (!have_get_ptr) { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval rv; + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -33544,9 +33631,11 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_TMP(ZEN } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (1) { zval_ptr_dtor(offset); @@ -33669,9 +33758,11 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (1) { zval_ptr_dtor(offset); @@ -34014,7 +34105,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE Z_ADDREF_P(expr_ptr); } } else { - expr_ptr=_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + expr_ptr=_get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); if (0) { /* temporary variable */ zval new_expr; @@ -34823,14 +34914,15 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina if (!have_get_ptr) { zval *z = NULL; + zval rv; if (opline->extended_value == ZEND_ASSIGN_OBJ) { if (Z_OBJ_HT_P(object)->read_property) { - z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); } } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { if (Z_OBJ_HT_P(object)->read_dimension) { - z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC); } } if (z) { @@ -35077,8 +35169,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in } if (!have_get_ptr) { + zval rv; + if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); @@ -35174,7 +35268,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i if (!have_get_ptr) { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval rv; + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -35340,6 +35435,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN } /* break missing intentionally */ default: +//??? if (Z_REFCOUNTED_P(retval)) Z_ADDREF_P(retval); ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); break; } @@ -35583,9 +35679,11 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_VAR(ZEN } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -35708,9 +35806,11 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -36001,7 +36101,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE } //??? ; -//??? if (free_op2.var) {zval_ptr_dtor_nogc(free_op2.var);}; + if (free_op2.var) {zval_ptr_dtor_nogc(free_op2.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -36112,7 +36212,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE Z_ADDREF_P(expr_ptr); } } else { - expr_ptr=_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + expr_ptr=_get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); if (0) { /* temporary variable */ zval new_expr; @@ -36819,14 +36919,15 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b if (!have_get_ptr) { zval *z = NULL; + zval rv; if (opline->extended_value == ZEND_ASSIGN_OBJ) { if (Z_OBJ_HT_P(object)->read_property) { - z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); } } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { if (Z_OBJ_HT_P(object)->read_dimension) { - z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC); } } if (z) { @@ -37142,6 +37243,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type, } /* break missing intentionally */ default: +//??? if (Z_REFCOUNTED_P(retval)) Z_ADDREF_P(retval); ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); break; } @@ -37376,7 +37478,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC Z_ADDREF_P(expr_ptr); } } else { - expr_ptr=_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + expr_ptr=_get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); if (0) { /* temporary variable */ zval new_expr; @@ -38082,14 +38184,15 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar if (!have_get_ptr) { zval *z = NULL; + zval rv; if (opline->extended_value == ZEND_ASSIGN_OBJ) { if (Z_OBJ_HT_P(object)->read_property) { - z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); } } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { if (Z_OBJ_HT_P(object)->read_dimension) { - z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); + z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC); } } if (z) { @@ -38335,8 +38438,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc } if (!have_get_ptr) { + zval rv; + if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); @@ -38432,7 +38537,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in if (!have_get_ptr) { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + zval rv; + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL), &rv TSRMLS_CC); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -38680,9 +38786,11 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_CV(ZEND } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -38805,9 +38913,11 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL } /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL), EX_VAR(opline->result.var) TSRMLS_CC); - ZVAL_COPY(EX_VAR(opline->result.var), retval); + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } if (0) { zval_ptr_dtor(offset); @@ -39095,7 +39205,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr); } -//??? ; //??? ; CHECK_EXCEPTION(); @@ -39205,7 +39314,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_ Z_ADDREF_P(expr_ptr); } } else { - expr_ptr=_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + expr_ptr=_get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); if (0) { /* temporary variable */ zval new_expr; diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 1489ac8184..24cbbd33a7 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -633,9 +633,9 @@ static HashTable *date_object_get_properties_period(zval *object TSRMLS_DC); static HashTable *date_object_get_properties_timezone(zval *object TSRMLS_DC); static HashTable *date_object_get_gc_timezone(zval *object, zval **table, int *n TSRMLS_DC); -zval *date_interval_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC); +zval *date_interval_read_property(zval *object, zval *member, int type, const zend_literal *key, zval *rv TSRMLS_DC); void date_interval_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC); -static zval *date_period_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC); +static zval *date_period_read_property(zval *object, zval *member, int type, const zend_literal *key, zval *rv TSRMLS_DC); static void date_period_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC); /* {{{ Module struct */ @@ -3959,7 +3959,7 @@ static int date_interval_initialize(timelib_rel_time **rt, /*const*/ char *forma } /* {{{ date_interval_read_property */ -zval *date_interval_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) +zval *date_interval_read_property(zval *object, zval *member, int type, const zend_literal *key, zval *rv TSRMLS_DC) { php_interval_obj *obj; zval *retval; @@ -3977,7 +3977,7 @@ zval *date_interval_read_property(zval *object, zval *member, int type, const ze obj = (php_interval_obj *)Z_OBJ_P(object); if (!obj->initialized) { - retval = (zend_get_std_object_handlers())->read_property(object, member, type, key TSRMLS_CC); + retval = (zend_get_std_object_handlers())->read_property(object, member, type, key, rv TSRMLS_CC); if (member == &tmp_member) { zval_dtor(member); } @@ -3999,7 +3999,7 @@ zval *date_interval_read_property(zval *object, zval *member, int type, const ze GET_VALUE_FROM_STRUCT(invert, "invert"); GET_VALUE_FROM_STRUCT(days, "days"); /* didn't find any */ - retval = (zend_get_std_object_handlers())->read_property(object, member, type, key TSRMLS_CC); + retval = (zend_get_std_object_handlers())->read_property(object, member, type, key, rv TSRMLS_CC); if (member == &tmp_member) { zval_dtor(member); @@ -4009,7 +4009,7 @@ zval *date_interval_read_property(zval *object, zval *member, int type, const ze } while(0); //??? ALLOC_INIT_ZVAL(retval); - Z_SET_REFCOUNT_P(retval, 0); +//??? Z_SET_REFCOUNT_P(retval, 0); if (value != -99999) { ZVAL_LONG(retval, value); @@ -4949,7 +4949,7 @@ PHP_METHOD(DatePeriod, __wakeup) /* }}} */ /* {{{ date_period_read_property */ -static zval *date_period_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) +static zval *date_period_read_property(zval *object, zval *member, int type, const zend_literal *key, zval *rv TSRMLS_DC) { zval *zv; if (type != BP_VAR_IS && type != BP_VAR_R) { @@ -4958,7 +4958,7 @@ static zval *date_period_read_property(zval *object, zval *member, int type, con Z_OBJPROP_P(object); /* build properties hash table */ - zv = std_object_handlers.read_property(object, member, type, key TSRMLS_CC); + zv = std_object_handlers.read_property(object, member, type, key, rv TSRMLS_CC); if (Z_TYPE_P(zv) == IS_OBJECT && Z_OBJ_HANDLER_P(zv, clone_obj)) { /* defensive copy */ //??? MAKE_STD_ZVAL(zv); diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index e552ca8fb4..3e2437fec4 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -820,7 +820,7 @@ static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* } /* }}} */ -static zval *spl_array_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */ +static zval *spl_array_read_property(zval *object, zval *member, int type, const zend_literal *key, zval *rv TSRMLS_DC) /* {{{ */ { spl_array_object *intern = (spl_array_object*)Z_OBJ_P(object); @@ -828,7 +828,7 @@ static zval *spl_array_read_property(zval *object, zval *member, int type, const && !std_object_handlers.has_property(object, member, 2, key TSRMLS_CC)) { return spl_array_read_dimension(object, member, type TSRMLS_CC); } - return std_object_handlers.read_property(object, member, type, key TSRMLS_CC); + return std_object_handlers.read_property(object, member, type, key, rv TSRMLS_CC); } /* }}} */ static void spl_array_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) /* {{{ */