]> granicus.if.org Git - php/commitdiff
Optimized conditions order
authorDmitry Stogov <dmitry@zend.com>
Mon, 2 Jun 2014 23:54:03 +0000 (03:54 +0400)
committerDmitry Stogov <dmitry@zend.com>
Mon, 2 Jun 2014 23:54:03 +0000 (03:54 +0400)
Zend/zend_variables.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/standard/array.c

index 282725a32520b89f2da0a7d73c1b269582cdd7d1..c55ce233a58bb232ad976d1fda103b925e3897b0 100644 (file)
@@ -62,6 +62,28 @@ static zend_always_inline void _zval_opt_copy_ctor(zval *zvalue ZEND_FILE_LINE_D
        }
 }
 
+static zend_always_inline void _zval_copy_ctor_no_imm(zval *zvalue ZEND_FILE_LINE_DC)
+{
+       if (Z_REFCOUNTED_P(zvalue)) {
+               if (Z_COPYABLE_P(zvalue)) {
+                       _zval_copy_ctor_func(zvalue ZEND_FILE_LINE_RELAY_CC);
+               } else {
+                       Z_ADDREF_P(zvalue);
+               }
+       }
+}
+
+static zend_always_inline void _zval_opt_copy_ctor_no_imm(zval *zvalue ZEND_FILE_LINE_DC)
+{
+       if (Z_OPT_REFCOUNTED_P(zvalue)) {
+               if (Z_OPT_COPYABLE_P(zvalue)) {
+                       _zval_copy_ctor_func(zvalue ZEND_FILE_LINE_RELAY_CC);
+               } else {
+                       Z_ADDREF_P(zvalue);
+               }
+       }
+}
+
 ZEND_API int zval_copy_static_var(zval *p TSRMLS_DC, int num_args, va_list args, zend_hash_key *key);
 
 ZEND_API int zend_print_variable(zval *var TSRMLS_DC);
@@ -72,6 +94,8 @@ ZEND_API void _zval_internal_ptr_dtor(zval *zvalue ZEND_FILE_LINE_DC);
 ZEND_API void _zval_dtor_wrapper(zval *zvalue);
 #define zval_copy_ctor(zvalue) _zval_copy_ctor((zvalue) ZEND_FILE_LINE_CC)
 #define zval_opt_copy_ctor(zvalue) _zval_opt_copy_ctor((zvalue) ZEND_FILE_LINE_CC)
+#define zval_copy_ctor_no_imm(zvalue) _zval_copy_ctor_no_imm((zvalue) ZEND_FILE_LINE_CC)
+#define zval_opt_copy_ctor_no_imm(zvalue) _zval_opt_copy_ctor_no_imm((zvalue) ZEND_FILE_LINE_CC)
 #define zval_dtor(zvalue) _zval_dtor((zvalue) ZEND_FILE_LINE_CC)
 #define zval_ptr_dtor(zval_ptr) _zval_ptr_dtor((zval_ptr) ZEND_FILE_LINE_CC)
 #define zval_internal_dtor(zvalue) _zval_internal_dtor((zvalue) ZEND_FILE_LINE_CC)
