From 4638f7b91407c48710007af82a68da0007c820f2 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 28 Jan 2015 07:43:28 +0300 Subject: Change "foreach" statement behavior (this is just a PoC yet) - "foreach by value" don't relay on internal array/object pointer and doesnt perform array duplication. It just locks it incrementing reference counter. If the original array is modified by some code, the copy on write is performed and "foreach" still work with the old copy. - it makes no difference if array given to "foreach by value" is reference itself - "foreach by reference" still use internal array/object pointer and should work similar to PHP-5. (This id not completely implemented) --- Zend/zend_hash.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'Zend/zend_hash.h') diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 377f508658..85f1890302 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -171,13 +171,6 @@ ZEND_API zval *zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos); ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos); ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos); -typedef struct _HashPointer { - HashPosition pos; - HashTable *ht; - zend_ulong h; - zend_string *key; -} HashPointer; - #define zend_hash_has_more_elements(ht) \ zend_hash_has_more_elements_ex(ht, &(ht)->nInternalPointer) #define zend_hash_move_forward(ht) \ -- cgit v1.2.1 From 15a23b1218b3e38630d677751a975907daa2cd54 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 29 Jan 2015 21:05:02 +0300 Subject: Reimplement iteration magic with HashTableIterators (see https://wiki.php.net/rfc/php7_foreach#implementation_details) --- Zend/zend_hash.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'Zend/zend_hash.h') diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 85f1890302..c8218f1112 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -50,8 +50,6 @@ typedef struct _zend_hash_key { typedef zend_bool (*merge_checker_func_t)(HashTable *target_ht, zval *source_data, zend_hash_key *hash_key, void *pParam); -typedef uint32_t HashPosition; - BEGIN_EXTERN_C() /* startup/shutdown */ @@ -227,6 +225,13 @@ void zend_hash_display(const HashTable *ht); ZEND_API int _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ulong *idx); + +ZEND_API uint32_t zend_hash_iterator_add(HashTable *ht); +ZEND_API HashPosition zend_hash_iterator_pos(uint32_t idx, HashTable *ht); +ZEND_API void zend_hash_iterator_del(uint32_t idx); +ZEND_API void zend_hash_iterators_update(HashTable *ht, HashPosition pos); + + END_EXTERN_C() #define ZEND_INIT_SYMTABLE(ht) \ -- cgit v1.2.1 From 4c5b385ff53ae9f0b52572e98c4db801f56603b0 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 30 Jan 2015 07:56:37 +0300 Subject: More careful iterators update. --- Zend/zend_hash.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Zend/zend_hash.h') diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index c8218f1112..749846aaf9 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -229,7 +229,8 @@ ZEND_API int _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ul ZEND_API uint32_t zend_hash_iterator_add(HashTable *ht); ZEND_API HashPosition zend_hash_iterator_pos(uint32_t idx, HashTable *ht); ZEND_API void zend_hash_iterator_del(uint32_t idx); -ZEND_API void zend_hash_iterators_update(HashTable *ht, HashPosition pos); +ZEND_API void zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to); +ZEND_API void zend_hash_iterators_reset(HashTable *ht); END_EXTERN_C() -- cgit v1.2.1 From 08302c0d6d1cab279b9f2129df03a057baddf2ff Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 30 Jan 2015 14:20:46 +0300 Subject: Make array_splice() to preserve foreach hash position --- Zend/zend_hash.h | 1 - 1 file changed, 1 deletion(-) (limited to 'Zend/zend_hash.h') diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 749846aaf9..d244995a9a 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -230,7 +230,6 @@ ZEND_API uint32_t zend_hash_iterator_add(HashTable *ht); ZEND_API HashPosition zend_hash_iterator_pos(uint32_t idx, HashTable *ht); ZEND_API void zend_hash_iterator_del(uint32_t idx); ZEND_API void zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to); -ZEND_API void zend_hash_iterators_reset(HashTable *ht); END_EXTERN_C() -- cgit v1.2.1 From fb2d079645829b12ed4e55a461034df6400bc430 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 30 Jan 2015 18:08:05 +0300 Subject: API cleanup --- Zend/zend_hash.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'Zend/zend_hash.h') diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index d244995a9a..982c63b492 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -229,7 +229,15 @@ ZEND_API int _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ul ZEND_API uint32_t zend_hash_iterator_add(HashTable *ht); ZEND_API HashPosition zend_hash_iterator_pos(uint32_t idx, HashTable *ht); ZEND_API void zend_hash_iterator_del(uint32_t idx); -ZEND_API void zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to); +ZEND_API HashPosition zend_hash_iterators_lower_pos(HashTable *ht, HashPosition start); +ZEND_API void _zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to); + +static zend_always_inline void zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to) +{ + if (UNEXPECTED(ht->u.v.nIteratorsCount)) { + _zend_hash_iterators_update(ht, from, to); + } +} END_EXTERN_C() -- cgit v1.2.1 From 1e41295097576dbce6c197ddb7507c07ccae3cbe Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Sat, 31 Jan 2015 07:28:58 +0300 Subject: Generalize HashTableIterator API to allows its usage without iinvolvement of HashTable.nInternalPonter --- Zend/zend_hash.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_hash.h') diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 982c63b492..602cd7a2e4 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -226,7 +226,7 @@ void zend_hash_display(const HashTable *ht); ZEND_API int _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ulong *idx); -ZEND_API uint32_t zend_hash_iterator_add(HashTable *ht); +ZEND_API uint32_t zend_hash_iterator_add(HashTable *ht, HashPosition pos); ZEND_API HashPosition zend_hash_iterator_pos(uint32_t idx, HashTable *ht); ZEND_API void zend_hash_iterator_del(uint32_t idx); ZEND_API HashPosition zend_hash_iterators_lower_pos(HashTable *ht, HashPosition start); -- cgit v1.2.1