]> granicus.if.org Git - php/commitdiff
Use reference counting instead of zval duplication
authorDmitry Stogov <dmitry@zend.com>
Thu, 5 Jun 2014 12:04:11 +0000 (16:04 +0400)
committerDmitry Stogov <dmitry@zend.com>
Thu, 5 Jun 2014 12:04:11 +0000 (16:04 +0400)
47 files changed:
Zend/zend.h
Zend/zend_API.c
Zend/zend_builtin_functions.c
Zend/zend_compile.c
Zend/zend_execute.c
Zend/zend_generators.c
Zend/zend_hash.c
Zend/zend_object_handlers.c
Zend/zend_variables.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/curl/multi.c
ext/ereg/ereg.c
ext/ftp/php_ftp.c
ext/json/json.c
ext/ldap/ldap.c
ext/mbstring/mbstring.c
ext/mbstring/php_mbregex.c
ext/openssl/openssl.c
ext/pcntl/pcntl.c
ext/pcre/php_pcre.c
ext/soap/php_encoding.c
ext/soap/soap.c
ext/sockets/sendrecvmsg.c
ext/sockets/sockets.c
ext/spl/spl_dllist.c
ext/spl/spl_fixedarray.c
ext/spl/spl_heap.c
ext/standard/array.c
ext/standard/basic_functions.c
ext/standard/dns.c
ext/standard/exec.c
ext/standard/file.c
ext/standard/formatted_print.c
ext/standard/fsock.c
ext/standard/head.c
ext/standard/image.c
ext/standard/proc_open.c
ext/standard/scanf.c
ext/standard/streamsfuncs.c
ext/standard/string.c
ext/standard/type.c
ext/standard/var.c
ext/sysvmsg/sysvmsg.c
ext/xml/xml.c
ext/xmlrpc/xmlrpc-epi-php.c
ext/zip/php_zip.c

index d9c8db19b698ad96ec7d3c58ed91fd576bb45fcd..c346c023c1cad0c367c629498d6100b113492556 100644 (file)
@@ -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)
 
index 45e2331518a65506e1a7c0f0911516e169e05b0b..33f1fc67ccd3a56c6cd2c0a9d8b8e5d56cb728a4 100644 (file)
@@ -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);
index d58099418f69d44f89bbea0f846a3f6b8a2db320..f8f6a435f53c39d7f9e2b24732dc718e354979d2 100644 (file)
@@ -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");
index fda1c7606e9027c78e108b44b44b76916925149c..c84937b645f613ec2f9db840736b368119fe78f1 100644 (file)
@@ -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);
index 80d4fbb5db04dcd09a98c66870f6f3280ea7e8b6..471a02976a9e21309f0884f99647fb72fb493f6a 100644 (file)
@@ -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);
                        }
index e275d92c9163ac3bfd220287f717e8ac5ca54175..c80e909565de4f2ffa7b258426e63c9a99b6a0e5 100644 (file)
@@ -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;
index 08b4cb5e4e436b3195a3d65a5b6484bb40ee2c8b..e7aa255d7812806e3f4b2d6f9307eb26a30ab851 100644 (file)
@@ -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;
                                }
index 0e30ca304edc558de69878722a83f6d931e160d3..4d2d7994418f21496ba30e837f397bf515a5b7e6 100644 (file)
@@ -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);
 
index 79bd00db139d4d7476992b97ed7df25ce6f0d4a5..2031b017eb487d09f1dfdc19b0858264d071a680 100644 (file)
@@ -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));
index 4f87f5b37525db34b9cf25fe7d22b1b0de08c908..554ac2ca80079307b9d6cddea6387523d4ae0a03 100644 (file)
@@ -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);
 
index 4a66c7390d2150fd95207a4edcaef5564db2a5da..c391cffdb9929cc2f39e886473e34b7532b150a3 100644 (file)
@@ -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);
 
index 1a69a3a37c2539f0a6ccaf24a97aada180639ee1..5550972bba40288df23b722d61ccec8689e81b07 100644 (file)
@@ -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;
        }
 
index 668f9551050b7696ed21de7b9d9451a91d486895..79bee9b79ff04e36067579afc3d848fd85afe0e9 100644 (file)
@@ -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", &regex, &findin, &findin_len, &array) == FAILURE) {
+       if (zend_parse_parameters(argc TSRMLS_CC, "zs|z/", &regex, &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;
index 46e336deb0f0145514067248ac1f8ab38620c8b8..1bf485f4ed282f0bee4f1802947e3c82571ab271 100644 (file)
@@ -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);
        }
index e7e07ce2c1478c488e1e29664bef0311eabdab8e..0bf8a645e6b1642fc775eff5f0f3a3d0b5e8ef83 100644 (file)
@@ -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;
index c5cb15f7c336aed9b52a048c1396c832487e61cf..8f52f1f3fbe9f9333b9c9bbb3ac2e003b10f12f6 100644 (file)
@@ -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);
index 54bd34fa7a975c9baa2651922be624676b6b4bbe..ebea66323caa057fc58ec43f5229b8379a631959 100644 (file)
@@ -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) {
index 24c1ff901977c1e2eef3dec04ee8abc705098791..ab03306f140acb83d3e3658b93c19e1a8826d15d 100644 (file)
@@ -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);
 