index 367ac86940d8f492d87f40f286a765762e24608d..f41803bfaedf21feff2fa20364fa5d324898c7e1 100644 (file)
@@ -2823,8 +2823,8 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
        } else {
                if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) {               
                        ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
-                       if (OP1_TYPE == IS_CONST && !Z_OPT_IMMUTABLE_P(EX(return_value))) {
-                               zval_opt_copy_ctor(EX(return_value));
+                       if (OP1_TYPE == IS_CONST) {
+                               zval_opt_copy_ctor_no_imm(EX(return_value));
                        }
                } else if (Z_ISREF_P(retval_ptr)) {
                        ZVAL_DUP(EX(return_value), Z_REFVAL_P(retval_ptr));
@@ -2860,8 +2860,8 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
                                }
                        } else {
                                ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
-                               if (OP1_TYPE != IS_TMP_VAR && !Z_OPT_IMMUTABLE_P(EX(return_value))) {
-                                       zval_opt_copy_ctor(EX(return_value));
+                               if (OP1_TYPE != IS_TMP_VAR) {
+                                       zval_opt_copy_ctor_no_imm(EX(return_value));
                                }
                        }
                        break;
@@ -3008,9 +3008,7 @@ ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY)
        if (OP1_TYPE == IS_CONST) {
                /* Immutable arrays may be passed without copying ??? */
                /* some internal functions may try to modify them !!! */
-               if (!Z_OPT_IMMUTABLE_P(top)) {
-                       zval_opt_copy_ctor(top);
-               }
+               zval_opt_copy_ctor_no_imm(top);
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -3027,9 +3025,7 @@ ZEND_VM_HELPER(zend_send_by_var_helper, VAR|CV, ANY)
                ZVAL_COPY_VALUE(top, Z_REFVAL_P(varptr));
                /* Immutable arrays may be passed without copying ??? */
                /* some internal functions may try to modify them !!! */
-               if (!Z_OPT_IMMUTABLE_P(top)) {
-                       zval_opt_copy_ctor(top);
-               } 
+               zval_opt_copy_ctor_no_imm(top);
                FREE_OP1();
        } else {
                ZVAL_COPY_VALUE(top, varptr);
@@ -3153,9 +3149,7 @@ ZEND_VM_HANDLER(66, ZEND_SEND_VAR, VAR|CV, ANY)
                ZVAL_COPY_VALUE(top, Z_REFVAL_P(varptr));
                /* Immutable arrays may be passed without copying ??? */
                /* some internal functions may try to modify them !!! */
-               if (!Z_OPT_IMMUTABLE_P(top)) {
-                       zval_opt_copy_ctor(top);
-               }
+               zval_opt_copy_ctor_no_imm(top);
                FREE_OP1();
        } else {
                ZVAL_COPY_VALUE(top, varptr);
@@ -4935,9 +4929,7 @@ ZEND_VM_HANDLER(22, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY)
 
        ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
        if (!IS_OP1_TMP_FREE()) {
-               if (!Z_OPT_IMMUTABLE_P(EX_VAR(opline->result.var))) {
-                       zval_opt_copy_ctor(EX_VAR(opline->result.var));
-               }
+               zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var));
        }
        FREE_OP1_IF_VAR();
        CHECK_EXCEPTION();
@@ -4958,9 +4950,7 @@ ZEND_VM_HANDLER(157, ZEND_QM_ASSIGN_VAR, CONST|TMP|VAR|CV, ANY)
        } else {
                ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
                if (!IS_OP1_TMP_FREE()) {
-                       if (!Z_OPT_IMMUTABLE_P(EX_VAR(opline->result.var))) {
-                               zval_opt_copy_ctor(EX_VAR(opline->result.var));
-                       }
+                       zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var));
                }
        }
 
