diff options
-rw-r--r-- | Zend/zend_execute.c | 77 | ||||
-rw-r--r-- | Zend/zend_hash.c | 32 | ||||
-rw-r--r-- | Zend/zend_hash.h | 50 | ||||
-rw-r--r-- | Zend/zend_operators.c | 35 | ||||
-rw-r--r-- | Zend/zend_operators.h | 1 |
5 files changed, 112 insertions, 83 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 53d506f9bd..204d69d4a3 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -666,7 +666,6 @@ static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, znode *op zval **retval; char *offset_key; int offset_key_length; - long index; switch (dim->type) { case IS_NULL: @@ -674,15 +673,12 @@ static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, znode *op offset_key_length = 0; goto fetch_string_dim; case IS_STRING: - if (zend_is_numeric_key(dim, &index)) { - goto fetch_int_dim; - } offset_key = dim->value.str.val; offset_key_length = dim->value.str.len; fetch_string_dim: - if (zend_hash_find(ht, offset_key, offset_key_length+1, (void **) &retval) == FAILURE) { + if (zend_symtable_find(ht, offset_key, offset_key_length+1, (void **) &retval) == FAILURE) { switch (type) { case BP_VAR_R: zend_error(E_NOTICE,"Undefined index: %s", offset_key); @@ -706,31 +702,33 @@ fetch_string_dim: case IS_DOUBLE: case IS_RESOURCE: case IS_BOOL: - case IS_LONG: - if (dim->type == IS_DOUBLE) { - index = (long)dim->value.dval; - } else { - index = dim->value.lval; - } -fetch_int_dim: - if (zend_hash_index_find(ht, index, (void **) &retval) == FAILURE) { - switch (type) { - case BP_VAR_R: - zend_error(E_NOTICE,"Undefined offset: %d", index); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval_ptr); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined offset: %d", index); - /* break missing intentionally */ - case BP_VAR_W: { - zval *new_zval = &EG(uninitialized_zval); + case IS_LONG: { + long index; - new_zval->refcount++; - zend_hash_index_update(ht, index, &new_zval, sizeof(zval *), (void **) &retval); + if (dim->type == IS_DOUBLE) { + index = (long)dim->value.dval; + } else { + index = dim->value.lval; + } + if (zend_hash_index_find(ht, index, (void **) &retval) == FAILURE) { + switch (type) { + case BP_VAR_R: + zend_error(E_NOTICE,"Undefined offset: %d", index); + /* break missing intentionally */ + case BP_VAR_IS: + retval = &EG(uninitialized_zval_ptr); + break; + case BP_VAR_RW: + zend_error(E_NOTICE,"Undefined offset: %d", index); + /* break missing intentionally */ + case BP_VAR_W: { + zval *new_zval = &EG(uninitialized_zval); + + new_zval->refcount++; + zend_hash_index_update(ht, index, &new_zval, sizeof(zval *), (void **) &retval); + } + break; } - break; } } break; @@ -3309,16 +3307,9 @@ inline int zend_init_add_array_helper(ZEND_OPCODE_HANDLER_ARGS) case IS_BOOL: zend_hash_index_update(array_ptr->value.ht, offset->value.lval, &expr_ptr, sizeof(zval *), NULL); break; - case IS_STRING: { - long idx; - - if (zend_is_numeric_key(offset, &idx)) { - zend_hash_index_update(array_ptr->value.ht, idx, &expr_ptr, sizeof(zval *), NULL); - } else { - zend_hash_update(array_ptr->value.ht, offset->value.str.val, offset->value.str.len+1, &expr_ptr, sizeof(zval *), NULL); - } + case IS_STRING: + zend_symtable_update(array_ptr->value.ht, offset->value.str.val, offset->value.str.len+1, &expr_ptr, sizeof(zval *), NULL); break; - } case IS_NULL: zend_hash_update(array_ptr->value.ht, "", sizeof(""), &expr_ptr, sizeof(zval *), NULL); break; @@ -3559,11 +3550,7 @@ int zend_unset_dim_obj_handler(ZEND_OPCODE_HANDLER_ARGS) zend_hash_index_del(ht, index); break; case IS_STRING: - if (zend_is_numeric_key(offset, &index)) { - zend_hash_index_del(ht, index); - } else { - zend_hash_del(ht, offset->value.str.val, offset->value.str.len+1); - } + zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1); break; case IS_NULL: zend_hash_del(ht, "", sizeof("")); @@ -3778,11 +3765,7 @@ int zend_isset_isempty_dim_obj_handler(ZEND_OPCODE_HANDLER_ARGS) } break; case IS_STRING: - if (zend_is_numeric_key(offset, &index)) { - if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) { - isset = 1; - } - } else if (zend_hash_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) { + if (zend_symtable_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) { isset = 1; } break; diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 08ca21ad31..1ba0b4b3ec 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -130,6 +130,38 @@ ZEND_API ulong zend_hash_func(char *arKey, uint nKeyLength) } +ZEND_API zend_bool zend_is_numeric_key(char *arKey, uint nKeyLength, long *val) +{ + char *tmp = arKey; + + if ((*tmp>='0' && *tmp<='9')) { /* possibly a numeric index */ + char *end=tmp+nKeyLength-1; + ulong idx; + + if (*tmp++=='0' && nKeyLength>2) { /* don't accept numbers with leading zeros */ + return 0; + } + + while (tmp<end) { + if (!(*tmp>='0' && *tmp<='9')) { + break; + } + tmp++; + } + + if (tmp==end && *tmp=='\0') { /* a numeric index */ + idx = strtol(arKey, NULL, 10); + if (idx!=LONG_MAX) { + *val = idx; + return 1; + } + } + } + + return 0; +} + + ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC) { uint i = 3; diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 976ec72dc5..20d46abdc4 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -89,6 +89,8 @@ typedef Bucket* HashPosition; BEGIN_EXTERN_C() +ZEND_API zend_bool zend_is_numeric_key(char *arKey, uint nKeyLength, long *val); + /* startup/shutdown */ ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC); ZEND_API int _zend_hash_init_ex(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC); @@ -163,6 +165,7 @@ ZEND_API int zend_hash_quick_exists(HashTable *ht, char *arKey, uint nKeyLength, ZEND_API int zend_hash_index_exists(HashTable *ht, ulong h); ZEND_API ulong zend_hash_next_free_element(HashTable *ht); + /* traversing */ #define zend_hash_has_more_elements_ex(ht, pos) \ (zend_hash_get_current_key_type_ex(ht, pos) == HASH_KEY_NON_EXISTANT ? FAILURE : SUCCESS) @@ -283,6 +286,53 @@ END_EXTERN_C() zend_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent) +static inline int zend_symtable_update(HashTable *ht, char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest) \ +{ + int idx; + + if (zend_is_numeric_key(arKey, nKeyLength, &idx)) { + return zend_hash_index_update(ht, idx, pData, nDataSize, pDest); + } else { + return zend_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest); + } +} + + +static inline int zend_symtable_del(HashTable *ht, char *arKey, uint nKeyLength) +{ + int idx; + + if (zend_is_numeric_key(arKey, nKeyLength, &idx)) { + return zend_hash_index_del(ht, idx); + } else { + return zend_hash_del(ht, arKey, nKeyLength); + } +} + + +static inline int zend_symtable_find(HashTable *ht, char *arKey, uint nKeyLength, void **pData) +{ + int idx; + + if (zend_is_numeric_key(arKey, nKeyLength, &idx)) { + return zend_hash_index_find(ht, idx, pData); + } else { + return zend_hash_find(ht, arKey, nKeyLength, pData); + } +} + + +static inline int zend_symtable_exists(HashTable *ht, char *arKey, uint nKeyLength) +{ + int idx; + + if (zend_is_numeric_key(arKey, nKeyLength, &idx)) { + return zend_hash_index_exists(ht, idx); + } else { + return zend_hash_exists(ht, arKey, nKeyLength); + } +} + #endif /* ZEND_HASH_H */ /* diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index ed63fa47c1..9f7bf6209b 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -33,41 +33,6 @@ #include "ext/bcmath/number.h" #endif -ZEND_API zend_bool zend_is_numeric_key(zval *zvalue, long *val) -{ - char *tmp; - long length; - - tmp = zvalue->value.str.val; - length = zvalue->value.str.len; - - if ((*tmp>='0' && *tmp<='9')) { /* possibly a numeric index */ - char *end=tmp+length; - ulong idx; - - if (*tmp++=='0' && length>2) { /* don't accept numbers with leading zeros */ - return 0; - } - - while (tmp<end) { - if (!(*tmp>='0' && *tmp<='9')) { - break; - } - tmp++; - } - - if (tmp==end && *tmp=='\0') { /* a numeric index */ - idx = strtol(zvalue->value.str.val, NULL, 10); - if (idx!=LONG_MAX) { - *val = idx; - return 1; - } - } - } - - return 0; -} - ZEND_API int zend_atoi(const char *str, int str_len) { int retval; diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index fefc8652dd..045490dd8d 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -60,7 +60,6 @@ ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); ZEND_API zend_bool instanceof_function(zend_class_entry *instance_ce, zend_class_entry *ce TSRMLS_DC); -ZEND_API zend_bool zend_is_numeric_key(zval *, long *); static inline zend_bool is_numeric_string(char *str, int length, long *lval, double *dval, zend_bool allow_errors) { |