]> granicus.if.org Git - php/commitdiff
Redesigned SRR_OFFSET handling
authorDmitry Stogov <dmitry@zend.com>
Fri, 28 Feb 2014 13:39:08 +0000 (17:39 +0400)
committerDmitry Stogov <dmitry@zend.com>
Fri, 28 Feb 2014 13:39:08 +0000 (17:39 +0400)
Zend/zend_execute.c
Zend/zend_types.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 135f19757261e713d45dc11a316fbd1e7b7e50c7..26965d92d22fdc04c329ec272383adba058d9799 100644 (file)
@@ -839,7 +839,7 @@ static inline void zend_assign_to_object(zval *retval, zval *object_ptr, zval *p
 
 static inline int zend_assign_to_string_offset(zval *str_offset, zval *value, int value_type TSRMLS_DC)
 {
-       zend_string *str = Z_STR_OFFSET_P(str_offset)->str;
+       zval *str = Z_STR_OFFSET_P(str_offset)->str;
        zend_uint offset = Z_STR_OFFSET_P(str_offset)->offset;
 
        if ((int)offset < 0) {
@@ -847,12 +847,13 @@ static inline int zend_assign_to_string_offset(zval *str_offset, zval *value, in
                return 0;
        }
 
-       if (offset >= str->len) {
-               str = STR_REALLOC(str, offset + 1, 0);
-               memset(str->val + str->len, ' ', offset - str->len);
-               str->val[offset+1] = 0;
-       } else if (IS_INTERNED(str)) {
-               str = STR_DUP(str, 0);
+       if (offset >= Z_STRLEN_P(str)) {
+               int old_len = Z_STRLEN_P(str);
+               Z_STR_P(str) = STR_REALLOC(Z_STR_P(str), offset + 1, 0);
+               memset(Z_STRVAL_P(str) + old_len, ' ', offset - old_len);
+               Z_STRVAL_P(str)[offset+1] = 0;
+       } else if (IS_INTERNED(Z_STR_P(str))) {
+               Z_STR_P(str) = STR_DUP(Z_STR_P(str), 0);
        }
 
        if (Z_TYPE_P(value) != IS_STRING) {
@@ -863,10 +864,10 @@ static inline int zend_assign_to_string_offset(zval *str_offset, zval *value, in
                        zval_copy_ctor(&tmp);
                }
                convert_to_string(&tmp);
-               str->val[offset] = Z_STRVAL(tmp)[0];
+               Z_STRVAL_P(str)[offset] = Z_STRVAL(tmp)[0];
                zval_dtor(&tmp);
        } else {
-               str->val[offset] = Z_STRVAL_P(value)[0];
+               Z_STRVAL_P(str)[offset] = Z_STRVAL_P(value)[0];
                if (value_type == IS_TMP_VAR) {
                        /* we can safely free final_value here
                         * because separation is done only
@@ -1240,7 +1241,7 @@ convert_to_array:
                                if (Z_TYPE_P(container) == IS_INDIRECT) {
                                        container = Z_INDIRECT_P(container);
                                }
-                               ZVAL_STR_OFFSET(result, Z_STR_P(container), Z_LVAL_P(dim));
+                               ZVAL_STR_OFFSET(result, container, Z_LVAL_P(dim));
                                Z_ADDREF_P(container);                          
                                return;
                        }
index 9a86bc761bcf85a46bc430d4d37367b2aa52a676..836d103e27a120263ff65a721a8e8a69e3571641 100644 (file)
@@ -117,7 +117,7 @@ struct _zend_string {
 
 struct _zend_str_offset {
        zend_refcounted   gc;
-       zend_string      *str;
+       zval             *str;
        int               offset;
 };
 
index 8736bb01eaccdbd26ad170d9781bf1536b2edbb5..f8ff0970f8c9c417da3061bedc3aa6fa674cad6d 100644 (file)
@@ -1684,11 +1684,14 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
                if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                        if (zend_assign_to_string_offset(EX_VAR((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
                                if (RETURN_VALUE_USED(opline)) {
-                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str->val + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
+                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str) + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
                                }
                        } else if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//??? instead of FREE_OP_VAR_PTR(free_op_data2);
+//???                  zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+                       efree(Z_STR_OFFSET_P(variable_ptr));
                } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
                        if (IS_TMP_FREE(free_op_data1)) {
                                zval_dtor(value);
@@ -1696,6 +1699,7 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//???          FREE_OP_VAR_PTR(free_op_data2);
                } else {
                        if ((opline+1)->op1_type == IS_TMP_VAR) {
                                value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC);
@@ -1707,8 +1711,8 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), value);
                        }
-               }
 //???          FREE_OP_VAR_PTR(free_op_data2);
+               }
                FREE_OP_IF_VAR(free_op_data1);
        }
        FREE_OP1_VAR_PTR();
@@ -1732,11 +1736,14 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV)
        if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                if (zend_assign_to_string_offset(EX_VAR(opline->op1.var), value, OP2_TYPE TSRMLS_CC)) {
                        if (RETURN_VALUE_USED(opline)) {
-                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str->val + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
+                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str) + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
                        }
                } else if (RETURN_VALUE_USED(opline)) {
                        ZVAL_NULL(EX_VAR(opline->result.var));
                }
+//??? instead of FREE_OP1_VAR_PTR()
+//???          zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+               efree(Z_STR_OFFSET_P(variable_ptr));
        } else if (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
                if (IS_OP2_TMP_FREE()) {
                        zval_dtor(value);
@@ -1755,10 +1762,9 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV)
                if (RETURN_VALUE_USED(opline)) {
                        ZVAL_COPY(EX_VAR(opline->result.var), value);
                }
+               FREE_OP1_VAR_PTR();
        }
 
-       FREE_OP1_VAR_PTR();
-
        /* zend_assign_to_variable() always takes care of op2, never free it! */
        FREE_OP2_IF_VAR();
 
index 52a98a4ce3dfb33f8cf1202ce817eae8316028f4..345e371e5a585f996afa5d84efdd14e558efd6ea 100644 (file)
@@ -14981,11 +14981,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
                if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                        if (zend_assign_to_string_offset(EX_VAR((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
                                if (RETURN_VALUE_USED(opline)) {
-                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str->val + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
+                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str) + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
                                }
                        } else if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//??? instead of FREE_OP_VAR_PTR(free_op_data2);
+//???                  zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+                       efree(Z_STR_OFFSET_P(variable_ptr));
                } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
                        if (IS_TMP_FREE(free_op_data1)) {
                                zval_dtor(value);
@@ -14993,6 +14996,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//???          FREE_OP_VAR_PTR(free_op_data2);
                } else {
                        if ((opline+1)->op1_type == IS_TMP_VAR) {
                                value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC);
@@ -15004,8 +15008,8 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), value);
                        }
-               }
 //???          FREE_OP_VAR_PTR(free_op_data2);
+               }
                FREE_OP_IF_VAR(free_op_data1);
        }
        if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
@@ -15029,11 +15033,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                if (zend_assign_to_string_offset(EX_VAR(opline->op1.var), value, IS_CONST TSRMLS_CC)) {
                        if (RETURN_VALUE_USED(opline)) {
-                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str->val + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
+                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str) + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
                        }
                } else if (RETURN_VALUE_USED(opline)) {
                        ZVAL_NULL(EX_VAR(opline->result.var));
                }
+//??? instead of if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}
+//???          zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+               efree(Z_STR_OFFSET_P(variable_ptr));
        } else if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
                if (0) {
                        zval_dtor(value);
@@ -15052,10 +15059,9 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER
                if (RETURN_VALUE_USED(opline)) {
                        ZVAL_COPY(EX_VAR(opline->result.var), value);
                }
+               if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
        }
 
