mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Update Iterators: Call next at the correct point in time.
This commit is contained in:
parent
77923b0eb1
commit
5112a4ae24
@ -3584,6 +3584,7 @@ int zend_fe_reset_handler(ZEND_OPCODE_HANDLER_ARGS)
|
||||
EX_T(EX(opline)->result.u.var).var.ptr_ptr = &EX_T(EX(opline)->result.u.var).var.ptr;
|
||||
|
||||
if (iter) {
|
||||
iter->index = 0;
|
||||
if (iter->funcs->rewind) {
|
||||
iter->funcs->rewind(iter TSRMLS_CC);
|
||||
}
|
||||
@ -3612,6 +3613,7 @@ int zend_fe_fetch_handler(ZEND_OPCODE_HANDLER_ARGS)
|
||||
ulong int_key;
|
||||
HashTable *fe_ht;
|
||||
zend_object_iterator *iter = NULL;
|
||||
int key_type;
|
||||
|
||||
PZVAL_LOCK(array);
|
||||
|
||||
@ -3629,16 +3631,29 @@ int zend_fe_fetch_handler(ZEND_OPCODE_HANDLER_ARGS)
|
||||
EX(opline) = op_array->opcodes+EX(opline)->op2.u.opline_num;
|
||||
return 0; /* CHECK_ME */
|
||||
}
|
||||
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 1, NULL);
|
||||
break;
|
||||
|
||||
case ZEND_ITER_OBJECT:
|
||||
/* !iter happens from exception */
|
||||
if (iter && iter->index++) {
|
||||
/* This could cause an endless loop if index becomes zero again.
|
||||
* In case that ever happens we need an additional flag. */
|
||||
iter->funcs->move_forward(iter TSRMLS_CC);
|
||||
}
|
||||
if (!iter || iter->funcs->has_more(iter TSRMLS_CC) == FAILURE) {
|
||||
/* reached end of iteration */
|
||||
EX(opline) = op_array->opcodes+EX(opline)->op2.u.opline_num;
|
||||
return 0; /* CHECK_ME */
|
||||
}
|
||||
iter->funcs->get_current_data(iter, &value TSRMLS_CC);
|
||||
if (iter->funcs->get_current_key) {
|
||||
key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
|
||||
} else {
|
||||
key_type = HASH_KEY_IS_LONG;
|
||||
int_key = iter->index;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3653,10 +3668,8 @@ int zend_fe_fetch_handler(ZEND_OPCODE_HANDLER_ARGS)
|
||||
|
||||
ALLOC_ZVAL(key);
|
||||
INIT_PZVAL(key);
|
||||
|
||||
switch (iter ?
|
||||
iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC) :
|
||||
zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 1, NULL)) {
|
||||
|
||||
switch (key_type) {
|
||||
case HASH_KEY_IS_STRING:
|
||||
key->value.str.val = str_key;
|
||||
key->value.str.len = str_key_len-1;
|
||||
@ -3670,9 +3683,7 @@ int zend_fe_fetch_handler(ZEND_OPCODE_HANDLER_ARGS)
|
||||
}
|
||||
zend_hash_index_update(result->value.ht, 1, &key, sizeof(zval *), NULL);
|
||||
|
||||
if (iter) {
|
||||
iter->funcs->move_forward(iter TSRMLS_CC);
|
||||
} else {
|
||||
if (!iter) {
|
||||
zend_hash_move_forward(fe_ht);
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ typedef struct _zend_object_iterator_funcs {
|
||||
/* fetch the item data for the current element */
|
||||
void (*get_current_data)(zend_object_iterator *iter, zval ***data TSRMLS_DC);
|
||||
|
||||
/* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) */
|
||||
/* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */
|
||||
int (*get_current_key)(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC);
|
||||
|
||||
/* step forwards to next element */
|
||||
@ -51,6 +51,7 @@ typedef struct _zend_object_iterator_funcs {
|
||||
struct _zend_object_iterator {
|
||||
void *data;
|
||||
zend_object_iterator_funcs *funcs;
|
||||
ulong index; /* private to fe_reset/fe_fetch opcodes */
|
||||
};
|
||||
|
||||
typedef zval *(*zend_object_new_iterator_t)(zend_class_entry *ce, zval *object TSRMLS_DC);
|
||||
|
Loading…
Reference in New Issue
Block a user