]> granicus.if.org Git - php/commitdiff
Use better data structures (incomplete)
authorDmitry Stogov <dmitry@zend.com>
Wed, 19 Feb 2014 10:35:28 +0000 (14:35 +0400)
committerDmitry Stogov <dmitry@zend.com>
Wed, 19 Feb 2014 10:35:28 +0000 (14:35 +0400)
Zend/zend_API.c
Zend/zend_builtin_functions.c
Zend/zend_compile.c
Zend/zend_execute_API.c
Zend/zend_operators.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 1f171adfa48d9e7bac416dacdc3180f860db95f2..80eb984b17e9250048d6b9e7b7201e48b6705dee 100644 (file)
@@ -300,6 +300,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
        const char *spec_walk = *spec;
        char c = *spec_walk++;
        int check_null = 0;
+       zval *real_arg = arg;
 
        /* scan through modifiers */
        while (1) {
@@ -313,6 +314,10 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
                spec_walk++;
        }
 
+       if (Z_TYPE_P(arg) == IS_REFERENCE) {
+               arg = Z_REFVAL_P(arg);
+       }
+
        switch (c) {
                case 'l':
                case 'L':
@@ -691,7 +696,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
                                if (check_null && Z_TYPE_P(arg) == IS_NULL) {
                                        *p = NULL;
                                } else {
-                                       *p = arg;
+                                       *p = real_arg;
                                }
                        }
                        break;
index 8daa7cdda48166df4b89194ba5090921433d6b8b..13a3fb49bf7274839f565ec6546bcfd616960ffd 100644 (file)
@@ -585,6 +585,9 @@ ZEND_FUNCTION(each)
                return;
        }
 
+       if (Z_TYPE_P(array) == IS_REFERENCE) {
+               array = Z_REFVAL_P(array);
+       }
        target_hash = HASH_OF(array);
        if (!target_hash) {
                zend_error(E_WARNING,"Variable passed to each() is not an array or object");
@@ -603,9 +606,9 @@ ZEND_FUNCTION(each)
                entry = &tmp;
        }
        zend_hash_index_update(Z_ARRVAL_P(return_value), 1, entry);
-       Z_ADDREF_P(entry);
+       if (IS_REFCOUNTED(Z_TYPE_P(entry))) Z_ADDREF_P(entry);
        zend_hash_str_update(Z_ARRVAL_P(return_value), "value", sizeof("value")-1, entry);
-       Z_ADDREF_P(entry);
+       if (IS_REFCOUNTED(Z_TYPE_P(entry))) Z_ADDREF_P(entry);
 
        /* add the key elements */
        switch (zend_hash_get_current_key_ex(target_hash, &key, &num_key, 0, NULL)) {
@@ -617,7 +620,7 @@ ZEND_FUNCTION(each)
                        break;
        }
        zend_hash_str_update(Z_ARRVAL_P(return_value), "key", sizeof("key")-1, inserted_pointer);
-       Z_ADDREF_P(inserted_pointer);
+       if (IS_REFCOUNTED(Z_TYPE_P(inserted_pointer))) Z_ADDREF_P(inserted_pointer);
        zend_hash_move_forward(target_hash);
 }
 /* }}} */
