From f6f02182c15fac1828188dab3a18af7351088a48 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 4 Feb 2016 12:59:44 -0800 Subject: [PATCH] Tail-call-optimize recursive functions Refs https://github.com/maxbrunsfeld/node-tree-sitter-compiler/pull/7 --- src/runtime/tree.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/runtime/tree.c b/src/runtime/tree.c index 6d15fb36..f631ad30 100644 --- a/src/runtime/tree.c +++ b/src/runtime/tree.c @@ -62,13 +62,21 @@ TSTree *ts_tree_make_copy(TSTree *self) { } void ts_tree_assign_parents(TSTree *self) { - TSLength offset = ts_length_zero(); + TSLength offset; + +recur: + offset = ts_length_zero(); for (size_t i = 0; i < self->child_count; i++) { TSTree *child = self->children[i]; if (child->context.parent != self) { child->context.parent = self; child->context.index = i; child->context.offset = offset; + if (i == self->child_count - 1) { + self = child; + goto recur; + } + ts_tree_assign_parents(child); } offset = ts_length_add(offset, ts_tree_total_size(child)); @@ -135,13 +143,23 @@ void ts_tree_retain(TSTree *self) { void ts_tree_release(TSTree *self) { if (!self) return; + +recur: assert(self->ref_count > 0); self->ref_count--; + if (self->ref_count == 0) { - for (size_t i = 0; i < self->child_count; i++) - ts_tree_release(self->children[i]); - if (self->child_count > 0) + if (self->child_count > 0) { + for (size_t i = 0; i < self->child_count - 1; i++) + ts_tree_release(self->children[i]); + TSTree *last_child = self->children[self->child_count - 1]; ts_free(self->children); + ts_free(self); + + self = last_child; + goto recur; + } + ts_free(self); } }