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/06/24 04:25:58 UTC
[lucy-commits] svn commit: r1139140 - in /incubator/lucy/trunk/clownfish: lib/Clownfish.xs
lib/Clownfish/Binding/Core/Class.pm src/CFCBindClass.c src/CFCBindClass.h
Author: marvin
Date: Fri Jun 24 02:25:58 2011
New Revision: 1139140
URL: http://svn.apache.org/viewvc?rev=1139140&view=rev
Log:
Port to_c() method from Clownfish::Binding::Core::Class to C.
Modified:
incubator/lucy/trunk/clownfish/lib/Clownfish.xs
incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Class.pm
incubator/lucy/trunk/clownfish/src/CFCBindClass.c
incubator/lucy/trunk/clownfish/src/CFCBindClass.h
Modified: incubator/lucy/trunk/clownfish/lib/Clownfish.xs
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/lib/Clownfish.xs?rev=1139140&r1=1139139&r2=1139140&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish.xs (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish.xs Fri Jun 24 02:25:58 2011
@@ -1771,6 +1771,13 @@ DESTROY(self)
PPCODE:
CFCBindClass_destroy(self);
+SV*
+to_c(self)
+ CFCBindClass *self;
+CODE:
+ RETVAL = S_sv_eat_c_string(CFCBindClass_to_c(self));
+OUTPUT: RETVAL
+
void
_set_or_get(self, ...)
CFCBindClass *self;
Modified: incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Class.pm
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Class.pm?rev=1139140&r1=1139139&r2=1139140&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Class.pm (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Class.pm Fri Jun 24 02:25:58 2011
@@ -193,88 +193,6 @@ $short_names
END_STUFF
}
-sub to_c {
- my $self = shift;
- my $client = $self->_get_client;
-
- return $client->get_autocode if $client->inert;
-
- my $include_h = $client->include_h;
- my $autocode = $client->get_autocode;
- my $offsets = '';
- my $abstract_funcs = '';
- my $callback_funcs = '';
- my $callbacks = '';
- my $vt_type = $client->full_vtable_type;
- my $meth_num = 0;
- my $cnick = $client->get_cnick;
- my $class_name_def = _name_var_definition($self);
- my $vtable_def = _vtable_definition($self);
- my @class_callbacks;
-
- # Prepare to identify novel methods.
- my %novel = map { ( $_->micro_sym => $_ ) } @{ $client->novel_methods };
-
- for my $method ( @{ $client->methods } ) {
- my $var_name = $method->full_offset_sym($cnick);
-
- # Create offset in bytes for the method from the top of the VTable
- # object.
- my $offset = "(offsetof($vt_type, methods)"
- . " + $meth_num * sizeof(cfish_method_t))";
- $offsets .= "size_t $var_name = $offset;\n";
-
- # Create a default implementation for abstract methods.
- if ( $method->abstract ) {
- if ( $novel{ $method->micro_sym } ) {
- $callback_funcs
- .= Clownfish::Binding::Core::Method->abstract_method_def(
- $method)
- . "\n";
- }
- }
-
- # Define callbacks for methods that can be overridden via the
- # host.
- if ( $method->public or $method->abstract ) {
- my $callback_sym = $method->full_callback_sym;
- if ( $novel{ $method->micro_sym } ) {
- $callback_funcs
- .= Clownfish::Binding::Core::Method->callback_def($method)
- . "\n";
- $callbacks
- .= Clownfish::Binding::Core::Method->callback_obj_def(
- method => $method,
- offset => $offset,
- );
- }
- push @class_callbacks, "&$callback_sym";
- }
- $meth_num++;
- }
-
- # Create a NULL-terminated array of cfish_Callback vars. Since C89
- # doesn't allow us to initialize a pointer to an anonymous array inside a
- # global struct, we have to give it a real symbol and then store a pointer
- # to that symbol inside the VTable struct.
- my $callbacks_var = _full_callbacks_var($self);
- $callbacks .= "cfish_Callback *$callbacks_var" . "[] = {\n ";
- $callbacks .= join( ",\n ", @class_callbacks, "NULL" );
- $callbacks .= "\n};\n";
-
- return <<END_STUFF;
-#include "$include_h"
-
-$offsets
-$callback_funcs
-$callbacks
-$class_name_def
-$vtable_def
-$autocode
-
-END_STUFF
-}
-
1;
__END__
Modified: incubator/lucy/trunk/clownfish/src/CFCBindClass.c
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCBindClass.c?rev=1139140&r1=1139139&r2=1139140&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCBindClass.c (original)
+++ incubator/lucy/trunk/clownfish/src/CFCBindClass.c Fri Jun 24 02:25:58 2011
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <string.h>
#include "CFCBindClass.h"
+#include "CFCBindMethod.h"
#include "CFCBase.h"
#include "CFCClass.h"
#include "CFCFunction.h"
@@ -71,6 +72,130 @@ CFCBindClass_destroy(CFCBindClass *self)
CFCBase_destroy((CFCBase*)self);
}
+static int
+S_method_is_novel(CFCMethod *method, CFCMethod **novel_methods)
+{
+ for (int i = 0; novel_methods[i] != NULL; i++) {
+ if (method == novel_methods[i]) { return 1; }
+ }
+ return 0;
+}
+
+char*
+CFCBindClass_to_c(CFCBindClass *self) {
+ CFCClass *client = self->client;
+
+ if (CFCClass_inert(client)) {
+ return CFCUtil_strdup(CFCClass_get_autocode(client));
+ }
+
+ const char *include_h = CFCClass_include_h(client);
+ const char *autocode = CFCClass_get_autocode(client);
+ const char *vt_type = CFCClass_full_vtable_type(client);
+ const char *cnick = CFCClass_get_cnick(client);
+ char *class_name_def = CFCBindClass_name_var_definition(self);
+ char *vtable_def = CFCBindClass_vtable_definition(self);
+
+ CFCMethod **methods = CFCClass_methods(client);
+ CFCMethod **novel_methods = CFCClass_novel_methods(client);
+
+ char *offsets = CFCUtil_strdup("");
+ char *cb_funcs = CFCUtil_strdup("");
+ char *cb_objects = CFCUtil_strdup("");
+
+ /* Start a NULL-terminated array of cfish_Callback vars. Since C89
+ * doesn't allow us to initialize a pointer to an anonymous array inside a
+ * global struct, we have to give it a real symbol and then store a pointer
+ * to that symbol inside the VTable struct. */
+ char *cb_var = CFCUtil_strdup("");
+ cb_var = CFCUtil_cat_strings(cb_var, "cfish_Callback *",
+ self->full_callbacks_var, "[] = {\n ",
+ NULL);
+
+ for (int meth_num = 0; methods[meth_num] != NULL; meth_num++) {
+ CFCMethod *method = methods[meth_num];
+ int method_is_novel = S_method_is_novel(method, novel_methods);
+ size_t off_sym_size
+ = CFCMethod_full_offset_sym(method, cnick, NULL, 0);
+ char *full_offset_sym = (char*)MALLOCATE(off_sym_size);
+ CFCMethod_full_offset_sym(method, cnick, full_offset_sym,
+ off_sym_size);
+ char meth_num_str[20];
+ sprintf(meth_num_str, "%d", meth_num);
+
+ // Create offset in bytes for the method from the top of the VTable
+ // object.
+ char *offset_str
+ = CFCUtil_cat_strings(CFCUtil_strdup(""), "(offsetof(", vt_type,
+ ", methods) + ", meth_num_str,
+ " * sizeof(cfish_method_t))", NULL);
+ offsets = CFCUtil_cat_strings(offsets, "size_t ", full_offset_sym,
+ " = ", offset_str, ";\n", NULL);
+ FREEMEM(full_offset_sym);
+
+ // Create a default implementation for abstract methods.
+ if (method_is_novel && CFCMethod_abstract(method)) {
+ char *method_def = CFCBindMeth_abstract_method_def(method);
+ cb_funcs = CFCUtil_cat_strings(cb_funcs, method_def, "\n", NULL);
+ FREEMEM(method_def);
+ }
+
+ // Define callbacks for methods that can be overridden via the
+ // host.
+ if (CFCMethod_public(method) || CFCMethod_abstract(method)) {
+ const char *full_cb_sym = CFCMethod_full_callback_sym(method);
+ if (method_is_novel) {
+ char *cb_def = CFCBindMeth_callback_def(method);
+ char *cb_obj_def
+ = CFCBindMeth_callback_obj_def(method, offset_str);
+ cb_funcs = CFCUtil_cat_strings(cb_funcs, cb_def, "\n", NULL);
+ cb_objects = CFCUtil_cat_strings(cb_objects, cb_obj_def, NULL);
+ FREEMEM(cb_def);
+ FREEMEM(cb_obj_def);
+ }
+ cb_var = CFCUtil_cat_strings(cb_var, "&", full_cb_sym, ",\n ",
+ NULL);
+ }
+
+ FREEMEM(offset_str);
+ }
+
+ // Close callbacks variable definition.
+ cb_var = CFCUtil_cat_strings(cb_var, "NULL\n};\n", NULL);
+
+ const char pattern[] =
+ "#include \"%s\"\n"
+ "\n"
+ "%s\n"
+ "%s\n"
+ "%s\n"
+ "%s\n"
+ "%s\n"
+ "%s\n"
+ "%s\n"
+ "\n";
+ size_t size = sizeof(pattern)
+ + strlen(include_h)
+ + strlen(offsets)
+ + strlen(cb_funcs)
+ + strlen(cb_objects)
+ + strlen(cb_var)
+ + strlen(class_name_def)
+ + strlen(vtable_def)
+ + strlen(autocode)
+ + 100;
+ char *code = (char*)MALLOCATE(size);
+ sprintf(code, pattern, include_h, offsets, cb_funcs, cb_objects, cb_var,
+ class_name_def, vtable_def, autocode);
+
+ FREEMEM(cb_funcs);
+ FREEMEM(cb_objects);
+ FREEMEM(cb_var);
+ FREEMEM(class_name_def);
+ FREEMEM(vtable_def);
+ return code;
+}
+
// Create the definition for the instantiable object struct.
char*
CFCBindClass_struct_definition(CFCBindClass *self) {
Modified: incubator/lucy/trunk/clownfish/src/CFCBindClass.h
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCBindClass.h?rev=1139140&r1=1139139&r2=1139140&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCBindClass.h (original)
+++ incubator/lucy/trunk/clownfish/src/CFCBindClass.h Fri Jun 24 02:25:58 2011
@@ -35,6 +35,9 @@ void
CFCBindClass_destroy(CFCBindClass *self);
char*
+CFCBindClass_to_c(CFCBindClass *self);
+
+char*
CFCBindClass_struct_definition(CFCBindClass *self);
char*