Repository: lucy-clownfish Updated Branches: refs/heads/markdown_v2 bedc4bc0d -> d481bd6e1
Keep array of fresh_methods in CFCClass Don't destroy the original array of fresh methods in S_bequeath_methods. This allows to get a list of fresh methods in the original order from the .cfh file and opens opportunity for faster access. Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/2aeb8db0 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/2aeb8db0 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/2aeb8db0 Branch: refs/heads/markdown_v2 Commit: 2aeb8db034b05bd66f3c76ea456deecfb787f617 Parents: bedc4bc Author: Nick Wellnhofer <[email protected]> Authored: Wed Dec 3 19:13:02 2014 +0100 Committer: Nick Wellnhofer <[email protected]> Committed: Wed Dec 3 19:13:02 2014 +0100 ---------------------------------------------------------------------- compiler/src/CFCClass.c | 56 +++++++++++++++++++++++----------------- compiler/src/CFCTestClass.c | 2 +- 2 files changed, 33 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2aeb8db0/compiler/src/CFCClass.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCClass.c b/compiler/src/CFCClass.c index cb5660c..10f4e92 100644 --- a/compiler/src/CFCClass.c +++ b/compiler/src/CFCClass.c @@ -56,6 +56,8 @@ struct CFCClass { size_t num_kids; CFCFunction **functions; size_t num_functions; + CFCMethod **fresh_methods; + size_t num_fresh; CFCMethod **methods; size_t num_methods; CFCVariable **member_vars; @@ -132,6 +134,8 @@ CFCClass_do_create(CFCClass *self, struct CFCParcel *parcel, self->num_kids = 0; self->functions = (CFCFunction**)CALLOCATE(1, sizeof(CFCFunction*)); self->num_functions = 0; + self->fresh_methods = (CFCMethod**)CALLOCATE(1, sizeof(CFCMethod*)); + self->num_fresh = 0; self->methods = (CFCMethod**)CALLOCATE(1, sizeof(CFCMethod*)); self->num_methods = 0; self->member_vars = (CFCVariable**)CALLOCATE(1, sizeof(CFCVariable*)); @@ -225,6 +229,7 @@ CFCClass_destroy(CFCClass *self) { CFCBase_decref((CFCBase*)self->file_spec); S_free_cfcbase_array((CFCBase**)self->children); S_free_cfcbase_array((CFCBase**)self->functions); + S_free_cfcbase_array((CFCBase**)self->fresh_methods); S_free_cfcbase_array((CFCBase**)self->methods); S_free_cfcbase_array((CFCBase**)self->member_vars); S_free_cfcbase_array((CFCBase**)self->inert_vars); @@ -401,12 +406,12 @@ CFCClass_add_method(CFCClass *self, CFCMethod *method) { if (self->is_inert) { CFCUtil_die("Can't add_method to an inert class"); } - self->num_methods++; - size_t size = (self->num_methods + 1) * sizeof(CFCMethod*); - self->methods = (CFCMethod**)REALLOCATE(self->methods, size); - self->methods[self->num_methods - 1] + self->num_fresh++; + size_t size = (self->num_fresh + 1) * sizeof(CFCMethod*); + self->fresh_methods = (CFCMethod**)REALLOCATE(self->fresh_methods, size); + self->fresh_methods[self->num_fresh - 1] = (CFCMethod*)CFCBase_incref((CFCBase*)method); - self->methods[self->num_methods] = NULL; + self->fresh_methods[self->num_fresh] = NULL; } void @@ -472,15 +477,7 @@ CFCClass_method(CFCClass *self, const char *sym) { CFCMethod* CFCClass_fresh_method(CFCClass *self, const char *sym) { - CFCMethod *method = CFCClass_method(self, sym); - if (method) { - const char *class_name = CFCClass_get_class_name(self); - const char *meth_class_name = CFCMethod_get_class_name(method); - if (strcmp(class_name, meth_class_name) == 0) { - return method; - } - } - return NULL; + return (CFCMethod*)S_find_func((CFCFunction**)self->fresh_methods, sym); } void @@ -488,8 +485,8 @@ CFCClass_resolve_types(CFCClass *self) { for (size_t i = 0; self->functions[i] != NULL; i++) { CFCFunction_resolve_types(self->functions[i]); } - for (size_t i = 0; self->methods[i] != NULL; i++) { - CFCMethod_resolve_types(self->methods[i]); + for (size_t i = 0; self->fresh_methods[i] != NULL; i++) { + CFCMethod_resolve_types(self->fresh_methods[i]); } for (size_t i = 0; self->member_vars[i] != NULL; i++) { CFCVariable_resolve_type(self->member_vars[i]); @@ -529,7 +526,7 @@ S_bequeath_methods(CFCClass *self) { // Create array of methods, preserving exact order so vtables match up. size_t num_methods = 0; - size_t max_methods = self->num_methods + child->num_methods; + size_t max_methods = self->num_methods + child->num_fresh; CFCMethod **methods = (CFCMethod**)MALLOCATE( (max_methods + 1) * sizeof(CFCMethod*)); @@ -537,7 +534,7 @@ S_bequeath_methods(CFCClass *self) { for (size_t i = 0; i < self->num_methods; i++) { CFCMethod *method = self->methods[i]; const char *macro_sym = CFCMethod_get_macro_sym(method); - CFCMethod *child_method = CFCClass_method(child, macro_sym); + CFCMethod *child_method = CFCClass_fresh_method(child, macro_sym); if (child_method) { CFCMethod_override(child_method, method); methods[num_methods++] = child_method; @@ -549,8 +546,8 @@ S_bequeath_methods(CFCClass *self) { // Append novel child methods to array. Child methods which were just // marked via CFCMethod_override() a moment ago are skipped. - for (size_t i = 0; i < child->num_methods; i++) { - CFCMethod *method = child->methods[i]; + for (size_t i = 0; i < child->num_fresh; i++) { + CFCMethod *method = child->fresh_methods[i]; if (CFCMethod_novel(method)) { methods[num_methods++] = method; } @@ -574,10 +571,6 @@ S_bequeath_methods(CFCClass *self) { CFCBase_incref((CFCBase*)methods[i]); } } - for (size_t i = 0; i < child->num_methods; i++) { - CFCBase_decref((CFCBase*)child->methods[i]); - } - FREEMEM(child->methods); child->methods = methods; child->num_methods = num_methods; @@ -615,7 +608,21 @@ CFCClass_grow_tree(CFCClass *self) { } S_establish_ancestry(self); S_bequeath_member_vars(self); + + // Copy fresh methods for root class. + size_t num_fresh = self->num_fresh; + CFCMethod **methods + = (CFCMethod**)MALLOCATE((num_fresh + 1) * sizeof(CFCMethod*)); + for (size_t i = 0; i < num_fresh; i++) { + methods[i] = self->fresh_methods[i]; + CFCBase_incref((CFCBase*)methods[i]); + } + methods[num_fresh] = NULL; + self->methods = methods; + self->num_methods = num_fresh; + S_bequeath_methods(self); + self->tree_grown = 1; } @@ -660,6 +667,7 @@ S_fresh_syms(CFCClass *self, CFCSymbol **syms) { CFCMethod** CFCClass_fresh_methods(CFCClass *self) { + // TODO: Return self->fresh_methods return (CFCMethod**)S_fresh_syms(self, (CFCSymbol**)self->methods); } http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2aeb8db0/compiler/src/CFCTestClass.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCTestClass.c b/compiler/src/CFCTestClass.c index c8184ee..a4e5ddc 100644 --- a/compiler/src/CFCTestClass.c +++ b/compiler/src/CFCTestClass.c @@ -290,7 +290,7 @@ S_run_tests(CFCTest *test) { OK(test, S_has_symbol(methods, "scratch"), "parsed public abstract nullable method"); - CFCMethod *scratch = CFCClass_method(klass, "scratch"); + CFCMethod *scratch = CFCClass_fresh_method(klass, "scratch"); OK(test, scratch != NULL, "find method 'scratch'"); OK(test, CFCType_nullable(CFCMethod_get_return_type(scratch)), "public abstract incremented nullable flagged as nullable");
