summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_execute.c61
-rw-r--r--Zend/zend_execute.h59
-rw-r--r--Zend/zend_object_handlers.c46
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;
}
}