From: twosee Date: Mon, 8 Jun 2020 10:45:01 +0000 (+0800) Subject: Add helper APIs for maybe-interned string creation X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=83a77015ad0dcd25d30342a08cbc8ec3de077305;p=php Add helper APIs for maybe-interned string creation Add ZVAL_CHAR/RETVAL_CHAR/RETURN_CHAR as a shortcut for using ZVAL_INTERNED_STRING and ZSTR_CHAR. Add zend_string_init_fast() as a helper for the empty string / one char interned string / zend_string_init() pattern. Also add corresponding ZVAL_STRINGL_FAST etc macros. Closes GH-5684. --- diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 9a34ab050d..944bef850d 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -636,6 +636,20 @@ END_EXTERN_C() ZVAL_PSTRINGL(z, "", 0); \ } while (0) +#define ZVAL_CHAR(z, c) do { \ + char _c = (c); \ + ZVAL_INTERNED_STR(z, ZSTR_CHAR((zend_uchar) _c)); \ + } while (0) + +#define ZVAL_STRINGL_FAST(z, s, l) do { \ + ZVAL_STR(z, zend_string_init_fast(s, l)); \ + } while (0) + +#define ZVAL_STRING_FAST(z, s) do { \ + const char *_s = (s); \ + ZVAL_STRINGL_FAST(z, _s, strlen(_s)); \ + } while (0) + #define ZVAL_ZVAL(z, zv, copy, dtor) do { \ zval *__z = (z); \ zval *__zv = (zv); \ @@ -654,46 +668,52 @@ END_EXTERN_C() } while (0) #define RETVAL_BOOL(b) ZVAL_BOOL(return_value, b) -#define RETVAL_NULL() ZVAL_NULL(return_value) -#define RETVAL_LONG(l) ZVAL_LONG(return_value, l) -#define RETVAL_DOUBLE(d) ZVAL_DOUBLE(return_value, d) -#define RETVAL_STR(s) ZVAL_STR(return_value, s) -#define RETVAL_INTERNED_STR(s) ZVAL_INTERNED_STR(return_value, s) -#define RETVAL_NEW_STR(s) ZVAL_NEW_STR(return_value, s) -#define RETVAL_STR_COPY(s) ZVAL_STR_COPY(return_value, s) -#define RETVAL_STRING(s) ZVAL_STRING(return_value, s) -#define RETVAL_STRINGL(s, l) ZVAL_STRINGL(return_value, s, l) -#define RETVAL_EMPTY_STRING() ZVAL_EMPTY_STRING(return_value) -#define RETVAL_RES(r) ZVAL_RES(return_value, r) -#define RETVAL_ARR(r) ZVAL_ARR(return_value, r) +#define RETVAL_NULL() ZVAL_NULL(return_value) +#define RETVAL_LONG(l) ZVAL_LONG(return_value, l) +#define RETVAL_DOUBLE(d) ZVAL_DOUBLE(return_value, d) +#define RETVAL_STR(s) ZVAL_STR(return_value, s) +#define RETVAL_INTERNED_STR(s) ZVAL_INTERNED_STR(return_value, s) +#define RETVAL_NEW_STR(s) ZVAL_NEW_STR(return_value, s) +#define RETVAL_STR_COPY(s) ZVAL_STR_COPY(return_value, s) +#define RETVAL_STRING(s) ZVAL_STRING(return_value, s) +#define RETVAL_STRINGL(s, l) ZVAL_STRINGL(return_value, s, l) +#define RETVAL_STRING_FAST(s) ZVAL_STRING_FAST(return_value, s) +#define RETVAL_STRINGL_FAST(s, l) ZVAL_STRINGL_FAST(return_value, s, l) +#define RETVAL_EMPTY_STRING() ZVAL_EMPTY_STRING(return_value) +#define RETVAL_CHAR(c) ZVAL_CHAR(return_value, c) +#define RETVAL_RES(r) ZVAL_RES(return_value, r) +#define RETVAL_ARR(r) ZVAL_ARR(return_value, r) #define RETVAL_EMPTY_ARRAY() ZVAL_EMPTY_ARRAY(return_value) -#define RETVAL_OBJ(r) ZVAL_OBJ(return_value, r) +#define RETVAL_OBJ(r) ZVAL_OBJ(return_value, r) #define RETVAL_COPY(zv) ZVAL_COPY(return_value, zv) #define RETVAL_COPY_VALUE(zv) ZVAL_COPY_VALUE(return_value, zv) #define RETVAL_ZVAL(zv, copy, dtor) ZVAL_ZVAL(return_value, zv, copy, dtor) -#define RETVAL_FALSE ZVAL_FALSE(return_value) -#define RETVAL_TRUE ZVAL_TRUE(return_value) +#define RETVAL_FALSE ZVAL_FALSE(return_value) +#define RETVAL_TRUE ZVAL_TRUE(return_value) -#define RETURN_BOOL(b) do { RETVAL_BOOL(b); return; } while (0) -#define RETURN_NULL() do { RETVAL_NULL(); return;} while (0) -#define RETURN_LONG(l) do { RETVAL_LONG(l); return; } while (0) -#define RETURN_DOUBLE(d) do { RETVAL_DOUBLE(d); return; } while (0) +#define RETURN_BOOL(b) do { RETVAL_BOOL(b); return; } while (0) +#define RETURN_NULL() do { RETVAL_NULL(); return;} while (0) +#define RETURN_LONG(l) do { RETVAL_LONG(l); return; } while (0) +#define RETURN_DOUBLE(d) do { RETVAL_DOUBLE(d); return; } while (0) #define RETURN_STR(s) do { RETVAL_STR(s); return; } while (0) #define RETURN_INTERNED_STR(s) do { RETVAL_INTERNED_STR(s); return; } while (0) #define RETURN_NEW_STR(s) do { RETVAL_NEW_STR(s); return; } while (0) #define RETURN_STR_COPY(s) do { RETVAL_STR_COPY(s); return; } while (0) #define RETURN_STRING(s) do { RETVAL_STRING(s); return; } while (0) #define RETURN_STRINGL(s, l) do { RETVAL_STRINGL(s, l); return; } while (0) +#define RETURN_STRING_FAST(s) do { RETVAL_STRING_FAST(s); return; } while (0) +#define RETURN_STRINGL_FAST(s, l) do { RETVAL_STRINGL_FAST(s, l); return; } while (0) #define RETURN_EMPTY_STRING() do { RETVAL_EMPTY_STRING(); return; } while (0) -#define RETURN_RES(r) do { RETVAL_RES(r); return; } while (0) -#define RETURN_ARR(r) do { RETVAL_ARR(r); return; } while (0) +#define RETURN_CHAR(c) do { RETVAL_CHAR(c); return; } while (0) +#define RETURN_RES(r) do { RETVAL_RES(r); return; } while (0) +#define RETURN_ARR(r) do { RETVAL_ARR(r); return; } while (0) #define RETURN_EMPTY_ARRAY() do { RETVAL_EMPTY_ARRAY(); return; } while (0) -#define RETURN_OBJ(r) do { RETVAL_OBJ(r); return; } while (0) +#define RETURN_OBJ(r) do { RETVAL_OBJ(r); return; } while (0) #define RETURN_COPY(zv) do { RETVAL_COPY(zv); return; } while (0) #define RETURN_COPY_VALUE(zv) do { RETVAL_COPY_VALUE(zv); return; } while (0) #define RETURN_ZVAL(zv, copy, dtor) do { RETVAL_ZVAL(zv, copy, dtor); return; } while (0) -#define RETURN_FALSE do { RETVAL_FALSE; return; } while (0) -#define RETURN_TRUE do { RETVAL_TRUE; return; } while (0) +#define RETURN_FALSE do { RETVAL_FALSE; return; } while (0) +#define RETURN_TRUE do { RETVAL_TRUE; return; } while (0) #define RETURN_THROWS() do { ZEND_ASSERT(EG(exception)); (void) return_value; return; } while (0) #define HASH_OF(p) (Z_TYPE_P(p)==IS_ARRAY ? Z_ARRVAL_P(p) : ((Z_TYPE_P(p)==IS_OBJECT ? Z_OBJ_HT_P(p)->get_properties(Z_OBJ_P(p)) : NULL))) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 2f2a2d41b5..a2c8b9f23e 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3525,7 +3525,7 @@ int zend_compile_func_chr(znode *result, zend_ast_list *args) /* {{{ */ zend_long c = Z_LVAL_P(zend_ast_get_zval(args->child[0])) & 0xff; result->op_type = IS_CONST; - ZVAL_INTERNED_STR(&result->u.constant, ZSTR_CHAR(c)); + ZVAL_CHAR(&result->u.constant, c); return SUCCESS; } else { return FAILURE; @@ -9383,7 +9383,7 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */ return; } c = (zend_uchar) Z_STRVAL_P(container)[offset]; - ZVAL_INTERNED_STR(&result, ZSTR_CHAR(c)); + ZVAL_CHAR(&result, c); } else if (Z_TYPE_P(container) <= IS_FALSE) { ZVAL_NULL(&result); } else { diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 6a56dfdb1e..3eb945cc57 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1584,7 +1584,7 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim, if (UNEXPECTED(RETURN_VALUE_USED(opline))) { /* Return the new character */ - ZVAL_INTERNED_STR(EX_VAR(opline->result.var), ZSTR_CHAR(c)); + ZVAL_CHAR(EX_VAR(opline->result.var), c); } } @@ -2332,7 +2332,7 @@ try_string_offset: ? (zend_long)Z_STRLEN_P(container) + offset : offset; c = (zend_uchar)Z_STRVAL_P(container)[real_offset]; - ZVAL_INTERNED_STR(result, ZSTR_CHAR(c)); + ZVAL_CHAR(result, c); } } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (ZEND_CONST_COND(dim_type == IS_CV, 1) && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index c8360fbf39..d07d228752 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -616,7 +616,7 @@ try_again: break; } case IS_TRUE: - ZVAL_INTERNED_STR(op, ZSTR_CHAR('1')); + ZVAL_CHAR(op, '1'); break; case IS_STRING: break; @@ -1449,7 +1449,7 @@ try_again: if (Z_STRLEN_P(op1) == 1) { zend_uchar not = (zend_uchar) ~*Z_STRVAL_P(op1); - ZVAL_INTERNED_STR(result, ZSTR_CHAR(not)); + ZVAL_CHAR(result, not); } else { ZVAL_NEW_STR(result, zend_string_alloc(Z_STRLEN_P(op1), 0)); for (i = 0; i < Z_STRLEN_P(op1); i++) { @@ -1497,7 +1497,7 @@ ZEND_API int ZEND_FASTCALL bitwise_or_function(zval *result, zval *op1, zval *op if (result==op1) { zval_ptr_dtor_str(result); } - ZVAL_INTERNED_STR(result, ZSTR_CHAR(or)); + ZVAL_CHAR(result, or); return SUCCESS; } longer = op1; @@ -1579,7 +1579,7 @@ ZEND_API int ZEND_FASTCALL bitwise_and_function(zval *result, zval *op1, zval *o if (result==op1) { zval_ptr_dtor_str(result); } - ZVAL_INTERNED_STR(result, ZSTR_CHAR(and)); + ZVAL_CHAR(result, and); return SUCCESS; } longer = op1; @@ -1661,7 +1661,7 @@ ZEND_API int ZEND_FASTCALL bitwise_xor_function(zval *result, zval *op1, zval *o if (result==op1) { zval_ptr_dtor_str(result); } - ZVAL_INTERNED_STR(result, ZSTR_CHAR(xor)); + ZVAL_CHAR(result, xor); return SUCCESS; } longer = op1; @@ -2244,7 +2244,7 @@ static void ZEND_FASTCALL increment_string(zval *str) /* {{{ */ if (Z_STRLEN_P(str) == 0) { zval_ptr_dtor_str(str); - ZVAL_INTERNED_STR(str, ZSTR_CHAR('1')); + ZVAL_CHAR(str, '1'); return; } diff --git a/Zend/zend_string.h b/Zend/zend_string.h index fa794278e5..eb5ab09a6e 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -167,6 +167,17 @@ static zend_always_inline zend_string *zend_string_init(const char *str, size_t return ret; } +static zend_always_inline zend_string *zend_string_init_fast(const char *str, size_t len) +{ + if (len > 1) { + return zend_string_init(str, len, 0); + } else if (len == 0) { + return zend_empty_string; + } else /* if (len == 1) */ { + return ZSTR_CHAR((zend_uchar) *str); + } +} + static zend_always_inline zend_string *zend_string_copy(zend_string *s) { if (!ZSTR_IS_INTERNED(s)) { diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index e54f1dd8d4..20e1b67834 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -504,7 +504,7 @@ again: ZVAL_BOOL(rv, *(uint8_t*)ptr); return; case ZEND_FFI_TYPE_CHAR: - ZVAL_INTERNED_STR(rv, ZSTR_CHAR(*(unsigned char*)ptr)); + ZVAL_CHAR(rv, *(char*)ptr); return; case ZEND_FFI_TYPE_ENUM: kind = type->enumeration.kind; @@ -1077,7 +1077,7 @@ again: ZVAL_BOOL(writeobj, *(uint8_t*)ptr); break; case ZEND_FFI_TYPE_CHAR: - ZVAL_INTERNED_STR(writeobj, ZSTR_CHAR(*(unsigned char*)ptr)); + ZVAL_CHAR(writeobj, *(char*)ptr); return SUCCESS; case ZEND_FFI_TYPE_ENUM: kind = ctype->enumeration.kind; diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 7526c42ae6..71b11019d0 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -1666,12 +1666,8 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_ROW_BUFFER * row_buffer, zval * } else if (Z_TYPE_P(current_field) == IS_STRING) { /* nothing to do here, as we want a string and ps_fetch_from_1_to_8_bytes() has given us one */ } - } else if (len == 0) { - ZVAL_EMPTY_STRING(current_field); - } else if (len == 1) { - ZVAL_INTERNED_STR(current_field, ZSTR_CHAR((zend_uchar)*(char *)p)); } else { - ZVAL_STRINGL(current_field, (char *)p, len); + ZVAL_STRINGL_FAST(current_field, (char *)p, len); } p += len; } diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c index 1bec01c5e2..ac363eaddc 100644 --- a/ext/opcache/Optimizer/sccp.c +++ b/ext/opcache/Optimizer/sccp.c @@ -801,7 +801,7 @@ static inline int ct_eval_func_call( } c = Z_LVAL_P(args[0]) & 0xff; - ZVAL_INTERNED_STR(result, ZSTR_CHAR(c)); + ZVAL_CHAR(result, c); return SUCCESS; } else if (zend_string_equals_literal(name, "count")) { if (Z_TYPE_P(args[0]) != IS_ARRAY) { diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 29f5d5f68e..7cc1e59322 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -638,7 +638,7 @@ try_string_offset: real_offset = (UNEXPECTED(offset < 0)) /* Handle negative offset */ ? (zend_long)Z_STRLEN_P(container) + offset : offset; c = (zend_uchar)Z_STRVAL_P(container)[real_offset]; - ZVAL_INTERNED_STR(result, ZSTR_CHAR(c)); + ZVAL_CHAR(result, c); } } @@ -685,7 +685,7 @@ try_string_offset: real_offset = (UNEXPECTED(offset < 0)) /* Handle negative offset */ ? (zend_long)Z_STRLEN_P(container) + offset : offset; c = (zend_uchar)Z_STRVAL_P(container)[real_offset]; - ZVAL_INTERNED_STR(result, ZSTR_CHAR(c)); + ZVAL_CHAR(result, c); } } @@ -952,7 +952,7 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim, if (result) { /* Return the new character */ - ZVAL_INTERNED_STR(result, ZSTR_CHAR(c)); + ZVAL_CHAR(result, c); } } diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 55f9d2db7b..2ed5d9d7dd 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -966,13 +966,7 @@ static void init_unmatched_empty_pair() { static zend_always_inline void populate_match_value_str( zval *val, const char *subject, PCRE2_SIZE start_offset, PCRE2_SIZE end_offset) { - if (start_offset == end_offset) { - ZVAL_EMPTY_STRING(val); - } else if (start_offset + 1 == end_offset) { - ZVAL_INTERNED_STR(val, ZSTR_CHAR((unsigned char) subject[start_offset])); - } else { - ZVAL_STRINGL(val, subject + start_offset, end_offset - start_offset); - } + ZVAL_STRINGL_FAST(val, subject + start_offset, end_offset - start_offset); } static inline void populate_match_value( diff --git a/ext/standard/array.c b/ext/standard/array.c index eda7ef589c..d942cfc184 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -2739,7 +2739,7 @@ PHP_FUNCTION(range) } ZEND_HASH_FILL_END(); } else { array_init(return_value); - ZVAL_INTERNED_STR(&tmp, ZSTR_CHAR(low)); + ZVAL_CHAR(&tmp, low); 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) { diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 883b5d45c5..056bc0ac37 100755 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -2041,6 +2041,21 @@ PHP_FUNCTION(highlight_string) } /* }}} */ +#define INI_RETVAL_STR(val) do { \ + /* copy to return value here, because alter might free it! */ \ + if (ZSTR_IS_INTERNED(val)) { \ + RETVAL_INTERNED_STR(val); \ + } else if (ZSTR_LEN(val) == 0) { \ + RETVAL_EMPTY_STRING(); \ + } else if (ZSTR_LEN(val) == 1) { \ + RETVAL_CHAR(ZSTR_VAL(val)[0]); \ + } else if (!(GC_FLAGS(val) & GC_PERSISTENT)) { \ + ZVAL_NEW_STR(return_value, zend_string_copy(val)); \ + } else { \ + ZVAL_NEW_STR(return_value, zend_string_init(ZSTR_VAL(val), ZSTR_LEN(val), 0)); \ + } \ +} while (0) + /* {{{ proto string|false ini_get(string varname) Get a configuration option */ PHP_FUNCTION(ini_get) @@ -2057,17 +2072,7 @@ PHP_FUNCTION(ini_get) RETURN_FALSE; } - if (ZSTR_IS_INTERNED(val)) { - RETVAL_INTERNED_STR(val); - } else if (ZSTR_LEN(val) == 0) { - RETVAL_EMPTY_STRING(); - } else if (ZSTR_LEN(val) == 1) { - RETVAL_INTERNED_STR(ZSTR_CHAR((zend_uchar)ZSTR_VAL(val)[0])); - } else if (!(GC_FLAGS(val) & GC_PERSISTENT)) { - ZVAL_NEW_STR(return_value, zend_string_copy(val)); - } else { - ZVAL_NEW_STR(return_value, zend_string_init(ZSTR_VAL(val), ZSTR_LEN(val), 0)); - } + INI_RETVAL_STR(val); } /* }}} */ @@ -2168,19 +2173,8 @@ PHP_FUNCTION(ini_set) val = zend_ini_get_value(varname); - /* copy to return here, because alter might free it! */ if (val) { - if (ZSTR_IS_INTERNED(val)) { - RETVAL_INTERNED_STR(val); - } else if (ZSTR_LEN(val) == 0) { - RETVAL_EMPTY_STRING(); - } else if (ZSTR_LEN(val) == 1) { - RETVAL_INTERNED_STR(ZSTR_CHAR((zend_uchar)ZSTR_VAL(val)[0])); - } else if (!(GC_FLAGS(val) & GC_PERSISTENT)) { - ZVAL_NEW_STR(return_value, zend_string_copy(val)); - } else { - ZVAL_NEW_STR(return_value, zend_string_init(ZSTR_VAL(val), ZSTR_LEN(val), 0)); - } + INI_RETVAL_STR(val); } else { RETVAL_FALSE; } @@ -2209,6 +2203,8 @@ PHP_FUNCTION(ini_set) } /* }}} */ +#undef INI_RETVAL_STR + /* {{{ proto void ini_restore(string varname) Restore the value of a configuration option specified by varname */ PHP_FUNCTION(ini_restore) diff --git a/ext/standard/string.c b/ext/standard/string.c index 635f5daf8f..8a8c889f08 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -1063,15 +1063,7 @@ PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp); } else { do { - size_t l = p2 - p1; - - if (l == 0) { - ZVAL_EMPTY_STRING(&tmp); - } else if (l == 1) { - ZVAL_INTERNED_STR(&tmp, ZSTR_CHAR((zend_uchar)(*p1))); - } else { - ZVAL_STRINGL(&tmp, p1, p2 - p1); - } + ZVAL_STRINGL_FAST(&tmp, p1, p2 - p1); zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp); p1 = p2 + ZSTR_LEN(delim); p2 = php_memnstr(p1, ZSTR_VAL(delim), ZSTR_LEN(delim), endp); @@ -2286,15 +2278,11 @@ truncate_len: l = (zend_long)ZSTR_LEN(str) - f; } - if (l == 0) { - RETURN_EMPTY_STRING(); - } else if (l == 1) { - RETURN_INTERNED_STR(ZSTR_CHAR((zend_uchar)(ZSTR_VAL(str)[f]))); - } else if (l == ZSTR_LEN(str)) { + if (l == ZSTR_LEN(str)) { RETURN_STR_COPY(str); + } else { + RETURN_STRINGL_FAST(ZSTR_VAL(str) + f, l); } - - RETURN_STRINGL(ZSTR_VAL(str) + f, l); } /* }}} */ @@ -2629,7 +2617,7 @@ PHP_FUNCTION(chr) ZEND_PARSE_PARAMETERS_END(); c &= 0xff; - ZVAL_INTERNED_STR(return_value, ZSTR_CHAR(c)); + RETURN_CHAR(c); } /* }}} */ @@ -3040,9 +3028,9 @@ static zend_string* php_char_to_str_ex(zend_string *str, char from, char *to, si static zend_string *php_str_to_str_ex(zend_string *haystack, const char *needle, size_t needle_len, const char *str, size_t str_len, zend_long *replace_count) { - zend_string *new_str; if (needle_len < ZSTR_LEN(haystack)) { + zend_string *new_str; const char *end; const char *p, *r; char *e; @@ -3103,16 +3091,8 @@ static zend_string *php_str_to_str_ex(zend_string *haystack, nothing_todo: return zend_string_copy(haystack); } else { - if (str_len == 0) { - new_str = ZSTR_EMPTY_ALLOC(); - } else if (str_len == 1) { - new_str = ZSTR_CHAR((zend_uchar)(*str)); - } else { - new_str = zend_string_init(str, str_len, 0); - } - (*replace_count)++; - return new_str; + return zend_string_init_fast(str, str_len); } } /* }}} */ @@ -4805,7 +4785,7 @@ PHP_FUNCTION(setlocale) /* C locale is represented as NULL. */ BG(ctype_string) = NULL; zend_string_release_ex(loc, 0); - RETURN_INTERNED_STR(ZSTR_CHAR('C')); + RETURN_CHAR('C'); } else if (len == ZSTR_LEN(loc) && !memcmp(ZSTR_VAL(loc), retval, len)) { BG(ctype_string) = zend_string_copy(loc); RETURN_STR(BG(ctype_string)); diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index c395f3cb5c..8766b3f2f1 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -943,14 +943,10 @@ use_double: YYCURSOR += 2; *p = YYCURSOR; - if (len == 0) { - ZVAL_EMPTY_STRING(rval); - } else if (len == 1) { - ZVAL_INTERNED_STR(rval, ZSTR_CHAR((zend_uchar)*str)); - } else if (as_key) { + if (as_key) { ZVAL_STR(rval, zend_string_init_interned(str, len, 0)); } else { - ZVAL_STRINGL(rval, str, len); + ZVAL_STRINGL_FAST(rval, str, len); } return 1; } diff --git a/ext/tokenizer/tokenizer.c b/ext/tokenizer/tokenizer.c index 901e609d2d..866977397d 100644 --- a/ext/tokenizer/tokenizer.c +++ b/ext/tokenizer/tokenizer.c @@ -226,7 +226,7 @@ PHP_METHOD(PhpToken, getTokenName) } if (Z_LVAL_P(id_zval) < 256) { - RETURN_INTERNED_STR(ZSTR_CHAR(Z_LVAL_P(id_zval))); + RETURN_CHAR(Z_LVAL_P(id_zval)); } else { const char *token_name = get_token_type_name(Z_LVAL_P(id_zval)); if (!token_name) { diff --git a/main/php_variables.c b/main/php_variables.c index 89b3dbf2d6..0a1eb0b4cd 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -41,14 +41,8 @@ PHPAPI void php_register_variable_safe(const char *var, const char *strval, size zval new_entry; assert(strval != NULL); - /* Prepare value */ - if (str_len == 0) { - ZVAL_EMPTY_STRING(&new_entry); - } else if (str_len == 1) { - ZVAL_INTERNED_STR(&new_entry, ZSTR_CHAR((zend_uchar)*strval)); - } else { - ZVAL_NEW_STR(&new_entry, zend_string_init(strval, str_len, 0)); - } + ZVAL_STRINGL_FAST(&new_entry, strval, str_len); + php_register_variable_ex(var, &new_entry, track_vars_array); } @@ -552,13 +546,7 @@ static zend_always_inline void import_environment_variable(HashTable *ht, char * name_len = p - env; p++; len = strlen(p); - if (len == 0) { - ZVAL_EMPTY_STRING(&val); - } else if (len == 1) { - ZVAL_INTERNED_STR(&val, ZSTR_CHAR((zend_uchar)*p)); - } else { - ZVAL_NEW_STR(&val, zend_string_init(p, len, 0)); - } + ZVAL_STRINGL_FAST(&val, p, len); if (ZEND_HANDLE_NUMERIC_STR(env, name_len, idx)) { zend_hash_index_update(ht, idx, &val); } else {