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