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);