diff options
-rw-r--r-- | Zend/zend_execute.c | 61 | ||||
-rw-r--r-- | Zend/zend_execute.h | 59 | ||||
-rw-r--r-- | Zend/zend_object_handlers.c | 46 |
3 files changed, 61 insertions, 105 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 00e72a0e61..b56f5d4086 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -692,7 +692,7 @@ static void zend_verify_missing_arg(zend_execute_data *execute_data, uint32_t ar static zend_always_inline void zend_assign_to_object(zval *retval, zval *object, uint32_t object_op_type, zval *property_name, int value_type, const znode_op *value_op, const zend_execute_data *execute_data, int opcode, void **cache_slot TSRMLS_DC) { zend_free_op free_value; - zval *value = get_zval_ptr(value_type, value_op, execute_data, &free_value, BP_VAR_R); + zval *value = get_zval_ptr_deref(value_type, value_op, execute_data, &free_value, BP_VAR_R); zval tmp; if (object_op_type != IS_UNUSED) { @@ -830,65 +830,6 @@ static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *valu } } -static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval *value, zend_uchar value_type TSRMLS_DC) -{ - do { - if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) { - zend_refcounted *garbage; - - if (Z_ISREF_P(variable_ptr)) { - variable_ptr = Z_REFVAL_P(variable_ptr); - if (EXPECTED(!Z_REFCOUNTED_P(variable_ptr))) { - break; - } - } - if (Z_TYPE_P(variable_ptr) == IS_OBJECT && - UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) { - Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr, value TSRMLS_CC); - return variable_ptr; - } - if ((value_type & (IS_VAR|IS_CV)) && variable_ptr == value) { - return variable_ptr; - } - garbage = Z_COUNTED_P(variable_ptr); - if (--GC_REFCOUNT(garbage) == 0) { - ZVAL_COPY_VALUE(variable_ptr, value); - if (value_type == IS_CONST) { - /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ - if (UNEXPECTED(Z_OPT_COPYABLE_P(variable_ptr))) { - zval_copy_ctor_func(variable_ptr); - } - } else if (value_type != IS_TMP_VAR) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) { - Z_ADDREF_P(variable_ptr); - } - } - _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); - return variable_ptr; - } else { /* we need to split */ - /* optimized version of GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr) */ - if ((Z_COLLECTABLE_P(variable_ptr)) && - UNEXPECTED(!GC_INFO(garbage))) { - gc_possible_root(garbage TSRMLS_CC); - } - } - } - } while (0); - - ZVAL_COPY_VALUE(variable_ptr, value); - if (value_type == IS_CONST) { - /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ - if (UNEXPECTED(Z_OPT_COPYABLE_P(variable_ptr))) { - zval_copy_ctor_func(variable_ptr); - } - } else if (value_type != IS_TMP_VAR) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) { - Z_ADDREF_P(variable_ptr); - } - } - return variable_ptr; -} - /* Utility Functions for Extensions */ static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC) { diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index bfa3394e0d..298a125e05 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -129,6 +129,65 @@ again: return result; } +static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval *value, zend_uchar value_type TSRMLS_DC) +{ + do { + if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) { + zend_refcounted *garbage; + + if (Z_ISREF_P(variable_ptr)) { + variable_ptr = Z_REFVAL_P(variable_ptr); + if (EXPECTED(!Z_REFCOUNTED_P(variable_ptr))) { + break; + } + } + if (Z_TYPE_P(variable_ptr) == IS_OBJECT && + UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) { + Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr, value TSRMLS_CC); + return variable_ptr; + } + if ((value_type & (IS_VAR|IS_CV)) && variable_ptr == value) { + return variable_ptr; + } + garbage = Z_COUNTED_P(variable_ptr); + if (--GC_REFCOUNT(garbage) == 0) { + ZVAL_COPY_VALUE(variable_ptr, value); + if (value_type == IS_CONST) { + /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ + if (UNEXPECTED(Z_OPT_COPYABLE_P(variable_ptr))) { + zval_copy_ctor_func(variable_ptr); + } + } else if (value_type != IS_TMP_VAR) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) { + Z_ADDREF_P(variable_ptr); + } + } + _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); + return variable_ptr; + } else { /* we need to split */ + /* optimized version of GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr) */ + if ((Z_COLLECTABLE_P(variable_ptr)) && + UNEXPECTED(!GC_INFO(garbage))) { + gc_possible_root(garbage TSRMLS_CC); + } + } + } + } while (0); + + ZVAL_COPY_VALUE(variable_ptr, value); + if (value_type == IS_CONST) { + /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ + if (UNEXPECTED(Z_OPT_COPYABLE_P(variable_ptr))) { + zval_copy_ctor_func(variable_ptr); + } + } else if (value_type != IS_TMP_VAR) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) { + Z_ADDREF_P(variable_ptr); + } + } + return variable_ptr; +} + ZEND_API int zval_update_constant(zval *pp, zend_bool inline_change TSRMLS_DC); ZEND_API int zval_update_constant_inline_change(zval *pp, zend_class_entry *scope TSRMLS_DC); ZEND_API int zval_update_constant_no_inline_change(zval *pp, zend_class_entry *scope TSRMLS_DC); diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index af2ba2d708..c474fa8662 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -545,51 +545,7 @@ ZEND_API void zend_std_write_property(zval *object, zval *member, zval *value, v } else if (EXPECTED(zobj->properties != NULL)) { if ((variable_ptr = zend_hash_find(zobj->properties, Z_STR_P(member))) != NULL) { found: - /* if we already have this value there, we don't actually need to do anything */ - if (EXPECTED(variable_ptr != value)) { - /* if we are assigning reference, we shouldn't move it, but instead assign variable - to the same pointer */ - if (Z_ISREF_P(variable_ptr)) { - zval garbage; - - ZVAL_COPY_VALUE(&garbage, Z_REFVAL_P(variable_ptr)); /* old value should be destroyed */ - - /* To check: can't *variable_ptr be some system variable like error_zval here? */ - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - if (EXPECTED(!Z_ISREF_P(value))) { - Z_ADDREF_P(value); - } else { - if (Z_REFCOUNT_P(value) == 1) { - ZVAL_UNREF(value); - } else { - value = Z_REFVAL_P(value); - } - if (Z_REFCOUNTED_P(value)) { - if (UNEXPECTED(Z_REFVAL_P(variable_ptr) == value)) { - goto exit; - } - Z_ADDREF_P(value); - } - } - } - ZVAL_COPY_VALUE(Z_REFVAL_P(variable_ptr), value); - zval_ptr_dtor(&garbage); - } else { - zval garbage; - - ZVAL_COPY_VALUE(&garbage, variable_ptr); - - /* if we assign referenced variable, we should separate it */ - ZVAL_COPY_VALUE(variable_ptr, value); - if (Z_REFCOUNTED_P(variable_ptr)) { - Z_ADDREF_P(variable_ptr); - if (Z_ISREF_P(variable_ptr)) { - SEPARATE_ZVAL(variable_ptr); - } - } - zval_ptr_dtor(&garbage); - } - } + zend_assign_to_variable(variable_ptr, value, (IS_VAR|IS_TMP_VAR) TSRMLS_CC); goto exit; } } |