From: Dmitry Stogov Date: Thu, 18 Sep 2014 14:50:05 +0000 (+0400) Subject: Split big _zend_handle_numeric_str() into small always inlined function that makes... X-Git-Tag: POST_NATIVE_TLS_MERGE^2~230 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1e0e1b4a7337209c5b5a58edd46c4f22a4ab856c;p=php Split big _zend_handle_numeric_str() into small always inlined function that makes initial check and regular big function --- diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index e603069e4a..d541b3168f 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -1846,6 +1846,56 @@ ZEND_API zval *zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint return &res->val; } +ZEND_API int _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ulong *idx) +{ + register const char *tmp = key; + const char *end; + + if (*tmp > '9') { + return 0; + } else if (*tmp < '0') { + if (*tmp != '-') { + return 0; + } + tmp++; + if (*tmp > '9' || *tmp < '0') { + return 0; + } + } + + /* possibly a numeric index */ + end = key + length; + + if ((*end != '\0') /* not a null terminated string */ + || (*tmp == '0' && length > 1) /* numbers with leading zeros */ + || (end - tmp > MAX_LENGTH_OF_LONG - 1) /* number too long */ + || (SIZEOF_ZEND_LONG == 4 && + end - tmp == MAX_LENGTH_OF_LONG - 1 && + *tmp > '2')) { /* overflow */ + return 0; + } + *idx = (*tmp - '0'); + while (1) { + ++tmp; + if (tmp == end) { + if (*key == '-') { + if (*idx-1 > ZEND_LONG_MAX) { /* overflow */ + return 0; + } + *idx = 0 - *idx; + } else if (*idx > ZEND_LONG_MAX) { /* overflow */ + return 0; + } + return 1; + } + if (*tmp <= '9' && *tmp >= '0') { + *idx = (*idx * 10) + (*tmp - '0'); + } else { + return 0; + } + } +} + /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 68a1811a55..5c27873aa1 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -229,10 +229,11 @@ END_EXTERN_C() #define ZEND_INIT_SYMTABLE_EX(ht, n, persistent) \ zend_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent) -static inline int _zend_handle_numeric_str(const char *key, size_t length, zend_ulong *idx) +ZEND_API int _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ulong *idx); + +static zend_always_inline int _zend_handle_numeric_str(const char *key, size_t length, zend_ulong *idx) { register const char *tmp = key; - const char *end; if (*tmp > '9') { return 0; @@ -245,45 +246,14 @@ static inline int _zend_handle_numeric_str(const char *key, size_t length, zend_ return 0; } } - - /* possibly a numeric index */ - end = key + length; - - if ((*end != '\0') /* not a null terminated string */ - || (*tmp == '0' && length > 1) /* numbers with leading zeros */ - || (end - tmp > MAX_LENGTH_OF_LONG - 1) /* number too long */ - || (SIZEOF_ZEND_LONG == 4 && - end - tmp == MAX_LENGTH_OF_LONG - 1 && - *tmp > '2')) { /* overflow */ - return 0; - } - *idx = (*tmp - '0'); - while (1) { - ++tmp; - if (tmp == end) { - if (*key == '-') { - if (*idx-1 > ZEND_LONG_MAX) { /* overflow */ - return 0; - } - *idx = 0 - *idx; - } else if (*idx > ZEND_LONG_MAX) { /* overflow */ - return 0; - } - return 1; - } - if (*tmp <= '9' && *tmp >= '0') { - *idx = (*idx * 10) + (*tmp - '0'); - } else { - return 0; - } - } + return _zend_handle_numeric_str_ex(key, length, idx); } #define ZEND_HANDLE_NUMERIC_STR(key, length, idx) \ _zend_handle_numeric_str(key, length, &idx) #define ZEND_HANDLE_NUMERIC(key, idx) \ - _zend_handle_numeric_str((key)->val, (key)->len, &idx) + ZEND_HANDLE_NUMERIC_STR((key)->val, (key)->len, idx) static zend_always_inline zval *zend_hash_find_ind(const HashTable *ht, zend_string *key)