You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2013/07/31 14:35:24 UTC

[lucy-commits] [3/3] git commit: refs/heads/master - Generate Perl method bindings for every fresh method

Generate Perl method bindings for every fresh method

This makes sure that methods overriding methods from another parcel will
always have bindings. Should fix test failures caused by missing
destructor bindings.

This increases the size of the Lucy bundle by about 2.6% on OS X 10.8.
Some of the size increase is due to method bindings we need anyway.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/635ad904
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/635ad904
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/635ad904

Branch: refs/heads/master
Commit: 635ad9045c2ef8e935f3579610211cb17571e710
Parents: f1585ac
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Fri Jul 26 16:57:22 2013 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Wed Jul 31 12:21:06 2013 +0200

----------------------------------------------------------------------
 clownfish/compiler/perl/lib/Clownfish/CFC.xs |  7 +--
 clownfish/compiler/src/CFCPerl.c             | 12 +++--
 clownfish/compiler/src/CFCPerlClass.c        | 62 +++++++++--------------
 clownfish/compiler/src/CFCPerlClass.h        |  2 +-
 4 files changed, 36 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/635ad904/clownfish/compiler/perl/lib/Clownfish/CFC.xs
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/lib/Clownfish/CFC.xs b/clownfish/compiler/perl/lib/Clownfish/CFC.xs
index fafe3c3..9faba1f 100644
--- a/clownfish/compiler/perl/lib/Clownfish/CFC.xs
+++ b/clownfish/compiler/perl/lib/Clownfish/CFC.xs
@@ -2286,10 +2286,11 @@ PPCODE:
     CFCPerlClass_append_xs(self, xs);
 
 SV*
-method_bindings(self)
-    CFCPerlClass *self;
+method_bindings(unused, klass)
+    SV *unused;
+    CFCClass *klass;
 CODE:
-    CFCPerlMethod **bound = CFCPerlClass_method_bindings(self);
+    CFCPerlMethod **bound = CFCPerlClass_method_bindings(klass);
     RETVAL = S_array_of_cfcbase_to_av((CFCBase**)bound);
     FREEMEM(bound);
 OUTPUT: RETVAL

http://git-wip-us.apache.org/repos/asf/lucy/blob/635ad904/clownfish/compiler/src/CFCPerl.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCPerl.c b/clownfish/compiler/src/CFCPerl.c
index d1d0dad..a1b961d 100644
--- a/clownfish/compiler/src/CFCPerl.c
+++ b/clownfish/compiler/src/CFCPerl.c
@@ -416,12 +416,12 @@ CFCPerl_write_bindings(CFCPerl *self) {
     }
     generated_xs = CFCUtil_cat(generated_xs, "\n", NULL);
 
+    // Constructors.
     for (size_t i = 0; registry[i] != NULL; i++) {
         CFCPerlClass *class_binding = registry[i];
         CFCClass *client = CFCPerlClass_get_client(class_binding);
         if (!client) { continue; }
 
-        // Constructors.
         CFCPerlConstructor **constructors
             = CFCPerlClass_constructor_bindings(class_binding);
         for (size_t j = 0; constructors[j] != NULL; j++) {
@@ -437,10 +437,14 @@ CFCPerl_write_bindings(CFCPerl *self) {
             xs_init = S_add_xs_init(xs_init, xsub);
         }
         FREEMEM(constructors);
+    }
+
+    // Methods.
+    for (size_t i = 0; ordered[i] != NULL; i++) {
+        CFCClass *klass = ordered[i];
+        if (CFCClass_included(klass)) { continue; }
 
-        // Methods.
-        CFCPerlMethod **methods
-            = CFCPerlClass_method_bindings(class_binding);
+        CFCPerlMethod **methods = CFCPerlClass_method_bindings(klass);
         for (size_t j = 0; methods[j] != NULL; j++) {
             CFCPerlSub *xsub = (CFCPerlSub*)methods[j];
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/635ad904/clownfish/compiler/src/CFCPerlClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCPerlClass.c b/clownfish/compiler/src/CFCPerlClass.c
index 05dc585..e239fff 100644
--- a/clownfish/compiler/src/CFCPerlClass.c
+++ b/clownfish/compiler/src/CFCPerlClass.c
@@ -243,41 +243,32 @@ S_can_be_bound(CFCParamList *param_list, CFCType *return_type) {
 }
 
 CFCPerlMethod**
-CFCPerlClass_method_bindings(CFCPerlClass *self) {
-    CFCClass       *client     = self->client;
-    CFCClass       *parent     = CFCClass_get_parent(client);
-    size_t          num_bound  = 0;
-    CFCMethod     **fresh_methods = CFCClass_fresh_methods(client);
-    CFCClass      **descendants   = CFCClass_tree_to_ladder(client);
+CFCPerlClass_method_bindings(CFCClass *klass) {
+    CFCClass       *parent        = CFCClass_get_parent(klass);
+    size_t          num_bound     = 0;
+    CFCMethod     **fresh_methods = CFCClass_fresh_methods(klass);
     CFCPerlMethod **bound 
         = (CFCPerlMethod**)CALLOCATE(1, sizeof(CFCPerlMethod*));
 
      // Iterate over the class's fresh methods.
     for (size_t i = 0; fresh_methods[i] != NULL; i++) {
-        CFCMethod  *method    = fresh_methods[i];
-        const char *meth_name = CFCMethod_get_macro_sym(method);
-        CFCMethod  *novel_method;
+        CFCMethod *method = fresh_methods[i];
+
+        // Skip private methods.
+        if (CFCSymbol_private((CFCSymbol*)method)) { continue; }
 
-        // Only deal with methods when they are novel (i.e. first declared)
-        // or the parent's definition is from an included parcel (i.e. they
-        // are first declared in this parcel).
+        CFCMethod *novel_method;
         if (CFCMethod_novel(method)) {
             novel_method = method;
         }
         else {
-            CFCMethod *parent_method = CFCClass_method(parent, meth_name);
-            CFCParcel *parcel = CFCMethod_get_parcel(parent_method);
-            if (!CFCParcel_included(parcel)) { continue; }
-
+            const char *meth_name = CFCMethod_get_macro_sym(method);
             novel_method = CFCClass_find_novel_method(parent, meth_name);
             if (!novel_method) {
                 CFCUtil_die("Novel method not found");
             }
         }
 
-        // Skip private methods.
-        if (CFCSymbol_private((CFCSymbol*)method)) { continue; }
-
         // Skip methods which have been explicitly excluded.
         if (CFCMethod_excluded_from_host(novel_method)) {
             continue;
@@ -296,30 +287,23 @@ CFCPerlClass_method_bindings(CFCPerlClass *self) {
             alias = CFCMethod_micro_sym(method);
         }
 
-        /* Create an XSub binding for each override.  Each of these directly
-         * calls the implementing function, rather than invokes the method on
-         * the object using VTable method dispatch.  Doing things this way
-         * allows SUPER:: invocations from Perl-space to work properly.
+        /* Create the binding, add it to the array.
+         *
+         * Also create an XSub binding for each override.  Each of these
+         * directly calls the implementing function, rather than invokes the
+         * method on the object using VTable method dispatch.  Doing things
+         * this way allows SUPER:: invocations from Perl-space to work
+         * properly.
          */
-        for (size_t j = 0; descendants[j] != NULL; j++) {
-            CFCClass *descendant = descendants[j];
-            CFCMethod *real_method
-                = CFCClass_fresh_method(descendant, meth_name);
-            if (!real_method) { continue; }
-
-            // Create the binding, add it to the array.
-            CFCPerlMethod *meth_binding = CFCPerlMethod_new(real_method, alias);
-            size_t size = (num_bound + 2) * sizeof(CFCPerlMethod*);
-            bound = (CFCPerlMethod**)REALLOCATE(bound, size);
-            bound[num_bound] = meth_binding;
-            num_bound++;
-            bound[num_bound] = NULL;
-        }
-
+        CFCPerlMethod *meth_binding = CFCPerlMethod_new(method, alias);
+        size_t size = (num_bound + 2) * sizeof(CFCPerlMethod*);
+        bound = (CFCPerlMethod**)REALLOCATE(bound, size);
+        bound[num_bound] = meth_binding;
+        num_bound++;
+        bound[num_bound] = NULL;
     }
 
     FREEMEM(fresh_methods);
-    FREEMEM(descendants);
 
     return bound;
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/635ad904/clownfish/compiler/src/CFCPerlClass.h
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCPerlClass.h b/clownfish/compiler/src/CFCPerlClass.h
index 89fd1fe..88a73c6 100644
--- a/clownfish/compiler/src/CFCPerlClass.h
+++ b/clownfish/compiler/src/CFCPerlClass.h
@@ -103,7 +103,7 @@ CFCPerlClass_exclude_constructor(CFCPerlClass *self);
  * representing all bound methods.
  */
 struct CFCPerlMethod**
-CFCPerlClass_method_bindings(CFCPerlClass *self);
+CFCPerlClass_method_bindings(struct CFCClass *klass);
 
 /** Return an array of Clownfish::CFC::Binding::Perl::Constructor objects
  * representing all bound constructors.