index cfb733e455c64a9b0cebbef8723b019149699649..c156748d279188bc9a7c364b0a4061aa947fc513 100644 (file)
@@ -2605,8 +2605,8 @@ static int ZEND_FASTCALL  ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
        } else {
                if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
-                       if (IS_CONST == IS_CONST && !Z_OPT_IMMUTABLE_P(EX(return_value))) {
-                               zval_opt_copy_ctor(EX(return_value));
+                       if (IS_CONST == IS_CONST) {
+                               zval_opt_copy_ctor_no_imm(EX(return_value));
                        }
                } else if (Z_ISREF_P(retval_ptr)) {
                        ZVAL_DUP(EX(return_value), Z_REFVAL_P(retval_ptr));
@@ -2642,8 +2642,8 @@ static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
                                }
                        } else {
                                ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
-                               if (IS_CONST != IS_TMP_VAR && !Z_OPT_IMMUTABLE_P(EX(return_value))) {
-                                       zval_opt_copy_ctor(EX(return_value));
+                               if (IS_CONST != IS_TMP_VAR) {
+                                       zval_opt_copy_ctor_no_imm(EX(return_value));
                                }
                        }
                        break;
@@ -2724,9 +2724,7 @@ static int ZEND_FASTCALL  ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
        if (IS_CONST == IS_CONST) {
                /* Immutable arrays may be passed without copying ??? */
                /* some internal functions may try to modify them !!! */
-               if (!Z_OPT_IMMUTABLE_P(top)) {
-                       zval_opt_copy_ctor(top);
-               }
+               zval_opt_copy_ctor_no_imm(top);
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -3263,9 +3261,7 @@ static int ZEND_FASTCALL  ZEND_QM_ASSIGN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_
 
        ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
        if (!0) {
-               if (!Z_OPT_IMMUTABLE_P(EX_VAR(opline->result.var))) {
-                       zval_opt_copy_ctor(EX_VAR(opline->result.var));
-               }
+               zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var));
        }
 
        CHECK_EXCEPTION();
@@ -3286,9 +3282,7 @@ static int ZEND_FASTCALL  ZEND_QM_ASSIGN_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
        } else {
                ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
                if (!0) {
-                       if (!Z_OPT_IMMUTABLE_P(EX_VAR(opline->result.var))) {
-                               zval_opt_copy_ctor(EX_VAR(opline->result.var));
-                       }
+                       zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var));
                }
        }
 
@@ -7746,8 +7740,8 @@ static int ZEND_FASTCALL  ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        } else {
                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 && !Z_OPT_IMMUTABLE_P(EX(return_value))) {
-                               zval_opt_copy_ctor(EX(return_value));
+                       if (IS_TMP_VAR == IS_CONST) {
+                               zval_opt_copy_ctor_no_imm(EX(return_value));
                        }
                } else if (Z_ISREF_P(retval_ptr)) {
                        ZVAL_DUP(EX(return_value), Z_REFVAL_P(retval_ptr));
@@ -7783,8 +7777,8 @@ static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
                                }
                        } else {
                                ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
-                               if (IS_TMP_VAR != IS_TMP_VAR && !Z_OPT_IMMUTABLE_P(EX(return_value))) {
-                                       zval_opt_copy_ctor(EX(return_value));
+                               if (IS_TMP_VAR != IS_TMP_VAR) {
+                                       zval_opt_copy_ctor_no_imm(EX(return_value));
                                }
                        }
                        break;
@@ -7865,9 +7859,7 @@ static int ZEND_FASTCALL  ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
        if (IS_TMP_VAR == IS_CONST) {
                /* Immutable arrays may be passed without copying ??? */
                /* some internal functions may try to modify them !!! */
-               if (!Z_OPT_IMMUTABLE_P(top)) {
-                       zval_opt_copy_ctor(top);
-               }
+               zval_opt_copy_ctor_no_imm(top);
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -8434,9 +8426,7 @@ static int ZEND_FASTCALL  ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
 
        ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
        if (!1) {
-               if (!Z_OPT_IMMUTABLE_P(EX_VAR(opline->result.var))) {
-                       zval_opt_copy_ctor(EX_VAR(opline->result.var));
-               }
+               zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var));
        }
 
        CHECK_EXCEPTION();
@@ -8457,9 +8447,7 @@ static int ZEND_FASTCALL  ZEND_QM_ASSIGN_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
        } else {
                ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
                if (!1) {
-                       if (!Z_OPT_IMMUTABLE_P(EX_VAR(opline->result.var))) {
-                               zval_opt_copy_ctor(EX_VAR(opline->result.var));
-                       }
+                       zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var));
                }
        }
 
