mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
move HANDLE_NUMERIC() from the hash table implementation upstream to the
places that actually need to use it.
This commit is contained in:
parent
b94bd055ee
commit
ae9106521a
4 changed files with 100 additions and 87 deletions
|
@ -727,6 +727,7 @@ static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, znode *op
|
||||||
zval **retval;
|
zval **retval;
|
||||||
char *offset_key;
|
char *offset_key;
|
||||||
int offset_key_length;
|
int offset_key_length;
|
||||||
|
long index;
|
||||||
|
|
||||||
switch (dim->type) {
|
switch (dim->type) {
|
||||||
case IS_NULL:
|
case IS_NULL:
|
||||||
|
@ -734,9 +735,13 @@ static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, znode *op
|
||||||
offset_key_length = 0;
|
offset_key_length = 0;
|
||||||
goto fetch_string_dim;
|
goto fetch_string_dim;
|
||||||
case IS_STRING:
|
case IS_STRING:
|
||||||
|
if (zend_is_numeric_key(dim, &index)) {
|
||||||
|
goto fetch_int_dim;
|
||||||
|
}
|
||||||
|
|
||||||
offset_key = dim->value.str.val;
|
offset_key = dim->value.str.val;
|
||||||
offset_key_length = dim->value.str.len;
|
offset_key_length = dim->value.str.len;
|
||||||
|
|
||||||
fetch_string_dim:
|
fetch_string_dim:
|
||||||
if (zend_hash_find(ht, offset_key, offset_key_length+1, (void **) &retval) == FAILURE) {
|
if (zend_hash_find(ht, offset_key, offset_key_length+1, (void **) &retval) == FAILURE) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -762,33 +767,31 @@ fetch_string_dim:
|
||||||
case IS_DOUBLE:
|
case IS_DOUBLE:
|
||||||
case IS_RESOURCE:
|
case IS_RESOURCE:
|
||||||
case IS_BOOL:
|
case IS_BOOL:
|
||||||
case IS_LONG: {
|
case IS_LONG:
|
||||||
long index;
|
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);
|
||||||
|
|
||||||
if (dim->type == IS_DOUBLE) {
|
new_zval->refcount++;
|
||||||
index = (long)dim->value.dval;
|
zend_hash_index_update(ht, index, &new_zval, sizeof(zval *), (void **) &retval);
|
||||||
} 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;
|
break;
|
||||||
|
@ -3286,9 +3289,16 @@ inline int zend_init_add_array_helper(ZEND_OPCODE_HANDLER_ARGS)
|
||||||
case IS_BOOL:
|
case IS_BOOL:
|
||||||
zend_hash_index_update(array_ptr->value.ht, offset->value.lval, &expr_ptr, sizeof(zval *), NULL);
|
zend_hash_index_update(array_ptr->value.ht, offset->value.lval, &expr_ptr, sizeof(zval *), NULL);
|
||||||
break;
|
break;
|
||||||
case IS_STRING:
|
case IS_STRING: {
|
||||||
zend_hash_update(array_ptr->value.ht, offset->value.str.val, offset->value.str.len+1, &expr_ptr, sizeof(zval *), NULL);
|
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);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case IS_NULL:
|
case IS_NULL:
|
||||||
zend_hash_update(array_ptr->value.ht, "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
|
zend_hash_update(array_ptr->value.ht, "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
|
||||||
break;
|
break;
|
||||||
|
@ -3508,6 +3518,7 @@ int zend_unset_dim_obj_handler(ZEND_OPCODE_HANDLER_ARGS)
|
||||||
{
|
{
|
||||||
zval **container = get_obj_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
|
zval **container = get_obj_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
|
||||||
zval *offset = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
|
zval *offset = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
|
||||||
|
long index;
|
||||||
|
|
||||||
if (container) {
|
if (container) {
|
||||||
HashTable *ht;
|
HashTable *ht;
|
||||||
|
@ -3526,20 +3537,20 @@ int zend_unset_dim_obj_handler(ZEND_OPCODE_HANDLER_ARGS)
|
||||||
case IS_RESOURCE:
|
case IS_RESOURCE:
|
||||||
case IS_BOOL:
|
case IS_BOOL:
|
||||||
case IS_LONG:
|
case IS_LONG:
|
||||||
{
|
if (offset->type == IS_DOUBLE) {
|
||||||
long index;
|
index = (long) offset->value.lval;
|
||||||
|
} else {
|
||||||
if (offset->type == IS_DOUBLE) {
|
index = offset->value.lval;
|
||||||
index = (long) offset->value.lval;
|
|
||||||
} else {
|
|
||||||
index = offset->value.lval;
|
|
||||||
}
|
|
||||||
|
|
||||||
zend_hash_index_del(ht, index);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zend_hash_index_del(ht, index);
|
||||||
|
break;
|
||||||
case IS_STRING:
|
case IS_STRING:
|
||||||
zend_hash_del(ht, offset->value.str.val, offset->value.str.len+1);
|
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);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case IS_NULL:
|
case IS_NULL:
|
||||||
zend_hash_del(ht, "", sizeof(""));
|
zend_hash_del(ht, "", sizeof(""));
|
||||||
|
@ -3730,6 +3741,7 @@ int zend_isset_isempty_dim_obj_handler(ZEND_OPCODE_HANDLER_ARGS)
|
||||||
zval *offset = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
|
zval *offset = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
|
||||||
zval **value = NULL;
|
zval **value = NULL;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
long index;
|
||||||
|
|
||||||
if (container) {
|
if (container) {
|
||||||
if ((*container)->type == IS_ARRAY) {
|
if ((*container)->type == IS_ARRAY) {
|
||||||
|
@ -3743,21 +3755,21 @@ int zend_isset_isempty_dim_obj_handler(ZEND_OPCODE_HANDLER_ARGS)
|
||||||
case IS_RESOURCE:
|
case IS_RESOURCE:
|
||||||
case IS_BOOL:
|
case IS_BOOL:
|
||||||
case IS_LONG:
|
case IS_LONG:
|
||||||
{
|
if (offset->type == IS_DOUBLE) {
|
||||||
long index;
|
index = (long) offset->value.lval;
|
||||||
|
} else {
|
||||||
if (offset->type == IS_DOUBLE) {
|
index = offset->value.lval;
|
||||||
index = (long) offset->value.lval;
|
}
|
||||||
} else {
|
if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
|
||||||
index = offset->value.lval;
|
isset = 1;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case IS_STRING:
|
||||||
|
if (zend_is_numeric_key(offset, &index)) {
|
||||||
if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
|
if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
|
||||||
isset = 1;
|
isset = 1;
|
||||||
}
|
}
|
||||||
break;
|
} else if (zend_hash_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
|
||||||
}
|
|
||||||
case IS_STRING:
|
|
||||||
if (zend_hash_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
|
|
||||||
isset = 1;
|
isset = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -21,32 +21,6 @@
|
||||||
|
|
||||||
#include "zend.h"
|
#include "zend.h"
|
||||||
|
|
||||||
#define HANDLE_NUMERIC(key, length, func) { \
|
|
||||||
register char *tmp=key; \
|
|
||||||
\
|
|
||||||
if ((*tmp>='0' && *tmp<='9')) do { /* possibly a numeric index */ \
|
|
||||||
char *end=tmp+length-1; \
|
|
||||||
ulong idx; \
|
|
||||||
\
|
|
||||||
if (*tmp++=='0' && length>2) { /* don't accept numbers with leading zeros */ \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
while (tmp<end) { \
|
|
||||||
if (!(*tmp>='0' && *tmp<='9')) { \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
tmp++; \
|
|
||||||
} \
|
|
||||||
if (tmp==end && *tmp=='\0') { /* a numeric index */ \
|
|
||||||
idx = strtol(key, NULL, 10); \
|
|
||||||
if (idx!=LONG_MAX) { \
|
|
||||||
return func; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} while (0); \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define CONNECT_TO_BUCKET_DLLIST(element, list_head) \
|
#define CONNECT_TO_BUCKET_DLLIST(element, list_head) \
|
||||||
(element)->pNext = (list_head); \
|
(element)->pNext = (list_head); \
|
||||||
(element)->pLast = NULL; \
|
(element)->pLast = NULL; \
|
||||||
|
@ -224,8 +198,6 @@ ZEND_API int zend_hash_add_or_update(HashTable *ht, char *arKey, uint nKeyLength
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_update_or_next_insert(ht, idx, pData, nDataSize, pDest, flag));
|
|
||||||
|
|
||||||
h = zend_inline_hash_func(arKey, nKeyLength);
|
h = zend_inline_hash_func(arKey, nKeyLength);
|
||||||
nIndex = h & ht->nTableMask;
|
nIndex = h & ht->nTableMask;
|
||||||
|
|
||||||
|
@ -474,7 +446,6 @@ ZEND_API int zend_hash_del_key_or_index(HashTable *ht, char *arKey, uint nKeyLen
|
||||||
IS_CONSISTENT(ht);
|
IS_CONSISTENT(ht);
|
||||||
|
|
||||||
if (flag == HASH_DEL_KEY) {
|
if (flag == HASH_DEL_KEY) {
|
||||||
HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_del_key_or_index(ht, arKey, nKeyLength, idx, HASH_DEL_INDEX));
|
|
||||||
h = zend_inline_hash_func(arKey, nKeyLength);
|
h = zend_inline_hash_func(arKey, nKeyLength);
|
||||||
}
|
}
|
||||||
nIndex = h & ht->nTableMask;
|
nIndex = h & ht->nTableMask;
|
||||||
|
@ -866,8 +837,6 @@ ZEND_API int zend_hash_find(HashTable *ht, char *arKey, uint nKeyLength, void **
|
||||||
|
|
||||||
IS_CONSISTENT(ht);
|
IS_CONSISTENT(ht);
|
||||||
|
|
||||||
HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_find(ht, idx, pData));
|
|
||||||
|
|
||||||
h = zend_inline_hash_func(arKey, nKeyLength);
|
h = zend_inline_hash_func(arKey, nKeyLength);
|
||||||
nIndex = h & ht->nTableMask;
|
nIndex = h & ht->nTableMask;
|
||||||
|
|
||||||
|
@ -920,8 +889,6 @@ ZEND_API int zend_hash_exists(HashTable *ht, char *arKey, uint nKeyLength)
|
||||||
|
|
||||||
IS_CONSISTENT(ht);
|
IS_CONSISTENT(ht);
|
||||||
|
|
||||||
HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_exists(ht, idx));
|
|
||||||
|
|
||||||
h = zend_inline_hash_func(arKey, nKeyLength);
|
h = zend_inline_hash_func(arKey, nKeyLength);
|
||||||
nIndex = h & ht->nTableMask;
|
nIndex = h & ht->nTableMask;
|
||||||
|
|
||||||
|
@ -949,8 +916,6 @@ ZEND_API int zend_hash_quick_exists(HashTable *ht, char *arKey, uint nKeyLength,
|
||||||
|
|
||||||
IS_CONSISTENT(ht);
|
IS_CONSISTENT(ht);
|
||||||
|
|
||||||
HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_exists(ht, idx));
|
|
||||||
|
|
||||||
nIndex = h & ht->nTableMask;
|
nIndex = h & ht->nTableMask;
|
||||||
|
|
||||||
p = ht->arBuckets[nIndex];
|
p = ht->arBuckets[nIndex];
|
||||||
|
|
|
@ -33,6 +33,41 @@
|
||||||
#include "ext/bcmath/number.h"
|
#include "ext/bcmath/number.h"
|
||||||
#endif
|
#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)
|
ZEND_API int zend_atoi(const char *str, int str_len)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
|
@ -60,6 +60,7 @@ 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 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 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)
|
static inline zend_bool is_numeric_string(char *str, int length, long *lval, double *dval, zend_bool allow_errors)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue