mirror of
https://github.com/php/php-src.git
synced 2024-12-03 23:05:57 +08:00
More ZEND_HASH_FOREACH_* related changes
This commit is contained in:
parent
277f8f6391
commit
54d9ad53f4
151
Zend/zend_hash.h
151
Zend/zend_hash.h
@ -533,105 +533,84 @@ static inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht, HashPositio
|
||||
#define zend_hash_get_current_data_ptr(ht) \
|
||||
zend_hash_get_current_data_ptr_ex(ht, &(ht)->nInternalPointer)
|
||||
|
||||
#define ZEND_HASH_FOREACH_VAL(_ht, _val) do { \
|
||||
#define ZEND_HASH_FOREACH(_ht, indirect) do { \
|
||||
uint _idx; \
|
||||
Bucket *_p; \
|
||||
for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
|
||||
_p = (_ht)->arData + _idx; \
|
||||
if (Z_TYPE(_p->val) == IS_UNDEF) continue; \
|
||||
_val = &_p->val;
|
||||
|
||||
#define ZEND_HASH_FOREACH_VAL_IND(_ht, _val) do { \
|
||||
uint _idx; \
|
||||
Bucket *_p; \
|
||||
zval *_z; \
|
||||
for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
|
||||
_p = (_ht)->arData + _idx; \
|
||||
_z = &_p->val; \
|
||||
if (Z_TYPE_P(_z) == IS_INDIRECT) { \
|
||||
Bucket *_p = (_ht)->arData + _idx; \
|
||||
zval *_z = &_p->val; \
|
||||
if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \
|
||||
_z = Z_INDIRECT_P(_z); \
|
||||
} \
|
||||
if (Z_TYPE_P(_z) == IS_UNDEF) continue; \
|
||||
_val = _z;
|
||||
if (Z_TYPE_P(_z) == IS_UNDEF) continue;
|
||||
|
||||
#define ZEND_HASH_FOREACH_PTR(_ht, _ptr) do { \
|
||||
#define ZEND_HASH_REVERSE_FOREACH(_ht, indirect) do { \
|
||||
uint _idx; \
|
||||
Bucket *_p; \
|
||||
for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
|
||||
_p = (_ht)->arData + _idx; \
|
||||
if (Z_TYPE(_p->val) == IS_UNDEF) continue; \
|
||||
_ptr = Z_PTR(_p->val);
|
||||
|
||||
#define ZEND_HASH_FOREACH_KEY(_ht, _h, _key) do { \
|
||||
uint _idx; \
|
||||
Bucket *_p; \
|
||||
for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
|
||||
_p = (_ht)->arData + _idx; \
|
||||
if (Z_TYPE(_p->val) == IS_UNDEF) continue; \
|
||||
_h = _p->h; \
|
||||
_key = _p->key; \
|
||||
|
||||
#define ZEND_HASH_FOREACH_KEY_VAL(_ht, _h, _key, _val) do { \
|
||||
uint _idx; \
|
||||
Bucket *_p; \
|
||||
for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
|
||||
_p = (_ht)->arData + _idx; \
|
||||
if (Z_TYPE(_p->val) == IS_UNDEF) continue; \
|
||||
_h = _p->h; \
|
||||
_key = _p->key; \
|
||||
_val = &_p->val;
|
||||
|
||||
#define ZEND_HASH_FOREACH_KEY_VAL(_ht, _h, _key, _val) do { \
|
||||
uint _idx; \
|
||||
Bucket *_p; \
|
||||
for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
|
||||
_p = (_ht)->arData + _idx; \
|
||||
if (Z_TYPE(_p->val) == IS_UNDEF) continue; \
|
||||
_h = _p->h; \
|
||||
_key = _p->key; \
|
||||
_val = &_p->val;
|
||||
|
||||
#define ZEND_HASH_FOREACH_KEY_VAL_IND(_ht, _h, _key, _val) do { \
|
||||
uint _idx; \
|
||||
Bucket *_p; \
|
||||
zval *_z; \
|
||||
for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
|
||||
_p = (_ht)->arData + _idx; \
|
||||
_z = &_p->val; \
|
||||
if (Z_TYPE_P(_z) == IS_INDIRECT) { \
|
||||
_z = Z_INDIRECT_P(_z); \
|
||||
} \
|
||||
if (Z_TYPE_P(_z) == IS_UNDEF) continue; \
|
||||
_h = _p->h; \
|
||||
_key = _p->key; \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_FOREACH_KEY_PTR(_ht, _h, _key, _ptr) do { \
|
||||
uint _idx; \
|
||||
Bucket *_p; \
|
||||
for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
|
||||
_p = (_ht)->arData + _idx; \
|
||||
if (Z_TYPE(_p->val) == IS_UNDEF) continue; \
|
||||
_h = _p->h; \
|
||||
_key = _p->key; \
|
||||
_ptr = Z_PTR(_p->val);
|
||||
|
||||
|
||||
#define ZEND_HASH_REVERSE_FOREACH_KEY_VAL(_ht, _h, _key, _val) do { \
|
||||
uint _idx; \
|
||||
Bucket *_p; \
|
||||
for (_idx = (_ht)->nNumUsed; _idx > 0; _idx--) { \
|
||||
_p = (_ht)->arData + _idx - 1; \
|
||||
if (Z_TYPE(_p->val) == IS_UNDEF) continue; \
|
||||
_h = _p->h; \
|
||||
_key = _p->key; \
|
||||
_val = &_p->val;
|
||||
Bucket *_p = (_ht)->arData + _idx - 1; \
|
||||
zval *_z = &_p->val; \
|
||||
if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \
|
||||
_z = Z_INDIRECT_P(_z); \
|
||||
} \
|
||||
if (Z_TYPE_P(_z) == IS_UNDEF) continue;
|
||||
|
||||
#define ZEND_HASH_FOREACH_END() \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ZEND_HASH_FOREACH_VAL(ht, _val) \
|
||||
ZEND_HASH_FOREACH(ht, 0); \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_FOREACH_VAL_IND(ht, _val) \
|
||||
ZEND_HASH_FOREACH(ht, 1); \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_FOREACH_PTR(ht, _ptr) \
|
||||
ZEND_HASH_FOREACH(ht, 0); \
|
||||
_ptr = Z_PTR_P(_z);
|
||||
|
||||
#define ZEND_HASH_FOREACH_KEY(ht, _h, _key) \
|
||||
ZEND_HASH_FOREACH(ht, 0); \
|
||||
_h = _p->h; \
|
||||
_key = _p->key;
|
||||
|
||||
#define ZEND_HASH_FOREACH_KEY_VAL(ht, _h, _key, _val) \
|
||||
ZEND_HASH_FOREACH(ht, 0); \
|
||||
_h = _p->h; \
|
||||
_key = _p->key; \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_FOREACH_KEY_VAL_IND(ht, _h, _key, _val) \
|
||||
ZEND_HASH_FOREACH(ht, 1); \
|
||||
_h = _p->h; \
|
||||
_key = _p->key; \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_FOREACH_KEY_PTR(ht, _h, _key, _ptr) \
|
||||
ZEND_HASH_FOREACH(ht, 0); \
|
||||
_h = _p->h; \
|
||||
_key = _p->key; \
|
||||
_ptr = Z_PTR_P(_z);
|
||||
|
||||
#define ZEND_HASH_REVERSE_FOREACH_VAL(ht, _val) \
|
||||
ZEND_HASH_REVERSE_FOREACH(ht, 0); \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_REVERSE_FOREACH_VAL_IND(ht, _val) \
|
||||
ZEND_HASH_REVERSE_FOREACH(ht, 1); \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_REVERSE_FOREACH_KEY_VAL(ht, _h, _key, _val) \
|
||||
ZEND_HASH_REVERSE_FOREACH(ht, 0); \
|
||||
_h = _p->h; \
|
||||
_key = _p->key; \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_REVERSE_FOREACH_KEY_VAL_IND(ht, _h, _key, _val) \
|
||||
ZEND_HASH_REVERSE_FOREACH(ht, 1); \
|
||||
_h = _p->h; \
|
||||
_key = _p->key; \
|
||||
_val = _z;
|
||||
|
||||
#endif /* ZEND_HASH_H */
|
||||
|
||||
|
@ -3112,19 +3112,14 @@ ZEND_VM_C_LABEL(send_again):
|
||||
switch (Z_TYPE_P(args)) {
|
||||
case IS_ARRAY: {
|
||||
HashTable *ht = Z_ARRVAL_P(args);
|
||||
HashPosition pos;
|
||||
zval *arg;
|
||||
|
||||
ZEND_VM_STACK_GROW_IF_NEEDED(zend_hash_num_elements(ht));
|
||||
|
||||
for (zend_hash_internal_pointer_reset_ex(ht, &pos);
|
||||
(arg = zend_hash_get_current_data_ex(ht, &pos)) != NULL;
|
||||
zend_hash_move_forward_ex(ht, &pos), ++arg_num
|
||||
) {
|
||||
zend_string *name;
|
||||
zend_ulong index;
|
||||
|
||||
if (zend_hash_get_current_key_ex(ht, &name, &index, 0, &pos) == HASH_KEY_IS_STRING) {
|
||||
ZEND_VM_STACK_GROW_IF_NEEDED(zend_hash_num_elements(ht));
|
||||
|
||||
ZEND_HASH_FOREACH_KEY_VAL(ht, index, name, arg) {
|
||||
if (name) {
|
||||
zend_error(E_RECOVERABLE_ERROR, "Cannot unpack array with string keys");
|
||||
FREE_OP1();
|
||||
CHECK_EXCEPTION();
|
||||
@ -3142,7 +3137,9 @@ ZEND_VM_C_LABEL(send_again):
|
||||
|
||||
zend_vm_stack_push(arg TSRMLS_CC);
|
||||
EX(call)->num_additional_args++;
|
||||
}
|
||||
arg_num++;
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
break;
|
||||
}
|
||||
case IS_OBJECT: {
|
||||
|
@ -720,19 +720,14 @@ send_again:
|
||||
switch (Z_TYPE_P(args)) {
|
||||
case IS_ARRAY: {
|
||||
HashTable *ht = Z_ARRVAL_P(args);
|
||||
HashPosition pos;
|
||||
zval *arg;
|
||||
|
||||
ZEND_VM_STACK_GROW_IF_NEEDED(zend_hash_num_elements(ht));
|
||||
|
||||
for (zend_hash_internal_pointer_reset_ex(ht, &pos);
|
||||
(arg = zend_hash_get_current_data_ex(ht, &pos)) != NULL;
|
||||
zend_hash_move_forward_ex(ht, &pos), ++arg_num
|
||||
) {
|
||||
zend_string *name;
|
||||
zend_ulong index;
|
||||
|
||||
if (zend_hash_get_current_key_ex(ht, &name, &index, 0, &pos) == HASH_KEY_IS_STRING) {
|
||||
ZEND_VM_STACK_GROW_IF_NEEDED(zend_hash_num_elements(ht));
|
||||
|
||||
ZEND_HASH_FOREACH_KEY_VAL(ht, index, name, arg) {
|
||||
if (name) {
|
||||
zend_error(E_RECOVERABLE_ERROR, "Cannot unpack array with string keys");
|
||||
FREE_OP(free_op1);
|
||||
CHECK_EXCEPTION();
|
||||
@ -750,7 +745,9 @@ send_again:
|
||||
|
||||
zend_vm_stack_push(arg TSRMLS_CC);
|
||||
EX(call)->num_additional_args++;
|
||||
}
|
||||
arg_num++;
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
break;
|
||||
}
|
||||
case IS_OBJECT: {
|
||||
|
@ -1975,9 +1975,21 @@ static void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int off_the_end)
|
||||
/* Get the first or last value and copy it into the return value */
|
||||
if (off_the_end) {
|
||||
zend_hash_internal_pointer_end(Z_ARRVAL_P(stack));
|
||||
while (1) {
|
||||
val = zend_hash_get_current_data(Z_ARRVAL_P(stack));
|
||||
if (!val) {
|
||||
return;
|
||||
} else if (Z_TYPE_P(val) == IS_INDIRECT) {
|
||||
val = Z_INDIRECT_P(val);
|
||||
if (Z_TYPE_P(val) == IS_UNDEF) {
|
||||
zend_hash_move_backwards(Z_ARRVAL_P(stack));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
zend_hash_internal_pointer_reset(Z_ARRVAL_P(stack));
|
||||
}
|
||||
while (1) {
|
||||
val = zend_hash_get_current_data(Z_ARRVAL_P(stack));
|
||||
if (!val) {
|
||||
@ -1991,6 +2003,7 @@ static void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int off_the_end)
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
RETVAL_ZVAL_FAST(val);
|
||||
|
||||
/* Delete the first or last value */
|
||||
|
Loading…
Reference in New Issue
Block a user