@@ -12843,8 +12831,8 @@ static int ZEND_FASTCALL  ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        } else {
                if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
-                       if (IS_VAR == IS_CONST && !Z_OPT_IMMUTABLE_P(EX(return_value))) {
-                               zval_opt_copy_ctor(EX(return_value));
+                       if (IS_VAR == IS_CONST) {
+                               zval_opt_copy_ctor_no_imm(EX(return_value));
                        }
                } else if (Z_ISREF_P(retval_ptr)) {
                        ZVAL_DUP(EX(return_value), Z_REFVAL_P(retval_ptr));
@@ -12880,8 +12868,8 @@ static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
                                }
                        } else {
                                ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
-                               if (IS_VAR != IS_TMP_VAR && !Z_OPT_IMMUTABLE_P(EX(return_value))) {
-                                       zval_opt_copy_ctor(EX(return_value));
+                               if (IS_VAR != IS_TMP_VAR) {
+                                       zval_opt_copy_ctor_no_imm(EX(return_value));
                                }
                        }
                        break;
@@ -12956,9 +12944,7 @@ static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_AR
                ZVAL_COPY_VALUE(top, Z_REFVAL_P(varptr));
                /* Immutable arrays may be passed without copying ??? */
                /* some internal functions may try to modify them !!! */
-               if (!Z_OPT_IMMUTABLE_P(top)) {
-                       zval_opt_copy_ctor(top);
-               }
+               zval_opt_copy_ctor_no_imm(top);
                zval_ptr_dtor_nogc(free_op1.var);
        } else {
                ZVAL_COPY_VALUE(top, varptr);
@@ -13082,9 +13068,7 @@ static int ZEND_FASTCALL  ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
                ZVAL_COPY_VALUE(top, Z_REFVAL_P(varptr));
                /* Immutable arrays may be passed without copying ??? */
                /* some internal functions may try to modify them !!! */
-               if (!Z_OPT_IMMUTABLE_P(top)) {
-                       zval_opt_copy_ctor(top);
-               }
+               zval_opt_copy_ctor_no_imm(top);
                zval_ptr_dtor_nogc(free_op1.var);
        } else {
                ZVAL_COPY_VALUE(top, varptr);
@@ -13780,9 +13764,7 @@ static int ZEND_FASTCALL  ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
 
        ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
        if (!0) {
-               if (!Z_OPT_IMMUTABLE_P(EX_VAR(opline->result.var))) {
-                       zval_opt_copy_ctor(EX_VAR(opline->result.var));
-               }
+               zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var));
        }
        zval_ptr_dtor_nogc(free_op1.var);
        CHECK_EXCEPTION();
@@ -13803,9 +13785,7 @@ static int ZEND_FASTCALL  ZEND_QM_ASSIGN_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
        } else {
                ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
                if (!0) {
-                       if (!Z_OPT_IMMUTABLE_P(EX_VAR(opline->result.var))) {
-                               zval_opt_copy_ctor(EX_VAR(opline->result.var));
-                       }
+                       zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var));
                }
        }
 