-       if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
-
        /* zend_assign_to_variable() always takes care of op2, never free it! */
 
        CHECK_EXCEPTION();
@@ -17265,11 +17271,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
                if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                        if (zend_assign_to_string_offset(EX_VAR((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
                                if (RETURN_VALUE_USED(opline)) {
-                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str->val + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
+                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str) + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
                                }
                        } else if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//??? instead of FREE_OP_VAR_PTR(free_op_data2);
+//???                  zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+                       efree(Z_STR_OFFSET_P(variable_ptr));
                } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
                        if (IS_TMP_FREE(free_op_data1)) {
                                zval_dtor(value);
@@ -17277,6 +17286,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//???          FREE_OP_VAR_PTR(free_op_data2);
                } else {
                        if ((opline+1)->op1_type == IS_TMP_VAR) {
                                value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC);
@@ -17288,8 +17298,8 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), value);
                        }
-               }
 //???          FREE_OP_VAR_PTR(free_op_data2);
+               }
                FREE_OP_IF_VAR(free_op_data1);
        }
        if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
@@ -17313,11 +17323,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                if (zend_assign_to_string_offset(EX_VAR(opline->op1.var), value, IS_TMP_VAR TSRMLS_CC)) {
                        if (RETURN_VALUE_USED(opline)) {
-                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str->val + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
+                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str) + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
                        }
                } else if (RETURN_VALUE_USED(opline)) {
                        ZVAL_NULL(EX_VAR(opline->result.var));
                }
