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/26 17:16:19 UTC

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

Updated Branches:
  refs/heads/perl-method-bindings [created] 7ef403131


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/7ef40313
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/7ef40313
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/7ef40313

Branch: refs/heads/perl-method-bindings
Commit: 7ef4031318d0e53941b00900c8b94e82c7fc306c
Parents: f1585ac
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Fri Jul 26 16:57:22 2013 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Fri Jul 26 17:12:33 2013 +0200

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


http://git-wip-us.apache.org/repos/asf/lucy/blob/7ef40313/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..6e9a51d 100644
--- a/clownfish/compiler/perl/lib/Clownfish/CFC.xs
+++ b/clownfish/compiler/perl/lib/Clownfish/CFC.xs
@@ -2286,10 +2286,10 @@ PPCODE:
     CFCPerlClass_append_xs(self, xs);
 
 SV*
-method_bindings(self)
-    CFCPerlClass *self;
+method_bindings(klass)
+    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/7ef40313/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/7ef40313/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/7ef40313/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.