diff --git a/src/runtime/array.h b/src/runtime/array.h index a0492526..4d2f478b 100644 --- a/src/runtime/array.h +++ b/src/runtime/array.h @@ -34,16 +34,16 @@ extern "C" { #define array_clear(self) ((self)->size = 0) -#define array_grow(self, new_capacity) \ - array__grow((VoidArray *)(self), array__elem_size(self), new_capacity) +#define array_reserve(self, new_capacity) \ + array__reserve((VoidArray *)(self), array__elem_size(self), new_capacity) #define array_erase(self, index) \ array__erase((VoidArray *)(self), array__elem_size(self), index) #define array_delete(self) array__delete((VoidArray *)self) -#define array_push(self, element) \ - (array_grow((self), (self)->size + 1), \ +#define array_push(self, element) \ + (array__grow((VoidArray *)(self), array__elem_size(self)), \ (self)->contents[(self)->size++] = (element)) #define array_push_all(self, other) \ @@ -80,21 +80,25 @@ static inline void array__erase(VoidArray *self, size_t element_size, self->size--; } -static inline void array__grow(VoidArray *self, size_t element_size, - uint32_t new_capacity) { +static inline void array__reserve(VoidArray *self, size_t element_size, uint32_t new_capacity) { if (new_capacity > self->capacity) { - if (new_capacity < 2 * self->capacity) - new_capacity = 2 * self->capacity; - if (new_capacity < 8) - new_capacity = 8; - if (self->contents) + if (self->contents) { self->contents = ts_realloc(self->contents, new_capacity * element_size); - else + } else { self->contents = ts_calloc(new_capacity, element_size); + } self->capacity = new_capacity; } } +static inline void array__grow(VoidArray *self, size_t element_size) { + if (self->size == self->capacity) { + size_t new_capacity = self->capacity * 2; + if (new_capacity < 8) new_capacity = 8; + array__reserve(self, element_size, new_capacity); + } +} + static inline void array__splice(VoidArray *self, size_t element_size, uint32_t index, uint32_t old_count, uint32_t new_count, void *elements) { @@ -103,7 +107,7 @@ static inline void array__splice(VoidArray *self, size_t element_size, uint32_t new_end = index + new_count; assert(old_end <= self->size); - array__grow(self, element_size, new_size); + array__reserve(self, element_size, new_size); char *contents = (char *)self->contents; if (self->size > old_end) diff --git a/src/runtime/parser.c b/src/runtime/parser.c index bfb0ab37..265354a2 100644 --- a/src/runtime/parser.c +++ b/src/runtime/parser.c @@ -1041,7 +1041,7 @@ static void parser__recover(Parser *self, StackVersion version, Tree *lookahead) LOG("skip_token symbol:%s", SYM_NAME(lookahead->symbol)); ts_tree_retain(lookahead); TreeArray children = array_new(); - array_grow(&children, 1); + array_reserve(&children, 1); array_push(&children, lookahead); Tree *error_repeat = ts_tree_make_node( &self->tree_pool, @@ -1253,7 +1253,7 @@ static unsigned parser__condense_stack(Parser *self) { bool parser_init(Parser *self) { ts_lexer_init(&self->lexer); array_init(&self->reduce_actions); - array_grow(&self->reduce_actions, 4); + array_reserve(&self->reduce_actions, 4); ts_tree_pool_init(&self->tree_pool); self->stack = ts_stack_new(&self->tree_pool); self->finished_tree = NULL; diff --git a/src/runtime/stack.c b/src/runtime/stack.c index 76a6e89c..f7383846 100644 --- a/src/runtime/stack.c +++ b/src/runtime/stack.c @@ -241,7 +241,7 @@ static void ts_stack__add_slice(Stack *self, StackVersion original_version, inline StackSliceArray stack__iter(Stack *self, StackVersion version, StackCallback callback, void *payload, - bool include_trees) { + int goal_tree_count) { array_clear(&self->slices); array_clear(&self->iterators); @@ -252,6 +252,13 @@ inline StackSliceArray stack__iter(Stack *self, StackVersion version, .tree_count = 0, .is_pending = true, }; + + bool include_trees = false; + if (goal_tree_count >= 0) { + include_trees = true; + array_reserve(&iterator.trees, goal_tree_count); + } + array_push(&self->iterators, iterator); while (self->iterators.size > 0) { @@ -330,10 +337,10 @@ Stack *ts_stack_new(TreePool *tree_pool) { array_init(&self->slices); array_init(&self->iterators); array_init(&self->node_pool); - array_grow(&self->heads, 4); - array_grow(&self->slices, 4); - array_grow(&self->iterators, 4); - array_grow(&self->node_pool, MAX_NODE_POOL_SIZE); + array_reserve(&self->heads, 4); + array_reserve(&self->slices, 4); + array_reserve(&self->iterators, 4); + array_reserve(&self->node_pool, MAX_NODE_POOL_SIZE); self->tree_pool = tree_pool; self->base_node = stack_node_new(NULL, NULL, false, 1, &self->node_pool); @@ -423,7 +430,7 @@ inline StackAction iterate_callback(void *payload, const Iterator *iterator) { void ts_stack_iterate(Stack *self, StackVersion version, StackIterateCallback callback, void *payload) { StackIterateSession session = {payload, callback}; - stack__iter(self, version, iterate_callback, &session, true); + stack__iter(self, version, iterate_callback, &session, -1); } inline StackAction pop_count_callback(void *payload, const Iterator *iterator) { @@ -436,7 +443,7 @@ inline StackAction pop_count_callback(void *payload, const Iterator *iterator) { } StackSliceArray ts_stack_pop_count(Stack *self, StackVersion version, uint32_t count) { - return stack__iter(self, version, pop_count_callback, &count, true); + return stack__iter(self, version, pop_count_callback, &count, count); } inline StackAction pop_pending_callback(void *payload, const Iterator *iterator) { @@ -452,7 +459,7 @@ inline StackAction pop_pending_callback(void *payload, const Iterator *iterator) } StackSliceArray ts_stack_pop_pending(Stack *self, StackVersion version) { - StackSliceArray pop = stack__iter(self, version, pop_pending_callback, NULL, true); + StackSliceArray pop = stack__iter(self, version, pop_pending_callback, NULL, 0); if (pop.size > 0) { ts_stack_renumber_version(self, pop.contents[0].version, version); pop.contents[0].version = version; @@ -479,7 +486,7 @@ TreeArray ts_stack_pop_error(Stack *self, StackVersion version) { for (unsigned i = 0; i < node->link_count; i++) { if (node->links[i].tree && node->links[i].tree->symbol == ts_builtin_sym_error) { bool found_error = false; - StackSliceArray pop = stack__iter(self, version, pop_error_callback, &found_error, true); + StackSliceArray pop = stack__iter(self, version, pop_error_callback, &found_error, 1); if (pop.size > 0) { assert(pop.size == 1); ts_stack_renumber_version(self, pop.contents[0].version, version); @@ -496,7 +503,7 @@ inline StackAction pop_all_callback(void *payload, const Iterator *iterator) { } StackSliceArray ts_stack_pop_all(Stack *self, StackVersion version) { - return stack__iter(self, version, pop_all_callback, NULL, true); + return stack__iter(self, version, pop_all_callback, NULL, 0); } typedef struct { @@ -528,7 +535,7 @@ void ts_stack_record_summary(Stack *self, StackVersion version, unsigned max_dep .max_depth = max_depth }; array_init(session.summary); - stack__iter(self, version, summarize_stack_callback, &session, false); + stack__iter(self, version, summarize_stack_callback, &session, -1); self->heads.contents[version].summary = session.summary; } diff --git a/src/runtime/tree.c b/src/runtime/tree.c index ad58bfd3..24e62466 100644 --- a/src/runtime/tree.c +++ b/src/runtime/tree.c @@ -82,7 +82,7 @@ TreeArray ts_tree_array_remove_last_n(TreeArray *self, uint32_t remove_count) { } } - array_grow(&result, self->size - split_index); + array_reserve(&result, self->size - split_index); for (uint32_t i = split_index; i < self->size; i++) { array_push(&result, self->contents[i]); }