You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2011/02/27 06:41:04 UTC
[lucy-commits] svn commit: r1074991 - in /incubator/lucy/trunk/clownfish: lib/Clownfish.xs
lib/Clownfish/Class.pm src/CFCClass.c src/CFCClass.h
Author: marvin
Date: Sun Feb 27 05:41:04 2011
New Revision: 1074991
URL: http://svn.apache.org/viewvc?rev=1074991&view=rev
Log:
Port more method processing code in CFCClass to C.
Modified:
incubator/lucy/trunk/clownfish/lib/Clownfish.xs
incubator/lucy/trunk/clownfish/lib/Clownfish/Class.pm
incubator/lucy/trunk/clownfish/src/CFCClass.c
incubator/lucy/trunk/clownfish/src/CFCClass.h
Modified: incubator/lucy/trunk/clownfish/lib/Clownfish.xs
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/lib/Clownfish.xs?rev=1074991&r1=1074990&r2=1074991&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish.xs (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish.xs Sun Feb 27 05:41:04 2011
@@ -189,6 +189,12 @@ CODE:
OUTPUT: RETVAL
void
+_bequeath_methods(self)
+ CFCClass *self;
+PPCODE:
+ CFCClass_bequeath_methods(self);
+
+void
_bequeath_member_vars(self)
CFCClass *self;
PPCODE:
@@ -229,6 +235,17 @@ CODE:
: newSV(0);
OUTPUT: RETVAL
+SV*
+novel_method(self, sym)
+ CFCClass *self;
+ const char *sym;
+CODE:
+ CFCMethod *method = CFCClass_novel_method(self, sym);
+ RETVAL = method
+ ? newRV((SV*)CFCBase_get_perl_obj((CFCBase*)method))
+ : newSV(0);
+OUTPUT: RETVAL
+
void
_zap_methods(self)
CFCClass *self;
@@ -262,7 +279,8 @@ ALIAS:
member_vars = 38
inert_vars = 40
tree_to_ladder = 42
- novel_member_vars = 44
+ novel_methods = 44
+ novel_member_vars = 46
PPCODE:
{
START_SET_OR_GET_SWITCH
@@ -380,6 +398,12 @@ PPCODE:
break;
}
case 44: {
+ CFCMethod **novel = CFCClass_novel_methods(self);
+ retval = S_array_of_cfcbase_to_av((CFCBase**)novel);
+ FREEMEM(novel);
+ break;
+ }
+ case 46: {
CFCVariable **novel = CFCClass_novel_member_vars(self);
retval = S_array_of_cfcbase_to_av((CFCBase**)novel);
FREEMEM(novel);
Modified: incubator/lucy/trunk/clownfish/lib/Clownfish/Class.pm
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/lib/Clownfish/Class.pm?rev=1074991&r1=1074990&r2=1074991&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish/Class.pm (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish/Class.pm Sun Feb 27 05:41:04 2011
@@ -105,26 +105,6 @@ sub create {
return $self;
}
-sub novel_methods {
- my $self = shift;
- my $cnick = $self->get_cnick;
- my @methods = grep { $_->get_class_cnick eq $cnick } @{ $self->methods };
- return \@methods;
-}
-
-sub novel_method {
- my ( $self, $micro_sym ) = @_;
- my $method = $self->method($micro_sym);
- if ( defined $method
- and $method->get_class_cnick eq $self->get_class_cnick )
- {
- return $method;
- }
- else {
- return;
- }
-}
-
# Create dumpable functions unless hand coded versions were supplied.
sub _create_dumpables {
my $self = shift;
@@ -151,42 +131,6 @@ sub _generate_automethods {
}
}
-sub _bequeath_methods {
- my $self = shift;
-
- for my $child ( @{ $self->children } ) {
- # Pass down methods, with some being overridden.
- my @common_methods; # methods which child inherits or overrides
- for my $method ( @{ $self->methods } ) {
- if ( my $child_method = $child->method( $method->micro_sym ) ) {
- $child_method->override($method);
- push @common_methods, $child_method;
- }
- else {
- push @common_methods, $method;
- }
- }
-
- # Create array of methods, preserving exact order so vtables match up.
- my @new_method_set;
- my %seen;
- for my $meth ( @common_methods, @{ $child->methods } ) {
- next if $seen{ $meth->micro_sym };
- $seen{ $meth->micro_sym } = 1;
- if ( $child->final ) {
- $meth = $meth->finalize if $child->final;
- }
- push @new_method_set, $meth;
- }
- $child->_zap_methods;
- $child->add_method($_) for @new_method_set;
-
- # Pass it all down to the next generation.
- $child->_bequeath_methods;
- $child->_set_tree_grown(1);
- }
-}
-
1;
__END__
Modified: incubator/lucy/trunk/clownfish/src/CFCClass.c
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCClass.c?rev=1074991&r1=1074990&r2=1074991&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCClass.c (original)
+++ incubator/lucy/trunk/clownfish/src/CFCClass.c Sun Feb 27 05:41:04 2011
@@ -363,6 +363,21 @@ CFCClass_method(CFCClass *self, const ch
return (CFCMethod*)S_find_func((CFCFunction**)self->methods, sym);
}
+CFCMethod*
+CFCClass_novel_method(CFCClass *self, const char *sym)
+{
+ CFCMethod *method = CFCClass_method(self, sym);
+ if (method) {
+ const char *cnick = CFCClass_get_cnick(self);
+ const char *meth_cnick
+ = CFCSymbol_get_class_cnick((CFCSymbol*)method);
+ if (strcmp(cnick, meth_cnick) == 0) {
+ return method;
+ }
+ }
+ return NULL;
+}
+
// Pass down member vars to from parent to children.
void
CFCClass_bequeath_member_vars(CFCClass *self)
@@ -389,6 +404,69 @@ CFCClass_bequeath_member_vars(CFCClass *
}
}
+void
+CFCClass_bequeath_methods(CFCClass *self)
+{
+ size_t child_num;
+ for (child_num = 0; self->children[child_num] != NULL; child_num++) {
+ CFCClass *child = self->children[child_num];
+
+ // 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;
+ CFCMethod **methods = (CFCMethod**)MALLOCATE(
+ (max_methods + 1) * sizeof(CFCMethod*));
+
+ // Gather methods which child inherits or overrides.
+ size_t i;
+ for (i = 0; i < self->num_methods; i++) {
+ CFCMethod *method = self->methods[i];
+ const char *micro_sym = CFCSymbol_micro_sym((CFCSymbol*)method);
+ CFCMethod *child_method = CFCClass_method(child, micro_sym);
+ if (child_method) {
+ CFCMethod_override(child_method, method);
+ methods[num_methods++] = child_method;
+ }
+ else {
+ methods[num_methods++] = method;
+ }
+ }
+
+ // Append novel child methods to array. Child methods which were just
+ // marked via CFCMethod_override() a moment ago are skipped.
+ for (i = 0; i < child->num_methods; i++) {
+ CFCMethod *method = child->methods[i];
+ if (CFCMethod_novel(method)) {
+ methods[num_methods++] = method;
+ }
+ }
+ methods[num_methods] = NULL;
+
+ // Manage refcounts and assign new array. Transform to final methods
+ // if child class is a final class.
+ if (child->is_final) {
+ for (i = 0; i < num_methods; i++) {
+ methods[i] = CFCMethod_finalize(methods[i]);
+ }
+ }
+ else {
+ for (i = 0; i < num_methods; i++) {
+ CFCBase_incref((CFCBase*)methods[i]);
+ }
+ }
+ for (i = 0; i < child->num_methods; i++) {
+ CFCBase_decref((CFCBase*)child->methods[i]);
+ }
+ FREEMEM(child->methods);
+ child->methods = methods;
+ child->num_methods = num_methods;
+
+ // Pass it all down to the next generation.
+ CFCClass_bequeath_methods(child);
+ CFCClass_set_tree_grown(child, true);
+ }
+}
+
// Let the children know who their parent class is.
void
CFCClass_establish_ancestry(CFCClass *self)
@@ -437,25 +515,39 @@ CFCClass_tree_to_ladder(CFCClass *self)
return ladder;
}
-CFCVariable**
-CFCClass_novel_member_vars(CFCClass *self)
+static CFCSymbol**
+S_novel_syms(CFCClass *self, CFCSymbol **syms)
{
const char *cnick = CFCSymbol_get_class_cnick((CFCSymbol*)self);
- size_t amount = (self->num_member_vars + 1) * sizeof(CFCVariable*);
- CFCVariable **novel = (CFCVariable**)MALLOCATE(amount);
- size_t i;
+ size_t count = 0;
+ while (syms[count] != NULL) { count++; }
+ size_t amount = (count + 1) * sizeof(CFCSymbol*);
+ CFCSymbol **novel = (CFCSymbol**)MALLOCATE(amount);
size_t num_novel = 0;
- for (i = 0; i < self->num_member_vars; i++) {
- CFCVariable *var = self->member_vars[i];
- const char *var_cnick = CFCSymbol_get_class_cnick((CFCSymbol*)var);
- if (strcmp(var_cnick, cnick) == 0) {
- novel[num_novel++] = var;
+ size_t i;
+ for (i = 0; i < count; i++) {
+ CFCSymbol *sym = syms[i];
+ const char *sym_cnick = CFCSymbol_get_class_cnick((CFCSymbol*)sym);
+ if (strcmp(sym_cnick, cnick) == 0) {
+ novel[num_novel++] = sym;
}
}
novel[num_novel] = NULL;
return novel;
}
+CFCMethod**
+CFCClass_novel_methods(CFCClass *self)
+{
+ return (CFCMethod**)S_novel_syms(self, (CFCSymbol**)self->methods);
+}
+
+CFCVariable**
+CFCClass_novel_member_vars(CFCClass *self)
+{
+ return (CFCVariable**)S_novel_syms(self, (CFCSymbol**)self->member_vars);
+}
+
CFCClass**
CFCClass_children(CFCClass *self)
{
Modified: incubator/lucy/trunk/clownfish/src/CFCClass.h
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCClass.h?rev=1074991&r1=1074990&r2=1074991&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCClass.h (original)
+++ incubator/lucy/trunk/clownfish/src/CFCClass.h Sun Feb 27 05:41:04 2011
@@ -72,6 +72,14 @@ CFCClass_function(CFCClass *self, const
struct CFCMethod*
CFCClass_method(CFCClass *self, const char *sym);
+struct CFCMethod*
+CFCClass_novel_method(CFCClass *self, const char *sym);
+
+/** Pass down methods to from parent to children.
+ */
+void
+CFCClass_bequeath_methods(CFCClass *self);
+
/** Pass down member vars to from parent to children.
*/
void
@@ -83,6 +91,9 @@ CFCClass_establish_ancestry(CFCClass *se
CFCClass**
CFCClass_tree_to_ladder(CFCClass *self);
+struct CFCMethod**
+CFCClass_novel_methods(CFCClass *self);
+
struct CFCVariable**
CFCClass_novel_member_vars(CFCClass *self);