index 327d4ce083f86300222d0952059cc4c70a5ba3a7..fb361e53e080500597c994b0cb5b912fe1286e70 100644 (file)
@@ -2115,7 +2115,7 @@ void zend_resolve_non_class_name(znode *element_name, zend_bool *check_namespace
        }
 
        if (current_import_sub) {
-               len = Z_STRLEN(element_name->u.constant)+1;
+               len = Z_STRLEN(element_name->u.constant);
                if (case_sensitive) {
                        lookup_name = STR_INIT(Z_STRVAL(element_name->u.constant), len, 0);
                } else {
@@ -2125,7 +2125,7 @@ void zend_resolve_non_class_name(znode *element_name, zend_bool *check_namespace
                /* Check if function/const matches imported name */
                if ((ns = zend_hash_find(current_import_sub, lookup_name)) != NULL) {
                        zval_dtor(&element_name->u.constant);
-                       zval_copy_ctor(&element_name->u.constant);
+                       ZVAL_DUP(&element_name->u.constant, ns);
                        STR_FREE(lookup_name);
                        *check_namespace = 0;
                        return;
@@ -2338,7 +2338,7 @@ void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
-static void label_dtor(zval *zv) /* {{{ */
+static void ptr_dtor(zval *zv) /* {{{ */
 {
        efree(Z_PTR_P(zv));
 }
@@ -2350,7 +2350,7 @@ void zend_do_label(znode *label TSRMLS_DC) /* {{{ */
 
        if (!CG(context).labels) {
                ALLOC_HASHTABLE(CG(context).labels);
-               zend_hash_init(CG(context).labels, 4, NULL, label_dtor, 0);
+               zend_hash_init(CG(context).labels, 4, NULL, ptr_dtor, 0);
        }
 
        dest.brk_cont = CG(context).current_brk_cont;
@@ -4030,7 +4030,7 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_s
                                }
                        } else {
                                ALLOC_HASHTABLE(*overriden);
-                               zend_hash_init_ex(*overriden, 2, NULL, NULL, 0, 0);
+                               zend_hash_init_ex(*overriden, 2, NULL, ptr_dtor, 0, 0);
                        }
                        fn = zend_hash_update_mem(*overriden, key, fn, sizeof(zend_function));
                        return;
@@ -5168,7 +5168,7 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name
        if (doing_inheritance) {
                /* Make sure a trait does not try to extend a class */
                if ((new_class_entry->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
-                       zend_error_noreturn(E_COMPILE_ERROR, "A trait (%s) cannot extend a class. Traits can only be composed from other traits with the 'use' keyword. Error", new_class_entry->name);
+                       zend_error_noreturn(E_COMPILE_ERROR, "A trait (%s) cannot extend a class. Traits can only be composed from other traits with the 'use' keyword. Error", new_class_entry->name->val);
                }
 
                opline->extended_value = parent_class_name->u.op.var;
index bbed28d7833b63fd24abf93c2024f8ae990ce0ed..dc194d051d98cff84f7fd39176ce046f2ea420b5 100644 (file)
@@ -1649,7 +1649,7 @@ ZEND_API void zend_delete_variable(zend_execute_data *ex, HashTable *ht, zend_st
                                        if (ex->op_array->vars[i]->h == name->h &&
                                                ex->op_array->vars[i]->len == name->len &&
                                                !memcmp(ex->op_array->vars[i]->val, name->val, name->len)) {
-                                               ZVAL_NULL(EX_VAR_NUM_2(ex, i));
+                                               ZVAL_UNDEF(EX_VAR_NUM_2(ex, i));
                                                break;
                                        }
                                }
index 1dff55c8f0f4acb8d89026b262e6d8c321b29154..4edd202bfc9eab027ba153f4a35f5179a5cfe964 100644 (file)
@@ -1407,10 +1407,20 @@ ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend
        int use_copy1 = 0, use_copy2 = 0;
 
        if (Z_TYPE_P(op1) != IS_STRING) {
-               zend_make_printable_zval(op1, &op1_copy, &use_copy1);
+               if (Z_TYPE_P(op1) == IS_REFERENCE) {
+                       op1 = Z_REFVAL_P(op1);
+               }
+               if (Z_TYPE_P(op1) != IS_STRING) {
+                       zend_make_printable_zval(op1, &op1_copy, &use_copy1);
+               }
        }
        if (Z_TYPE_P(op2) != IS_STRING) {
-               zend_make_printable_zval(op2, &op2_copy, &use_copy2);
+               if (Z_TYPE_P(op2) == IS_REFERENCE) {
+                       op2 = Z_REFVAL_P(op2);
+               }
+               if (Z_TYPE_P(op2) != IS_STRING) {
+                       zend_make_printable_zval(op2, &op2_copy, &use_copy2);
+               }
        }
 
        if (use_copy1) {
index 58dcb48ce83402409757372dd0ececdac4717083..2fdaed974e67066faa29ade5d278c1b10e069913 100644 (file)
@@ -1065,6 +1065,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|
        }
 //     ZVAL_COPY(EX_VAR(opline->result.var), retval);
        ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+       if (IS_REFCOUNTED(Z_TYPE_P(retval))) Z_ADDREF_P(retval);
 //???  switch (type) {
 //???          case BP_VAR_R:
 //???          case BP_VAR_IS:
@@ -1161,9 +1162,9 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
        if (UNEXPECTED(opline->extended_value != 0)) {
                zval *retval_ptr = EX_VAR(opline->result.var);
 
-               Z_DELREF_P(retval_ptr);
+//???          Z_DELREF_P(retval_ptr);
                SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
-               Z_ADDREF_P(retval_ptr);
+//???          Z_ADDREF_P(retval_ptr);
        }
 
        CHECK_EXCEPTION();
@@ -3963,6 +3964,10 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
        offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
 
        if (OP1_TYPE != IS_VAR || container) {
+//???deref
+               if (Z_TYPE_P(container) == IS_REFERENCE) {
+                       container = Z_REFVAL_P(container);
+               }
                switch (Z_TYPE_P(container)) {
                        case IS_ARRAY: {
                                HashTable *ht = Z_ARRVAL_P(container);
index cd0395c6c61cc7b51e18bb56b19b733a39ac9036..467c576eedecd6b6d797b390691b2119fe3f3b6a 100644 (file)
@@ -3584,6 +3584,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type
        }
 //     ZVAL_COPY(EX_VAR(opline->result.var), retval);
        ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+       if (IS_REFCOUNTED(Z_TYPE_P(retval))) Z_ADDREF_P(retval);
 //???  switch (type) {
 //???          case BP_VAR_R:
 //???          case BP_VAR_IS:
@@ -5331,6 +5332,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type,
        }
 //     ZVAL_COPY(EX_VAR(opline->result.var), retval);
        ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+       if (IS_REFCOUNTED(Z_TYPE_P(retval))) Z_ADDREF_P(retval);
 //???  switch (type) {
 //???          case BP_VAR_R:
 //???          case BP_VAR_IS:
@@ -6011,6 +6013,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ
        }
 //     ZVAL_COPY(EX_VAR(opline->result.var), retval);
        ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+       if (IS_REFCOUNTED(Z_TYPE_P(retval))) Z_ADDREF_P(retval);
 //???  switch (type) {
 //???          case BP_VAR_R:
 //???          case BP_VAR_IS:
@@ -8602,6 +8605,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type,
        }
 //     ZVAL_COPY(EX_VAR(opline->result.var), retval);
        ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+       if (IS_REFCOUNTED(Z_TYPE_P(retval))) Z_ADDREF_P(retval);
 //???  switch (type) {
 //???          case BP_VAR_R:
 //???          case BP_VAR_IS:
@@ -10225,6 +10229,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE
        }
 //     ZVAL_COPY(EX_VAR(opline->result.var), retval);
        ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+       if (IS_REFCOUNTED(Z_TYPE_P(retval))) Z_ADDREF_P(retval);
 //???  switch (type) {
 //???          case BP_VAR_R:
 //???          case BP_VAR_IS:
@@ -10908,6 +10913,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type,
        }
 //     ZVAL_COPY(EX_VAR(opline->result.var), retval);
        ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+       if (IS_REFCOUNTED(Z_TYPE_P(retval))) Z_ADDREF_P(retval);
 //???  switch (type) {
 //???          case BP_VAR_R:
 //???          case BP_VAR_IS:
@@ -14130,6 +14136,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type,
        }
 //     ZVAL_COPY(EX_VAR(opline->result.var), retval);
        ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+       if (IS_REFCOUNTED(Z_TYPE_P(retval))) Z_ADDREF_P(retval);
 //???  switch (type) {
 //???          case BP_VAR_R:
 //???          case BP_VAR_IS:
@@ -14225,9 +14232,9 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
        if (UNEXPECTED(opline->extended_value != 0)) {
                zval *retval_ptr = EX_VAR(opline->result.var);
 
-               Z_DELREF_P(retval_ptr);
+//???          Z_DELREF_P(retval_ptr);
                SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
-               Z_ADDREF_P(retval_ptr);
+//???          Z_ADDREF_P(retval_ptr);
        }
 
        CHECK_EXCEPTION();
@@ -15197,6 +15204,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
        offset = opline->op2.zv;
 
        if (IS_VAR != IS_VAR || container) {
+//???deref
+               if (Z_TYPE_P(container) == IS_REFERENCE) {
+                       container = Z_REFVAL_P(container);
+               }
                switch (Z_TYPE_P(container)) {
                        case IS_ARRAY: {
                                HashTable *ht = Z_ARRVAL_P(container);
@@ -16439,9 +16450,9 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
        if (UNEXPECTED(opline->extended_value != 0)) {
                zval *retval_ptr = EX_VAR(opline->result.var);
 
-               Z_DELREF_P(retval_ptr);
+//???          Z_DELREF_P(retval_ptr);
                SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
-               Z_ADDREF_P(retval_ptr);
+//???          Z_ADDREF_P(retval_ptr);
        }
 
        CHECK_EXCEPTION();
@@ -17246,6 +17257,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE
        offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
 
        if (IS_VAR != IS_VAR || container) {
+//???deref
+               if (Z_TYPE_P(container) == IS_REFERENCE) {
+                       container = Z_REFVAL_P(container);
+               }
                switch (Z_TYPE_P(container)) {
                        case IS_ARRAY: {
                                HashTable *ht = Z_ARRVAL_P(container);
@@ -18460,6 +18475,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE
        }
 //     ZVAL_COPY(EX_VAR(opline->result.var), retval);
        ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+       if (IS_REFCOUNTED(Z_TYPE_P(retval))) Z_ADDREF_P(retval);
 //???  switch (type) {
 //???          case BP_VAR_R:
 //???          case BP_VAR_IS:
@@ -18555,9 +18571,9 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
        if (UNEXPECTED(opline->extended_value != 0)) {
                zval *retval_ptr = EX_VAR(opline->result.var);
 
-               Z_DELREF_P(retval_ptr);
+//???          Z_DELREF_P(retval_ptr);
                SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
-               Z_ADDREF_P(retval_ptr);
+//???          Z_ADDREF_P(retval_ptr);
        }
 
        CHECK_EXCEPTION();
@@ -19491,6 +19507,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
        offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
 
        if (IS_VAR != IS_VAR || container) {
+//???deref
+               if (Z_TYPE_P(container) == IS_REFERENCE) {
+                       container = Z_REFVAL_P(container);
+               }
                switch (Z_TYPE_P(container)) {
                        case IS_ARRAY: {
                                HashTable *ht = Z_ARRVAL_P(container);
@@ -20320,6 +20340,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type,
        }
 //     ZVAL_COPY(EX_VAR(opline->result.var), retval);
        ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+       if (IS_REFCOUNTED(Z_TYPE_P(retval))) Z_ADDREF_P(retval);
 //???  switch (type) {
 //???          case BP_VAR_R:
 //???          case BP_VAR_IS:
@@ -20398,9 +20419,9 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H
        if (UNEXPECTED(opline->extended_value != 0)) {
                zval *retval_ptr = EX_VAR(opline->result.var);
 
-               Z_DELREF_P(retval_ptr);
+//???          Z_DELREF_P(retval_ptr);
                SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
-               Z_ADDREF_P(retval_ptr);
+//???          Z_ADDREF_P(retval_ptr);
        }
 
        CHECK_EXCEPTION();
@@ -21804,9 +21825,9 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
        if (UNEXPECTED(opline->extended_value != 0)) {
                zval *retval_ptr = EX_VAR(opline->result.var);
 
-               Z_DELREF_P(retval_ptr);
+//???          Z_DELREF_P(retval_ptr);
                SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
-               Z_ADDREF_P(retval_ptr);
+//???          Z_ADDREF_P(retval_ptr);
        }
 
        CHECK_EXCEPTION();
@@ -22661,6 +22682,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER
        offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
 
        if (IS_VAR != IS_VAR || container) {
+//???deref
+               if (Z_TYPE_P(container) == IS_REFERENCE) {
+                       container = Z_REFVAL_P(container);
+               }
                switch (Z_TYPE_P(container)) {
                        case IS_ARRAY: {
                                HashTable *ht = Z_ARRVAL_P(container);
@@ -24080,6 +24105,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H
        offset = opline->op2.zv;
 
        if (IS_UNUSED != IS_VAR || container) {
+//???deref
+               if (Z_TYPE_P(container) == IS_REFERENCE) {
+                       container = Z_REFVAL_P(container);
+               }
                switch (Z_TYPE_P(container)) {
                        case IS_ARRAY: {
                                HashTable *ht = Z_ARRVAL_P(container);
@@ -25324,6 +25353,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_DIM_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN
        offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
 
        if (IS_UNUSED != IS_VAR || container) {
+//???deref
+               if (Z_TYPE_P(container) == IS_REFERENCE) {
+                       container = Z_REFVAL_P(container);
+               }
                switch (Z_TYPE_P(container)) {
                        case IS_ARRAY: {
                                HashTable *ht = Z_ARRVAL_P(container);
@@ -26568,6 +26601,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN
        offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
 
        if (IS_UNUSED != IS_VAR || container) {
+//???deref
+               if (Z_TYPE_P(container) == IS_REFERENCE) {
+                       container = Z_REFVAL_P(container);
+               }
                switch (Z_TYPE_P(container)) {
                        case IS_ARRAY: {
                                HashTable *ht = Z_ARRVAL_P(container);
@@ -28209,6 +28246,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND
        offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
 
        if (IS_UNUSED != IS_VAR || container) {
+//???deref
+               if (Z_TYPE_P(container) == IS_REFERENCE) {
+                       container = Z_REFVAL_P(container);
+               }
                switch (Z_TYPE_P(container)) {
                        case IS_ARRAY: {
                                HashTable *ht = Z_ARRVAL_P(container);
@@ -30577,6 +30618,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z
        }
 //     ZVAL_COPY(EX_VAR(opline->result.var), retval);
        ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+       if (IS_REFCOUNTED(Z_TYPE_P(retval))) Z_ADDREF_P(retval);
 //???  switch (type) {
 //???          case BP_VAR_R:
 //???          case BP_VAR_IS:
@@ -30671,9 +30713,9 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
        if (UNEXPECTED(opline->extended_value != 0)) {
                zval *retval_ptr = EX_VAR(opline->result.var);
 
-               Z_DELREF_P(retval_ptr);
+//???          Z_DELREF_P(retval_ptr);
                SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
-               Z_ADDREF_P(retval_ptr);
+//???          Z_ADDREF_P(retval_ptr);
        }
 
        CHECK_EXCEPTION();
@@ -31432,6 +31474,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
        offset = opline->op2.zv;
 
        if (IS_CV != IS_VAR || container) {
+//???deref
+               if (Z_TYPE_P(container) == IS_REFERENCE) {
+                       container = Z_REFVAL_P(container);
+               }
                switch (Z_TYPE_P(container)) {
                        case IS_ARRAY: {
                                HashTable *ht = Z_ARRVAL_P(container);
@@ -32666,9 +32712,9 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
        if (UNEXPECTED(opline->extended_value != 0)) {
                zval *retval_ptr = EX_VAR(opline->result.var);
 
-               Z_DELREF_P(retval_ptr);
+//???          Z_DELREF_P(retval_ptr);
                SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
-               Z_ADDREF_P(retval_ptr);
+//???          Z_ADDREF_P(retval_ptr);
        }
 
        CHECK_EXCEPTION();
@@ -33355,6 +33401,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER
        offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
 
        if (IS_CV != IS_VAR || container) {
+//???deref
+               if (Z_TYPE_P(container) == IS_REFERENCE) {
+                       container = Z_REFVAL_P(container);
+               }
                switch (Z_TYPE_P(container)) {
                        case IS_ARRAY: {
                                HashTable *ht = Z_ARRVAL_P(container);
@@ -34562,6 +34612,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN
        }
 //     ZVAL_COPY(EX_VAR(opline->result.var), retval);
        ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+       if (IS_REFCOUNTED(Z_TYPE_P(retval))) Z_ADDREF_P(retval);
 //???  switch (type) {
 //???          case BP_VAR_R:
 //???          case BP_VAR_IS:
@@ -34656,9 +34707,9 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
        if (UNEXPECTED(opline->extended_value != 0)) {
                zval *retval_ptr = EX_VAR(opline->result.var);
 
-               Z_DELREF_P(retval_ptr);
+//???          Z_DELREF_P(retval_ptr);
                SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
-               Z_ADDREF_P(retval_ptr);
+//???          Z_ADDREF_P(retval_ptr);
        }
 
        CHECK_EXCEPTION();
@@ -35474,6 +35525,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
        offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
 
        if (IS_CV != IS_VAR || container) {
+//???deref
+               if (Z_TYPE_P(container) == IS_REFERENCE) {
+                       container = Z_REFVAL_P(container);
+               }
                switch (Z_TYPE_P(container)) {
                        case IS_ARRAY: {
                                HashTable *ht = Z_ARRVAL_P(container);
@@ -36296,6 +36351,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type,
        }
 //     ZVAL_COPY(EX_VAR(opline->result.var), retval);
        ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+       if (IS_REFCOUNTED(Z_TYPE_P(retval))) Z_ADDREF_P(retval);
 //???  switch (type) {
 //???          case BP_VAR_R:
 //???          case BP_VAR_IS:
@@ -36373,9 +36429,9 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HA
        if (UNEXPECTED(opline->extended_value != 0)) {
                zval *retval_ptr = EX_VAR(opline->result.var);
 
-               Z_DELREF_P(retval_ptr);
+//???          Z_DELREF_P(retval_ptr);
                SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
-               Z_ADDREF_P(retval_ptr);
+//???          Z_ADDREF_P(retval_ptr);
        }
 
        CHECK_EXCEPTION();
@@ -37647,9 +37703,9 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
        if (UNEXPECTED(opline->extended_value != 0)) {
                zval *retval_ptr = EX_VAR(opline->result.var);
 
-               Z_DELREF_P(retval_ptr);
+//???          Z_DELREF_P(retval_ptr);
                SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
-               Z_ADDREF_P(retval_ptr);
+//???          Z_ADDREF_P(retval_ptr);
        }
 
        CHECK_EXCEPTION();
@@ -38386,6 +38442,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_
        offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
 
        if (IS_CV != IS_VAR || container) {
+//???deref
+               if (Z_TYPE_P(container) == IS_REFERENCE) {
+                       container = Z_REFVAL_P(container);
+               }
                switch (Z_TYPE_P(container)) {
                        case IS_ARRAY: {
                                HashTable *ht = Z_ARRVAL_P(container);