+//??? instead of if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}
+//???          zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+               efree(Z_STR_OFFSET_P(variable_ptr));
        } else if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
                if (1) {
                        zval_dtor(value);
@@ -17336,10 +17349,9 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
                if (RETURN_VALUE_USED(opline)) {
                        ZVAL_COPY(EX_VAR(opline->result.var), value);
                }
+               if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
        }
 
-       if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
-
        /* zend_assign_to_variable() always takes care of op2, never free it! */
 
        CHECK_EXCEPTION();
@@ -19447,11 +19459,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
                if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                        if (zend_assign_to_string_offset(EX_VAR((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
                                if (RETURN_VALUE_USED(opline)) {
-                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str->val + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
+                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str) + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
                                }
                        } else if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//??? instead of FREE_OP_VAR_PTR(free_op_data2);
+//???                  zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+                       efree(Z_STR_OFFSET_P(variable_ptr));
                } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
                        if (IS_TMP_FREE(free_op_data1)) {
                                zval_dtor(value);
@@ -19459,6 +19474,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//???          FREE_OP_VAR_PTR(free_op_data2);
                } else {
                        if ((opline+1)->op1_type == IS_TMP_VAR) {
                                value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC);
@@ -19470,8 +19486,8 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), value);
                        }
-               }
 //???          FREE_OP_VAR_PTR(free_op_data2);
+               }
                FREE_OP_IF_VAR(free_op_data1);
        }
        if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
@@ -19495,11 +19511,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                if (zend_assign_to_string_offset(EX_VAR(opline->op1.var), value, IS_VAR TSRMLS_CC)) {
                        if (RETURN_VALUE_USED(opline)) {
-                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str->val + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
+                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str) + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
                        }
                } else if (RETURN_VALUE_USED(opline)) {
                        ZVAL_NULL(EX_VAR(opline->result.var));
                }
+//??? instead of if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}
+//???          zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+               efree(Z_STR_OFFSET_P(variable_ptr));
        } else if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
                if (0) {
                        zval_dtor(value);
@@ -19518,10 +19537,9 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
                if (RETURN_VALUE_USED(opline)) {
                        ZVAL_COPY(EX_VAR(opline->result.var), value);
                }
+               if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
        }
 
-       if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
-
        /* zend_assign_to_variable() always takes care of op2, never free it! */
        zval_ptr_dtor_nogc(free_op2.var);
 
@@ -21031,11 +21049,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
                if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                        if (zend_assign_to_string_offset(EX_VAR((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
                                if (RETURN_VALUE_USED(opline)) {
-                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str->val + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
+                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str) + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
                                }
                        } else if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//??? instead of FREE_OP_VAR_PTR(free_op_data2);
+//???                  zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+                       efree(Z_STR_OFFSET_P(variable_ptr));
                } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
                        if (IS_TMP_FREE(free_op_data1)) {
                                zval_dtor(value);
@@ -21043,6 +21064,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//???          FREE_OP_VAR_PTR(free_op_data2);
                } else {
                        if ((opline+1)->op1_type == IS_TMP_VAR) {
                                value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC);
@@ -21054,8 +21076,8 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), value);
                        }
-               }
 //???          FREE_OP_VAR_PTR(free_op_data2);
+               }
                FREE_OP_IF_VAR(free_op_data1);
        }
        if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
@@ -22818,11 +22840,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
                if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                        if (zend_assign_to_string_offset(EX_VAR((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
                                if (RETURN_VALUE_USED(opline)) {
-                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str->val + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
+                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str) + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
                                }
                        } else if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//??? instead of FREE_OP_VAR_PTR(free_op_data2);
+//???                  zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+                       efree(Z_STR_OFFSET_P(variable_ptr));
                } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
                        if (IS_TMP_FREE(free_op_data1)) {
                                zval_dtor(value);
@@ -22830,6 +22855,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//???          FREE_OP_VAR_PTR(free_op_data2);
                } else {
                        if ((opline+1)->op1_type == IS_TMP_VAR) {
                                value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC);
@@ -22841,8 +22867,8 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), value);
                        }
-               }
 //???          FREE_OP_VAR_PTR(free_op_data2);
+               }
                FREE_OP_IF_VAR(free_op_data1);
        }
        if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