@@ -29955,8 +29935,8 @@ static int ZEND_FASTCALL  ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        } else {
                if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
-                       if (IS_CV == IS_CONST && !Z_OPT_IMMUTABLE_P(EX(return_value))) {
-                               zval_opt_copy_ctor(EX(return_value));
+                       if (IS_CV == IS_CONST) {
+                               zval_opt_copy_ctor_no_imm(EX(return_value));
                        }
                } else if (Z_ISREF_P(retval_ptr)) {
                        ZVAL_DUP(EX(return_value), Z_REFVAL_P(retval_ptr));
@@ -29992,8 +29972,8 @@ static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
                                }
                        } else {
                                ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
-                               if (IS_CV != IS_TMP_VAR && !Z_OPT_IMMUTABLE_P(EX(return_value))) {
-                                       zval_opt_copy_ctor(EX(return_value));
+                               if (IS_CV != IS_TMP_VAR) {
+                                       zval_opt_copy_ctor_no_imm(EX(return_value));
                                }
                        }
                        break;
@@ -30067,9 +30047,7 @@ static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARG
                ZVAL_COPY_VALUE(top, Z_REFVAL_P(varptr));
                /* Immutable arrays may be passed without copying ??? */
                /* some internal functions may try to modify them !!! */
-               if (!Z_OPT_IMMUTABLE_P(top)) {
-                       zval_opt_copy_ctor(top);
-               }
+               zval_opt_copy_ctor_no_imm(top);
 
        } else {
                ZVAL_COPY_VALUE(top, varptr);
@@ -30192,9 +30170,7 @@ static int ZEND_FASTCALL  ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
                ZVAL_COPY_VALUE(top, Z_REFVAL_P(varptr));
                /* Immutable arrays may be passed without copying ??? */
                /* some internal functions may try to modify them !!! */
-               if (!Z_OPT_IMMUTABLE_P(top)) {
-                       zval_opt_copy_ctor(top);
-               }
+               zval_opt_copy_ctor_no_imm(top);
 
        } else {
                ZVAL_COPY_VALUE(top, varptr);
@@ -30737,9 +30713,7 @@ static int ZEND_FASTCALL  ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
 
        ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
        if (!0) {
-               if (!Z_OPT_IMMUTABLE_P(EX_VAR(opline->result.var))) {
-                       zval_opt_copy_ctor(EX_VAR(opline->result.var));
-               }
+               zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var));
        }
 
        CHECK_EXCEPTION();
@@ -30760,9 +30734,7 @@ static int ZEND_FASTCALL  ZEND_QM_ASSIGN_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
        } else {
                ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
                if (!0) {
-                       if (!Z_OPT_IMMUTABLE_P(EX_VAR(opline->result.var))) {
-                               zval_opt_copy_ctor(EX_VAR(opline->result.var));
-                       }
+                       zval_opt_copy_ctor_no_imm(EX_VAR(opline->result.var));
                }
        }
 
