diff options
47 files changed, 915 insertions, 878 deletions
diff --git a/Zend/zend.h b/Zend/zend.h index d9c8db19b6..c346c023c1 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -707,6 +707,13 @@ END_EXTERN_C() } \ } while (0) +#define ZVAL_MAKE_REF(zv) do { \ + zval *__zv = (zv); \ + if (!Z_ISREF_P(__zv)) { \ + ZVAL_NEW_REF(__zv, __zv); \ + } \ + } while (0) + #define ZVAL_UNREF(z) do { \ zval *_z = (z); \ zend_reference *ref; \ @@ -716,6 +723,38 @@ END_EXTERN_C() efree(ref); \ } while (0) +#define SEPARATE_STRING(zv) do { \ + zval *_zv = (zv); \ + if (Z_REFCOUNTED_P(_zv) && \ + Z_REFCOUNT_P(_zv) > 1) { \ + Z_DELREF_P(_zv); \ + zval_copy_ctor_func(_zv); \ + } \ + } while (0) + +#define SEPARATE_ARRAY(zv) do { \ + zval *_zv = (zv); \ + if (Z_IMMUTABLE_P(_zv)) { \ + zval_copy_ctor_func(_zv); \ + } else if (Z_REFCOUNT_P(_zv) > 1) { \ + Z_DELREF_P(_zv); \ + zval_copy_ctor_func(_zv); \ + } \ + } while (0) + +#define SEPARATE_ZVAL_NOREF(zv) do { \ + zval *_zv = (zv); \ + if (Z_COPYABLE_P(_zv) || \ + Z_IMMUTABLE_P(_zv)) { \ + if (Z_IMMUTABLE_P(_zv)) { \ + zval_copy_ctor_func(_zv); \ + } else if (Z_REFCOUNT_P(_zv) > 1) { \ + Z_DELREF_P(_zv); \ + zval_copy_ctor_func(_zv); \ + } \ + } \ + } while (0) + #define SEPARATE_ZVAL(zv) do { \ zval *_zv = (zv); \ if (Z_REFCOUNTED_P(_zv) || \ @@ -749,38 +788,10 @@ END_EXTERN_C() } \ } while (0) -#define SEPARATE_ZVAL_IF_REF(zv) do { \ - zval *__zv = (zv); \ - if (Z_ISREF_P(__zv)) { \ - if (Z_REFCOUNT_P(__zv) == 1) { \ - ZVAL_UNREF(__zv); \ - } else { \ - Z_DELREF_P(__zv); \ - ZVAL_DUP(__zv, Z_REFVAL_P(__zv)); \ - } \ - } \ - } while (0) - -#define SEPARATE_ZVAL_TO_MAKE_IS_REF(zv) do { \ - zval *__zv = (zv); \ - if (!Z_ISREF_P(__zv)) { \ - if (Z_COPYABLE_P(__zv) && \ - Z_REFCOUNT_P(__zv) > 1) { \ - Z_DELREF_P(__zv); \ - zval_copy_ctor_func(__zv); \ - } \ - ZVAL_NEW_REF(__zv, __zv); \ - } \ - } while (0) - #define SEPARATE_ARG_IF_REF(varptr) do { \ - zval *_varptr = (varptr); \ - if (Z_ISREF_P(_varptr)) { \ - zval tmp; \ - ZVAL_DUP(&tmp, Z_REFVAL_P(_varptr)); \ - varptr = &tmp; \ - } else if (Z_REFCOUNTED_P(_varptr)) { \ - Z_ADDREF_P(_varptr); \ + ZVAL_DEREF(varptr); \ + if (Z_REFCOUNTED_P(varptr)) { \ + Z_ADDREF_P(varptr); \ } \ } while (0) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 45e2331518..33f1fc67cc 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -273,7 +273,7 @@ static int parse_arg_object_to_string(zval *arg, char **p, int *pl, int type TSR } /* Standard PHP objects */ if (Z_OBJ_HT_P(arg) == &std_object_handlers || !Z_OBJ_HANDLER_P(arg, cast_object)) { - SEPARATE_ZVAL_IF_NOT_REF(arg); + SEPARATE_ZVAL_NOREF(arg); if (zend_std_cast_object_tostring(arg, arg, type TSRMLS_CC) == SUCCESS) { *pl = Z_STRLEN_P(arg); *p = Z_STRVAL_P(arg); @@ -315,7 +315,7 @@ static int parse_arg_object_to_str(zval *arg, zend_string **str, int type TSRMLS } /* Standard PHP objects */ if (Z_OBJ_HT_P(arg) == &std_object_handlers || !Z_OBJ_HANDLER_P(arg, cast_object)) { - SEPARATE_ZVAL_IF_NOT_REF(arg); + SEPARATE_ZVAL_NOREF(arg); if (zend_std_cast_object_tostring(arg, arg, type TSRMLS_CC) == SUCCESS) { *str = Z_STR_P(arg); return SUCCESS; @@ -350,9 +350,11 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons zval *real_arg = arg; /* scan through modifiers */ + ZVAL_DEREF(arg); while (1) { if (*spec_walk == '/') { - SEPARATE_ZVAL_IF_NOT_REF(arg); + SEPARATE_ZVAL(arg); + real_arg = arg; } else if (*spec_walk == '!') { check_null = 1; } else { @@ -361,8 +363,6 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons spec_walk++; } - ZVAL_DEREF(arg); - switch (c) { case 'l': case 'L': @@ -486,12 +486,6 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons case IS_TRUE: convert_to_string_ex(arg); case IS_STRING: - if (UNEXPECTED(Z_ISREF_P(arg))) { - /* it's dangerous to return pointers to string - buffer of referenced variable, because it can - be clobbered throug magic callbacks */ - SEPARATE_ZVAL(arg); - } *p = Z_STRVAL_P(arg); *pl = Z_STRLEN_P(arg); if (c == 'p' && CHECK_ZVAL_NULL_PATH(arg)) { @@ -533,12 +527,6 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons case IS_TRUE: convert_to_string_ex(arg); case IS_STRING: - if (UNEXPECTED(Z_ISREF_P(arg))) { - /* it's dangerous to return pointers to string - buffer of referenced variable, because it can - be clobbered throug magic callbacks */ - SEPARATE_ZVAL(arg); - } *str = Z_STR_P(arg); if (c == 'P' && CHECK_ZVAL_NULL_PATH(arg)) { return "a valid path"; @@ -2714,8 +2702,8 @@ ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_lengt if (num_symbol_tables <= 0) return FAILURE; - if (is_ref && !Z_ISREF_P(symbol)) { - ZVAL_NEW_REF(symbol, symbol); + if (is_ref) { + ZVAL_MAKE_REF(symbol); } va_start(symbol_table_list, num_symbol_tables); diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index d58099418f..f8f6a435f5 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -585,11 +585,10 @@ ZEND_FUNCTION(each) HashTable *target_hash; zend_string *key; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &array) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &array) == FAILURE) { return; } - ZVAL_DEREF(array); target_hash = HASH_OF(array); if (!target_hash) { zend_error(E_WARNING,"Variable passed to each() is not an array or object"); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index fda1c7606e..c84937b645 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3793,7 +3793,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent } } for (i = 0; i < parent_ce->default_static_members_count; i++) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(&CE_STATIC_MEMBERS(parent_ce)[i]); + ZVAL_MAKE_REF(&CE_STATIC_MEMBERS(parent_ce)[i]); ce->default_static_members_table[i] = CE_STATIC_MEMBERS(parent_ce)[i]; Z_ADDREF(ce->default_static_members_table[i]); } @@ -3811,7 +3811,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent } } for (i = 0; i < parent_ce->default_static_members_count; i++) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(&parent_ce->default_static_members_table[i]); + ZVAL_MAKE_REF(&parent_ce->default_static_members_table[i]); ce->default_static_members_table[i] = parent_ce->default_static_members_table[i]; Z_ADDREF(ce->default_static_members_table[i]); } @@ -3896,9 +3896,7 @@ static int do_inherit_iface_constant(zval *zv TSRMLS_DC, int num_args, va_list a zend_class_entry *iface = va_arg(args, zend_class_entry *); if (hash_key->key && do_inherit_constant_check(&ce->constants_table, zv, hash_key, iface)) { - if (!Z_ISREF_P(zv)) { - ZVAL_NEW_REF(zv, zv); - } + ZVAL_MAKE_REF(zv); Z_ADDREF_P(zv); zend_hash_update(&ce->constants_table, hash_key->key, zv); } @@ -7524,6 +7522,9 @@ void zend_do_constant_expression(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ if (ast->kind == ZEND_CONST) { ZVAL_COPY_VALUE(&result->u.constant, &ast->u.val); efree(ast); + if (Z_TYPE(result->u.constant) == IS_ARRAY) { + zend_make_immutable_array_r(&result->u.constant TSRMLS_CC); + } } else if (zend_ast_is_ct_constant(ast)) { zend_ast_evaluate(&result->u.constant, ast, NULL TSRMLS_CC); zend_ast_destroy(ast); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 80d4fbb5db..471a02976a 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -114,13 +114,6 @@ static zend_always_inline void zend_pzval_unlock_func(zval *z, zend_free_op *sho #define IS_TMP_FREE(should_free) ((zend_uintptr_t)should_free.var & 1L) -#define MAKE_REAL_ZVAL_PTR(val) \ - do { \ - zval _tmp; \ - ZVAL_COPY_VALUE(&_tmp, (val)); \ - (val) = &_tmp; \ - } while (0) - /* End of zend_execute_locks.h */ #define CV_DEF_OF(i) (EG(active_op_array)->vars[i]) @@ -488,12 +481,12 @@ static inline zval *_get_obj_zval_ptr_ptr(int op_type, const znode_op *node, con static inline void zend_assign_to_variable_reference(zval *variable_ptr, zval *value_ptr TSRMLS_DC) { if (EXPECTED(variable_ptr != value_ptr)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); Z_ADDREF_P(value_ptr); zval_ptr_dtor(variable_ptr); - ZVAL_COPY_VALUE(variable_ptr, value_ptr); - } else if (!Z_ISREF_P(variable_ptr)) { - ZVAL_NEW_REF(variable_ptr, variable_ptr); + ZVAL_REF(variable_ptr, Z_REF_P(value_ptr)); + } else { + ZVAL_MAKE_REF(variable_ptr); } } @@ -507,11 +500,7 @@ static inline zval* make_real_object(zval *object_ptr TSRMLS_DC) if (Z_TYPE_P(object) == IS_NULL || Z_TYPE_P(object) == IS_FALSE || (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0)) { - if (EXPECTED(object == object_ptr)) { - /* object_ptr is not a reference */ - SEPARATE_ZVAL(object); - } - zval_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); zend_error(E_WARNING, "Creating default object from empty value"); } @@ -730,7 +719,8 @@ static inline void zend_assign_to_object(zval *retval, zval *object_ptr, zval *p value = &tmp; } else if (value_type == IS_CONST) { if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { - ZVAL_DUP(&tmp, value); + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); value = &tmp; } } else if (Z_REFCOUNTED_P(value)) { @@ -793,15 +783,10 @@ static void zend_assign_to_string_offset(zval *str_offset, zval *value, int valu } if (Z_TYPE_P(value) != IS_STRING) { - zval tmp; + zend_string *tmp = zval_get_string(value); - ZVAL_COPY_VALUE(&tmp, value); - if (value_type != IS_TMP_VAR) { - zval_opt_copy_ctor(&tmp); - } - convert_to_string(&tmp); - Z_STRVAL_P(str)[offset] = Z_STRVAL(tmp)[0]; - zval_dtor(&tmp); + Z_STRVAL_P(str)[offset] = tmp->val[0]; + STR_RELEASE(tmp); } else { Z_STRVAL_P(str)[offset] = Z_STRVAL_P(value)[0]; if (value_type == IS_TMP_VAR) { @@ -888,7 +873,7 @@ static inline zval* zend_assign_const_to_variable(zval *variable_ptr, zval *valu ZVAL_COPY_VALUE(variable_ptr, value); /* 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 ZEND_FILE_LINE_CC); + zval_copy_ctor_func(variable_ptr); } _zval_dtor_func(garbage ZEND_FILE_LINE_CC); return variable_ptr; @@ -898,7 +883,7 @@ static inline zval* zend_assign_const_to_variable(zval *variable_ptr, zval *valu ZVAL_COPY_VALUE(variable_ptr, value); /* 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 ZEND_FILE_LINE_CC); + zval_copy_ctor_func(variable_ptr); } return variable_ptr; @@ -907,42 +892,33 @@ static inline zval* zend_assign_const_to_variable(zval *variable_ptr, zval *valu static inline zval* zend_assign_to_variable(zval *variable_ptr, zval *value TSRMLS_DC) { zend_refcounted *garbage; - zval *is_ref = NULL; if (EXPECTED(!Z_REFCOUNTED_P(variable_ptr))) { - if (EXPECTED(!Z_ISREF_P(value))) { - ZVAL_COPY(variable_ptr, value); - } else { - goto assign_ref; - } + goto assign_simple; + } else if (UNEXPECTED(variable_ptr == value)) { return variable_ptr; - } else if (Z_ISREF_P(variable_ptr)) { - is_ref = variable_ptr; + } + if (Z_ISREF_P(variable_ptr)) { variable_ptr = Z_REFVAL_P(variable_ptr); + if (EXPECTED(!Z_REFCOUNTED_P(variable_ptr))) { + goto assign_simple; + } } - if (EXPECTED(!Z_REFCOUNTED_P(variable_ptr))) { - goto assign_simple; - } else if (Z_TYPE_P(variable_ptr) == IS_OBJECT && + 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); } else if (EXPECTED(variable_ptr != value)) { if (Z_REFCOUNT_P(variable_ptr)==1) { garbage = Z_COUNTED_P(variable_ptr); if (EXPECTED(!Z_ISREF_P(value))) { - if (!is_ref) { - ZVAL_COPY(variable_ptr, value); - } else { - ZVAL_DUP(variable_ptr, value); - } - } else if (is_ref == value) { - return variable_ptr; + ZVAL_COPY(variable_ptr, value); } else { if (Z_REFCOUNT_P(value) == 1) { ZVAL_UNREF(value); ZVAL_COPY(variable_ptr, value); } else { - ZVAL_DUP(variable_ptr, Z_REFVAL_P(value)); + ZVAL_COPY(variable_ptr, Z_REFVAL_P(value)); } } _zval_dtor_func(garbage ZEND_FILE_LINE_CC); @@ -951,18 +927,13 @@ static inline zval* zend_assign_to_variable(zval *variable_ptr, zval *value TSRM GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr); assign_simple: if (EXPECTED(!Z_ISREF_P(value))) { - if (!is_ref) { - ZVAL_COPY(variable_ptr, value); - } else { - ZVAL_DUP(variable_ptr, value); - } - } else if (is_ref != value) { -assign_ref: + ZVAL_COPY(variable_ptr, value); + } else { if (Z_REFCOUNT_P(value) == 1) { ZVAL_UNREF(value); ZVAL_COPY(variable_ptr, value); } else { - ZVAL_DUP(variable_ptr, Z_REFVAL_P(value)); + ZVAL_COPY(variable_ptr, Z_REFVAL_P(value)); } } } @@ -1124,12 +1095,7 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval * ZVAL_DEREF(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - if (Z_IMMUTABLE_P(container)) { - zval_copy_ctor_func(container); - } else if (Z_REFCOUNT_P(container) > 1) { - Z_DELREF_P(container); - zval_copy_ctor_func(container); - } + SEPARATE_ARRAY(container); fetch_from_array: if (dim == NULL) { retval = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); @@ -1141,12 +1107,15 @@ fetch_from_array: retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC); } if (is_ref) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); - ZVAL_COPY(result, retval); + ZVAL_MAKE_REF(retval); + Z_ADDREF_P(retval); + ZVAL_REF(result, Z_REF_P(retval)); } else { ZVAL_INDIRECT(result, retval); } } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { + long offset; + if (type != BP_VAR_UNSET && UNEXPECTED(Z_STRLEN_P(container) == 0)) { convert_to_array: zval_dtor(container); @@ -1158,14 +1127,10 @@ convert_to_array: } if (type != BP_VAR_UNSET) { - if (container == container_ptr) { - SEPARATE_ZVAL(container); - } + SEPARATE_STRING(container); } if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) { - zval tmp; - switch(Z_TYPE_P(dim)) { case IS_STRING: if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) { @@ -1186,13 +1151,13 @@ convert_to_array: break; } - ZVAL_DUP(&tmp, dim); - convert_to_long(&tmp); - dim = &tmp; + offset = zval_get_long(dim); + } else { + offset = Z_LVAL_P(dim); } if (!IS_INTERNED(Z_STR_P(container))) STR_ADDREF(Z_STR_P(container)); - ZVAL_STR_OFFSET(result, container, Z_LVAL_P(dim)); + ZVAL_STR_OFFSET(result, container, offset); } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (!Z_OBJ_HT_P(container)->read_dimension) { zend_error_noreturn(E_ERROR, "Cannot use object as array"); @@ -1221,8 +1186,9 @@ convert_to_array: } if (result != retval) { if (is_ref) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); - ZVAL_COPY(result, retval); + ZVAL_MAKE_REF(retval); + Z_ADDREF_P(retval); + ZVAL_REF(result, Z_REF_P(retval)); } else { ZVAL_INDIRECT(result, retval); } @@ -1284,9 +1250,9 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC); ZVAL_COPY(result, retval); } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) { - zval tmp; + long offset; + if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) { switch(Z_TYPE_P(dim)) { /* case IS_LONG: */ case IS_STRING: @@ -1310,23 +1276,23 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z break; } - ZVAL_DUP(&tmp, dim); - convert_to_long(&tmp); - dim = &tmp; + offset = zval_get_long(dim); + } else { + offset = Z_LVAL_P(dim); } - if (UNEXPECTED(Z_LVAL_P(dim) < 0) || UNEXPECTED(Z_STRLEN_P(container) <= Z_LVAL_P(dim))) { + if (UNEXPECTED(offset < 0) || UNEXPECTED(Z_STRLEN_P(container) <= offset)) { if (type != BP_VAR_IS) { - zend_error(E_NOTICE, "Uninitialized string offset: %ld", Z_LVAL_P(dim)); + zend_error(E_NOTICE, "Uninitialized string offset: %ld", offset); } ZVAL_EMPTY_STRING(result); } else { - zend_uchar c = (zend_uchar)Z_STRVAL_P(container)[Z_LVAL_P(dim)]; + zend_uchar c = (zend_uchar)Z_STRVAL_P(container)[offset]; if (CG(one_char_string)[c]) { ZVAL_INT_STR(result, CG(one_char_string)[c]); } else { - ZVAL_NEW_STR(result, STR_INIT(Z_STRVAL_P(container) + Z_LVAL_P(dim), 1, 0)); + ZVAL_NEW_STR(result, STR_INIT(Z_STRVAL_P(container) + offset, 1, 0)); } } } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { @@ -1376,9 +1342,7 @@ static void zend_fetch_property_address(zval *result, zval *container_ptr, zval ((Z_TYPE_P(container) == IS_NULL || Z_TYPE_P(container) == IS_FALSE || (Z_TYPE_P(container) == IS_STRING && Z_STRLEN_P(container)==0)))) { - if (container == container_ptr) { - SEPARATE_ZVAL(container); - } + zval_ptr_dtor_nogc(container); object_init(container); } else { zend_error(E_WARNING, "Attempt to modify property of non-object"); @@ -1394,8 +1358,9 @@ static void zend_fetch_property_address(zval *result, zval *container_ptr, zval (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result TSRMLS_CC)) != NULL) { if (ptr != result) { if (is_ref && ptr != &EG(uninitialized_zval)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(ptr); - ZVAL_COPY(result, ptr); + ZVAL_MAKE_REF(ptr); + Z_ADDREF_P(ptr); + ZVAL_REF(result, Z_REF_P(ptr)); } else { ZVAL_INDIRECT(result, ptr); } @@ -1405,8 +1370,9 @@ static void zend_fetch_property_address(zval *result, zval *container_ptr, zval } } else { if (is_ref) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(ptr); - ZVAL_COPY(result, ptr); + ZVAL_MAKE_REF(ptr); + Z_ADDREF_P(ptr); + ZVAL_REF(result, Z_REF_P(ptr)); } else { ZVAL_INDIRECT(result, ptr); } @@ -1415,8 +1381,9 @@ static void zend_fetch_property_address(zval *result, zval *container_ptr, zval zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result TSRMLS_CC); if (ptr != result) { if (is_ref && ptr != &EG(uninitialized_zval)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(ptr); - ZVAL_COPY(result, ptr); + ZVAL_MAKE_REF(ptr); + Z_ADDREF_P(ptr); + ZVAL_REF(result, Z_REF_P(ptr)); } else { ZVAL_INDIRECT(result, ptr); } diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index e275d92c91..c80e909565 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -239,7 +239,7 @@ static int copy_closure_static_var(zval *var TSRMLS_DC, int num_args, va_list ar { HashTable *target = va_arg(args, HashTable *); - SEPARATE_ZVAL_TO_MAKE_IS_REF(var); + ZVAL_MAKE_REF(var); Z_ADDREF_P(var); zend_hash_update(target, key->key, var); return 0; diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 08b4cb5e4e..e7aa255d78 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -1207,7 +1207,7 @@ ZEND_API void zend_array_dup(HashTable *target, HashTable *source) q->key = NULL; if (Z_OPT_REFCOUNTED_P(data)) { if (Z_ISREF_P(data) && Z_REFCOUNT_P(data) == 1) { - ZVAL_DUP(&q->val, Z_REFVAL_P(data)); + ZVAL_COPY(&q->val, Z_REFVAL_P(data)); } else { ZVAL_COPY(&q->val, data); } @@ -1256,7 +1256,7 @@ ZEND_API void zend_array_dup(HashTable *target, HashTable *source) target->arHash[nIndex] = target_idx; if (Z_OPT_REFCOUNTED_P(data)) { if (Z_ISREF_P(data) && Z_REFCOUNT_P(data) == 1) { - ZVAL_DUP(&q->val, Z_REFVAL_P(data)); + ZVAL_COPY(&q->val, Z_REFVAL_P(data)); } else { ZVAL_COPY(&q->val, data); } @@ -1495,14 +1495,15 @@ ZEND_API int zend_hash_set_pointer(HashTable *ht, const HashPointer *ptr) } else if (ht->nInternalPointer != ptr->pos) { IS_CONSISTENT(ht); if (ht->u.flags & HASH_FLAG_PACKED) { - if (Z_TYPE(ht->arData[ptr->h].val) != IS_UNDEF) { + if (ptr->h < ht->nNumUsed && + Z_TYPE(ht->arData[ptr->h].val) != IS_UNDEF) { ht->nInternalPointer = ptr->h; return 1; } } else { idx = ht->arHash[ptr->h & ht->nTableMask]; while (idx != INVALID_IDX) { - if (idx == ptr->pos) { + if (ht->arData[idx].h == ptr->h && idx == ptr->pos) { ht->nInternalPointer = idx; return 1; } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 0e30ca304e..4d2d799441 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -188,7 +188,7 @@ static void zend_std_call_getter(zval *object, zval *member, zval *retval TSRMLS it should return whether the call was successfull or not */ - SEPARATE_ARG_IF_REF(member); + if (Z_REFCOUNTED_P(member)) Z_ADDREF_P(member); zend_call_method_with_1_params(object, ce, &ce->__get, ZEND_GET_FUNC_NAME, retval, member); @@ -202,7 +202,7 @@ static int zend_std_call_setter(zval *object, zval *member, zval *value TSRMLS_D int result; zend_class_entry *ce = Z_OBJCE_P(object); - SEPARATE_ARG_IF_REF(member); + if (Z_REFCOUNTED_P(member)) Z_ADDREF_P(member); if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value); /* __set handler is called with two arguments: @@ -234,7 +234,7 @@ static void zend_std_call_unsetter(zval *object, zval *member TSRMLS_DC) /* {{{ property name */ - SEPARATE_ARG_IF_REF(member); + if (Z_REFCOUNTED_P(member)) Z_ADDREF_P(member); zend_call_method_with_1_params(object, ce, &ce->__unset, ZEND_UNSET_FUNC_NAME, NULL, member); @@ -252,7 +252,7 @@ static void zend_std_call_issetter(zval *object, zval *member, zval *retval TSRM it should return whether the property is set or not */ - SEPARATE_ARG_IF_REF(member); + if (Z_REFCOUNTED_P(member)) Z_ADDREF_P(member); zend_call_method_with_1_params(object, ce, &ce->__isset, ZEND_ISSET_FUNC_NAME, retval, member); diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index 79bd00db13..2031b017eb 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -210,7 +210,7 @@ ZEND_API void zval_add_ref(zval *p) { if (Z_REFCOUNTED_P(p)) { if (Z_ISREF_P(p) && Z_REFCOUNT_P(p) == 1) { - ZVAL_DUP(p, Z_REFVAL_P(p)); + ZVAL_COPY(p, Z_REFVAL_P(p)); } else { Z_ADDREF_P(p); } @@ -340,7 +340,7 @@ ZEND_API int zval_copy_static_var(zval *p TSRMLS_DC, int num_args, va_list args, } } if (is_ref) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(p); + ZVAL_MAKE_REF(p); Z_ADDREF_P(p); } else if (Z_ISREF_P(p)) { ZVAL_DUP(&tmp, Z_REFVAL_P(p)); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 4f87f5b375..554ac2ca80 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -457,7 +457,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMP|VAR } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -512,7 +512,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNU } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -896,7 +896,7 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY) if (UNEXPECTED(Z_ISREF_P(var_ptr))) { var_ptr = Z_REFVAL_P(var_ptr); } else { - SEPARATE_ZVAL(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) @@ -954,7 +954,7 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY) if (UNEXPECTED(Z_ISREF_P(var_ptr))) { var_ptr = Z_REFVAL_P(var_ptr); } else { - SEPARATE_ZVAL(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) @@ -1012,7 +1012,7 @@ ZEND_VM_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY) ZVAL_DUP(retval, var_ptr); } else { ZVAL_DUP(retval, var_ptr); - SEPARATE_ZVAL(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) @@ -1066,7 +1066,7 @@ ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY) ZVAL_DUP(retval, var_ptr); } else { ZVAL_DUP(retval, var_ptr); - SEPARATE_ZVAL(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) @@ -1216,7 +1216,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST| ZVAL_COPY(EX_VAR(opline->result.var), retval); } else { if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + ZVAL_MAKE_REF(retval); } ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -2830,10 +2830,12 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY) if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); if (OP1_TYPE == IS_CONST) { - zval_opt_copy_ctor_no_imm(EX(return_value)); + if (UNEXPECTED(Z_OPT_COPYABLE_P(EX(return_value)))) { + zval_copy_ctor_func(EX(return_value)); + } } } else if (Z_ISREF_P(retval_ptr)) { - ZVAL_DUP(EX(return_value), Z_REFVAL_P(retval_ptr)); + ZVAL_COPY(EX(return_value), Z_REFVAL_P(retval_ptr)); FREE_OP1_IF_VAR(); } else { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); @@ -2894,8 +2896,9 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY) } if (EX(return_value)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr); - ZVAL_COPY(EX(return_value), retval_ptr); + ZVAL_MAKE_REF(retval_ptr); + Z_ADDREF_P(retval_ptr); + ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr)); } } while (0); @@ -3012,9 +3015,9 @@ ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY) top = zend_vm_stack_top_inc(TSRMLS_C); ZVAL_COPY_VALUE(top, value); if (OP1_TYPE == IS_CONST) { - /* Immutable arrays may be passed without copying ??? */ - /* some internal functions may try to modify them !!! */ - zval_opt_copy_ctor_no_imm(top); + if (UNEXPECTED(Z_OPT_COPYABLE_P(top))) { + zval_copy_ctor_func(top); + } } ZEND_VM_NEXT_OPCODE(); } @@ -3028,10 +3031,7 @@ ZEND_VM_HELPER(zend_send_by_var_helper, VAR|CV, ANY) varptr = GET_OP1_ZVAL_PTR(BP_VAR_R); top = zend_vm_stack_top_inc(TSRMLS_C); if (Z_ISREF_P(varptr)) { - ZVAL_COPY_VALUE(top, Z_REFVAL_P(varptr)); - /* Immutable arrays may be passed without copying ??? */ - /* some internal functions may try to modify them !!! */ - zval_opt_copy_ctor_no_imm(top); + ZVAL_COPY(top, Z_REFVAL_P(varptr)); FREE_OP1(); } else { ZVAL_COPY_VALUE(top, varptr); @@ -3067,13 +3067,7 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) Z_TYPE_P(varptr) == IS_OBJECT || (Z_REFCOUNTED_P(varptr) && Z_REFCOUNT_P(varptr) == 1))) { - if (!Z_ISREF_P(varptr)) { - ZVAL_NEW_REF(varptr, varptr); - } - // TODO: Try to avoid copying of immutable arrays ??? - if (Z_OPT_IMMUTABLE_P(Z_REFVAL_P(varptr))) { - zval_opt_copy_ctor(Z_REFVAL_P(varptr)); - } + ZVAL_MAKE_REF(varptr); if (OP1_TYPE == IS_CV) { Z_ADDREF_P(varptr); } @@ -3085,8 +3079,7 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) zend_error(E_STRICT, "Only variables should be passed by reference"); } top = zend_vm_stack_top_inc(TSRMLS_C); - // TODO: Try to avoid copying of immutable arrays ??? - ZVAL_DUP(top, varptr); + ZVAL_COPY(top, varptr); FREE_OP1_IF_VAR(); } CHECK_EXCEPTION(); @@ -3113,24 +3106,16 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY) } if (Z_ISREF_P(varptr)) { - // TODO: Try to avoid copying of immutable arrays ??? - if (Z_OPT_IMMUTABLE_P(Z_REFVAL_P(varptr))) { - zval_opt_copy_ctor(Z_REFVAL_P(varptr)); - } Z_ADDREF_P(varptr); ZVAL_COPY_VALUE(top, varptr); } else if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) { ZVAL_COPY_VALUE(top, varptr); - SEPARATE_ZVAL_TO_MAKE_IS_REF(top); + ZVAL_MAKE_REF(top); } else { - // TODO: Try to avoid copying of immutable arrays ??? - if (Z_OPT_IMMUTABLE_P(varptr)) { - zval_opt_copy_ctor(varptr); - } - SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr); + ZVAL_MAKE_REF(varptr); Z_ADDREF_P(varptr); - ZVAL_COPY_VALUE(top, varptr); + ZVAL_REF(top, Z_REF_P(varptr)); } FREE_OP1_VAR_PTR(); @@ -3152,10 +3137,7 @@ ZEND_VM_HANDLER(66, ZEND_SEND_VAR, VAR|CV, ANY) varptr = GET_OP1_ZVAL_PTR(BP_VAR_R); top = zend_vm_stack_top_inc(TSRMLS_C); if (Z_ISREF_P(varptr)) { - ZVAL_COPY_VALUE(top, Z_REFVAL_P(varptr)); - /* Immutable arrays may be passed without copying ??? */ - /* some internal functions may try to modify them !!! */ - zval_opt_copy_ctor_no_imm(top); + ZVAL_COPY(top, Z_REFVAL_P(varptr)); FREE_OP1(); } else { ZVAL_COPY_VALUE(top, varptr); @@ -3214,9 +3196,9 @@ ZEND_VM_C_LABEL(send_again): top = zend_vm_stack_top_inc(TSRMLS_C); if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { if (!Z_IMMUTABLE_P(args)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(arg); + ZVAL_MAKE_REF(arg); Z_ADDREF_P(arg); - ZVAL_COPY_VALUE(top, arg); + ZVAL_REF(top, Z_REF_P(arg)); } else { ZVAL_DUP(top, arg); } @@ -3375,7 +3357,7 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST) } else { /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ if (UNEXPECTED(Z_OPT_COPYABLE_P(var_ptr))) { - _zval_copy_ctor_func(var_ptr ZEND_FILE_LINE_CC); + zval_copy_ctor_func(var_ptr); } } } else { @@ -3655,7 +3637,14 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST) CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), c); } retval = EX_VAR(opline->result.var); - ZVAL_DUP(retval, &c->value); + ZVAL_COPY_VALUE(retval, &c->value); + if (Z_OPT_COPYABLE_P(retval) || Z_OPT_REFCOUNTED_P(retval)) { + if (Z_OPT_COPYABLE_P(retval) && (c->flags & CONST_PERSISTENT)) { + zval_copy_ctor_func(retval); + } else { + Z_ADDREF_P(retval); + } + } } else { /* class constant */ zend_class_entry *ce; @@ -3729,7 +3718,7 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUS if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); FREE_OP1_VAR_PTR(); } else { @@ -3839,11 +3828,11 @@ ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY) { USE_OPLINE zend_free_op free_op1; - zval *expr; + zval *expr, tmp; zval *result = EX_VAR(opline->result.var); SAVE_OPLINE(); - expr = GET_OP1_ZVAL_PTR(BP_VAR_R); + expr = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R); switch (opline->extended_value) { case IS_NULL: @@ -3880,27 +3869,59 @@ ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY) if (Z_TYPE_P(expr) == opline->extended_value) { ZVAL_COPY_VALUE(result, expr); if (OP1_TYPE == IS_CONST) { - zval_opt_copy_ctor(result); - } else if (OP1_TYPE == IS_CV) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(result))) { + zval_copy_ctor_func(result); + } + } else if (OP1_TYPE != IS_TMP_VAR) { if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); } + FREE_OP1(); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } - if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) { - ZVAL_DEREF(expr); - } - ZVAL_COPY_VALUE(result, expr); - if (!IS_OP1_TMP_FREE()) { - zval_opt_copy_ctor(result); - } - if (opline->extended_value == IS_ARRAY) { - convert_to_array(result); + if (Z_TYPE_P(expr) != IS_OBJECT) { + ZVAL_NEW_ARR(result); + zend_hash_init(Z_ARRVAL_P(result), 8, NULL, ZVAL_PTR_DTOR, 0); + if (Z_TYPE_P(expr) != IS_NULL) { + expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr); + if (OP1_TYPE == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) { + zval_copy_ctor_func(expr); + } + } else if (OP1_TYPE != IS_TMP_VAR) { + if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); + } + } + } else { + ZVAL_COPY_VALUE(result, expr); + if (!IS_OP1_TMP_FREE()) { + zval_opt_copy_ctor(result); + } + convert_to_array(result); + } } else { - convert_to_object(result); + if (Z_TYPE_P(expr) != IS_ARRAY) { + object_init(result); + if (Z_TYPE_P(expr) != IS_NULL) { + expr = zend_hash_str_add_new(Z_OBJPROP_P(result), "scalar", sizeof("scalar")-1, expr); + if (OP1_TYPE == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) { + zval_copy_ctor_func(expr); + } + } else if (OP1_TYPE != IS_TMP_VAR) { + if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); + } + } + } else { + ZVAL_COPY_VALUE(result, expr); + if (!IS_OP1_TMP_FREE()) { + zval_opt_copy_ctor(result); + } + convert_to_object(result); + } } FREE_OP1_IF_VAR(); @@ -4258,7 +4279,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) ZVAL_DEREF(array_ptr); if (Z_TYPE_P(array_ptr) == IS_ARRAY) { if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL(array_ptr); + SEPARATE_ZVAL_NOREF(array_ptr); array_ref = array_ptr; if (opline->extended_value & ZEND_FE_FETCH_BYREF) { ZVAL_NEW_REF(array_ptr, array_ptr); @@ -4278,7 +4299,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) ce = Z_OBJCE_P(array_ptr); if (!ce || ce->get_iterator == NULL) { if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL(array_ptr); + SEPARATE_ZVAL_NOREF(array_ptr); } Z_ADDREF_P(array_ptr); } @@ -4430,7 +4451,13 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY) zval *key = NULL; array = array_ref = EX_VAR(opline->op1.var); - ZVAL_DEREF(array); + if (Z_ISREF_P(array)) { + array = Z_REFVAL_P(array); + // TODO: referenced value might be changed to different array ??? + if (Z_IMMUTABLE_P(array)) { + zval_copy_ctor(array); + } + } if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) { key = EX_VAR((opline+1)->result.var); } @@ -4549,9 +4576,12 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY) } if (opline->extended_value & ZEND_FE_FETCH_BYREF) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value); + ZVAL_MAKE_REF(value); + Z_ADDREF_P(value); + ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(value)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); } - ZVAL_COPY(EX_VAR(opline->result.var), value); CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -4891,10 +4921,13 @@ ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, ANY) if (i_zend_is_true(value TSRMLS_CC)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!IS_OP1_TMP_FREE()) { - zval_opt_copy_ctor(EX_VAR(opline->result.var)); + if (OP1_TYPE == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); + } + } else if (OP1_TYPE == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - FREE_OP1_IF_VAR(); ZEND_VM_JMP(opline->op2.jmp_addr); } @@ -4913,15 +4946,14 @@ ZEND_VM_HANDLER(158, ZEND_JMP_SET_VAR, CONST|TMP|VAR|CV, ANY) value = GET_OP1_ZVAL_PTR(BP_VAR_R); if (i_zend_is_true(value TSRMLS_CC)) { - if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!IS_OP1_TMP_FREE()) { - zval_opt_copy_ctor(EX_VAR(opline->result.var)); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + if (OP1_TYPE == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); } + } else if (OP1_TYPE == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - FREE_OP1_IF_VAR(); ZEND_VM_JMP(opline->op2.jmp_addr); } @@ -4940,11 +4972,13 @@ ZEND_VM_HANDLER(22, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY) value = GET_OP1_ZVAL_PTR(BP_VAR_R); ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!IS_OP1_TMP_FREE()) { - zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var)); + if (OP1_TYPE == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); + } + } else if (OP1_TYPE == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - FREE_OP1_IF_VAR(); - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -4957,17 +4991,14 @@ ZEND_VM_HANDLER(157, ZEND_QM_ASSIGN_VAR, CONST|TMP|VAR|CV, ANY) SAVE_OPLINE(); value = GET_OP1_ZVAL_PTR(BP_VAR_R); - if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!IS_OP1_TMP_FREE()) { - zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var)); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + if (OP1_TYPE == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); } + } else if (OP1_TYPE == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - - FREE_OP1_IF_VAR(); - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5343,7 +5374,7 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST) } else { /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ if (UNEXPECTED(Z_OPT_COPYABLE(c.value))) { - _zval_copy_ctor_func(&c.value ZEND_FILE_LINE_CC); + zval_copy_ctor_func(&c.value); } } c.flags = CONST_CS; /* non persistent, case sensetive */ @@ -5446,7 +5477,7 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 4a66c7390d..c391cffdb9 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -782,9 +782,9 @@ send_again: top = zend_vm_stack_top_inc(TSRMLS_C); if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { if (!Z_IMMUTABLE_P(args)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(arg); + ZVAL_MAKE_REF(arg); Z_ADDREF_P(arg); - ZVAL_COPY_VALUE(top, arg); + ZVAL_REF(top, Z_REF_P(arg)); } else { ZVAL_DUP(top, arg); } @@ -1657,7 +1657,7 @@ static int ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ } else { /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ if (UNEXPECTED(Z_OPT_COPYABLE_P(var_ptr))) { - _zval_copy_ctor_func(var_ptr ZEND_FILE_LINE_CC); + zval_copy_ctor_func(var_ptr); } } } else { @@ -2606,10 +2606,12 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); if (IS_CONST == IS_CONST) { - zval_opt_copy_ctor_no_imm(EX(return_value)); + if (UNEXPECTED(Z_OPT_COPYABLE_P(EX(return_value)))) { + zval_copy_ctor_func(EX(return_value)); + } } } else if (Z_ISREF_P(retval_ptr)) { - ZVAL_DUP(EX(return_value), Z_REFVAL_P(retval_ptr)); + ZVAL_COPY(EX(return_value), Z_REFVAL_P(retval_ptr)); } else { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); @@ -2670,8 +2672,9 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND } if (EX(return_value)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr); - ZVAL_COPY(EX(return_value), retval_ptr); + ZVAL_MAKE_REF(retval_ptr); + Z_ADDREF_P(retval_ptr); + ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr)); } } while (0); @@ -2722,9 +2725,9 @@ static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A top = zend_vm_stack_top_inc(TSRMLS_C); ZVAL_COPY_VALUE(top, value); if (IS_CONST == IS_CONST) { - /* Immutable arrays may be passed without copying ??? */ - /* some internal functions may try to modify them !!! */ - zval_opt_copy_ctor_no_imm(top); + if (UNEXPECTED(Z_OPT_COPYABLE_P(top))) { + zval_copy_ctor_func(top); + } } ZEND_VM_NEXT_OPCODE(); } @@ -2805,7 +2808,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *expr; + zval *expr, tmp; zval *result = EX_VAR(opline->result.var); SAVE_OPLINE(); @@ -2846,8 +2849,10 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (Z_TYPE_P(expr) == opline->extended_value) { ZVAL_COPY_VALUE(result, expr); if (IS_CONST == IS_CONST) { - zval_opt_copy_ctor(result); - } else if (IS_CONST == IS_CV) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(result))) { + zval_copy_ctor_func(result); + } + } else if (IS_CONST != IS_TMP_VAR) { if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); } @@ -2855,18 +2860,47 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ZEND_VM_NEXT_OPCODE(); } - if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { - ZVAL_DEREF(expr); - } - ZVAL_COPY_VALUE(result, expr); - if (!0) { - zval_opt_copy_ctor(result); - } - if (opline->extended_value == IS_ARRAY) { - convert_to_array(result); + if (Z_TYPE_P(expr) != IS_OBJECT) { + ZVAL_NEW_ARR(result); + zend_hash_init(Z_ARRVAL_P(result), 8, NULL, ZVAL_PTR_DTOR, 0); + if (Z_TYPE_P(expr) != IS_NULL) { + expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) { + zval_copy_ctor_func(expr); + } + } else if (IS_CONST != IS_TMP_VAR) { + if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); + } + } + } else { + ZVAL_COPY_VALUE(result, expr); + if (!0) { + zval_opt_copy_ctor(result); + } + convert_to_array(result); + } } else { - convert_to_object(result); + if (Z_TYPE_P(expr) != IS_ARRAY) { + object_init(result); + if (Z_TYPE_P(expr) != IS_NULL) { + expr = zend_hash_str_add_new(Z_OBJPROP_P(result), "scalar", sizeof("scalar")-1, expr); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) { + zval_copy_ctor_func(expr); + } + } else if (IS_CONST != IS_TMP_VAR) { + if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); + } + } + } else { + ZVAL_COPY_VALUE(result, expr); + if (!0) { + zval_opt_copy_ctor(result); + } + convert_to_object(result); + } } CHECK_EXCEPTION(); @@ -3019,7 +3053,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A ZVAL_DEREF(array_ptr); if (Z_TYPE_P(array_ptr) == IS_ARRAY) { if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL(array_ptr); + SEPARATE_ZVAL_NOREF(array_ptr); array_ref = array_ptr; if (opline->extended_value & ZEND_FE_FETCH_BYREF) { ZVAL_NEW_REF(array_ptr, array_ptr); @@ -3039,7 +3073,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A ce = Z_OBJCE_P(array_ptr); if (!ce || ce->get_iterator == NULL) { if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL(array_ptr); + SEPARATE_ZVAL_NOREF(array_ptr); } Z_ADDREF_P(array_ptr); } @@ -3213,10 +3247,13 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR if (i_zend_is_true(value TSRMLS_CC)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!0) { - zval_opt_copy_ctor(EX_VAR(opline->result.var)); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); + } + } else if (IS_CONST == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - ZEND_VM_JMP(opline->op2.jmp_addr); } @@ -3234,15 +3271,14 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLE value = opline->op1.zv; if (i_zend_is_true(value TSRMLS_CC)) { - if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!0) { - zval_opt_copy_ctor(EX_VAR(opline->result.var)); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); } + } else if (IS_CONST == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - ZEND_VM_JMP(opline->op2.jmp_addr); } @@ -3260,11 +3296,13 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ value = opline->op1.zv; ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!0) { - zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var)); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); + } + } else if (IS_CONST == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -3277,16 +3315,14 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); value = opline->op1.zv; - if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!0) { - zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var)); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); } + } else if (IS_CONST == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -3669,7 +3705,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type ZVAL_COPY(EX_VAR(opline->result.var), retval); } else { if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + ZVAL_MAKE_REF(retval); } ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -3912,7 +3948,14 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), c); } retval = EX_VAR(opline->result.var); - ZVAL_DUP(retval, &c->value); + ZVAL_COPY_VALUE(retval, &c->value); + if (Z_OPT_COPYABLE_P(retval) || Z_OPT_REFCOUNTED_P(retval)) { + if (Z_OPT_COPYABLE_P(retval) && (c->flags & CONST_PERSISTENT)) { + zval_copy_ctor_func(retval); + } else { + Z_ADDREF_P(retval); + } + } } else { /* class constant */ zend_class_entry *ce; @@ -3986,7 +4029,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); } else { @@ -4261,7 +4304,7 @@ static int ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCOD } else { /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ if (UNEXPECTED(Z_OPT_COPYABLE(c.value))) { - _zval_copy_ctor_func(&c.value ZEND_FILE_LINE_CC); + zval_copy_ctor_func(&c.value); } } c.flags = CONST_CS; /* non persistent, case sensetive */ @@ -4327,7 +4370,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -4856,7 +4899,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPC if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); } else { @@ -5013,7 +5056,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -5486,7 +5529,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type, ZVAL_COPY(EX_VAR(opline->result.var), retval); } else { if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + ZVAL_MAKE_REF(retval); } ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -5690,7 +5733,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPC if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); } else { @@ -5998,7 +6041,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -6196,7 +6239,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ ZVAL_COPY(EX_VAR(opline->result.var), retval); } else { if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + ZVAL_MAKE_REF(retval); } ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -6367,7 +6410,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_ if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); } else { @@ -6693,7 +6736,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -7259,7 +7302,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); } else { @@ -7416,7 +7459,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -7751,10 +7794,12 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); if (IS_TMP_VAR == IS_CONST) { - zval_opt_copy_ctor_no_imm(EX(return_value)); + if (UNEXPECTED(Z_OPT_COPYABLE_P(EX(return_value)))) { + zval_copy_ctor_func(EX(return_value)); + } } } else if (Z_ISREF_P(retval_ptr)) { - ZVAL_DUP(EX(return_value), Z_REFVAL_P(retval_ptr)); + ZVAL_COPY(EX(return_value), Z_REFVAL_P(retval_ptr)); } else { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); @@ -7815,8 +7860,9 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE } if (EX(return_value)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr); - ZVAL_COPY(EX(return_value), retval_ptr); + ZVAL_MAKE_REF(retval_ptr); + Z_ADDREF_P(retval_ptr); + ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr)); } } while (0); @@ -7867,9 +7913,9 @@ static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG top = zend_vm_stack_top_inc(TSRMLS_C); ZVAL_COPY_VALUE(top, value); if (IS_TMP_VAR == IS_CONST) { - /* Immutable arrays may be passed without copying ??? */ - /* some internal functions may try to modify them !!! */ - zval_opt_copy_ctor_no_imm(top); + if (UNEXPECTED(Z_OPT_COPYABLE_P(top))) { + zval_copy_ctor_func(top); + } } ZEND_VM_NEXT_OPCODE(); } @@ -7951,7 +7997,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op1; - zval *expr; + zval *expr, tmp; zval *result = EX_VAR(opline->result.var); SAVE_OPLINE(); @@ -7992,27 +8038,59 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (Z_TYPE_P(expr) == opline->extended_value) { ZVAL_COPY_VALUE(result, expr); if (IS_TMP_VAR == IS_CONST) { - zval_opt_copy_ctor(result); - } else if (IS_TMP_VAR == IS_CV) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(result))) { + zval_copy_ctor_func(result); + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); } + zval_dtor(free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } - if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - ZVAL_DEREF(expr); - } - ZVAL_COPY_VALUE(result, expr); - if (!1) { - zval_opt_copy_ctor(result); - } - if (opline->extended_value == IS_ARRAY) { - convert_to_array(result); + if (Z_TYPE_P(expr) != IS_OBJECT) { + ZVAL_NEW_ARR(result); + zend_hash_init(Z_ARRVAL_P(result), 8, NULL, ZVAL_PTR_DTOR, 0); + if (Z_TYPE_P(expr) != IS_NULL) { + expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) { + zval_copy_ctor_func(expr); + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); + } + } + } else { + ZVAL_COPY_VALUE(result, expr); + if (!1) { + zval_opt_copy_ctor(result); + } + convert_to_array(result); + } } else { - convert_to_object(result); + if (Z_TYPE_P(expr) != IS_ARRAY) { + object_init(result); + if (Z_TYPE_P(expr) != IS_NULL) { + expr = zend_hash_str_add_new(Z_OBJPROP_P(result), "scalar", sizeof("scalar")-1, expr); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) { + zval_copy_ctor_func(expr); + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); + } + } + } else { + ZVAL_COPY_VALUE(result, expr); + if (!1) { + zval_opt_copy_ctor(result); + } + convert_to_object(result); + } } CHECK_EXCEPTION(); @@ -8165,7 +8243,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG ZVAL_DEREF(array_ptr); if (Z_TYPE_P(array_ptr) == IS_ARRAY) { if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL(array_ptr); + SEPARATE_ZVAL_NOREF(array_ptr); array_ref = array_ptr; if (opline->extended_value & ZEND_FE_FETCH_BYREF) { ZVAL_NEW_REF(array_ptr, array_ptr); @@ -8185,7 +8263,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG ce = Z_OBJCE_P(array_ptr); if (!ce || ce->get_iterator == NULL) { if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL(array_ptr); + SEPARATE_ZVAL_NOREF(array_ptr); } Z_ADDREF_P(array_ptr); } @@ -8386,10 +8464,13 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (i_zend_is_true(value TSRMLS_CC)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!1) { - zval_opt_copy_ctor(EX_VAR(opline->result.var)); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); + } + } else if (IS_TMP_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - ZEND_VM_JMP(opline->op2.jmp_addr); } @@ -8408,15 +8489,14 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (i_zend_is_true(value TSRMLS_CC)) { - if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!1) { - zval_opt_copy_ctor(EX_VAR(opline->result.var)); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); } + } else if (IS_TMP_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - ZEND_VM_JMP(opline->op2.jmp_addr); } @@ -8435,11 +8515,13 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!1) { - zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var)); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); + } + } else if (IS_TMP_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -8452,16 +8534,14 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!1) { - zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var)); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); } + } else if (IS_TMP_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -8865,7 +8945,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type, ZVAL_COPY(EX_VAR(opline->result.var), retval); } else { if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + ZVAL_MAKE_REF(retval); } ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -9083,7 +9163,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); } else { @@ -9391,7 +9471,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -9920,7 +10000,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); } else { @@ -10077,7 +10157,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -10550,7 +10630,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE ZVAL_COPY(EX_VAR(opline->result.var), retval); } else { if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + ZVAL_MAKE_REF(retval); } ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -10754,7 +10834,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); } else { @@ -11062,7 +11142,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -11260,7 +11340,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type, ZVAL_COPY(EX_VAR(opline->result.var), retval); } else { if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + ZVAL_MAKE_REF(retval); } ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -11317,7 +11397,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); } else { @@ -11625,7 +11705,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -12136,7 +12216,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); } else { @@ -12293,7 +12373,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -12445,7 +12525,7 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (UNEXPECTED(Z_ISREF_P(var_ptr))) { var_ptr = Z_REFVAL_P(var_ptr); } else { - SEPARATE_ZVAL(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) @@ -12503,7 +12583,7 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (UNEXPECTED(Z_ISREF_P(var_ptr))) { var_ptr = Z_REFVAL_P(var_ptr); } else { - SEPARATE_ZVAL(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) @@ -12561,7 +12641,7 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG ZVAL_DUP(retval, var_ptr); } else { ZVAL_DUP(retval, var_ptr); - SEPARATE_ZVAL(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) @@ -12615,7 +12695,7 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG ZVAL_DUP(retval, var_ptr); } else { ZVAL_DUP(retval, var_ptr); - SEPARATE_ZVAL(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) @@ -12852,10 +12932,12 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); if (IS_VAR == IS_CONST) { - zval_opt_copy_ctor_no_imm(EX(return_value)); + if (UNEXPECTED(Z_OPT_COPYABLE_P(EX(return_value)))) { + zval_copy_ctor_func(EX(return_value)); + } } } else if (Z_ISREF_P(retval_ptr)) { - ZVAL_DUP(EX(return_value), Z_REFVAL_P(retval_ptr)); + ZVAL_COPY(EX(return_value), Z_REFVAL_P(retval_ptr)); zval_ptr_dtor_nogc(free_op1.var); } else { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); @@ -12916,8 +12998,9 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE } if (EX(return_value)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr); - ZVAL_COPY(EX(return_value), retval_ptr); + ZVAL_MAKE_REF(retval_ptr); + Z_ADDREF_P(retval_ptr); + ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr)); } } while (0); @@ -12961,10 +13044,7 @@ static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_AR varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); top = zend_vm_stack_top_inc(TSRMLS_C); if (Z_ISREF_P(varptr)) { - ZVAL_COPY_VALUE(top, Z_REFVAL_P(varptr)); - /* Immutable arrays may be passed without copying ??? */ - /* some internal functions may try to modify them !!! */ - zval_opt_copy_ctor_no_imm(top); + ZVAL_COPY(top, Z_REFVAL_P(varptr)); zval_ptr_dtor_nogc(free_op1.var); } else { ZVAL_COPY_VALUE(top, varptr); @@ -13000,13 +13080,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND Z_TYPE_P(varptr) == IS_OBJECT || (Z_REFCOUNTED_P(varptr) && Z_REFCOUNT_P(varptr) == 1))) { - if (!Z_ISREF_P(varptr)) { - ZVAL_NEW_REF(varptr, varptr); - } - // TODO: Try to avoid copying of immutable arrays ??? - if (Z_OPT_IMMUTABLE_P(Z_REFVAL_P(varptr))) { - zval_opt_copy_ctor(Z_REFVAL_P(varptr)); - } + ZVAL_MAKE_REF(varptr); if (IS_VAR == IS_CV) { Z_ADDREF_P(varptr); } @@ -13018,8 +13092,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND zend_error(E_STRICT, "Only variables should be passed by reference"); } top = zend_vm_stack_top_inc(TSRMLS_C); - // TODO: Try to avoid copying of immutable arrays ??? - ZVAL_DUP(top, varptr); + ZVAL_COPY(top, varptr); zval_ptr_dtor_nogc(free_op1.var); } CHECK_EXCEPTION(); @@ -13046,24 +13119,16 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG } if (Z_ISREF_P(varptr)) { - // TODO: Try to avoid copying of immutable arrays ??? - if (Z_OPT_IMMUTABLE_P(Z_REFVAL_P(varptr))) { - zval_opt_copy_ctor(Z_REFVAL_P(varptr)); - } Z_ADDREF_P(varptr); ZVAL_COPY_VALUE(top, varptr); } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) { ZVAL_COPY_VALUE(top, varptr); - SEPARATE_ZVAL_TO_MAKE_IS_REF(top); + ZVAL_MAKE_REF(top); } else { - // TODO: Try to avoid copying of immutable arrays ??? - if (Z_OPT_IMMUTABLE_P(varptr)) { - zval_opt_copy_ctor(varptr); - } - SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr); + ZVAL_MAKE_REF(varptr); Z_ADDREF_P(varptr); - ZVAL_COPY_VALUE(top, varptr); + ZVAL_REF(top, Z_REF_P(varptr)); } if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; @@ -13085,10 +13150,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); top = zend_vm_stack_top_inc(TSRMLS_C); if (Z_ISREF_P(varptr)) { - ZVAL_COPY_VALUE(top, Z_REFVAL_P(varptr)); - /* Immutable arrays may be passed without copying ??? */ - /* some internal functions may try to modify them !!! */ - zval_opt_copy_ctor_no_imm(top); + ZVAL_COPY(top, Z_REFVAL_P(varptr)); zval_ptr_dtor_nogc(free_op1.var); } else { ZVAL_COPY_VALUE(top, varptr); @@ -13186,11 +13248,11 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op1; - zval *expr; + zval *expr, tmp; zval *result = EX_VAR(opline->result.var); SAVE_OPLINE(); - expr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); switch (opline->extended_value) { case IS_NULL: @@ -13227,27 +13289,59 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (Z_TYPE_P(expr) == opline->extended_value) { ZVAL_COPY_VALUE(result, expr); if (IS_VAR == IS_CONST) { - zval_opt_copy_ctor(result); - } else if (IS_VAR == IS_CV) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(result))) { + zval_copy_ctor_func(result); + } + } else if (IS_VAR != IS_TMP_VAR) { if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); } + zval_ptr_dtor_nogc(free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } - if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { - ZVAL_DEREF(expr); - } - ZVAL_COPY_VALUE(result, expr); - if (!0) { - zval_opt_copy_ctor(result); - } - if (opline->extended_value == IS_ARRAY) { - convert_to_array(result); + if (Z_TYPE_P(expr) != IS_OBJECT) { + ZVAL_NEW_ARR(result); + zend_hash_init(Z_ARRVAL_P(result), 8, NULL, ZVAL_PTR_DTOR, 0); + if (Z_TYPE_P(expr) != IS_NULL) { + expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr); + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) { + zval_copy_ctor_func(expr); + } + } else if (IS_VAR != IS_TMP_VAR) { + if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); + } + } + } else { + ZVAL_COPY_VALUE(result, expr); + if (!0) { + zval_opt_copy_ctor(result); + } + convert_to_array(result); + } } else { - convert_to_object(result); + if (Z_TYPE_P(expr) != IS_ARRAY) { + object_init(result); + if (Z_TYPE_P(expr) != IS_NULL) { + expr = zend_hash_str_add_new(Z_OBJPROP_P(result), "scalar", sizeof("scalar")-1, expr); + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) { + zval_copy_ctor_func(expr); + } + } else if (IS_VAR != IS_TMP_VAR) { + if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); + } + } + } else { + ZVAL_COPY_VALUE(result, expr); + if (!0) { + zval_opt_copy_ctor(result); + } + convert_to_object(result); + } } zval_ptr_dtor_nogc(free_op1.var); @@ -13401,7 +13495,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG ZVAL_DEREF(array_ptr); if (Z_TYPE_P(array_ptr) == IS_ARRAY) { if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL(array_ptr); + SEPARATE_ZVAL_NOREF(array_ptr); array_ref = array_ptr; if (opline->extended_value & ZEND_FE_FETCH_BYREF) { ZVAL_NEW_REF(array_ptr, array_ptr); @@ -13421,7 +13515,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG ce = Z_OBJCE_P(array_ptr); if (!ce || ce->get_iterator == NULL) { if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL(array_ptr); + SEPARATE_ZVAL_NOREF(array_ptr); } Z_ADDREF_P(array_ptr); } @@ -13573,7 +13667,13 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG zval *key = NULL; array = array_ref = EX_VAR(opline->op1.var); - ZVAL_DEREF(array); + if (Z_ISREF_P(array)) { + array = Z_REFVAL_P(array); + // TODO: referenced value might be changed to different array ??? + if (Z_IMMUTABLE_P(array)) { + zval_copy_ctor(array); + } + } if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) { key = EX_VAR((opline+1)->result.var); } @@ -13692,9 +13792,12 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG } if (opline->extended_value & ZEND_FE_FETCH_BYREF) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value); + ZVAL_MAKE_REF(value); + Z_ADDREF_P(value); + ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(value)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); } - ZVAL_COPY(EX_VAR(opline->result.var), value); CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -13734,10 +13837,13 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (i_zend_is_true(value TSRMLS_CC)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!0) { - zval_opt_copy_ctor(EX_VAR(opline->result.var)); + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); + } + } else if (IS_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - zval_ptr_dtor_nogc(free_op1.var); ZEND_VM_JMP(opline->op2.jmp_addr); } @@ -13756,15 +13862,14 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (i_zend_is_true(value TSRMLS_CC)) { - if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!0) { - zval_opt_copy_ctor(EX_VAR(opline->result.var)); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); } + } else if (IS_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - zval_ptr_dtor_nogc(free_op1.var); ZEND_VM_JMP(opline->op2.jmp_addr); } @@ -13783,11 +13888,13 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!0) { - zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var)); + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); + } + } else if (IS_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - zval_ptr_dtor_nogc(free_op1.var); - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13800,17 +13907,14 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!0) { - zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var)); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); } + } else if (IS_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - - zval_ptr_dtor_nogc(free_op1.var); - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14240,7 +14344,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -14295,7 +14399,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -14749,7 +14853,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, ZVAL_COPY(EX_VAR(opline->result.var), retval); } else { if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + ZVAL_MAKE_REF(retval); } ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -15453,7 +15557,14 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), c); } retval = EX_VAR(opline->result.var); - ZVAL_DUP(retval, &c->value); + ZVAL_COPY_VALUE(retval, &c->value); + if (Z_OPT_COPYABLE_P(retval) || Z_OPT_REFCOUNTED_P(retval)) { + if (Z_OPT_COPYABLE_P(retval) && (c->flags & CONST_PERSISTENT)) { + zval_copy_ctor_func(retval); + } else { + Z_ADDREF_P(retval); + } + } } else { /* class constant */ zend_class_entry *ce; @@ -15527,7 +15638,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; } else { @@ -16109,7 +16220,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -16615,7 +16726,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -16670,7 +16781,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_ } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -17669,7 +17780,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; } else { @@ -18102,7 +18213,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -18608,7 +18719,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -18663,7 +18774,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_ } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -19119,7 +19230,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE ZVAL_COPY(EX_VAR(opline->result.var), retval); } else { if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + ZVAL_MAKE_REF(retval); } ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -19874,7 +19985,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; } else { @@ -20458,7 +20569,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -20688,7 +20799,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (* } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -20743,7 +20854,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -21019,7 +21130,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, ZVAL_COPY(EX_VAR(opline->result.var), retval); } else { if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + ZVAL_MAKE_REF(retval); } ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -21333,7 +21444,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; } else { @@ -21659,7 +21770,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -22149,7 +22260,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -22204,7 +22315,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -23258,7 +23369,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; } else { @@ -23689,7 +23800,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -23998,7 +24109,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -24053,7 +24164,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*bi } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -24734,7 +24845,14 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), c); } retval = EX_VAR(opline->result.var); - ZVAL_DUP(retval, &c->value); + ZVAL_COPY_VALUE(retval, &c->value); + if (Z_OPT_COPYABLE_P(retval) || Z_OPT_REFCOUNTED_P(retval)) { + if (Z_OPT_COPYABLE_P(retval) && (c->flags & CONST_PERSISTENT)) { + zval_copy_ctor_func(retval); + } else { + Z_ADDREF_P(retval); + } + } } else { /* class constant */ zend_class_entry *ce; @@ -25151,7 +25269,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -25365,7 +25483,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (* } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -25420,7 +25538,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*bina } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -26439,7 +26557,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -26653,7 +26771,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (* } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -26708,7 +26826,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -27727,7 +27845,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -27940,7 +28058,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -27995,7 +28113,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*b } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -28249,7 +28367,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -28462,7 +28580,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*b } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -28517,7 +28635,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binar } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -29528,7 +29646,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -29670,7 +29788,7 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (UNEXPECTED(Z_ISREF_P(var_ptr))) { var_ptr = Z_REFVAL_P(var_ptr); } else { - SEPARATE_ZVAL(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) @@ -29727,7 +29845,7 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (UNEXPECTED(Z_ISREF_P(var_ptr))) { var_ptr = Z_REFVAL_P(var_ptr); } else { - SEPARATE_ZVAL(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) @@ -29784,7 +29902,7 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS ZVAL_DUP(retval, var_ptr); } else { ZVAL_DUP(retval, var_ptr); - SEPARATE_ZVAL(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) @@ -29837,7 +29955,7 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS ZVAL_DUP(retval, var_ptr); } else { ZVAL_DUP(retval, var_ptr); - SEPARATE_ZVAL(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) @@ -30058,10 +30176,12 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); if (IS_CV == IS_CONST) { - zval_opt_copy_ctor_no_imm(EX(return_value)); + if (UNEXPECTED(Z_OPT_COPYABLE_P(EX(return_value)))) { + zval_copy_ctor_func(EX(return_value)); + } } } else if (Z_ISREF_P(retval_ptr)) { - ZVAL_DUP(EX(return_value), Z_REFVAL_P(retval_ptr)); + ZVAL_COPY(EX(return_value), Z_REFVAL_P(retval_ptr)); } else { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); @@ -30122,8 +30242,9 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER } if (EX(return_value)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr); - ZVAL_COPY(EX(return_value), retval_ptr); + ZVAL_MAKE_REF(retval_ptr); + Z_ADDREF_P(retval_ptr); + ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr)); } } while (0); @@ -30166,10 +30287,7 @@ static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARG varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); top = zend_vm_stack_top_inc(TSRMLS_C); if (Z_ISREF_P(varptr)) { - ZVAL_COPY_VALUE(top, Z_REFVAL_P(varptr)); - /* Immutable arrays may be passed without copying ??? */ - /* some internal functions may try to modify them !!! */ - zval_opt_copy_ctor_no_imm(top); + ZVAL_COPY(top, Z_REFVAL_P(varptr)); } else { ZVAL_COPY_VALUE(top, varptr); @@ -30205,13 +30323,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL Z_TYPE_P(varptr) == IS_OBJECT || (Z_REFCOUNTED_P(varptr) && Z_REFCOUNT_P(varptr) == 1))) { - if (!Z_ISREF_P(varptr)) { - ZVAL_NEW_REF(varptr, varptr); - } - // TODO: Try to avoid copying of immutable arrays ??? - if (Z_OPT_IMMUTABLE_P(Z_REFVAL_P(varptr))) { - zval_opt_copy_ctor(Z_REFVAL_P(varptr)); - } + ZVAL_MAKE_REF(varptr); if (IS_CV == IS_CV) { Z_ADDREF_P(varptr); } @@ -30223,8 +30335,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL zend_error(E_STRICT, "Only variables should be passed by reference"); } top = zend_vm_stack_top_inc(TSRMLS_C); - // TODO: Try to avoid copying of immutable arrays ??? - ZVAL_DUP(top, varptr); + ZVAL_COPY(top, varptr); } CHECK_EXCEPTION(); @@ -30251,24 +30362,16 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS } if (Z_ISREF_P(varptr)) { - // TODO: Try to avoid copying of immutable arrays ??? - if (Z_OPT_IMMUTABLE_P(Z_REFVAL_P(varptr))) { - zval_opt_copy_ctor(Z_REFVAL_P(varptr)); - } Z_ADDREF_P(varptr); ZVAL_COPY_VALUE(top, varptr); } else if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) { ZVAL_COPY_VALUE(top, varptr); - SEPARATE_ZVAL_TO_MAKE_IS_REF(top); + ZVAL_MAKE_REF(top); } else { - // TODO: Try to avoid copying of immutable arrays ??? - if (Z_OPT_IMMUTABLE_P(varptr)) { - zval_opt_copy_ctor(varptr); - } - SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr); + ZVAL_MAKE_REF(varptr); Z_ADDREF_P(varptr); - ZVAL_COPY_VALUE(top, varptr); + ZVAL_REF(top, Z_REF_P(varptr)); } ZEND_VM_NEXT_OPCODE(); @@ -30289,10 +30392,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); top = zend_vm_stack_top_inc(TSRMLS_C); if (Z_ISREF_P(varptr)) { - ZVAL_COPY_VALUE(top, Z_REFVAL_P(varptr)); - /* Immutable arrays may be passed without copying ??? */ - /* some internal functions may try to modify them !!! */ - zval_opt_copy_ctor_no_imm(top); + ZVAL_COPY(top, Z_REFVAL_P(varptr)); } else { ZVAL_COPY_VALUE(top, varptr); @@ -30379,11 +30479,11 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *expr; + zval *expr, tmp; zval *result = EX_VAR(opline->result.var); SAVE_OPLINE(); - expr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + expr = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); switch (opline->extended_value) { case IS_NULL: @@ -30420,8 +30520,10 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (Z_TYPE_P(expr) == opline->extended_value) { ZVAL_COPY_VALUE(result, expr); if (IS_CV == IS_CONST) { - zval_opt_copy_ctor(result); - } else if (IS_CV == IS_CV) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(result))) { + zval_copy_ctor_func(result); + } + } else if (IS_CV != IS_TMP_VAR) { if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); } @@ -30429,18 +30531,47 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ZEND_VM_NEXT_OPCODE(); } - if (IS_CV == IS_VAR || IS_CV == IS_CV) { - ZVAL_DEREF(expr); - } - ZVAL_COPY_VALUE(result, expr); - if (!0) { - zval_opt_copy_ctor(result); - } - if (opline->extended_value == IS_ARRAY) { - convert_to_array(result); + if (Z_TYPE_P(expr) != IS_OBJECT) { + ZVAL_NEW_ARR(result); + zend_hash_init(Z_ARRVAL_P(result), 8, NULL, ZVAL_PTR_DTOR, 0); + if (Z_TYPE_P(expr) != IS_NULL) { + expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) { + zval_copy_ctor_func(expr); + } + } else if (IS_CV != IS_TMP_VAR) { + if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); + } + } + } else { + ZVAL_COPY_VALUE(result, expr); + if (!0) { + zval_opt_copy_ctor(result); + } + convert_to_array(result); + } } else { - convert_to_object(result); + if (Z_TYPE_P(expr) != IS_ARRAY) { + object_init(result); + if (Z_TYPE_P(expr) != IS_NULL) { + expr = zend_hash_str_add_new(Z_OBJPROP_P(result), "scalar", sizeof("scalar")-1, expr); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) { + zval_copy_ctor_func(expr); + } + } else if (IS_CV != IS_TMP_VAR) { + if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); + } + } + } else { + ZVAL_COPY_VALUE(result, expr); + if (!0) { + zval_opt_copy_ctor(result); + } + convert_to_object(result); + } } CHECK_EXCEPTION(); @@ -30593,7 +30724,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS ZVAL_DEREF(array_ptr); if (Z_TYPE_P(array_ptr) == IS_ARRAY) { if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL(array_ptr); + SEPARATE_ZVAL_NOREF(array_ptr); array_ref = array_ptr; if (opline->extended_value & ZEND_FE_FETCH_BYREF) { ZVAL_NEW_REF(array_ptr, array_ptr); @@ -30613,7 +30744,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS ce = Z_OBJCE_P(array_ptr); if (!ce || ce->get_iterator == NULL) { if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL(array_ptr); + SEPARATE_ZVAL_NOREF(array_ptr); } Z_ADDREF_P(array_ptr); } @@ -30787,10 +30918,13 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (i_zend_is_true(value TSRMLS_CC)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!0) { - zval_opt_copy_ctor(EX_VAR(opline->result.var)); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); + } + } else if (IS_CV == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - ZEND_VM_JMP(opline->op2.jmp_addr); } @@ -30808,15 +30942,14 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); if (i_zend_is_true(value TSRMLS_CC)) { - if (IS_CV == IS_VAR || IS_CV == IS_CV) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!0) { - zval_opt_copy_ctor(EX_VAR(opline->result.var)); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); } + } else if (IS_CV == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - ZEND_VM_JMP(opline->op2.jmp_addr); } @@ -30834,11 +30967,13 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!0) { - zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var)); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); + } + } else if (IS_CV == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -30851,16 +30986,14 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR || IS_CV == IS_CV) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (!0) { - zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var)); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + zval_copy_ctor_func(EX_VAR(opline->result.var)); } + } else if (IS_CV == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -31289,7 +31422,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*bi } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -31344,7 +31477,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -31798,7 +31931,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z ZVAL_COPY(EX_VAR(opline->result.var), retval); } else { if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + ZVAL_MAKE_REF(retval); } ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -32369,7 +32502,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); } else { @@ -32951,7 +33084,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -33455,7 +33588,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*bina } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -33510,7 +33643,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -34394,7 +34527,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); } else { @@ -34827,7 +34960,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -35331,7 +35464,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*bina } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -35386,7 +35519,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -35842,7 +35975,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN ZVAL_COPY(EX_VAR(opline->result.var), retval); } else { if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + ZVAL_MAKE_REF(retval); } ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -36481,7 +36614,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); } else { @@ -37065,7 +37198,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -37293,7 +37426,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*b } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -37348,7 +37481,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binar } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -37624,7 +37757,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type, ZVAL_COPY(EX_VAR(opline->result.var), retval); } else { if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + ZVAL_MAKE_REF(retval); } ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -37824,7 +37957,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); } else { @@ -38132,7 +38265,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); @@ -38620,7 +38753,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binar } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -38675,7 +38808,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op } if (EXPECTED(!Z_ISREF_P(var_ptr))) { - SEPARATE_ZVAL_IF_NOT_REF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); } else { ZVAL_DEREF(var_ptr); } @@ -39613,7 +39746,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_ if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } - SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr); + ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); } else { @@ -40044,7 +40177,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); + ZVAL_MAKE_REF(value_ptr); } ZVAL_COPY(&generator->value, value_ptr); diff --git a/ext/curl/multi.c b/ext/curl/multi.c index 1a69a3a37c..5550972bba 100644 --- a/ext/curl/multi.c +++ b/ext/curl/multi.c @@ -199,12 +199,11 @@ PHP_FUNCTION(curl_multi_exec) int still_running; int result; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz", &z_mh, &z_still_running) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz/", &z_mh, &z_still_running) == FAILURE) { return; } ZEND_FETCH_RESOURCE(mh, php_curlm *, z_mh, -1, le_curl_multi_handle_name, le_curl_multi_handle); - ZVAL_DEREF(z_still_running); { zend_llist_position pos; @@ -260,7 +259,7 @@ PHP_FUNCTION(curl_multi_info_read) int queued_msgs; zval *zmsgs_in_queue = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|z", &z_mh, &zmsgs_in_queue) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|z/", &z_mh, &zmsgs_in_queue) == FAILURE) { return; } diff --git a/ext/ereg/ereg.c b/ext/ereg/ereg.c index 668f955105..79bee9b79f 100644 --- a/ext/ereg/ereg.c +++ b/ext/ereg/ereg.c @@ -305,7 +305,7 @@ static void php_ereg(INTERNAL_FUNCTION_PARAMETERS, int icase) char *string = NULL; int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "zs|z", ®ex, &findin, &findin_len, &array) == FAILURE) { + if (zend_parse_parameters(argc TSRMLS_CC, "zs|z/", ®ex, &findin, &findin_len, &array) == FAILURE) { return; } @@ -351,10 +351,6 @@ static void php_ereg(INTERNAL_FUNCTION_PARAMETERS, int icase) } match_len = 1; - if (array) { - ZVAL_DEREF(array); - } - if (array && err != REG_NOMATCH) { match_len = (int) (subs[0].rm_eo - subs[0].rm_so); string_len = findin_len + 1; diff --git a/ext/ftp/php_ftp.c b/ext/ftp/php_ftp.c index 46e336deb0..1bf485f4ed 100644 --- a/ext/ftp/php_ftp.c +++ b/ext/ftp/php_ftp.c @@ -632,7 +632,7 @@ PHP_FUNCTION(ftp_alloc) long size, ret; zend_string *response = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &z_ftp, &size, &zresponse) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z/", &z_ftp, &size, &zresponse) == FAILURE) { RETURN_FALSE; } @@ -640,7 +640,6 @@ PHP_FUNCTION(ftp_alloc) ret = ftp_alloc(ftp, size, zresponse ? &response : NULL); if (response) { - ZVAL_DEREF(zresponse); zval_dtor(zresponse); ZVAL_STR(zresponse, response); } diff --git a/ext/json/json.c b/ext/json/json.c index e7e07ce2c1..0bf8a645e6 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -276,7 +276,7 @@ static void json_encode_array(smart_str *buf, zval *val, int options TSRMLS_DC) if (key) { if (key->val[0] == '\0' && Z_TYPE_P(val) == IS_OBJECT) { /* Skip protected and private members. */ - if (tmp_ht) { + if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) { ZEND_HASH_DEC_APPLY_COUNT(tmp_ht); } continue; diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index c5cb15f7c3..8f52f1f3fb 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -1910,13 +1910,12 @@ PHP_FUNCTION(ldap_get_option) ldap_linkdata *ld; long option; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz", &link, &option, &retval) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz/", &link, &option, &retval) != SUCCESS) { return; } ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link); - ZVAL_DEREF(retval); switch (option) { /* options with int value */ case LDAP_OPT_DEREF: @@ -2186,7 +2185,7 @@ PHP_FUNCTION(ldap_parse_result) char *lmatcheddn, *lerrmsg; int rc, lerrcode, myargcount = ZEND_NUM_ARGS(); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz|zzz", &link, &result, &errcode, &matcheddn, &errmsg, &referrals) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz/|z/z/z/", &link, &result, &errcode, &matcheddn, &errmsg, &referrals) != SUCCESS) { return; } @@ -2204,14 +2203,12 @@ PHP_FUNCTION(ldap_parse_result) RETURN_FALSE; } - ZVAL_DEREF(errcode); zval_ptr_dtor(errcode); ZVAL_LONG(errcode, lerrcode); /* Reverse -> fall through */ switch (myargcount) { case 6: - ZVAL_DEREF(referrals); zval_ptr_dtor(referrals); array_init(referrals); if (lreferrals != NULL) { @@ -2223,7 +2220,6 @@ PHP_FUNCTION(ldap_parse_result) ldap_value_free(lreferrals); } case 5: - ZVAL_DEREF(errmsg); zval_ptr_dtor(errmsg); if (lerrmsg == NULL) { ZVAL_EMPTY_STRING(errmsg); @@ -2232,7 +2228,6 @@ PHP_FUNCTION(ldap_parse_result) ldap_memfree(lerrmsg); } case 4: - ZVAL_DEREF(matcheddn); zval_ptr_dtor(matcheddn); if (lmatcheddn == NULL) { ZVAL_EMPTY_STRING(matcheddn); @@ -2312,7 +2307,7 @@ PHP_FUNCTION(ldap_parse_reference) ldap_resultentry *resultentry; char **lreferrals, **refp; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz", &link, &result_entry, &referrals) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz/", &link, &result_entry, &referrals) != SUCCESS) { return; } @@ -2323,7 +2318,6 @@ PHP_FUNCTION(ldap_parse_reference) RETURN_FALSE; } - ZVAL_DEREF(referrals); zval_ptr_dtor(referrals); array_init(referrals); if (lreferrals != NULL) { @@ -2721,7 +2715,7 @@ PHP_FUNCTION(ldap_control_paged_result_response) ber_tag_t tag; int rc, lerrcode, myargcount = ZEND_NUM_ARGS(); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr|zz", &link, &result, &cookie, &estimated) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr|z/z/", &link, &result, &cookie, &estimated) != SUCCESS) { return; } @@ -2787,7 +2781,6 @@ PHP_FUNCTION(ldap_control_paged_result_response) ZVAL_LONG(estimated, lestimated); } - ZVAL_DEREF(cookie); zval_ptr_dtor(cookie); if (lcookie.bv_len == 0) { ZVAL_EMPTY_STRING(cookie); diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 54bd34fa7a..ebea66323c 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2059,13 +2059,12 @@ PHP_FUNCTION(mb_parse_str) const mbfl_encoding *detected; track_vars_array = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &encstr, &encstr_len, &track_vars_array) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z/", &encstr, &encstr_len, &track_vars_array) == FAILURE) { return; } if (track_vars_array != NULL) { /* Clear out the array */ - ZVAL_DEREF(track_vars_array); zval_dtor(track_vars_array); array_init(track_vars_array); } @@ -3600,6 +3599,7 @@ PHP_FUNCTION(mb_convert_variables) if (stack_level <= 0) { var = &args[n++]; ZVAL_DEREF(var); + SEPARATE_ZVAL_NOREF(var); if (Z_TYPE_P(var) == IS_ARRAY || Z_TYPE_P(var) == IS_OBJECT) { target_hash = HASH_OF(var); if (target_hash != NULL) { @@ -3686,6 +3686,7 @@ detect_end: if (stack_level <= 0) { var = &args[n++]; ZVAL_DEREF(var); + SEPARATE_ZVAL_NOREF(var); if (Z_TYPE_P(var) == IS_ARRAY || Z_TYPE_P(var) == IS_OBJECT) { target_hash = HASH_OF(var); if (target_hash != NULL) { diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c index 24c1ff9019..ab03306f14 100644 --- a/ext/mbstring/php_mbregex.c +++ b/ext/mbstring/php_mbregex.c @@ -698,7 +698,7 @@ static void _php_mb_regex_ereg_exec(INTERNAL_FUNCTION_PARAMETERS, int icase) array = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs|z", &arg_pattern, &string, &string_len, &array) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs|z/", &arg_pattern, &string, &string_len, &array) == FAILURE) { RETURN_FALSE; } @@ -740,7 +740,6 @@ static void _php_mb_regex_ereg_exec(INTERNAL_FUNCTION_PARAMETERS, int icase) match_len = 1; str = string; if (array != NULL) { - ZVAL_DEREF(array); zval_dtor(array); array_init(array); diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 94056ce04b..16c609ffb9 100755 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -1715,10 +1715,9 @@ PHP_FUNCTION(openssl_x509_export) BIO * bio_out; zend_resource *certresource; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|b", &zcert, &zout, ¬ext) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz/|b", &zcert, &zout, ¬ext) == FAILURE) { return; } - ZVAL_DEREF(zout); RETVAL_FALSE; cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC); @@ -2481,10 +2480,9 @@ PHP_FUNCTION(openssl_pkcs12_export) zval * item; STACK_OF(X509) *ca = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzzs|a", &zcert, &zout, &zpkey, &pass, &pass_len, &args) == FAILURE) + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz/zs|a", &zcert, &zout, &zpkey, &pass, &pass_len, &args) == FAILURE) return; - ZVAL_DEREF(zout); RETVAL_FALSE; cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC); @@ -2552,9 +2550,9 @@ PHP_FUNCTION(openssl_pkcs12_read) BIO * bio_in = NULL; int i; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szs", &zp12, &zp12_len, &zout, &pass, &pass_len) == FAILURE) + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/s", &zp12, &zp12_len, &zout, &pass, &pass_len) == FAILURE) return; - ZVAL_DEREF(zout); + RETVAL_FALSE; bio_in = BIO_new(BIO_s_mem()); @@ -2879,10 +2877,10 @@ PHP_FUNCTION(openssl_csr_export) BIO * bio_out; zend_resource *csr_resource; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|b", &zcsr, &zout, ¬ext) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz/|b", &zcsr, &zout, ¬ext) == FAILURE) { return; } - ZVAL_DEREF(zout); + RETVAL_FALSE; csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource TSRMLS_CC); @@ -3060,10 +3058,9 @@ PHP_FUNCTION(openssl_csr_new) int we_made_the_key = 1; zend_resource *key_resource; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az|a!a!", &dn, &out_pkey, &args, &attribs) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az/|a!a!", &dn, &out_pkey, &args, &attribs) == FAILURE) { return; } - ZVAL_DEREF(out_pkey); RETVAL_FALSE; PHP_SSL_REQ_INIT(&req); @@ -3694,10 +3691,9 @@ PHP_FUNCTION(openssl_pkey_export) BIO * bio_out = NULL; const EVP_CIPHER * cipher; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|s!a!", &zpkey, &out, &passphrase, &passphrase_len, &args) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz/|s!a!", &zpkey, &out, &passphrase, &passphrase_len, &args) == FAILURE) { return; } - ZVAL_DEREF(out); RETVAL_FALSE; key = php_openssl_evp_from_zval(zpkey, 0, passphrase, 0, &key_resource TSRMLS_CC); @@ -4380,10 +4376,9 @@ PHP_FUNCTION(openssl_private_encrypt) int data_len; long padding = RSA_PKCS1_PADDING; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/z|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) { return; } - ZVAL_DEREF(crypted); RETVAL_FALSE; pkey = php_openssl_evp_from_zval(key, 0, "", 0, &keyresource TSRMLS_CC); @@ -4442,10 +4437,9 @@ PHP_FUNCTION(openssl_private_decrypt) char * data; int data_len; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/z|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) { return; } - ZVAL_DEREF(crypted); RETVAL_FALSE; pkey = php_openssl_evp_from_zval(key, 0, "", 0, &keyresource TSRMLS_CC); @@ -4510,9 +4504,8 @@ PHP_FUNCTION(openssl_public_encrypt) char * data; int data_len; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/z|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) return; - ZVAL_DEREF(crypted); RETVAL_FALSE; pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC); @@ -4571,10 +4564,9 @@ PHP_FUNCTION(openssl_public_decrypt) char * data; int data_len; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/z|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) { return; } - ZVAL_DEREF(crypted); RETVAL_FALSE; pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC); @@ -4663,10 +4655,9 @@ PHP_FUNCTION(openssl_sign) long signature_algo = OPENSSL_ALGO_SHA1; const EVP_MD *mdtype; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz|z", &data, &data_len, &signature, &key, &method) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/z|z", &data, &data_len, &signature, &key, &method) == FAILURE) { return; } - ZVAL_DEREF(signature); pkey = php_openssl_evp_from_zval(key, 0, "", 0, &keyresource TSRMLS_CC); if (pkey == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "supplied key param cannot be coerced into a private key"); @@ -4781,11 +4772,9 @@ PHP_FUNCTION(openssl_seal) const EVP_CIPHER *cipher; EVP_CIPHER_CTX ctx; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szza/|s", &data, &data_len, &sealdata, &ekeys, &pubkeys, &method, &method_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/z/a/|s", &data, &data_len, &sealdata, &ekeys, &pubkeys, &method, &method_len) == FAILURE) { return; } - ZVAL_DEREF(sealdata); - ZVAL_DEREF(ekeys); pubkeysht = HASH_OF(pubkeys); nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0; if (!nkeys) { @@ -4909,10 +4898,9 @@ PHP_FUNCTION(openssl_open) int method_len = 0; const EVP_CIPHER *cipher; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szsz|s", &data, &data_len, &opendata, &ekey, &ekey_len, &privkey, &method, &method_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/sz|s", &data, &data_len, &opendata, &ekey, &ekey_len, &privkey, &method, &method_len) == FAILURE) { return; } - ZVAL_DEREF(opendata); pkey = php_openssl_evp_from_zval(privkey, 0, "", 0, &keyresource TSRMLS_CC); if (pkey == NULL) { @@ -5324,10 +5312,9 @@ PHP_FUNCTION(openssl_random_pseudo_bytes) zval *zstrong_result_returned = NULL; int strong_result = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|z", &buffer_length, &zstrong_result_returned) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|z/", &buffer_length, &zstrong_result_returned) == FAILURE) { return; } - ZVAL_DEREF(zstrong_result_returned); if (buffer_length <= 0) { RETURN_FALSE; diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index 5de4ae1cd4..448e34b5cc 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -574,10 +574,9 @@ PHP_FUNCTION(pcntl_waitpid) int status; pid_t child_id; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz|l", &pid, &z_status, &options) == FAILURE) + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz/|l", &pid, &z_status, &options) == FAILURE) return; - ZVAL_DEREF(z_status); convert_to_long_ex(z_status); status = Z_LVAL_P(z_status); @@ -603,10 +602,9 @@ PHP_FUNCTION(pcntl_wait) int status; pid_t child_id; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &z_status, &options) == FAILURE) + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/|l", &z_status, &options) == FAILURE) return; - ZVAL_DEREF(z_status); convert_to_long_ex(z_status); status = Z_LVAL_P(z_status); @@ -918,7 +916,7 @@ PHP_FUNCTION(pcntl_sigprocmask) zval *user_set, *user_oldset = NULL, *user_signo; sigset_t set, oldset; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "la|z", &how, &user_set, &user_oldset) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "la|z/", &how, &user_set, &user_oldset) == FAILURE) { return; } @@ -948,7 +946,6 @@ PHP_FUNCTION(pcntl_sigprocmask) } if (user_oldset != NULL) { - ZVAL_DEREF(user_oldset); if (Z_TYPE_P(user_oldset) != IS_ARRAY) { zval_dtor(user_oldset); array_init(user_oldset); @@ -979,11 +976,11 @@ static void pcntl_sigwaitinfo(INTERNAL_FUNCTION_PARAMETERS, int timedwait) /* {{ struct timespec timeout; if (timedwait) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|zll", &user_set, &user_siginfo, &tv_sec, &tv_nsec) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|z/ll", &user_set, &user_siginfo, &tv_sec, &tv_nsec) == FAILURE) { return; } } else { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|z", &user_set, &user_siginfo) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|z/", &user_set, &user_siginfo) == FAILURE) { return; } } @@ -1028,7 +1025,6 @@ static void pcntl_sigwaitinfo(INTERNAL_FUNCTION_PARAMETERS, int timedwait) /* {{ } if (signo > 0 && user_siginfo) { - ZVAL_DEREF(user_siginfo); if (Z_TYPE_P(user_siginfo) != IS_ARRAY) { zval_dtor(user_siginfo); array_init(user_siginfo); diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 193234c131..0ce3600005 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -542,7 +542,7 @@ static void php_do_pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global) /* {{{ * long flags = 0; /* Match control flags */ long start_offset = 0; /* Where the new search starts */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ss|zll", ®ex, + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ss|z/ll", ®ex, &subject, &subject_len, &subpats, &flags, &start_offset) == FAILURE) { RETURN_FALSE; } @@ -552,9 +552,6 @@ static void php_do_pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global) /* {{{ * RETURN_FALSE; } - if (subpats) { - ZVAL_DEREF(subpats); - } php_pcre_match_impl(pce, subject, subject_len, return_value, subpats, global, ZEND_NUM_ARGS() >= 4, flags, start_offset TSRMLS_CC); } @@ -1355,7 +1352,7 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl int replace_count=0, old_replace_count; /* Get function parameters and do error-checking. */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz|lz", ®ex, &replace, &subject, &limit, &zcount) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz|lz/", ®ex, &replace, &subject, &limit, &zcount) == FAILURE) { return; } @@ -1419,7 +1416,6 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl } } if (ZEND_NUM_ARGS() > 4) { - ZVAL_DEREF(zcount); zval_dtor(zcount); ZVAL_LONG(zcount, replace_count); } diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index c35cae2d33..0ec71d7625 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -360,7 +360,6 @@ static zend_bool soap_check_xml_ref(zval *data, xmlNodePtr node TSRMLS_DC) !Z_REFCOUNTED_P(data_ptr) || Z_COUNTED_P(data) != Z_COUNTED_P(data_ptr)) { zval_ptr_dtor(data); -//??? SEPARATE_ZVAL_TO_MAKE_IS_REF(data_ptr); ZVAL_COPY(data, data_ptr); return 1; } diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 55da782e39..7150738051 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -2862,7 +2862,7 @@ PHP_METHOD(SoapClient, __call) zend_bool free_soap_headers = 0; zval *this_ptr; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|a!zz", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|a!zz/", &function, &function_len, &args, &options, &headers, &output_headers) == FAILURE) { return; } diff --git a/ext/sockets/sendrecvmsg.c b/ext/sockets/sendrecvmsg.c index 901972da36..4ddae3f6ff 100644 --- a/ext/sockets/sendrecvmsg.c +++ b/ext/sockets/sendrecvmsg.c @@ -217,7 +217,7 @@ PHP_FUNCTION(socket_recvmsg) struct err_s err = {0}; //ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|l", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra/|l", &zsocket, &zmsg, &flags) == FAILURE) { return; } diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index b858a4733e..dd7f27260f 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -838,7 +838,7 @@ PHP_FUNCTION(socket_select) int retval, sets = 0; long usec = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!a!z!|l", &r_array, &w_array, &e_array, &sec, &usec) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/!a/!a/!z!|l", &r_array, &w_array, &e_array, &sec, &usec) == FAILURE) { return; } @@ -1179,7 +1179,7 @@ PHP_FUNCTION(socket_getsockname) char *addr_string; socklen_t salen = sizeof(php_sockaddr_storage); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|z", &arg1, &addr, &port) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz/|z/", &arg1, &addr, &port) == FAILURE) { return; } @@ -1192,7 +1192,6 @@ PHP_FUNCTION(socket_getsockname) RETURN_FALSE; } - ZVAL_DEREF(addr); if (port != NULL) { ZVAL_DEREF(port); } @@ -1261,7 +1260,7 @@ PHP_FUNCTION(socket_getpeername) char *addr_string; socklen_t salen = sizeof(php_sockaddr_storage); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|z", &arg1, &arg2, &arg3) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz/|z/", &arg1, &arg2, &arg3) == FAILURE) { return; } @@ -1274,8 +1273,6 @@ PHP_FUNCTION(socket_getpeername) RETURN_FALSE; } - ZVAL_DEREF(arg2); - ZVAL_DEREF(arg3); switch (sa->sa_family) { #if HAVE_IPV6 case AF_INET6: @@ -1563,7 +1560,7 @@ PHP_FUNCTION(socket_recv) int retval; long len, flags; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzll", &php_sock_res, &buf, &len, &flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz/ll", &php_sock_res, &buf, &len, &flags) == FAILURE) { return; } @@ -1576,7 +1573,6 @@ PHP_FUNCTION(socket_recv) recv_buf = STR_ALLOC(len, 0); - ZVAL_DEREF(buf); if ((retval = recv(php_sock->bsd_socket, recv_buf->val, len, flags)) < 1) { efree(recv_buf); @@ -1645,7 +1641,7 @@ PHP_FUNCTION(socket_recvfrom) char *address; zend_string *recv_buf; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzllz|z", &arg1, &arg2, &arg3, &arg4, &arg5, &arg6) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz/llz/|z/", &arg1, &arg2, &arg3, &arg4, &arg5, &arg6) == FAILURE) { return; } @@ -1672,8 +1668,6 @@ PHP_FUNCTION(socket_recvfrom) recv_buf->len = retval; recv_buf->val[recv_buf->len] = '\0'; - ZVAL_DEREF(arg2); - ZVAL_DEREF(arg5); zval_dtor(arg2); zval_dtor(arg5); @@ -1701,9 +1695,6 @@ PHP_FUNCTION(socket_recvfrom) recv_buf->len = retval; recv_buf->val[recv_buf->len] = '\0'; - ZVAL_DEREF(arg2); - ZVAL_DEREF(arg5); - ZVAL_DEREF(arg6); zval_dtor(arg2); zval_dtor(arg5); zval_dtor(arg6); @@ -1735,9 +1726,6 @@ PHP_FUNCTION(socket_recvfrom) recv_buf->len = retval; recv_buf->val[recv_buf->len] = '\0'; - ZVAL_DEREF(arg2); - ZVAL_DEREF(arg5); - ZVAL_DEREF(arg6); zval_dtor(arg2); zval_dtor(arg5); zval_dtor(arg6); @@ -2097,14 +2085,13 @@ PHP_FUNCTION(socket_create_pair) PHP_SOCKET fds_array[2]; long domain, type, protocol; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lllz", &domain, &type, &protocol, &fds_array_zval) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lllz/", &domain, &type, &protocol, &fds_array_zval) == FAILURE) { return; } php_sock[0] = php_create_socket(); php_sock[1] = php_create_socket(); - ZVAL_DEREF(fds_array_zval); if (domain != AF_INET #if HAVE_IPV6 && domain != AF_INET6 diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index cc357bc6be..70f2d84128 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -560,8 +560,6 @@ SPL_METHOD(SplDoublyLinkedList, push) return; } - SEPARATE_ZVAL_IF_REF(value); - intern = Z_SPLDLLIST_P(getThis()); spl_ptr_llist_push(intern->llist, value TSRMLS_CC); @@ -580,8 +578,6 @@ SPL_METHOD(SplDoublyLinkedList, unshift) return; } - SEPARATE_ZVAL_IF_REF(value); - intern = Z_SPLDLLIST_P(getThis()); spl_ptr_llist_unshift(intern->llist, value TSRMLS_CC); @@ -806,7 +802,6 @@ SPL_METHOD(SplDoublyLinkedList, offsetSet) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &zindex, &value) == FAILURE) { return; } - SEPARATE_ZVAL_IF_REF(value); intern = Z_SPLDLLIST_P(getThis()); diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index f9f89dfd9c..62aaffbc3c 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -405,8 +405,8 @@ static inline void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_o if (!Z_ISUNDEF(intern->array->elements[index])) { zval_ptr_dtor(&(intern->array->elements[index])); } - SEPARATE_ARG_IF_REF(value); - ZVAL_COPY_VALUE(&intern->array->elements[index], value); + ZVAL_DEREF(value); + ZVAL_COPY(&intern->array->elements[index], value); } } /* }}} */ @@ -708,8 +708,8 @@ SPL_METHOD(SplFixedArray, fromArray) spl_fixedarray_init(array, tmp TSRMLS_CC); ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(data), num_index, str_index, element) { - SEPARATE_ARG_IF_REF(element); - ZVAL_COPY_VALUE(&array->elements[num_index], element); + ZVAL_DEREF(element); + ZVAL_COPY(&array->elements[num_index], element); } ZEND_HASH_FOREACH_END(); } else if (num > 0 && !save_indexes) { @@ -719,8 +719,8 @@ SPL_METHOD(SplFixedArray, fromArray) spl_fixedarray_init(array, num TSRMLS_CC); ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(data), element) { - SEPARATE_ARG_IF_REF(element); - ZVAL_COPY_VALUE(&array->elements[i], element); + ZVAL_DEREF(element); + ZVAL_COPY(&array->elements[i], element); i++; } ZEND_HASH_FOREACH_END(); } else { diff --git a/ext/spl/spl_heap.c b/ext/spl/spl_heap.c index 52b4371f57..90d78db6ee 100644 --- a/ext/spl/spl_heap.c +++ b/ext/spl/spl_heap.c @@ -616,7 +616,7 @@ SPL_METHOD(SplHeap, insert) return; } - SEPARATE_ARG_IF_REF(value); + if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value); spl_ptr_heap_insert(intern->heap, value, getThis() TSRMLS_CC); RETURN_TRUE; @@ -670,8 +670,8 @@ SPL_METHOD(SplPriorityQueue, insert) return; } - SEPARATE_ARG_IF_REF(data); - SEPARATE_ARG_IF_REF(priority); + if (Z_REFCOUNTED_P(data)) Z_ADDREF_P(data); + if (Z_REFCOUNTED_P(priority)) Z_ADDREF_P(priority); array_init(&elem); add_assoc_zval_ex(&elem, "data", sizeof("data") - 1, data); diff --git a/ext/standard/array.c b/ext/standard/array.c index b5caf090fe..30cea91434 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -219,7 +219,7 @@ PHP_FUNCTION(krsort) zval *array; long sort_type = PHP_SORT_REGULAR; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &array, &sort_type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/|l", &array, &sort_type) == FAILURE) { RETURN_FALSE; } @@ -239,7 +239,7 @@ PHP_FUNCTION(ksort) zval *array; long sort_type = PHP_SORT_REGULAR; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &array, &sort_type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/|l", &array, &sort_type) == FAILURE) { RETURN_FALSE; } @@ -265,16 +265,16 @@ PHPAPI int php_count_recursive(zval *array, long mode TSRMLS_DC) /* {{{ */ cnt = zend_hash_num_elements(Z_ARRVAL_P(array)); if (mode == COUNT_RECURSIVE) { + if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(array))) { + Z_ARRVAL_P(array)->u.v.nApplyCount++; + } ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(array), element) { - if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(array))) { - Z_ARRVAL_P(array)->u.v.nApplyCount++; - } ZVAL_DEREF(element); cnt += php_count_recursive(element, COUNT_RECURSIVE TSRMLS_CC); - if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(array))) { - Z_ARRVAL_P(array)->u.v.nApplyCount--; - } } ZEND_HASH_FOREACH_END(); + if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(array))) { + Z_ARRVAL_P(array)->u.v.nApplyCount--; + } } } @@ -288,6 +288,8 @@ PHP_FUNCTION(count) { zval *array; long mode = COUNT_NORMAL; + long cnt; + zval *element; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &array, &mode) == FAILURE) { return; @@ -298,7 +300,14 @@ PHP_FUNCTION(count) RETURN_LONG(0); break; case IS_ARRAY: - RETURN_LONG (php_count_recursive (array, mode TSRMLS_CC)); + cnt = zend_hash_num_elements(Z_ARRVAL_P(array)); + if (mode == COUNT_RECURSIVE) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(array), element) { + ZVAL_DEREF(element); + cnt += php_count_recursive(element, COUNT_RECURSIVE TSRMLS_CC); + } ZEND_HASH_FOREACH_END(); + } + RETURN_LONG(cnt); break; case IS_OBJECT: { #ifdef HAVE_SPL @@ -409,7 +418,7 @@ static void php_natsort(INTERNAL_FUNCTION_PARAMETERS, int fold_case) /* {{{ */ { zval *array; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/", &array) == FAILURE) { return; } @@ -450,7 +459,7 @@ PHP_FUNCTION(asort) zval *array; long sort_type = PHP_SORT_REGULAR; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &array, &sort_type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/|l", &array, &sort_type) == FAILURE) { RETURN_FALSE; } @@ -470,7 +479,7 @@ PHP_FUNCTION(arsort) zval *array; long sort_type = PHP_SORT_REGULAR; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &array, &sort_type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/|l", &array, &sort_type) == FAILURE) { RETURN_FALSE; } @@ -490,7 +499,7 @@ PHP_FUNCTION(sort) zval *array; long sort_type = PHP_SORT_REGULAR; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &array, &sort_type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/|l", &array, &sort_type) == FAILURE) { RETURN_FALSE; } @@ -510,7 +519,7 @@ PHP_FUNCTION(rsort) zval *array; long sort_type = PHP_SORT_REGULAR; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &array, &sort_type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/|l", &array, &sort_type) == FAILURE) { RETURN_FALSE; } @@ -593,7 +602,7 @@ PHP_FUNCTION(usort) PHP_ARRAY_CMP_FUNC_BACKUP(); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "af", &array, &BG(user_compare_fci), &BG(user_compare_fci_cache)) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/f", &array, &BG(user_compare_fci), &BG(user_compare_fci_cache)) == FAILURE) { PHP_ARRAY_CMP_FUNC_RESTORE(); return; } @@ -636,7 +645,7 @@ PHP_FUNCTION(uasort) PHP_ARRAY_CMP_FUNC_BACKUP(); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "af", &array, &BG(user_compare_fci), &BG(user_compare_fci_cache)) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/f", &array, &BG(user_compare_fci), &BG(user_compare_fci_cache)) == FAILURE) { PHP_ARRAY_CMP_FUNC_RESTORE(); return; } @@ -722,7 +731,7 @@ PHP_FUNCTION(uksort) PHP_ARRAY_CMP_FUNC_BACKUP(); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "af", &array, &BG(user_compare_fci), &BG(user_compare_fci_cache)) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/f", &array, &BG(user_compare_fci), &BG(user_compare_fci_cache)) == FAILURE) { PHP_ARRAY_CMP_FUNC_RESTORE(); return; } @@ -762,7 +771,7 @@ PHP_FUNCTION(end) HashTable *array; zval *entry; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H/", &array) == FAILURE) { return; } @@ -789,7 +798,7 @@ PHP_FUNCTION(prev) HashTable *array; zval *entry; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H/", &array) == FAILURE) { return; } @@ -816,7 +825,7 @@ PHP_FUNCTION(next) HashTable *array; zval *entry; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H/", &array) == FAILURE) { return; } @@ -843,7 +852,7 @@ PHP_FUNCTION(reset) HashTable *array; zval *entry; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H/", &array) == FAILURE) { return; } @@ -870,7 +879,7 @@ PHP_FUNCTION(current) HashTable *array; zval *entry; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H/", &array) == FAILURE) { return; } @@ -892,7 +901,7 @@ PHP_FUNCTION(key) { HashTable *array; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H/", &array) == FAILURE) { return; } @@ -1111,7 +1120,7 @@ PHP_FUNCTION(array_walk) orig_array_walk_fci = BG(array_walk_fci); orig_array_walk_fci_cache = BG(array_walk_fci_cache); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Hf|z/", &array, &BG(array_walk_fci), &BG(array_walk_fci_cache), &userdata) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H/f|z/", &array, &BG(array_walk_fci), &BG(array_walk_fci_cache), &userdata) == FAILURE) { BG(array_walk_fci) = orig_array_walk_fci; BG(array_walk_fci_cache) = orig_array_walk_fci_cache; return; @@ -1136,7 +1145,7 @@ PHP_FUNCTION(array_walk_recursive) orig_array_walk_fci = BG(array_walk_fci); orig_array_walk_fci_cache = BG(array_walk_fci_cache); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Hf|z/", &array, &BG(array_walk_fci), &BG(array_walk_fci_cache), &userdata) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H/f|z/", &array, &BG(array_walk_fci), &BG(array_walk_fci_cache), &userdata) == FAILURE) { BG(array_walk_fci) = orig_array_walk_fci; BG(array_walk_fci_cache) = orig_array_walk_fci_cache; return; @@ -1284,7 +1293,7 @@ PHP_FUNCTION(extract) int var_exists, count = 0; int extract_refs = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|lz/", &var_array, &extract_type, &prefix) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/|lz/", &var_array, &extract_type, &prefix) == FAILURE) { return; } @@ -1313,13 +1322,6 @@ PHP_FUNCTION(extract) zend_rebuild_symbol_table(TSRMLS_C); } - /* var_array is passed by ref for the needs of EXTR_REFS (needs to - * work on the original array to create refs to its members) - * simulate pass_by_value if EXTR_REFS is not used */ - if (!extract_refs) { - SEPARATE_ARG_IF_REF(var_array); - } - ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(var_array), num_key, var_name, entry) { zval final_name; @@ -1394,7 +1396,7 @@ PHP_FUNCTION(extract) if (extract_refs) { zval *orig_var; - SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); + ZVAL_MAKE_REF(entry); Z_ADDREF_P(entry); if ((orig_var = zend_hash_find(&EG(active_symbol_table)->ht, Z_STR(final_name))) != NULL) { @@ -1407,18 +1409,14 @@ PHP_FUNCTION(extract) zend_hash_update(&EG(active_symbol_table)->ht, Z_STR(final_name), entry); } } else { - ZVAL_DUP(&data, entry); - zend_set_local_var(Z_STR(final_name), &data, 1 TSRMLS_CC); + if (Z_REFCOUNTED_P(entry)) Z_ADDREF_P(entry); + zend_set_local_var(Z_STR(final_name), entry, 1 TSRMLS_CC); } count++; } zval_dtor(&final_name); } ZEND_HASH_FOREACH_END(); - if (!extract_refs) { - zval_ptr_dtor(var_array); - } - RETURN_LONG(count); } /* }}} */ @@ -1776,7 +1774,7 @@ PHP_FUNCTION(shuffle) { zval *array; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/", &array) == FAILURE) { RETURN_FALSE; } @@ -1902,7 +1900,7 @@ PHP_FUNCTION(array_push) argc; /* Number of function arguments */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a+", &stack, &args, &argc) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/+", &stack, &args, &argc) == FAILURE) { return; } @@ -1930,7 +1928,7 @@ static void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int off_the_end) zend_string *key = NULL; ulong index; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &stack) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/", &stack) == FAILURE) { return; } @@ -2043,7 +2041,7 @@ PHP_FUNCTION(array_unshift) HashTable old_hash; int argc; /* Number of function arguments */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a+", &stack, &args, &argc) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/+", &stack, &args, &argc) == FAILURE) { return; } @@ -2078,7 +2076,7 @@ PHP_FUNCTION(array_splice) repl_num = 0; /* Number of replacement elements */ int num_in; /* Number of elements in the input array */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "al|lz/", &array, &offset, &length, &repl_array) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/l|lz/", &array, &offset, &length, &repl_array) == FAILURE) { return; } @@ -2980,7 +2978,7 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa zval *args; int (*intersect_data_compare_func)(zval *, zval * TSRMLS_DC) = NULL; zend_bool ok; - zval *data; + zval *val, *data; int req_args; char *param_spec; @@ -3022,40 +3020,44 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa for (idx = 0; idx < Z_ARRVAL(args[0])->nNumUsed; idx++) { p = Z_ARRVAL(args[0])->arData + idx; - if (Z_TYPE(p->val) == IS_UNDEF) continue; + val = &p->val; + if (Z_TYPE_P(val) == IS_UNDEF) continue; + if (Z_ISREF_P(val) && Z_REFCOUNT_P(val) == 1) { + ZVAL_UNREF(val); + } if (p->key == NULL) { ok = 1; for (i = 1; i < argc; i++) { if ((data = zend_hash_index_find(Z_ARRVAL(args[i]), p->h)) == NULL || (intersect_data_compare_func && - intersect_data_compare_func(&p->val, data TSRMLS_CC) != 0) + intersect_data_compare_func(val, data TSRMLS_CC) != 0) ) { ok = 0; break; } } if (ok) { - if (Z_REFCOUNTED(p->val)) { - Z_ADDREF(p->val); + if (Z_REFCOUNTED_P(val)) { + Z_ADDREF_P(val); } - zend_hash_index_update(Z_ARRVAL_P(return_value), p->h, &p->val); + zend_hash_index_update(Z_ARRVAL_P(return_value), p->h, val); } } else { ok = 1; for (i = 1; i < argc; i++) { if ((data = zend_hash_find(Z_ARRVAL(args[i]), p->key)) == NULL || (intersect_data_compare_func && - intersect_data_compare_func(&p->val, data TSRMLS_CC) != 0) + intersect_data_compare_func(val, data TSRMLS_CC) != 0) ) { ok = 0; break; } } if (ok) { - if (Z_REFCOUNTED(p->val)) { - Z_ADDREF(p->val); + if (Z_REFCOUNTED_P(val)) { + Z_ADDREF_P(val); } - zend_hash_update(Z_ARRVAL_P(return_value), p->key, &p->val); + zend_hash_update(Z_ARRVAL_P(return_value), p->key, val); } } } @@ -3405,7 +3407,7 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty zval *args; int (*diff_data_compare_func)(zval *, zval * TSRMLS_DC) = NULL; zend_bool ok; - zval *data; + zval *val, *data; /* Get the argument count */ argc = ZEND_NUM_ARGS(); @@ -3442,40 +3444,44 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty for (idx = 0; idx < Z_ARRVAL(args[0])->nNumUsed; idx++) { p = Z_ARRVAL(args[0])->arData + idx; - if (Z_TYPE(p->val) == IS_UNDEF) continue; + val = &p->val; + if (Z_TYPE_P(val) == IS_UNDEF) continue; + if (Z_ISREF_P(val) && Z_REFCOUNT_P(val) == 1) { + ZVAL_UNREF(val); + } if (p->key == NULL) { ok = 1; for (i = 1; i < argc; i++) { if ((data = zend_hash_index_find(Z_ARRVAL(args[i]), p->h)) != NULL && (!diff_data_compare_func || - diff_data_compare_func(&p->val, data TSRMLS_CC) == 0) + diff_data_compare_func(val, data TSRMLS_CC) == 0) ) { ok = 0; break; } } if (ok) { - if (Z_REFCOUNTED(p->val)) { - Z_ADDREF(p->val); + if (Z_REFCOUNTED_P(val)) { + Z_ADDREF_P(val); } - zend_hash_index_update(Z_ARRVAL_P(return_value), p->h, &p->val); + zend_hash_index_update(Z_ARRVAL_P(return_value), p->h, val); } } else { ok = 1; for (i = 1; i < argc; i++) { if ((data = zend_hash_find(Z_ARRVAL(args[i]), p->key)) != NULL && (!diff_data_compare_func || - diff_data_compare_func(&p->val, data TSRMLS_CC) == 0) + diff_data_compare_func(val, data TSRMLS_CC) == 0) ) { ok = 0; break; } } if (ok) { - if (Z_REFCOUNTED(p->val)) { - Z_ADDREF(p->val); + if (Z_REFCOUNTED_P(val)) { + Z_ADDREF_P(val); } - zend_hash_update(Z_ARRVAL_P(return_value), p->key, &p->val); + zend_hash_update(Z_ARRVAL_P(return_value), p->key, val); } } } diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 70c029ecca..0242f8aaba 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -395,7 +395,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_array_merge, 0, 0, 2) ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg, 0) */ ZEND_ARG_VARIADIC_INFO(0, arrays) ZEND_END_ARG_INFO() - + ZEND_BEGIN_ARG_INFO_EX(arginfo_array_merge_recursive, 0, 0, 2) ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg, 0) */ ZEND_ARG_VARIADIC_INFO(0, arrays) diff --git a/ext/standard/dns.c b/ext/standard/dns.c index de0e24a2d7..fd0acd7e3c 100644 --- a/ext/standard/dns.c +++ b/ext/standard/dns.c @@ -943,16 +943,14 @@ PHP_FUNCTION(dns_get_mx) struct __res_state *handle = &state; #endif - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|z", &hostname, &hostname_len, &mx_list, &weight_list) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/|z/", &hostname, &hostname_len, &mx_list, &weight_list) == FAILURE) { return; } - mx_list = Z_REFVAL_P(mx_list); zval_dtor(mx_list); array_init(mx_list); if (weight_list) { - weight_list = Z_REFVAL_P(weight_list); zval_dtor(weight_list); array_init(weight_list); } diff --git a/ext/standard/exec.c b/ext/standard/exec.c index 3b07e00443..6720231089 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -192,7 +192,6 @@ static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ if (!ret_array) { ret = php_exec(mode, cmd, NULL, return_value TSRMLS_CC); } else { - ret_array = Z_REFVAL_P(ret_array); if (Z_TYPE_P(ret_array) != IS_ARRAY) { zval_dtor(ret_array); array_init(ret_array); @@ -200,7 +199,6 @@ static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ ret = php_exec(2, cmd, ret_array, return_value TSRMLS_CC); } if (ret_code) { - ret_code = Z_REFVAL_P(ret_code); zval_dtor(ret_code); ZVAL_LONG(ret_code, ret); } diff --git a/ext/standard/file.c b/ext/standard/file.c index f8c3e98108..897eaa7be8 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -344,7 +344,7 @@ PHP_FUNCTION(flock) php_stream *stream; long operation = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &arg1, &operation, &arg3) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z/", &arg1, &operation, &arg3) == FAILURE) { return; } @@ -356,16 +356,16 @@ PHP_FUNCTION(flock) RETURN_FALSE; } - if (arg3 && Z_ISREF_P(arg3)) { - convert_to_long_ex(Z_REFVAL_P(arg3)); - Z_LVAL_P(Z_REFVAL_P(arg3)) = 0; + if (arg3) { + zval_dtor(arg3); + ZVAL_LONG(arg3, 0); } /* flock_values contains all possible actions if (operation & 4) we won't block on the lock */ act = flock_values[act - 1] | (operation & PHP_LOCK_NB ? LOCK_NB : 0); if (php_stream_lock(stream, act)) { - if (operation && errno == EWOULDBLOCK && arg3 && Z_ISREF_P(arg3)) { - Z_LVAL_P(Z_REFVAL_P(arg3)) = 1; + if (operation && errno == EWOULDBLOCK && arg3) { + ZVAL_LONG(arg3, 1); } RETURN_FALSE; } diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c index aa83b30c45..edd704b068 100644 --- a/ext/standard/formatted_print.c +++ b/ext/standard/formatted_print.c @@ -398,8 +398,10 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC) z_format = &args[format_offset]; array = &args[1 + format_offset]; - SEPARATE_ZVAL(array); - convert_to_array_ex(array); + if (Z_TYPE_P(array) != IS_ARRAY) { + SEPARATE_ZVAL(array); + convert_to_array(array); + } argc = 1 + zend_hash_num_elements(Z_ARRVAL_P(array)); newargs = (zval *)safe_emalloc(argc, sizeof(zval), 0); @@ -421,7 +423,7 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC) while (inpos < Z_STRLEN(args[format_offset])) { int expprec = 0; - zval tmp; + zval *tmp; PRINTF_DEBUG(("sprintf: format[%d]='%c'\n", inpos, format[inpos])); PRINTF_DEBUG(("sprintf: outpos=%d\n", outpos)); @@ -551,17 +553,10 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC) } PRINTF_DEBUG(("sprintf: format character='%c'\n", format[inpos])); /* now we expect to find a type specifier */ - //???? We don't hold zval** in args anymore - //if (multiuse) { - ZVAL_DUP(&tmp, &args[argnum]); - //} else { - // SEPARATE_ZVAL(&args[argnum]); - // ZVAL_COPY_VALUE(&tmp, &args[argnum]); - //} - + tmp = &args[argnum]; switch (format[inpos]) { case 's': { - zend_string *str = zval_get_string(&tmp); + zend_string *str = zval_get_string(tmp); php_sprintf_appendstring(&result, &outpos, str->val, width, precision, padding, @@ -573,17 +568,15 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC) } case 'd': - convert_to_long(&tmp); php_sprintf_appendint(&result, &outpos, - Z_LVAL(tmp), + zval_get_long(tmp), width, padding, alignment, always_sign); break; case 'u': - convert_to_long(&tmp); php_sprintf_appenduint(&result, &outpos, - Z_LVAL(tmp), + zval_get_long(tmp), width, padding, alignment); break; @@ -593,9 +586,8 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC) case 'E': case 'f': case 'F': - convert_to_double(&tmp); php_sprintf_appenddouble(&result, &outpos, - Z_DVAL(tmp), + zval_get_double(tmp), width, padding, alignment, precision, adjusting, format[inpos], always_sign @@ -603,39 +595,34 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC) break; case 'c': - convert_to_long(&tmp); php_sprintf_appendchar(&result, &outpos, - (char) Z_LVAL(tmp) TSRMLS_CC); + (char) zval_get_long(tmp) TSRMLS_CC); break; case 'o': - convert_to_long(&tmp); php_sprintf_append2n(&result, &outpos, - Z_LVAL(tmp), + zval_get_long(tmp), width, padding, alignment, 3, hexchars, expprec); break; case 'x': - convert_to_long(&tmp); php_sprintf_append2n(&result, &outpos, - Z_LVAL(tmp), + zval_get_long(tmp), width, padding, alignment, 4, hexchars, expprec); break; case 'X': - convert_to_long(&tmp); php_sprintf_append2n(&result, &outpos, - Z_LVAL(tmp), + zval_get_long(tmp), width, padding, alignment, 4, HEXCHARS, expprec); break; case 'b': - convert_to_long(&tmp); php_sprintf_append2n(&result, &outpos, - Z_LVAL(tmp), + zval_get_long(tmp), width, padding, alignment, 1, hexchars, expprec); break; @@ -647,7 +634,6 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC) default: break; } - zval_ptr_dtor(&tmp); inpos++; } } diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c index 5eacc2fe46..e11bb84056 100644 --- a/ext/standard/fsock.c +++ b/ext/standard/fsock.c @@ -47,7 +47,7 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent) RETVAL_FALSE; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lzzd", &host, &host_len, &port, &zerrno, &zerrstr, &timeout) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/z/d", &host, &host_len, &port, &zerrno, &zerrstr, &timeout) == FAILURE) { RETURN_FALSE; } @@ -68,12 +68,10 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent) tv.tv_usec = conv % 1000000; if (zerrno) { - zerrno = Z_REFVAL_P(zerrno); zval_dtor(zerrno); ZVAL_LONG(zerrno, 0); } if (zerrstr) { - zerrstr = Z_REFVAL_P(zerrstr); zval_dtor(zerrstr); ZVAL_EMPTY_STRING(zerrstr); } diff --git a/ext/standard/head.c b/ext/standard/head.c index 30846215f8..7c4b963285 100644 --- a/ext/standard/head.c +++ b/ext/standard/head.c @@ -228,7 +228,7 @@ PHP_FUNCTION(headers_sent) const char *file=""; int line=0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zz", &arg1, &arg2) == FAILURE) + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z/z/", &arg1, &arg2) == FAILURE) return; if (SG(headers_sent)) { diff --git a/ext/standard/image.c b/ext/standard/image.c index 4dcfe83e38..0ec4cd3885 100644 --- a/ext/standard/image.c +++ b/ext/standard/image.c @@ -1396,12 +1396,11 @@ static void php_getimagesize_from_any(INTERNAL_FUNCTION_PARAMETERS, int mode) { int input_len; const int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "s|z", &input, &input_len, &info) == FAILURE) { + if (zend_parse_parameters(argc TSRMLS_CC, "s|z/", &input, &input_len, &info) == FAILURE) { return; } if (argc == 2) { - info = Z_REFVAL_P(info); zval_dtor(info); array_init(info); } diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index 3fa4ad19a3..dea8c16c07 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -459,7 +459,7 @@ PHP_FUNCTION(proc_open) php_file_descriptor_t slave_pty = -1; #endif - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "saz|s!a!a!", &command, + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "saz/|s!a!a!", &command, &command_len, &descriptorspec, &pipes, &cwd, &cwd_len, &environment, &other_options) == FAILURE) { RETURN_FALSE; @@ -877,7 +877,6 @@ PHP_FUNCTION(proc_open) proc->env = env; if (pipes != NULL) { - ZVAL_DEREF(pipes); zval_dtor(pipes); } diff --git a/ext/standard/scanf.c b/ext/standard/scanf.c index 3eb58e1837..ef3fe2969c 100644 --- a/ext/standard/scanf.c +++ b/ext/standard/scanf.c @@ -742,11 +742,9 @@ literal: if (numVars && objIndex >= argCount) { break; } else if (numVars) { - current = &args[objIndex++]; - zval_dtor(Z_REFVAL_P(current)); - ZVAL_LONG(Z_REFVAL_P(current), (long)(string - baseString) ); -// Z_SET_REFCOUNT_P(current, refcount); -//??? Z_SET_ISREF_P(current); + current = Z_REFVAL(args[objIndex++]); + zval_ptr_dtor(current); + ZVAL_LONG(current, (long)(string - baseString) ); } else { add_index_long(return_value, objIndex++, string - baseString); } @@ -863,11 +861,9 @@ literal: if (numVars && objIndex >= argCount) { break; } else if (numVars) { - current = &args[objIndex++]; - zval_dtor(Z_REFVAL_P(current)); - ZVAL_STRINGL(Z_REFVAL_P(current), string, end-string); -//??? Z_SET_REFCOUNT_P(current, refcount); -//??? Z_SET_ISREF_PP(current); + current = Z_REFVAL(args[objIndex++]); + zval_ptr_dtor(current); + ZVAL_STRINGL(current, string, end-string); } else { add_index_stringl(return_value, objIndex++, string, end-string); } @@ -906,9 +902,9 @@ literal: if (numVars && objIndex >= argCount) { break; } else if (numVars) { - current = &args[objIndex++]; - zval_dtor(Z_REFVAL_P(current)); - ZVAL_STRINGL(Z_REFVAL_P(current), string, end-string); + current = Z_REFVAL(args[objIndex++]); + zval_ptr_dtor(current); + ZVAL_STRINGL(current, string, end-string); } else { add_index_stringl(return_value, objIndex++, string, end-string); } @@ -1060,9 +1056,9 @@ addToInt: break; } else if (numVars) { /* change passed value type to string */ - current = &args[objIndex++]; - zval_dtor(Z_REFVAL_P(current)); - ZVAL_STRING(Z_REFVAL_P(current), buf); + current = Z_REFVAL(args[objIndex++]); + zval_ptr_dtor(current); + ZVAL_STRING(current, buf); } else { add_index_string(return_value, objIndex++, buf); } @@ -1070,9 +1066,9 @@ addToInt: if (numVars && objIndex >= argCount) { break; } else if (numVars) { - current = &args[objIndex++]; - zval_dtor(Z_REFVAL_P(current)); - ZVAL_LONG(Z_REFVAL_P(current), value); + current = Z_REFVAL(args[objIndex++]); + zval_ptr_dtor(current); + ZVAL_LONG(current, value); } else { add_index_long(return_value, objIndex++, value); } @@ -1175,9 +1171,9 @@ addToFloat: if (numVars && objIndex >= argCount) { break; } else if (numVars) { - current = &args[objIndex++]; - zval_dtor(Z_REFVAL_P(current)); - ZVAL_DOUBLE(Z_REFVAL_P(current), dvalue); + current = Z_REFVAL(args[objIndex++]); + zval_ptr_dtor(current); + ZVAL_DOUBLE(current, dvalue); } else { add_index_double(return_value, objIndex++, dvalue ); } diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 1d59a97a94..bd0c0de31b 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -102,7 +102,7 @@ PHP_FUNCTION(stream_socket_client) RETVAL_FALSE; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zzdlr", &host, &host_len, &zerrno, &zerrstr, &timeout, &flags, &zcontext) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z/z/dlr", &host, &host_len, &zerrno, &zerrstr, &timeout, &flags, &zcontext) == FAILURE) { RETURN_FALSE; } @@ -122,12 +122,10 @@ PHP_FUNCTION(stream_socket_client) tv.tv_usec = conv % 1000000; #endif if (zerrno) { - zerrno = Z_REFVAL_P(zerrno); zval_dtor(zerrno); ZVAL_LONG(zerrno, 0); } if (zerrstr) { - zerrstr = Z_REFVAL_P(zerrstr); zval_dtor(zerrstr); ZVAL_EMPTY_STRING(zerrstr); } @@ -191,7 +189,7 @@ PHP_FUNCTION(stream_socket_server) RETVAL_FALSE; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zzlr", &host, &host_len, &zerrno, &zerrstr, &flags, &zcontext) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z/z/lr", &host, &host_len, &zerrno, &zerrstr, &flags, &zcontext) == FAILURE) { RETURN_FALSE; } @@ -258,7 +256,7 @@ PHP_FUNCTION(stream_socket_accept) char *errstr = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|dz", &zstream, &timeout, &zpeername) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|dz/", &zstream, &timeout, &zpeername) == FAILURE) { RETURN_FALSE; } @@ -374,7 +372,7 @@ PHP_FUNCTION(stream_socket_recvfrom) long flags = 0; int recvd; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|lz", &zstream, &to_read, &flags, &zremote) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|lz/", &zstream, &to_read, &flags, &zremote) == FAILURE) { RETURN_FALSE; } @@ -743,7 +741,7 @@ PHP_FUNCTION(stream_select) long usec = 0; int set_count, max_set_count = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!a!z!|l", &r_array, &w_array, &e_array, &sec, &usec) == FAILURE) + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/!a/!a/!z!|l", &r_array, &w_array, &e_array, &sec, &usec) == FAILURE) return; FD_ZERO(&rfds); diff --git a/ext/standard/string.c b/ext/standard/string.c index a600fc800e..3250241bc6 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -2264,25 +2264,21 @@ PHP_FUNCTION(substr_replace) HashPosition pos_from, pos_repl, pos_len; zval *tmp_str = NULL, *tmp_from = NULL, *tmp_repl = NULL, *tmp_len= NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz|z", &str, &repl, &from, &len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz|z/", &str, &repl, &from, &len) == FAILURE) { return; } if (Z_TYPE_P(str) != IS_ARRAY) { - SEPARATE_ZVAL_IF_REF(str); convert_to_string_ex(str); } if (Z_TYPE_P(repl) != IS_ARRAY) { - SEPARATE_ZVAL_IF_REF(repl); convert_to_string_ex(repl); } if (Z_TYPE_P(from) != IS_ARRAY) { - SEPARATE_ZVAL_IF_REF(from); convert_to_long_ex(from); } if (argc > 3) { - SEPARATE_ZVAL(len); if (Z_TYPE_P(len) != IS_ARRAY) { l = zval_get_long(len); } @@ -3014,12 +3010,11 @@ PHP_FUNCTION(similar_text) int sim; int t1_len, t2_len; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|z", &t1, &t1_len, &t2, &t2_len, &percent) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|z/", &t1, &t1_len, &t2, &t2_len, &percent) == FAILURE) { return; } if (ac > 2) { - percent = Z_REFVAL_P(percent); convert_to_double_ex(percent); } @@ -3727,7 +3722,7 @@ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensit int count = 0; int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz|z", &search, &replace, &subject, &zcount) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz|z/", &search, &replace, &subject, &zcount) == FAILURE) { return; } @@ -3767,8 +3762,8 @@ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensit php_str_replace_in_subject(search, replace, subject, return_value, case_sensitivity, (argc > 3) ? &count : NULL TSRMLS_CC); } if (argc > 3) { - zval_dtor(Z_REFVAL_P(zcount)); - ZVAL_LONG(Z_REFVAL_P(zcount), count); + zval_dtor(zcount); + ZVAL_LONG(zcount, count); } } /* }}} */ @@ -4218,7 +4213,7 @@ PHP_FUNCTION(parse_str) char *res = NULL; int arglen; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &arg, &arglen, &arrayArg) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z/", &arg, &arglen, &arrayArg) == FAILURE) { return; } @@ -4235,11 +4230,10 @@ PHP_FUNCTION(parse_str) } else { zval ret; - array_init(&ret); - sapi_module.treat_data(PARSE_STRING, res, &ret TSRMLS_CC); /* Clear out the array that was passed in. */ - ZVAL_DEREF(arrayArg); zval_dtor(arrayArg); + array_init(&ret); + sapi_module.treat_data(PARSE_STRING, res, &ret TSRMLS_CC); ZVAL_COPY_VALUE(arrayArg, &ret); } } diff --git a/ext/standard/type.c b/ext/standard/type.c index 5c7da45ae9..a42dd0bd0b 100644 --- a/ext/standard/type.c +++ b/ext/standard/type.c @@ -100,6 +100,7 @@ PHP_FUNCTION(settype) } ZVAL_DEREF(var); + SEPARATE_ZVAL_NOREF(var); if (!strcasecmp(type, "integer")) { convert_to_long(var); } else if (!strcasecmp(type, "int")) { @@ -378,7 +379,7 @@ PHP_FUNCTION(is_callable) zend_bool syntax_only = 0; int check_flags = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|bz", &var, + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|bz/", &var, &syntax_only, &callable_name) == FAILURE) { return; } @@ -387,7 +388,6 @@ PHP_FUNCTION(is_callable) check_flags |= IS_CALLABLE_CHECK_SYNTAX_ONLY; } if (ZEND_NUM_ARGS() > 2) { - ZVAL_DEREF(callable_name); retval = zend_is_callable_ex(var, NULL, check_flags, &name, NULL, &error TSRMLS_CC); zval_dtor(callable_name); //??? is it necessary to be consistent with old PHP ("\0" support) diff --git a/ext/standard/var.c b/ext/standard/var.c index 6abb70c047..1a6a16508c 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -132,7 +132,7 @@ again: break; case IS_ARRAY: myht = Z_ARRVAL_P(struc); - if (ZEND_HASH_APPLY_PROTECTION(myht) && ++myht->u.v.nApplyCount > 1) { + if (level > 1 && ZEND_HASH_APPLY_PROTECTION(myht) && ++myht->u.v.nApplyCount > 1) { PUTS("*RECURSION*\n"); --myht->u.v.nApplyCount; return; @@ -143,7 +143,7 @@ again: ZEND_HASH_FOREACH_KEY_VAL_IND(myht, num, key, val) { php_array_element_dump(val, num, key, level TSRMLS_CC); } ZEND_HASH_FOREACH_END(); - if (ZEND_HASH_APPLY_PROTECTION(myht)) { + if (level > 1 && ZEND_HASH_APPLY_PROTECTION(myht)) { --myht->u.v.nApplyCount; } if (is_temp) { @@ -303,7 +303,7 @@ again: break; case IS_ARRAY: myht = Z_ARRVAL_P(struc); - if (ZEND_HASH_APPLY_PROTECTION(myht) && myht->u.v.nApplyCount++ > 1) { + if (level > 1 && ZEND_HASH_APPLY_PROTECTION(myht) && myht->u.v.nApplyCount++ > 1) { myht->u.v.nApplyCount--; PUTS("*RECURSION*\n"); return; @@ -312,7 +312,7 @@ again: ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, val) { zval_array_element_dump(val, index, key, level TSRMLS_CC); } ZEND_HASH_FOREACH_END(); - if (ZEND_HASH_APPLY_PROTECTION(myht)) { + if (level > 1 && ZEND_HASH_APPLY_PROTECTION(myht)) { myht->u.v.nApplyCount--; } if (is_temp) { @@ -1018,7 +1018,7 @@ PHP_FUNCTION(unserialize) php_unserialize_data_t var_hash; zval *consumed = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &buf, &buf_len, &consumed) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z/", &buf, &buf_len, &consumed) == FAILURE) { RETURN_FALSE; } @@ -1038,9 +1038,9 @@ PHP_FUNCTION(unserialize) } PHP_VAR_UNSERIALIZE_DESTROY(var_hash); - if (consumed && Z_ISREF_P(consumed)) { - zval_dtor(Z_REFVAL_P(consumed)); - ZVAL_LONG(Z_REFVAL_P(consumed), ((char*)p) - buf); + if (consumed) { + zval_dtor(consumed); + ZVAL_LONG(consumed, ((char*)p) - buf); } } /* }}} */ diff --git a/ext/sysvmsg/sysvmsg.c b/ext/sysvmsg/sysvmsg.c index 83875ac9ee..b1cbedbbc1 100644 --- a/ext/sysvmsg/sysvmsg.c +++ b/ext/sysvmsg/sysvmsg.c @@ -308,7 +308,7 @@ PHP_FUNCTION(msg_receive) RETVAL_FALSE; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlzlz|blz", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz/lz/|blz/", &queue, &desiredmsgtype, &out_msgtype, &maxsize, &out_message, &do_unserialize, &flags, &zerrcode) == FAILURE) { return; @@ -342,8 +342,6 @@ PHP_FUNCTION(msg_receive) result = msgrcv(mq->id, messagebuffer, maxsize, desiredmsgtype, realflags); - ZVAL_DEREF(out_msgtype); - ZVAL_DEREF(out_message); zval_dtor(out_msgtype); zval_dtor(out_message); ZVAL_LONG(out_msgtype, 0); @@ -397,7 +395,7 @@ PHP_FUNCTION(msg_send) RETVAL_FALSE; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz|bbz", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz|bbz/", &queue, &msgtype, &message, &do_serialize, &blocking, &zerror) == FAILURE) { return; } @@ -461,7 +459,6 @@ PHP_FUNCTION(msg_send) if (result == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "msgsnd failed: %s", strerror(errno)); if (zerror) { - ZVAL_DEREF(zerror); ZVAL_LONG(zerror, errno); } } else { diff --git a/ext/xml/xml.c b/ext/xml/xml.c index 0e9f19a199..bbceb6dcf2 100644 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@ -1164,7 +1164,7 @@ PHP_FUNCTION(xml_set_object) xml_parser *parser; zval *pind, *mythis; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ro", &pind, &mythis) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ro/", &pind, &mythis) == FAILURE) { return; } @@ -1389,19 +1389,17 @@ PHP_FUNCTION(xml_parse_into_struct) char *data; int data_len, ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz|z", &pind, &data, &data_len, &xdata, &info) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz/|z/", &pind, &data, &data_len, &xdata, &info) == FAILURE) { return; } if (info) { - ZVAL_DEREF(info); zval_ptr_dtor(info); array_init(info); } ZEND_FETCH_RESOURCE(parser, xml_parser *, pind, -1, "XML Parser", le_xml_parser); - ZVAL_DEREF(xdata); zval_ptr_dtor(xdata); array_init(xdata); diff --git a/ext/xmlrpc/xmlrpc-epi-php.c b/ext/xmlrpc/xmlrpc-epi-php.c index 9378529013..e4be0f032c 100644 --- a/ext/xmlrpc/xmlrpc-epi-php.c +++ b/ext/xmlrpc/xmlrpc-epi-php.c @@ -775,12 +775,10 @@ PHP_FUNCTION(xmlrpc_decode_request) zval *method; int xml_len, encoding_len = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|s", &xml, &xml_len, &method, &encoding, &encoding_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/|s", &xml, &xml_len, &method, &encoding, &encoding_len) == FAILURE) { return; } - ZVAL_DEREF(method); - if (USED_RET()) { decode_request_worker(xml, xml_len, encoding_len ? encoding : NULL, method, return_value); } @@ -1377,12 +1375,10 @@ PHP_FUNCTION(xmlrpc_set_type) int type_len; XMLRPC_VALUE_TYPE vtype; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &arg, &type, &type_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/s", &arg, &type, &type_len) == FAILURE) { return; } - ZVAL_DEREF(arg); - vtype = xmlrpc_str_as_type(type); if (vtype != xmlrpc_none) { if (set_zval_xmlrpc_type(arg, vtype) == SUCCESS) { diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 053cc68058..e73d9c095c 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -2111,7 +2111,7 @@ static ZIPARCHIVE_METHOD(getExternalAttributesName) ZIP_FROM_OBJECT(intern, self); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz|l", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/z/|l", &name, &name_len, &z_opsys, &z_attr, &flags) == FAILURE) { return; } @@ -2128,10 +2128,8 @@ static ZIPARCHIVE_METHOD(getExternalAttributesName) (zip_flags_t)flags, &opsys, &attr) < 0) { RETURN_FALSE; } - ZVAL_DEREF(z_opsys); zval_ptr_dtor(z_opsys); ZVAL_LONG(z_opsys, opsys); - ZVAL_DEREF(z_attr); zval_ptr_dtor(z_attr); ZVAL_LONG(z_attr, attr); RETURN_TRUE; @@ -2155,7 +2153,7 @@ static ZIPARCHIVE_METHOD(getExternalAttributesIndex) ZIP_FROM_OBJECT(intern, self); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lzz|l", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz/z/|l", &index, &z_opsys, &z_attr, &flags) == FAILURE) { return; } @@ -2165,10 +2163,8 @@ static ZIPARCHIVE_METHOD(getExternalAttributesIndex) (zip_flags_t)flags, &opsys, &attr) < 0) { RETURN_FALSE; } - ZVAL_DEREF(z_opsys); zval_dtor(z_opsys); ZVAL_LONG(z_opsys, opsys); - ZVAL_DEREF(z_attr); zval_dtor(z_attr); ZVAL_LONG(z_attr, attr); RETURN_TRUE; |