@@ -22866,11 +22892,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                if (zend_assign_to_string_offset(EX_VAR(opline->op1.var), value, IS_CV TSRMLS_CC)) {
                        if (RETURN_VALUE_USED(opline)) {
-                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str->val + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
+                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str) + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
                        }
                } else if (RETURN_VALUE_USED(opline)) {
                        ZVAL_NULL(EX_VAR(opline->result.var));
                }
+//??? instead of if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}
+//???          zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+               efree(Z_STR_OFFSET_P(variable_ptr));
        } else if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
                if (0) {
                        zval_dtor(value);
@@ -22889,10 +22918,9 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
                if (RETURN_VALUE_USED(opline)) {
                        ZVAL_COPY(EX_VAR(opline->result.var), value);
                }
+               if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
        }
 
-       if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
-
        /* zend_assign_to_variable() always takes care of op2, never free it! */
 
        CHECK_EXCEPTION();
@@ -31936,11 +31964,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
                if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                        if (zend_assign_to_string_offset(EX_VAR((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
                                if (RETURN_VALUE_USED(opline)) {
-                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str->val + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
+                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str) + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
                                }
                        } else if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//??? instead of FREE_OP_VAR_PTR(free_op_data2);
+//???                  zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+                       efree(Z_STR_OFFSET_P(variable_ptr));
                } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
                        if (IS_TMP_FREE(free_op_data1)) {
                                zval_dtor(value);
@@ -31948,6 +31979,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//???          FREE_OP_VAR_PTR(free_op_data2);
                } else {
                        if ((opline+1)->op1_type == IS_TMP_VAR) {
                                value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC);
@@ -31959,8 +31991,8 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), value);
                        }
-               }
 //???          FREE_OP_VAR_PTR(free_op_data2);
+               }
                FREE_OP_IF_VAR(free_op_data1);
        }
 
@@ -31984,11 +32016,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                if (zend_assign_to_string_offset(EX_VAR(opline->op1.var), value, IS_CONST TSRMLS_CC)) {
                        if (RETURN_VALUE_USED(opline)) {
-                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str->val + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
+                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str) + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
                        }
                } else if (RETURN_VALUE_USED(opline)) {
                        ZVAL_NULL(EX_VAR(opline->result.var));
                }
+//??? instead of
+//???          zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+               efree(Z_STR_OFFSET_P(variable_ptr));
        } else if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
                if (0) {
                        zval_dtor(value);
@@ -32007,6 +32042,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_
                if (RETURN_VALUE_USED(opline)) {
                        ZVAL_COPY(EX_VAR(opline->result.var), value);
                }
+
        }
 
        /* zend_assign_to_variable() always takes care of op2, never free it! */
@@ -34002,11 +34038,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
                if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                        if (zend_assign_to_string_offset(EX_VAR((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
                                if (RETURN_VALUE_USED(opline)) {
-                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str->val + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
+                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str) + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
                                }
                        } else if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//??? instead of FREE_OP_VAR_PTR(free_op_data2);
+//???                  zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+                       efree(Z_STR_OFFSET_P(variable_ptr));
                } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
                        if (IS_TMP_FREE(free_op_data1)) {
                                zval_dtor(value);
@@ -34014,6 +34053,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//???          FREE_OP_VAR_PTR(free_op_data2);
                } else {
                        if ((opline+1)->op1_type == IS_TMP_VAR) {
                                value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC);
@@ -34025,8 +34065,8 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), value);
                        }
-               }
 //???          FREE_OP_VAR_PTR(free_op_data2);
+               }
                FREE_OP_IF_VAR(free_op_data1);
        }
 
@@ -34050,11 +34090,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                if (zend_assign_to_string_offset(EX_VAR(opline->op1.var), value, IS_TMP_VAR TSRMLS_CC)) {
                        if (RETURN_VALUE_USED(opline)) {
-                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str->val + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
+                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str) + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
                        }
                } else if (RETURN_VALUE_USED(opline)) {
                        ZVAL_NULL(EX_VAR(opline->result.var));
                }
+//??? instead of
+//???          zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+               efree(Z_STR_OFFSET_P(variable_ptr));
        } else if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
                if (1) {
                        zval_dtor(value);
@@ -34073,6 +34116,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
                if (RETURN_VALUE_USED(opline)) {
                        ZVAL_COPY(EX_VAR(opline->result.var), value);
                }
+
        }
 
        /* zend_assign_to_variable() always takes care of op2, never free it! */
