Update Iterators: Call next at the correct point in time.

This commit is contained in:
Marcus Boerger 2003-11-07 10:47:47 +00:00
parent 77923b0eb1
commit 5112a4ae24
2 changed files with 20 additions and 8 deletions

View File

@ -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);
}

View File

@ -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);