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*