index 94056ce04b551cd5ba6c6cd9e31c125efbe4b583..16c609ffb9ec3fa5c7ccb48f26f7afc8e98b8b3c 100755 (executable)
@@ -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, &notext) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz/|b", &zcert, &zout, &notext) == 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, &notext) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz/|b", &zcsr, &zout, &notext) == 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;
index 5de4ae1cd4594b996eb9c966184613a610d6dba8..448e34b5cca2df61bb846e152c83f6612a3adcaf 100644 (file)
@@ -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);
index 193234c131406d3b26f774a55f3282a6f0fbae7f..0ce3600005f0fabde039ea47fd04e9c3106d2a90 100644 (file)
@@ -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", &regex,
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ss|z/ll", &regex,
                                                          &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", &regex, &replace, &subject, &limit, &zcount) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz|lz/", &regex, &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);
        }
index c35cae2d335252558f8fed695321b64431105ab6..0ec71d762556ed0dc3dd1da44231c32dd0cd550e 100644 (file)
@@ -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;
                        }
index 55da782e39eead0ca907c2bdfa95e514a135ea83..715073805144d2169652109a13add2b79e26d4d0 100644 (file)
@@ -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;
        }
index 901972da36e6f9b0273bf42ade4e2e1d22ce117c..4ddae3f6ffd5ba38935b4120263454255d6d1fb8 100644 (file)
@@ -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;
        }
index b858a4733ed5ef85cf13e56a095116688cb3c695..dd7f27260f57b9933f7c15dbdd16a63c8f81c851 100644 (file)
@@ -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
index cc357bc6be44defec386b48b99faa05f6012b080..70f2d841284e4cc0006ac9ffa207ffe0fa4bd800 100644 (file)
@@ -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());
 
index f9f89dfd9ce0e9e9abdc51b81335ddec80aa25bf..62aaffbc3cbd638e92c272935ad37106466c0256 100644 (file)
@@ -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 {
index 52b4371f5750c858e62c25822087ce0c0e4e48e7..90d78db6ee1da309e723ddbee30c230f3579b63c 100644 (file)
@@ -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);
index b5caf090febdc7f51e3460b12a9c29f4ed636bbb..30cea91434bab02e0ab0694b46445234e4be01ce 100644 (file)
@@ -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);
                        }
                }
        }
index 70c029ecca15881cb5c921fd1d876c9a576f37f7..0242f8aaba10fd722070156ce6cae651ab120501 100644 (file)
@@ -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)
index de0e24a2d7841b6da0a357aa0df677e23997ada1..fd0acd7e3c7e54a8982e2c521e0f16bce625527a 100644 (file)
@@ -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);
        }
index 3b07e0044335d965c3251be9ab9c37dd5454af85..67202310890fcf533f58aa1342135d0e75b8498d 100644 (file)
@@ -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);
        }
index f8c3e98108c9d106d72414045552dd6938d68268..897eaa7be835d1fb43617b445fea24a255adb591 100644 (file)
@@ -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;
        }
index aa83b30c454e72cba161a8bc7c01e048183ee7be..edd704b068a6b1076d8e0c73b78a1a2c5bd455f9 100644 (file)
@@ -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++;
                }
        }
index 5eacc2fe46ed203dc1f1843b85f216fe921c2f99..e11bb84056823721782826f7065221b367f28900 100644 (file)
@@ -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);
        }
index 30846215f8fab155ffd15ace22c53d99cbb6e636..7c4b963285941e154f89adbfc4dc242db5ad62db 100644 (file)
@@ -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)) {
index 4dcfe83e389bb7aa3d13cff1c5a04be33584451c..0ec4cd38859c686d42a679a0f416937ebab0a26a 100644 (file)
@@ -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);
        }
index 3fa4ad19a3283c2cbb6422c4f12621da101f8b92..dea8c16c07e589ad2cfebba26f92a33466fd712a 100644 (file)
@@ -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);
        } 
 
index 3eb58e183722855a1419508f4a492d578488c52b..ef3fe2969cc7d17319009c585dafcb91ca0b37ef 100644 (file)
@@ -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 );
                                        }
index 1d59a97a94d90f128873609311ee88a3874e0b16..bd0c0de31b86ab2bfba959255176f8ff8205b411 100644 (file)
@@ -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);
index a600fc800ea6ce61de0698d95cd29e54acb41d5e..3250241bc6d7d783dce15b4be739c85a55c80a21 100644 (file)
@@ -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);
        }
 }
index 5c7da45ae9821cef37bedfa597f02aa42ed23ef9..a42dd0bd0bb68ab7669e4121efe8c2c9589fc469 100644 (file)
@@ -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)
index 6abb70c0471eba4d4c7c9fedf6c08df7afda2dd8..1a6a16508cc23b4fa296162186a292f4cc6a6bc1 100644 (file)
@@ -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);
        }
 }
 /* }}} */
index 83875ac9eeee9691fda0aebf27680a87f0286ae9..b1cbedbbc11b09318c68008ebc2e9a451780672a 100644 (file)
@@ -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 {
index 0e9f19a1996fab345fd7fad07ad3c1c36a301c01..bbceb6dcf2d0e8faa7845fe719a2e36e77ec8b95 100644 (file)
@@ -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);
 
index 93785290135309d01fbb49c6aa8587402687636d..e4be0f032cc304c73c10316c918203787e31f17b 100644 (file)
@@ -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) {
index 053cc680580fb3d81e5a951c5a7ab1291d3d6670..e73d9c095c10cb9afa13882001ea7ad2c74e2a58 100644 (file)
@@ -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;