Keep array of fresh member variables in CFCClass
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/e7d70dd7 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/e7d70dd7 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/e7d70dd7 Branch: refs/heads/markdown_v2 Commit: e7d70dd766539b19255c23e56c80e60f4018be14 Parents: 17c9ce3 Author: Nick Wellnhofer <[email protected]> Authored: Fri Dec 12 18:52:14 2014 +0100 Committer: Nick Wellnhofer <[email protected]> Committed: Wed Dec 24 14:56:52 2014 +0100 ---------------------------------------------------------------------- compiler/perl/lib/Clownfish/CFC.xs | 1 - compiler/src/CFCClass.c | 103 ++++++++++++++++---------------- compiler/src/CFCTestClass.c | 10 ++-- compiler/src/CFCTestFile.c | 2 +- 4 files changed, 58 insertions(+), 58 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/e7d70dd7/compiler/perl/lib/Clownfish/CFC.xs ---------------------------------------------------------------------- diff --git a/compiler/perl/lib/Clownfish/CFC.xs b/compiler/perl/lib/Clownfish/CFC.xs index 65442a3..a27e193 100644 --- a/compiler/perl/lib/Clownfish/CFC.xs +++ b/compiler/perl/lib/Clownfish/CFC.xs @@ -401,7 +401,6 @@ PPCODE: case 46: { CFCVariable **fresh = CFCClass_fresh_member_vars(self); retval = S_array_of_cfcbase_to_av((CFCBase**)fresh); - FREEMEM(fresh); break; } case 48: { http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/e7d70dd7/compiler/src/CFCClass.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCClass.c b/compiler/src/CFCClass.c index ff20715..71108f5 100644 --- a/compiler/src/CFCClass.c +++ b/compiler/src/CFCClass.c @@ -57,9 +57,11 @@ struct CFCClass { CFCFunction **functions; size_t num_functions; CFCMethod **fresh_methods; - size_t num_fresh; + size_t num_fresh_meths; CFCMethod **methods; size_t num_methods; + CFCVariable **fresh_vars; + size_t num_fresh_vars; CFCVariable **member_vars; size_t num_member_vars; CFCVariable **inert_vars; @@ -135,9 +137,11 @@ CFCClass_do_create(CFCClass *self, struct CFCParcel *parcel, self->functions = (CFCFunction**)CALLOCATE(1, sizeof(CFCFunction*)); self->num_functions = 0; self->fresh_methods = (CFCMethod**)CALLOCATE(1, sizeof(CFCMethod*)); - self->num_fresh = 0; + self->num_fresh_meths = 0; self->methods = (CFCMethod**)CALLOCATE(1, sizeof(CFCMethod*)); self->num_methods = 0; + self->fresh_vars = (CFCVariable**)CALLOCATE(1, sizeof(CFCVariable*)); + self->num_fresh_vars = 0; self->member_vars = (CFCVariable**)CALLOCATE(1, sizeof(CFCVariable*)); self->num_member_vars = 0; self->inert_vars = (CFCVariable**)CALLOCATE(1, sizeof(CFCVariable*)); @@ -231,6 +235,7 @@ CFCClass_destroy(CFCClass *self) { 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->fresh_vars); S_free_cfcbase_array((CFCBase**)self->member_vars); S_free_cfcbase_array((CFCBase**)self->inert_vars); FREEMEM(self->parent_class_name); @@ -406,12 +411,12 @@ CFCClass_add_method(CFCClass *self, CFCMethod *method) { if (self->is_inert) { CFCUtil_die("Can't add_method to an inert class"); } - self->num_fresh++; - size_t size = (self->num_fresh + 1) * sizeof(CFCMethod*); + self->num_fresh_meths++; + size_t size = (self->num_fresh_meths + 1) * sizeof(CFCMethod*); self->fresh_methods = (CFCMethod**)REALLOCATE(self->fresh_methods, size); - self->fresh_methods[self->num_fresh - 1] + self->fresh_methods[self->num_fresh_meths - 1] = (CFCMethod*)CFCBase_incref((CFCBase*)method); - self->fresh_methods[self->num_fresh] = NULL; + self->fresh_methods[self->num_fresh_meths] = NULL; } void @@ -420,12 +425,12 @@ CFCClass_add_member_var(CFCClass *self, CFCVariable *var) { if (self->tree_grown) { CFCUtil_die("Can't call add_member_var after grow_tree"); } - self->num_member_vars++; - size_t size = (self->num_member_vars + 1) * sizeof(CFCVariable*); - self->member_vars = (CFCVariable**)REALLOCATE(self->member_vars, size); - self->member_vars[self->num_member_vars - 1] + self->num_fresh_vars++; + size_t size = (self->num_fresh_vars + 1) * sizeof(CFCVariable*); + self->fresh_vars = (CFCVariable**)REALLOCATE(self->fresh_vars, size); + self->fresh_vars[self->num_fresh_vars - 1] = (CFCVariable*)CFCBase_incref((CFCBase*)var); - self->member_vars[self->num_member_vars] = NULL; + self->fresh_vars[self->num_fresh_vars] = NULL; } void @@ -488,8 +493,8 @@ CFCClass_resolve_types(CFCClass *self) { 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]); + for (size_t i = 0; self->fresh_vars[i] != NULL; i++) { + CFCVariable_resolve_type(self->fresh_vars[i]); } for (size_t i = 0; self->inert_vars[i] != NULL; i++) { CFCVariable_resolve_type(self->inert_vars[i]); @@ -501,16 +506,16 @@ static void S_bequeath_member_vars(CFCClass *self) { for (size_t i = 0; self->children[i] != NULL; i++) { CFCClass *child = self->children[i]; - size_t num_vars = self->num_member_vars + child->num_member_vars; + size_t num_vars = self->num_member_vars + child->num_fresh_vars; size_t size = (num_vars + 1) * sizeof(CFCVariable*); child->member_vars = (CFCVariable**)REALLOCATE(child->member_vars, size); - memmove(child->member_vars + self->num_member_vars, - child->member_vars, - child->num_member_vars * sizeof(CFCVariable*)); memcpy(child->member_vars, self->member_vars, self->num_member_vars * sizeof(CFCVariable*)); - for (size_t j = 0; self->member_vars[j] != NULL; j++) { + memcpy(child->member_vars + self->num_member_vars, + child->fresh_vars, + child->num_fresh_vars * sizeof(CFCVariable*)); + for (size_t j = 0; child->member_vars[j] != NULL; j++) { CFCBase_incref((CFCBase*)child->member_vars[j]); } child->num_member_vars = num_vars; @@ -526,7 +531,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_fresh; + size_t max_methods = self->num_methods + child->num_fresh_meths; CFCMethod **methods = (CFCMethod**)MALLOCATE( (max_methods + 1) * sizeof(CFCMethod*)); @@ -546,7 +551,7 @@ 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_fresh; i++) { + for (size_t i = 0; i < child->num_fresh_meths; i++) { CFCMethod *method = child->fresh_methods[i]; if (CFCMethod_novel(method)) { methods[num_methods++] = method; @@ -601,25 +606,36 @@ S_family_tree_size(CFCClass *self) { return count; } +static CFCBase** +S_copy_cfcbase_array(CFCBase **array, size_t num_elems) { + CFCBase **copy = (CFCBase**)MALLOCATE((num_elems + 1) * sizeof(CFCBase*)); + for (size_t i = 0; i < num_elems; i++) { + copy[i] = CFCBase_incref(array[i]); + } + copy[num_elems] = NULL; + return copy; +} + void CFCClass_grow_tree(CFCClass *self) { if (self->tree_grown) { CFCUtil_die("Can't call grow_tree more than once"); } S_establish_ancestry(self); + + // Copy fresh variabless for root class. + self->member_vars + = (CFCVariable**)S_copy_cfcbase_array((CFCBase**)self->fresh_vars, + self->num_fresh_vars); + self->num_member_vars = self->num_fresh_vars; + 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; + self->methods + = (CFCMethod**)S_copy_cfcbase_array((CFCBase**)self->fresh_methods, + self->num_fresh_meths); + self->num_methods = self->num_fresh_meths; S_bequeath_methods(self); @@ -646,25 +662,6 @@ CFCClass_tree_to_ladder(CFCClass *self) { return ladder; } -static CFCSymbol** -S_fresh_syms(CFCClass *self, CFCSymbol **syms) { - const char *class_name = CFCClass_get_class_name(self); - size_t count = 0; - while (syms[count] != NULL) { count++; } - size_t amount = (count + 1) * sizeof(CFCSymbol*); - CFCSymbol **fresh = (CFCSymbol**)MALLOCATE(amount); - size_t num_fresh = 0; - for (size_t i = 0; i < count; i++) { - CFCSymbol *sym = syms[i]; - const char *sym_class_name = CFCSymbol_get_class_name(sym); - if (strcmp(sym_class_name, class_name) == 0) { - fresh[num_fresh++] = sym; - } - } - fresh[num_fresh] = NULL; - return fresh; -} - CFCMethod** CFCClass_fresh_methods(CFCClass *self) { return self->fresh_methods; @@ -672,7 +669,7 @@ CFCClass_fresh_methods(CFCClass *self) { CFCVariable** CFCClass_fresh_member_vars(CFCClass *self) { - return (CFCVariable**)S_fresh_syms(self, (CFCSymbol**)self->member_vars); + return self->fresh_vars; } CFCClass** @@ -703,11 +700,17 @@ CFCClass_num_methods(CFCClass *self) { CFCVariable** CFCClass_member_vars(CFCClass *self) { + if (!self->tree_grown) { + CFCUtil_die("Can't call 'member_vars' before 'grow_tree'"); + } return self->member_vars; } size_t CFCClass_num_member_vars(CFCClass *self) { + if (!self->tree_grown) { + CFCUtil_die("Can't call 'num_member_vars' before 'grow_tree'"); + } return self->num_member_vars; } http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/e7d70dd7/compiler/src/CFCTestClass.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCTestClass.c b/compiler/src/CFCTestClass.c index 1bdc5e4..762180a 100644 --- a/compiler/src/CFCTestClass.c +++ b/compiler/src/CFCTestClass.c @@ -168,8 +168,6 @@ S_run_tests(CFCTest *test) { CFCVariable **fresh_member_vars = CFCClass_fresh_member_vars(foo); OK(test, fresh_member_vars[0] == thing, "fresh_member_vars[0]"); OK(test, fresh_member_vars[1] == NULL, "fresh_member_vars[1]"); - - FREEMEM(fresh_member_vars); } { @@ -185,8 +183,6 @@ S_run_tests(CFCTest *test) { CFCVariable **inert_vars = CFCClass_inert_vars(foo_jr); OK(test, inert_vars[0] == NULL, "inert_vars[0]"); - - FREEMEM(fresh_member_vars); } { @@ -235,7 +231,8 @@ S_run_tests(CFCTest *test) { " int num;\n" "}\n"; CFCClass *klass = CFCTest_parse_class(test, parser, class_src); - CFCSymbol **member_vars = (CFCSymbol**)CFCClass_member_vars(klass); + CFCSymbol **member_vars + = (CFCSymbol**)CFCClass_fresh_member_vars(klass); OK(test, S_has_symbol(member_vars, "num"), "parsed member var"); @@ -275,7 +272,8 @@ S_run_tests(CFCTest *test) { CFCClass *klass = CFCTest_parse_class(test, parser, class_src); CFCSymbol **inert_vars = (CFCSymbol**)CFCClass_inert_vars(klass); - CFCSymbol **member_vars = (CFCSymbol**)CFCClass_member_vars(klass); + CFCSymbol **member_vars + = (CFCSymbol**)CFCClass_fresh_member_vars(klass); CFCSymbol **functions = (CFCSymbol**)CFCClass_functions(klass); CFCSymbol **methods = (CFCSymbol**)CFCClass_fresh_methods(klass); OK(test, S_has_symbol(inert_vars, "num_dogs"), "parsed inert var"); http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/e7d70dd7/compiler/src/CFCTestFile.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCTestFile.c b/compiler/src/CFCTestFile.c index 4be6cef..921eaf4 100644 --- a/compiler/src/CFCTestFile.c +++ b/compiler/src/CFCTestFile.c @@ -95,7 +95,7 @@ S_run_tests(CFCTest *test) { classes[0] != NULL && classes[1] != NULL && classes[2] != NULL && classes[3] == NULL, "classes() filters blocks"); - CFCVariable **member_vars = CFCClass_member_vars(classes[0]); + CFCVariable **member_vars = CFCClass_fresh_member_vars(classes[0]); CFCType *foo_type = CFCVariable_get_type(member_vars[0]); CFCType_resolve(foo_type); STR_EQ(test, CFCType_get_specifier(foo_type), "stuff_Foo",