index 1398d45b7e65804ff0173a51a2250e8c9b187e6d..b5caf090febdc7f51e3460b12a9c29f4ed636bbb 100644 (file)
@@ -1555,7 +1555,7 @@ PHP_FUNCTION(array_fill_keys)
    Create an array containing the range of integers or characters from low to high (inclusive) */
 PHP_FUNCTION(range)
 {
-       zval *zlow, *zhigh, *zstep = NULL;
+       zval *zlow, *zhigh, *zstep = NULL, tmp;
        int err = 0, is_step_double = 0;
        double step = 1.0;
 
@@ -1584,7 +1584,7 @@ PHP_FUNCTION(range)
        /* If the range is given as strings, generate an array of characters. */
        if (Z_TYPE_P(zlow) == IS_STRING && Z_TYPE_P(zhigh) == IS_STRING && Z_STRLEN_P(zlow) >= 1 && Z_STRLEN_P(zhigh) >= 1) {
                int type1, type2;
-               unsigned char *low, *high;
+               unsigned char low, high;
                long lstep = (long) step;
 
                type1 = is_numeric_string(Z_STRVAL_P(zlow), Z_STRLEN_P(zlow), NULL, NULL, 0);
@@ -1596,37 +1596,48 @@ PHP_FUNCTION(range)
                        goto long_str;
                }
 
-               low = (unsigned char *)Z_STRVAL_P(zlow);
-               high = (unsigned char *)Z_STRVAL_P(zhigh);
-
-               if (*low > *high) {             /* Negative Steps */
-                       unsigned char ch = *low;
+               low = (unsigned char *)Z_STRVAL_P(zlow)[0];
+               high = (unsigned char *)Z_STRVAL_P(zhigh)[0];
 
+               if (low > high) {               /* Negative Steps */
                        if (lstep <= 0) {
                                err = 1;
                                goto err;
                        }
-                       for (; ch >= *high; ch -= (unsigned int)lstep) {
-                               add_next_index_stringl(return_value, (const char *)&ch, 1);
-                               if (((signed int)ch - lstep) < 0) {
+                       for (; low >= high; low -= (unsigned int)lstep) {
+                               if (CG(one_char_string)[low]) {
+                                       ZVAL_INT_STR(&tmp, CG(one_char_string)[low]);
+                               } else {
+                                       ZVAL_STRINGL(&tmp, &low, 1);
+                               }
+                               zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
+                               if (((signed int)low - lstep) < 0) {
                                        break;
                                }
                        }
-               } else if (*high > *low) {      /* Positive Steps */
-                       unsigned char ch = *low;
-
+               } else if (high > low) {        /* Positive Steps */
                        if (lstep <= 0) {
                                err = 1;
                                goto err;
                        }
-                       for (; ch <= *high; ch += (unsigned int)lstep) {
-                               add_next_index_stringl(return_value, (const char *)&ch, 1);
-                               if (((signed int)ch + lstep) > 255) {
+                       for (; low <= high; low += (unsigned int)lstep) {
+                               if (CG(one_char_string)[low]) {
+                                       ZVAL_INT_STR(&tmp, CG(one_char_string)[low]);
+                               } else {
+                                       ZVAL_STRINGL(&tmp, &low, 1);
+                               }
+                               zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
+                               if (((signed int)low + lstep) > 255) {
                                        break;
                                }
                        }
                } else {
-                       add_next_index_stringl(return_value, (const char *)low, 1);
+                       if (CG(one_char_string)[low]) {
+                               ZVAL_INT_STR(&tmp, CG(one_char_string)[low]);
+                       } else {
+                               ZVAL_STRINGL(&tmp, (char*)&low, 1);
+                       }
+                       zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
                }
 
        } else if (Z_TYPE_P(zlow) == IS_DOUBLE || Z_TYPE_P(zhigh) == IS_DOUBLE || is_step_double) {
@@ -1637,6 +1648,7 @@ double_str:
                high = zval_get_double(zhigh);
                i = 0;
 
+               Z_TYPE_INFO(tmp) = IS_DOUBLE;
                if (low > high) {               /* Negative steps */
                        if (low - high < step || step <= 0) {
                                err = 1;
@@ -1644,7 +1656,8 @@ double_str:
                        }
 
                        for (value = low; value >= (high - DOUBLE_DRIFT_FIX); value = low - (++i * step)) {
-                               add_next_index_double(return_value, value);
+                               Z_DVAL(tmp) = value;
+                               zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
                        }
                } else if (high > low) {        /* Positive steps */
                        if (high - low < step || step <= 0) {
@@ -1653,10 +1666,12 @@ double_str:
                        }
 
                        for (value = low; value <= (high + DOUBLE_DRIFT_FIX); value = low + (++i * step)) {
-                               add_next_index_double(return_value, value);
+                               Z_DVAL(tmp) = value;
+                               zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
                        }
                } else {
-                       add_next_index_double(return_value, low);
+                       Z_DVAL(tmp) = low;
+                       zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
                }
        } else {
                double low, high;
@@ -1666,13 +1681,15 @@ long_str:
                high = zval_get_double(zhigh);
                lstep = (long) step;
 
+               Z_TYPE_INFO(tmp) = IS_LONG;
                if (low > high) {               /* Negative steps */
                        if (low - high < lstep || lstep <= 0) {
                                err = 1;
                                goto err;
                        }
                        for (; low >= high; low -= lstep) {
-                               add_next_index_long(return_value, (long)low);
+                               Z_LVAL(tmp) = (long)low;
+                               zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
                        }
                } else if (high > low) {        /* Positive steps */
                        if (high - low < lstep || lstep <= 0) {
@@ -1680,10 +1697,12 @@ long_str:
                                goto err;
                        }
                        for (; low <= high; low += lstep) {
-                               add_next_index_long(return_value, (long)low);
+                               Z_LVAL(tmp) = (long)low;
+                               zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
                        }
                } else {
-                       add_next_index_long(return_value, (long)low);
+                       Z_LVAL(tmp) = (long)low;
+                       zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
                }
        }
 err: