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 2012/02/23 02:44:23 UTC

[lucy-commits] svn commit: r1292616 - in /incubator/lucy/trunk/clownfish: perl/lib/Clownfish/CFC.xs perl/lib/Clownfish/CFC/Binding/Perl.pm src/CFCPerl.c src/CFCPerl.h

Author: marvin
Date: Thu Feb 23 01:44:22 2012
New Revision: 1292616

URL: http://svn.apache.org/viewvc?rev=1292616&view=rev
Log:
Port remaining CFCPerl routines to C.

Modified:
    incubator/lucy/trunk/clownfish/perl/lib/Clownfish/CFC.xs
    incubator/lucy/trunk/clownfish/perl/lib/Clownfish/CFC/Binding/Perl.pm
    incubator/lucy/trunk/clownfish/src/CFCPerl.c
    incubator/lucy/trunk/clownfish/src/CFCPerl.h

Modified: incubator/lucy/trunk/clownfish/perl/lib/Clownfish/CFC.xs
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/perl/lib/Clownfish/CFC.xs?rev=1292616&r1=1292615&r2=1292616&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/perl/lib/Clownfish/CFC.xs (original)
+++ incubator/lucy/trunk/clownfish/perl/lib/Clownfish/CFC.xs Thu Feb 23 01:44:22 2012
@@ -1898,6 +1898,18 @@ write_boot(self)
 PPCODE:
     CFCPerl_write_boot(self);
 
+void
+write_bindings(self)
+    CFCPerl *self;
+PPCODE:
+    CFCPerl_write_bindings(self);
+
+void
+write_xs_typemap(self)
+    CFCPerl *self;
+PPCODE:
+    CFCPerl_write_xs_typemap(self);
+
 
 MODULE = Clownfish   PACKAGE = Clownfish::CFC::Binding::Perl::Subroutine
 

Modified: incubator/lucy/trunk/clownfish/perl/lib/Clownfish/CFC/Binding/Perl.pm
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/perl/lib/Clownfish/CFC/Binding/Perl.pm?rev=1292616&r1=1292615&r2=1292616&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/perl/lib/Clownfish/CFC/Binding/Perl.pm (original)
+++ incubator/lucy/trunk/clownfish/perl/lib/Clownfish/CFC/Binding/Perl.pm Thu Feb 23 01:44:22 2012
@@ -54,97 +54,6 @@ sub new {
         @args{qw( parcel hierarchy lib_dir boot_class header footer )} );
 }
 
-sub write_bindings {
-    my $self           = shift;
-    my $ordered        = $self->_get_hierarchy->ordered_classes;
-    my $registered     = Clownfish::CFC::Binding::Perl::Class->registered;
-    my $hand_rolled_xs = "";
-    my $generated_xs   = "";
-    my $xs             = "";
-    my @xsubs;
-
-    # Build up a roster of all requested bindings.
-    my %has_xs_code;
-    for my $class (@$registered) {
-        my $class_name = $class->get_class_name;
-        my $class_binding
-            = Clownfish::CFC::Binding::Perl::Class->singleton($class_name)
-            or next;
-        $has_xs_code{$class_name} = 1
-            if $class_binding->get_xs_code;
-    }
-
-    # Pound-includes for generated headers.
-    for my $class (@$ordered) {
-        my $include_h = $class->include_h;
-        $generated_xs .= qq|#include "$include_h"\n|;
-    }
-    $generated_xs .= "\n";
-
-    # Constructors.
-    for my $class (@$ordered) {
-        my $class_name = $class->get_class_name;
-        my $class_binding
-            = Clownfish::CFC::Binding::Perl::Class->singleton($class_name);
-        next unless $class_binding;
-        my $bound = $class_binding->constructor_bindings;
-        $generated_xs .= $_->xsub_def . "\n" for @$bound;
-        push @xsubs, @$bound;
-    }
-
-    # Methods.
-    for my $class (@$ordered) {
-        my $class_name = $class->get_class_name;
-        my $class_binding
-            = Clownfish::CFC::Binding::Perl::Class->singleton($class_name);
-        next unless $class_binding;
-        my $bound = $class_binding->method_bindings;
-        $generated_xs .= $_->xsub_def . "\n" for @$bound;
-        push @xsubs, @$bound;
-    }
-
-    # Hand-rolled XS.
-    for my $class_name ( keys %has_xs_code ) {
-        my $class_binding
-            = Clownfish::CFC::Binding::Perl::Class->singleton($class_name);
-        $hand_rolled_xs .= $class_binding->get_xs_code . "\n";
-    }
-    %has_xs_code = ();
-
-    # Verify that all binding specs were processed.
-    my @leftover_xs = keys %has_xs_code;
-    if (@leftover_xs) {
-        confess(  "Hand-rolled XS spec'd for non-existant classes: "
-                . "'@leftover_xs'" );
-    }
-
-    # Build up code for booting XSUBs at module load time.
-    my @xs_init_lines;
-    for my $xsub (@xsubs) {
-        my $c_name    = $xsub->c_name;
-        my $perl_name = $xsub->perl_name;
-        push @xs_init_lines, qq|newXS("$perl_name", $c_name, file);|;
-    }
-    my $xs_init = join( "\n    ", @xs_init_lines );
-
-    # Params hashes for arg checking of XSUBs that take labeled params.
-    my @params_hash_defs = grep {defined} map { $_->params_hash_def } @xsubs;
-    my $params_hash_defs = join( "\n", @params_hash_defs );
-
-    # Write out if there have been any changes.
-    my $xs_file_contents = $self->_xs_file_contents( $generated_xs, $xs_init,
-        $hand_rolled_xs );
-    my $pm_file_contents = $self->_pm_file_contents($params_hash_defs);
-    write_if_changed( $self->_get_xs_path, $xs_file_contents );
-    write_if_changed( $self->_get_pm_path, $pm_file_contents );
-}
-
-sub write_xs_typemap {
-    my $self = shift;
-    Clownfish::CFC::Binding::Perl::TypeMap->write_xs_typemap(
-        hierarchy => $self->_get_hierarchy, );
-}
-
 1;
 
 __END__

Modified: incubator/lucy/trunk/clownfish/src/CFCPerl.c
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCPerl.c?rev=1292616&r1=1292615&r2=1292616&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCPerl.c (original)
+++ incubator/lucy/trunk/clownfish/src/CFCPerl.c Thu Feb 23 01:44:22 2012
@@ -25,6 +25,10 @@
 #include "CFCHierarchy.h"
 #include "CFCUtil.h"
 #include "CFCPerlClass.h"
+#include "CFCPerlSub.h"
+#include "CFCPerlConstructor.h"
+#include "CFCPerlMethod.h"
+#include "CFCPerlTypeMap.h"
 
 struct CFCPerl {
     CFCBase base;
@@ -444,6 +448,128 @@ CFCPerl_xs_file_contents(CFCPerl *self, 
     return contents;
 }
 
+void
+CFCPerl_write_bindings(CFCPerl *self) {
+    CFCClass **ordered = CFCHierarchy_ordered_classes(self->hierarchy);
+    CFCPerlClass **registry = CFCPerlClass_registry();
+    char *hand_rolled_xs = CFCUtil_strdup("");
+    char *generated_xs   = CFCUtil_strdup("");
+    size_t num_xsubs     = 0;
+    CFCPerlSub **xsubs   = CALLOCATE(num_xsubs + 1, sizeof(CFCPerlSub*));
+
+    // Pound-includes for generated headers.
+    for (size_t i = 0; ordered[i] != NULL; i++) {
+        const char *include_h = CFCClass_include_h(ordered[i]);
+        generated_xs = CFCUtil_cat(generated_xs, "#include \"", include_h,
+                                   "\"\n", NULL);
+    }
+    generated_xs = CFCUtil_cat(generated_xs, "\n", NULL);
+
+    // Constructors.
+    for (size_t i = 0; ordered[i] != NULL; i++) {
+        CFCClass *klass = ordered[i];
+        const char *class_name = CFCClass_get_class_name(klass);
+        CFCPerlClass *class_binding = CFCPerlClass_singleton(class_name);
+        if (class_binding) {
+            CFCPerlConstructor **bound
+                = CFCPerlClass_constructor_bindings(class_binding);
+            for (size_t j = 0; bound[j] != NULL; j++) {
+                char *xsub_def = CFCPerlConstructor_xsub_def(bound[j]);
+                generated_xs = CFCUtil_cat(generated_xs, xsub_def, "\n",
+                                           NULL);
+                FREEMEM(xsub_def);
+
+                // Add to xsubs array.
+                size_t new_size = (num_xsubs + 2) * sizeof(CFCPerlSub*);
+                xsubs = (CFCPerlSub**)REALLOCATE(xsubs, new_size);
+                xsubs[num_xsubs++] = (CFCPerlSub*)bound[j];
+                xsubs[num_xsubs]   = NULL;
+            }
+            FREEMEM(bound);
+        }
+    }
+
+    // Methods.
+    for (size_t i = 0; ordered[i] != NULL; i++) {
+        CFCClass *klass = ordered[i];
+        const char *class_name = CFCClass_get_class_name(klass);
+        CFCPerlClass *class_binding = CFCPerlClass_singleton(class_name);
+        if (class_binding) {
+            CFCPerlMethod **bound
+                = CFCPerlClass_method_bindings(class_binding);
+            for (size_t j = 0; bound[j] != NULL; j++) {
+                char *xsub_def = CFCPerlMethod_xsub_def(bound[j]);
+                generated_xs = CFCUtil_cat(generated_xs, xsub_def, "\n",
+                                           NULL);
+                FREEMEM(xsub_def);
+
+                // Add to xsubs array.
+                size_t new_size = (num_xsubs + 2) * sizeof(CFCPerlSub*);
+                xsubs = (CFCPerlSub**)REALLOCATE(xsubs, new_size);
+                xsubs[num_xsubs++] = (CFCPerlSub*)bound[j];
+                xsubs[num_xsubs]   = NULL;
+            }
+            FREEMEM(bound);
+        }
+    }
+
+    // Hand-rolled XS.
+    for (size_t i = 0; registry[i] != NULL; i++) {
+        CFCPerlClass *class_binding = registry[i];
+        const char *xs = CFCPerlClass_get_xs_code(registry[i]);
+        hand_rolled_xs = CFCUtil_cat(hand_rolled_xs, xs, "\n", NULL);
+    }
+
+    // Build up code for booting XSUBs at module load time.
+    char *xs_init = CFCUtil_strdup("");
+    for (size_t i = 0; xsubs[i] != NULL; i++) {
+        CFCPerlSub *xsub = xsubs[i];
+        const char *c_name = CFCPerlSub_c_name(xsub);
+        const char *perl_name = CFCPerlSub_perl_name(xsub);
+        if (strlen(xs_init)) {
+            xs_init = CFCUtil_cat(xs_init, "\n    ", NULL);
+        }
+        xs_init = CFCUtil_cat(xs_init, "newXS(\"", perl_name, "\", ", c_name,
+                              ", file);", NULL);
+    }
+
+    // Params hashes for arg checking of XSUBs that take labeled params.
+    char *params_hash_defs = CFCUtil_strdup("");
+    for (size_t i = 0; xsubs[i] != NULL; i++) {
+        CFCPerlSub *xsub = xsubs[i];
+        char *def = CFCPerlSub_params_hash_def(xsub);
+        if (def) {
+            if (strlen(params_hash_defs)) {
+                params_hash_defs = CFCUtil_cat(params_hash_defs, "\n", NULL);
+            }
+            params_hash_defs = CFCUtil_cat(params_hash_defs, def, NULL);
+        }
+    }
+
+    // Write out if there have been any changes.
+    char *xs_file_contents
+        = CFCPerl_xs_file_contents(self, generated_xs, xs_init,
+                                   hand_rolled_xs);
+    char *pm_file_contents
+        = CFCPerl_pm_file_contents(self, params_hash_defs);
+    CFCUtil_write_if_changed(self->xs_path, xs_file_contents,
+                             strlen(xs_file_contents));
+    CFCUtil_write_if_changed(self->pm_path, pm_file_contents,
+                             strlen(pm_file_contents));
+
+    FREEMEM(pm_file_contents);
+    FREEMEM(xs_file_contents);
+    FREEMEM(params_hash_defs);
+    FREEMEM(hand_rolled_xs);
+    FREEMEM(xs_init);
+    FREEMEM(generated_xs);
+}
+
+void
+CFCPerl_write_xs_typemap(CFCPerl *self) {
+    CFCPerlTypeMap_write_xs_typemap(self->hierarchy);
+}
+
 CFCParcel*
 CFCPerl_get_parcel(CFCPerl *self) {
     return self->parcel;

Modified: incubator/lucy/trunk/clownfish/src/CFCPerl.h
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCPerl.h?rev=1292616&r1=1292615&r2=1292616&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCPerl.h (original)
+++ incubator/lucy/trunk/clownfish/src/CFCPerl.h Thu Feb 23 01:44:22 2012
@@ -49,6 +49,12 @@ CFCPerl_write_pod(CFCPerl *self);
 void
 CFCPerl_write_boot(CFCPerl *self);
 
+void
+CFCPerl_write_bindings(CFCPerl *self);
+
+void
+CFCPerl_write_xs_typemap(CFCPerl *self);
+
 char*
 CFCPerl_pm_file_contents(CFCPerl *self, const char *params_hash_defs);