Simplify CFC class registry There's no need to store separate keys in the class registry.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/2dcbb316 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/2dcbb316 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/2dcbb316 Branch: refs/heads/master Commit: 2dcbb316522005b90b4f944d3cffe6c6a48a430d Parents: 27dfd3a Author: Nick Wellnhofer <[email protected]> Authored: Mon May 30 14:21:51 2016 +0200 Committer: Nick Wellnhofer <[email protected]> Committed: Mon May 30 15:13:26 2016 +0200 ---------------------------------------------------------------------- compiler/perl/lib/Clownfish/CFC.pm | 16 -------- compiler/perl/lib/Clownfish/CFC.xs | 7 ++-- compiler/perl/t/401-class.t | 5 +-- compiler/src/CFCClass.c | 73 ++++++++++++--------------------- compiler/src/CFCClass.h | 4 +- compiler/src/CFCGoClass.c | 4 +- compiler/src/CFCPerlClass.c | 2 +- compiler/src/CFCTestClass.c | 2 +- 8 files changed, 37 insertions(+), 76 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2dcbb316/compiler/perl/lib/Clownfish/CFC.pm ---------------------------------------------------------------------- diff --git a/compiler/perl/lib/Clownfish/CFC.pm b/compiler/perl/lib/Clownfish/CFC.pm index 50bcab7..f405875 100644 --- a/compiler/perl/lib/Clownfish/CFC.pm +++ b/compiler/perl/lib/Clownfish/CFC.pm @@ -128,22 +128,6 @@ BEGIN { XSLoader::load( 'Clownfish::CFC', '0.5.0' ) } exposure => 'parcel', ); - our %fetch_singleton_PARAMS = ( - parcel => undef, - class_name => undef, - ); - - sub fetch_singleton { - my ( undef, %args ) = @_; - verify_args( \%fetch_singleton_PARAMS, %args ) or confess $@; - # Maybe prepend parcel prefix. - my $parcel = $args{parcel}; - if ( defined $parcel ) { - $parcel = Clownfish::CFC::Model::Parcel->acquire($parcel); - } - return _fetch_singleton( $parcel, $args{class_name} ); - } - sub new { confess( "The constructor for Clownfish::CFC::Model::Class is create()"); http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2dcbb316/compiler/perl/lib/Clownfish/CFC.xs ---------------------------------------------------------------------- diff --git a/compiler/perl/lib/Clownfish/CFC.xs b/compiler/perl/lib/Clownfish/CFC.xs index 52cb5f5..49c4187 100644 --- a/compiler/perl/lib/Clownfish/CFC.xs +++ b/compiler/perl/lib/Clownfish/CFC.xs @@ -164,11 +164,12 @@ CODE: OUTPUT: RETVAL SV* -_fetch_singleton(parcel, class_name) - CFCParcel *parcel; +fetch_singleton(unused, class_name) + SV *unused; const char *class_name; CODE: - CFCClass *klass = CFCClass_fetch_singleton(parcel, class_name); + CHY_UNUSED_VAR(unused); + CFCClass *klass = CFCClass_fetch_singleton(class_name); RETVAL = S_cfcbase_to_perlref(klass); OUTPUT: RETVAL http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2dcbb316/compiler/perl/t/401-class.t ---------------------------------------------------------------------- diff --git a/compiler/perl/t/401-class.t b/compiler/perl/t/401-class.t index 04f0bc3..0649b16 100644 --- a/compiler/perl/t/401-class.t +++ b/compiler/perl/t/401-class.t @@ -45,10 +45,7 @@ my $foo = Clownfish::CFC::Model::Class->create(%foo_create_args); $foo->add_function($tread_water); $foo->add_member_var($thing); $foo->add_inert_var($widget); -my $should_be_foo = Clownfish::CFC::Model::Class->fetch_singleton( - parcel => 'Neato', - class_name => 'Foo', -); +my $should_be_foo = Clownfish::CFC::Model::Class->fetch_singleton('Foo'); is( $$foo, $$should_be_foo, "fetch_singleton" ); eval { Clownfish::CFC::Model::Class->create(%foo_create_args) }; http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2dcbb316/compiler/src/CFCClass.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCClass.c b/compiler/src/CFCClass.c index 319b1ae..1bcc433 100644 --- a/compiler/src/CFCClass.c +++ b/compiler/src/CFCClass.c @@ -34,12 +34,7 @@ #include "CFCVariable.h" #include "CFCFileSpec.h" -typedef struct CFCClassRegEntry { - char *key; - struct CFCClass *klass; -} CFCClassRegEntry; - -static CFCClassRegEntry *registry = NULL; +static CFCClass **registry = NULL; static size_t registry_size = 0; static size_t registry_cap = 0; @@ -373,77 +368,64 @@ static void S_register(CFCClass *self) { if (registry_size == registry_cap) { size_t new_cap = registry_cap + 10; - registry = (CFCClassRegEntry*)REALLOCATE( + registry = (CFCClass**)REALLOCATE( registry, - (new_cap + 1) * sizeof(CFCClassRegEntry)); + (new_cap + 1) * sizeof(CFCClass*)); for (size_t i = registry_cap; i <= new_cap; i++) { - registry[i].key = NULL; - registry[i].klass = NULL; + registry[i] = NULL; } registry_cap = new_cap; } - const char *prefix = CFCParcel_get_prefix(self->parcel); - const char *name = self->name; - const char *nickname = self->nickname; - const char *key = self->full_struct_sym; + const char *prefix = CFCParcel_get_prefix(self->parcel); + const char *name = self->name; + const char *nickname = self->nickname; + const char *struct_sym = self->full_struct_sym; for (size_t i = 0; i < registry_size; i++) { - CFCClass *other = registry[i].klass; - const char *other_prefix = CFCParcel_get_prefix(other->parcel); - const char *other_name = other->name; - const char *other_nickname = other->nickname; + CFCClass *other = registry[i]; + const char *other_prefix = CFCParcel_get_prefix(other->parcel); - if (strcmp(name, other_name) == 0) { + if (strcmp(name, other->name) == 0) { CFCUtil_die("Two classes with name %s", name); } - if (strcmp(registry[i].key, key) == 0) { + if (strcmp(struct_sym, other->full_struct_sym) == 0) { CFCUtil_die("Class name conflict between %s and %s", - name, other_name); + name, other->name); } if (strcmp(prefix, other_prefix) == 0 - && strcmp(nickname, other_nickname) == 0 + && strcmp(nickname, other->nickname) == 0 ) { CFCUtil_die("Class nickname conflict between %s and %s", - name, other_name); + name, other->name); } } - registry[registry_size].key = CFCUtil_strdup(key); - registry[registry_size].klass = (CFCClass*)CFCBase_incref((CFCBase*)self); + registry[registry_size] = (CFCClass*)CFCBase_incref((CFCBase*)self); registry_size++; } #define MAX_SINGLETON_LEN 256 CFCClass* -CFCClass_fetch_singleton(CFCParcel *parcel, const char *class_name) { +CFCClass_fetch_singleton(const char *class_name) { CFCUTIL_NULL_CHECK(class_name); - // Build up the key. - const char *last_colon = strrchr(class_name, ':'); - const char *struct_sym = last_colon - ? last_colon + 1 - : class_name; - const char *prefix = parcel ? CFCParcel_get_prefix(parcel) : ""; - size_t prefix_len = strlen(prefix); - size_t struct_sym_len = strlen(struct_sym); - if (prefix_len + struct_sym_len > MAX_SINGLETON_LEN) { - CFCUtil_die("names too long: '%s', '%s'", prefix, struct_sym); + for (size_t i = 0; i < registry_size; i++) { + if (strcmp(registry[i]->name, class_name) == 0) { + return registry[i]; + } } - char key[MAX_SINGLETON_LEN + 1]; - sprintf(key, "%s%s", prefix, struct_sym); - - return CFCClass_fetch_by_struct_sym(key); + return NULL; } CFCClass* -CFCClass_fetch_by_struct_sym(const char *key) { - CFCUTIL_NULL_CHECK(key); +CFCClass_fetch_by_struct_sym(const char *struct_sym) { + CFCUTIL_NULL_CHECK(struct_sym); for (size_t i = 0; i < registry_size; i++) { - if (strcmp(registry[i].key, key) == 0) { - return registry[i].klass; + if (strcmp(registry[i]->full_struct_sym, struct_sym) == 0) { + return registry[i]; } } return NULL; @@ -452,14 +434,13 @@ CFCClass_fetch_by_struct_sym(const char *key) { void CFCClass_clear_registry(void) { for (size_t i = 0; i < registry_size; i++) { - CFCClass *klass = registry[i].klass; + CFCClass *klass = registry[i]; if (klass->parent) { // Break circular ref. CFCBase_decref((CFCBase*)klass->parent); klass->parent = NULL; } CFCBase_decref((CFCBase*)klass); - FREEMEM(registry[i].key); } FREEMEM(registry); registry_size = 0; http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2dcbb316/compiler/src/CFCClass.h ---------------------------------------------------------------------- diff --git a/compiler/src/CFCClass.h b/compiler/src/CFCClass.h index c4cf52b..5da05f5 100644 --- a/compiler/src/CFCClass.h +++ b/compiler/src/CFCClass.h @@ -88,15 +88,13 @@ CFCClass_destroy(CFCClass *self); /** Retrieve a Class, if one has already been created. * - * @param A Clownfish::CFC::Model::Parcel. * @param class_name The name of the Class. */ CFCClass* -CFCClass_fetch_singleton(struct CFCParcel *parcel, const char *class_name); +CFCClass_fetch_singleton(const char *class_name); /** Retrieve a Class by its struct sym. * - * @param A Clownfish::CFC::Model::Parcel. * @param full_struct_sym The Class's full struct sym. */ CFCClass* http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2dcbb316/compiler/src/CFCGoClass.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCGoClass.c b/compiler/src/CFCGoClass.c index a60ce5c..cf1b74c 100644 --- a/compiler/src/CFCGoClass.c +++ b/compiler/src/CFCGoClass.c @@ -73,7 +73,7 @@ CFCGoClass_new(CFCParcel *parcel, const char *class_name) { self->parcel = (CFCParcel*)CFCBase_incref((CFCBase*)parcel); self->class_name = CFCUtil_strdup(class_name); // Client may be NULL, since fetch_singleton() does not always succeed. - CFCClass *client = CFCClass_fetch_singleton(parcel, class_name); + CFCClass *client = CFCClass_fetch_singleton(class_name); self->client = (CFCClass*)CFCBase_incref((CFCBase*)client); return self; } @@ -133,7 +133,7 @@ CFCGoClass_singleton(const char *class_name) { CFCClass* CFCGoClass_get_client(CFCGoClass *self) { if (!self->client) { - CFCClass *client = CFCClass_fetch_singleton(self->parcel, self->class_name); + CFCClass *client = CFCClass_fetch_singleton(self->class_name); self->client = (CFCClass*)CFCBase_incref((CFCBase*)client); } return self->client; http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2dcbb316/compiler/src/CFCPerlClass.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPerlClass.c b/compiler/src/CFCPerlClass.c index 30dc1d6..6716a3d 100644 --- a/compiler/src/CFCPerlClass.c +++ b/compiler/src/CFCPerlClass.c @@ -77,7 +77,7 @@ CFCPerlClass_init(CFCPerlClass *self, CFCParcel *parcel, self->parcel = (CFCParcel*)CFCBase_incref((CFCBase*)parcel); self->class_name = CFCUtil_strdup(class_name); // Client may be NULL, since fetch_singleton() does not always succeed. - CFCClass *client = CFCClass_fetch_singleton(parcel, class_name); + CFCClass *client = CFCClass_fetch_singleton(class_name); self->client = (CFCClass*)CFCBase_incref((CFCBase*)client); self->pod_spec = NULL; self->xs_code = NULL; http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2dcbb316/compiler/src/CFCTestClass.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCTestClass.c b/compiler/src/CFCTestClass.c index 20ae9ac..009bdfb 100644 --- a/compiler/src/CFCTestClass.c +++ b/compiler/src/CFCTestClass.c @@ -105,7 +105,7 @@ S_run_tests(CFCTest *test) { CFCClass_add_inert_var(foo, widget); { - CFCClass *should_be_foo = CFCClass_fetch_singleton(neato, "Foo"); + CFCClass *should_be_foo = CFCClass_fetch_singleton("Foo"); OK(test, should_be_foo == foo, "fetch_singleton"); }
