diff --git a/src/libecmaobjects/ecma-helpers-values-collection.c b/src/libecmaobjects/ecma-helpers-values-collection.c index af40a435b..e5fa638de 100644 --- a/src/libecmaobjects/ecma-helpers-values-collection.c +++ b/src/libecmaobjects/ecma-helpers-values-collection.c @@ -147,6 +147,66 @@ ecma_new_strings_collection (ecma_string_t* string_ptrs_buffer[], /**< pointers return ecma_new_values_collection (values_buffer, strings_number, false); } /* ecma_new_strings_collection */ +/** + * Initialize new collection iterator for the collection + */ +void +ecma_collection_iterator_init (ecma_collection_iterator_t *iterator_p, /**< context of iterator */ + ecma_collection_header_t *collection_p) /**< header of collection */ +{ + iterator_p->header_p = collection_p; + iterator_p->next_chunk_cp = collection_p->next_chunk_cp; + iterator_p->current_index = 0; + iterator_p->current_value_p = NULL; + iterator_p->current_chunk_end_p = ((ecma_value_t*) iterator_p->header_p->data + + sizeof (iterator_p->header_p->data) / sizeof (ecma_value_t)); +} /* ecma_collection_iterator_init */ + +/** + * Move collection iterator to next element if there is any. + * + * @return true - if iterator moved, + * false - otherwise (current element is last element in the collection) + */ +bool +ecma_collection_iterator_next (ecma_collection_iterator_t *iterator_p) /**< context of iterator */ +{ + if (unlikely (iterator_p->header_p->unit_number == 0 + || iterator_p->current_index + 1 == iterator_p->header_p->unit_number)) + { + return false; + } + + JERRY_ASSERT (iterator_p->current_index + 1 < iterator_p->header_p->unit_number); + + if (iterator_p->current_value_p == NULL) + { + JERRY_ASSERT (iterator_p->current_index == 0); + iterator_p->current_value_p = (ecma_value_t*) iterator_p->header_p->data; + + return true; + } + + iterator_p->current_index++; + iterator_p->current_value_p++; + + if (iterator_p->current_value_p == iterator_p->current_chunk_end_p) + { + ecma_collection_chunk_t *next_chunk_p = ECMA_GET_POINTER (iterator_p->next_chunk_cp); + JERRY_ASSERT (next_chunk_p != NULL); + + iterator_p->next_chunk_cp = next_chunk_p->next_chunk_cp; + iterator_p->current_value_p = (ecma_value_t*) &next_chunk_p->data; + iterator_p->current_chunk_end_p = iterator_p->current_value_p + sizeof (next_chunk_p->data) / sizeof (ecma_value_t); + } + else + { + JERRY_ASSERT (iterator_p->current_value_p < iterator_p->current_chunk_end_p); + } + + return true; +} /* ecma_collection_iterator_next */ + /** * @} * @} diff --git a/src/libecmaobjects/ecma-helpers.c b/src/libecmaobjects/ecma-helpers.c index 722ed1253..49cdef0e8 100644 --- a/src/libecmaobjects/ecma-helpers.c +++ b/src/libecmaobjects/ecma-helpers.c @@ -491,28 +491,6 @@ ecma_delete_property (ecma_object_t *obj_p, /**< object */ JERRY_UNREACHABLE(); } /* ecma_delete_property */ -/** - * Free all chunks of a collection - */ -void -ecma_free_collection (ecma_collection_header_t *collection_header_p) /**< header of collection */ -{ - JERRY_ASSERT(collection_header_p != NULL); - - ecma_collection_chunk_t *non_first_chunk_p = ECMA_GET_POINTER (collection_header_p->next_chunk_cp); - - ecma_dealloc_collection_header (collection_header_p); - - while (non_first_chunk_p != NULL) - { - ecma_collection_chunk_t *next_chunk_p = ECMA_GET_POINTER (non_first_chunk_p->next_chunk_cp); - - ecma_dealloc_collection_chunk (non_first_chunk_p); - - non_first_chunk_p = next_chunk_p; - } -} /* ecma_free_collection */ - /** * Construct empty property descriptor. * diff --git a/src/libecmaobjects/ecma-helpers.h b/src/libecmaobjects/ecma-helpers.h index c79ec9ec8..e0ce63392 100644 --- a/src/libecmaobjects/ecma-helpers.h +++ b/src/libecmaobjects/ecma-helpers.h @@ -106,6 +106,26 @@ extern ecma_collection_header_t *ecma_new_values_collection (ecma_value_t values extern void ecma_free_values_collection (ecma_collection_header_t* header_p, bool do_deref_if_object); extern ecma_collection_header_t *ecma_new_strings_collection (ecma_string_t* string_ptrs_buffer[], ecma_length_t strings_number); + +/** + * Context of ecma-values' collection iterator + */ +typedef struct +{ + ecma_collection_header_t *header_p; /**< collection header */ + uint16_t next_chunk_cp; /**< compressed pointer to next chunk */ + ecma_length_t current_index; /**< index of current element */ + ecma_value_t *current_value_p; /**< pointer to current element */ + ecma_value_t *current_chunk_beg_p; /**< pointer to beginning of current chunk's data */ + ecma_value_t *current_chunk_end_p; /**< pointer to place right after the end of current chunk's data */ +} ecma_collection_iterator_t; + +extern void +ecma_collection_iterator_init (ecma_collection_iterator_t *iterator_p, + ecma_collection_header_t *collection_p); +extern bool +ecma_collection_iterator_next (ecma_collection_iterator_t *iterator_p); + /* ecma-helpers.c */ extern ecma_object_t* ecma_create_object (ecma_object_t *prototype_object_p, bool is_extensible, @@ -147,8 +167,6 @@ extern void ecma_free_property (ecma_property_t *prop_p); extern void ecma_delete_property (ecma_object_t *obj_p, ecma_property_t *prop_p); -extern void ecma_free_collection (ecma_collection_header_t *collection_header_p); - extern ecma_property_descriptor_t ecma_make_empty_property_descriptor (void); #endif /* !JERRY_ECMA_HELPERS_H */