diff options
Diffstat (limited to 'ext/spl/spl_array.c')
-rw-r--r-- | ext/spl/spl_array.c | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 9270132ff7..541f7b67a7 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -101,33 +101,39 @@ static inline HashTable *spl_array_get_hash_table(spl_array_object* intern, int static void spl_array_rewind(spl_array_object *intern TSRMLS_DC); -static void spl_array_update_pos(spl_array_object* intern) /* {{{ */ +static void spl_array_update_pos(HashTable *ht, spl_array_object* intern) /* {{{ */ { - Bucket *pos = intern->pos; - if (pos != NULL) { - intern->pos_h = pos->h; + uint pos = intern->pos; + if (pos != INVALID_IDX) { + intern->pos_h = ht->arData[pos].h; } } /* }}} */ -static void spl_array_set_pos(spl_array_object* intern, HashPosition pos) /* {{{ */ +static void spl_array_set_pos(spl_array_object* intern, HashTable *ht, HashPosition pos) /* {{{ */ { intern->pos = pos; - spl_array_update_pos(intern); + spl_array_update_pos(ht, intern); } /* }}} */ SPL_API int spl_hash_verify_pos_ex(spl_array_object * intern, HashTable * ht TSRMLS_DC) /* {{{ */ { - Bucket *p; + uint idx; /* IS_CONSISTENT(ht);*/ /* HASH_PROTECT_RECURSION(ht);*/ - p = ht->arBuckets[intern->pos_h & ht->nTableMask]; - while (p != NULL) { - if (p == intern->pos) { + if (ht->flags & HASH_FLAG_PACKED) { + if (intern->pos_h == intern->pos && ht->arData[intern->pos_h].xData) { return SUCCESS; } - p = p->pNext; + } else { + idx = ht->arHash[intern->pos_h & ht->nTableMask].idx; + while (idx != INVALID_IDX) { + if (idx == intern->pos) { + return SUCCESS; + } + idx = ht->arData[idx].next; + } } /* HASH_UNPROTECT_RECURSION(ht); */ spl_array_rewind(intern TSRMLS_CC); @@ -667,7 +673,7 @@ static inline int spl_array_object_verify_pos_ex(spl_array_object *object, HashT return FAILURE; } - if (object->pos && (object->ar_flags & SPL_ARRAY_IS_REF) && spl_hash_verify_pos_ex(object, ht TSRMLS_CC) == FAILURE) { + if (object->pos != INVALID_IDX && (object->ar_flags & SPL_ARRAY_IS_REF) && spl_hash_verify_pos_ex(object, ht TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%sArray was modified outside object and internal position is no longer valid", msg_prefix); return FAILURE; } @@ -734,8 +740,10 @@ void spl_array_iterator_append(zval *object, zval *append_value TSRMLS_DC) /* {{ } spl_array_write_dimension(object, NULL, append_value TSRMLS_CC); - if (!intern->pos) { - spl_array_set_pos(intern, aht->pListTail); + if (intern->pos == INVALID_IDX) { + if (aht->nNumUsed && aht->arData[aht->nNumUsed-1].xData) { + spl_array_set_pos(intern, aht, aht->nNumUsed - 1); + } } } /* }}} */ @@ -932,7 +940,7 @@ static int spl_array_skip_protected(spl_array_object *intern, HashTable *aht TSR return FAILURE; } zend_hash_move_forward_ex(aht, &intern->pos); - spl_array_update_pos(intern); + spl_array_update_pos(aht, intern); } while (1); } return FAILURE; @@ -941,7 +949,7 @@ static int spl_array_skip_protected(spl_array_object *intern, HashTable *aht TSR static int spl_array_next_no_verify(spl_array_object *intern, HashTable *aht TSRMLS_DC) /* {{{ */ { zend_hash_move_forward_ex(aht, &intern->pos); - spl_array_update_pos(intern); + spl_array_update_pos(aht, intern); if (Z_TYPE_P(intern->array) == IS_OBJECT) { return spl_array_skip_protected(intern, aht TSRMLS_CC); } else { @@ -1064,7 +1072,7 @@ static void spl_array_rewind_ex(spl_array_object *intern, HashTable *aht TSRMLS_ { zend_hash_internal_pointer_reset_ex(aht, &intern->pos); - spl_array_update_pos(intern); + spl_array_update_pos(aht, intern); spl_array_skip_protected(intern, aht TSRMLS_CC); } /* }}} */ @@ -1381,10 +1389,10 @@ int static spl_array_object_count_elements_helper(spl_array_object *intern, long pos = intern->pos; *count = 0; spl_array_rewind(intern TSRMLS_CC); - while(intern->pos && spl_array_next(intern TSRMLS_CC) == SUCCESS) { + while(intern->pos != INVALID_IDX && spl_array_next(intern TSRMLS_CC) == SUCCESS) { (*count)++; } - spl_array_set_pos(intern, pos); + spl_array_set_pos(intern, aht, pos); return SUCCESS; } else { *count = zend_hash_num_elements(aht); |