@@ -36059,11 +36103,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
                if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                        if (zend_assign_to_string_offset(EX_VAR((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
                                if (RETURN_VALUE_USED(opline)) {
-                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str->val + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
+                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str) + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
                                }
                        } else if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//??? instead of FREE_OP_VAR_PTR(free_op_data2);
+//???                  zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+                       efree(Z_STR_OFFSET_P(variable_ptr));
                } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
                        if (IS_TMP_FREE(free_op_data1)) {
                                zval_dtor(value);
@@ -36071,6 +36118,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//???          FREE_OP_VAR_PTR(free_op_data2);
                } else {
                        if ((opline+1)->op1_type == IS_TMP_VAR) {
                                value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC);
@@ -36082,8 +36130,8 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), value);
                        }
-               }
 //???          FREE_OP_VAR_PTR(free_op_data2);
+               }
                FREE_OP_IF_VAR(free_op_data1);
        }
 
@@ -36107,11 +36155,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                if (zend_assign_to_string_offset(EX_VAR(opline->op1.var), value, IS_VAR TSRMLS_CC)) {
                        if (RETURN_VALUE_USED(opline)) {
-                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str->val + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
+                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str) + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
                        }
                } else if (RETURN_VALUE_USED(opline)) {
                        ZVAL_NULL(EX_VAR(opline->result.var));
                }
+//??? instead of
+//???          zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+               efree(Z_STR_OFFSET_P(variable_ptr));
        } else if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
                if (0) {
                        zval_dtor(value);
@@ -36130,6 +36181,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
                if (RETURN_VALUE_USED(opline)) {
                        ZVAL_COPY(EX_VAR(opline->result.var), value);
                }
+
        }
 
        /* zend_assign_to_variable() always takes care of op2, never free it! */
@@ -37522,11 +37574,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
                if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                        if (zend_assign_to_string_offset(EX_VAR((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
                                if (RETURN_VALUE_USED(opline)) {
-                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str->val + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
+                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str) + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
                                }
                        } else if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//??? instead of FREE_OP_VAR_PTR(free_op_data2);
+//???                  zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+                       efree(Z_STR_OFFSET_P(variable_ptr));
                } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
                        if (IS_TMP_FREE(free_op_data1)) {
                                zval_dtor(value);
@@ -37534,6 +37589,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//???          FREE_OP_VAR_PTR(free_op_data2);
                } else {
                        if ((opline+1)->op1_type == IS_TMP_VAR) {
                                value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC);
@@ -37545,8 +37601,8 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), value);
                        }
-               }
 //???          FREE_OP_VAR_PTR(free_op_data2);
+               }
                FREE_OP_IF_VAR(free_op_data1);
        }
 
@@ -39174,11 +39230,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
                if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                        if (zend_assign_to_string_offset(EX_VAR((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
                                if (RETURN_VALUE_USED(opline)) {
-                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str->val + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
+                                       ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->str) + Z_STR_OFFSET_P(EX_VAR((opline+1)->op2.var))->offset, 1);
                                }
                        } else if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//??? instead of FREE_OP_VAR_PTR(free_op_data2);
+//???                  zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+                       efree(Z_STR_OFFSET_P(variable_ptr));
                } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
                        if (IS_TMP_FREE(free_op_data1)) {
                                zval_dtor(value);
@@ -39186,6 +39245,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
+//???          FREE_OP_VAR_PTR(free_op_data2);
                } else {
                        if ((opline+1)->op1_type == IS_TMP_VAR) {
                                value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC);
@@ -39197,8 +39257,8 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), value);
                        }
-               }
 //???          FREE_OP_VAR_PTR(free_op_data2);
+               }
                FREE_OP_IF_VAR(free_op_data1);
        }
 
@@ -39222,11 +39282,14 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
                if (zend_assign_to_string_offset(EX_VAR(opline->op1.var), value, IS_CV TSRMLS_CC)) {
                        if (RETURN_VALUE_USED(opline)) {
-                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str->val + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
+                               ZVAL_STRINGL(EX_VAR(opline->result.var), Z_STRVAL_P(Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->str) + Z_STR_OFFSET_P(EX_VAR(opline->op1.var))->offset, 1);
                        }
                } else if (RETURN_VALUE_USED(opline)) {
                        ZVAL_NULL(EX_VAR(opline->result.var));
                }
+//??? instead of
+//???          zval_ptr_dtor(Z_STR_OFFSET_P(variable_ptr)->str);
+               efree(Z_STR_OFFSET_P(variable_ptr));
        } else if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
                if (0) {
                        zval_dtor(value);
@@ -39245,6 +39308,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
                if (RETURN_VALUE_USED(opline)) {
                        ZVAL_COPY(EX_VAR(opline->result.var), value);
                }
+
        }
 
        /* zend_assign_to_variable() always takes care of op2, never free it! */