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/25 03:01:48 UTC

[lucy-commits] svn commit: r1139475 - in /incubator/lucy/trunk/clownfish: lib/Clownfish.xs lib/Clownfish/Binding/Core/Class.pm src/CFCBindClass.c src/CFCBindClass.h

Author: marvin
Date: Sat Jun 25 01:01:48 2011
New Revision: 1139475

URL: http://svn.apache.org/viewvc?rev=1139475&view=rev
Log:
Refactor many chunks of the C header file generation by
Clownfish::Binding::Core::Class into helper routines, ported 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=1139475&r1=1139474&r2=1139475&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish.xs (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish.xs Sat Jun 25 01:01:48 2011
@@ -1783,6 +1783,14 @@ _set_or_get(self, ...)
     CFCBindClass *self;
 ALIAS:
     _short_names_macro  = 6
+    _callback_declarations = 8
+    _method_typedefs = 10
+    _parent_include = 12
+    _sub_declarations = 14
+    _inert_var_declarations = 16
+    _method_defs = 18
+    _vt_singleton_def = 20
+    _short_names = 22
 PPCODE:
 {
     START_SET_OR_GET_SWITCH
@@ -1791,6 +1799,46 @@ PPCODE:
                 retval = newSVpv(value, strlen(value));
             }
             break;
+        case 8: {
+                char *value = CFCBindClass_callback_declarations(self);
+                retval = S_sv_eat_c_string(value);
+            }
+            break;
+        case 10: {
+                char *value = CFCBindClass_method_typedefs(self);
+                retval = S_sv_eat_c_string(value);
+            }
+            break;
+        case 12: {
+                char *value = CFCBindClass_parent_include(self);
+                retval = S_sv_eat_c_string(value);
+            }
+            break;
+        case 14: {
+                char *value = CFCBindClass_sub_declarations(self);
+                retval = S_sv_eat_c_string(value);
+            }
+            break;
+        case 16: {
+                char *value = CFCBindClass_inert_var_declarations(self);
+                retval = S_sv_eat_c_string(value);
+            }
+            break;
+        case 18: {
+                char *value = CFCBindClass_method_defs(self);
+                retval = S_sv_eat_c_string(value);
+            }
+            break;
+        case 20: {
+                char *value = CFCBindClass_vt_singleton_def(self);
+                retval = S_sv_eat_c_string(value);
+            }
+            break;
+        case 22: {
+                char *value = CFCBindClass_short_names(self);
+                retval = S_sv_eat_c_string(value);
+            }
+            break;
     END_SET_OR_GET_SWITCH
 }
 

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=1139475&r1=1139474&r2=1139475&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Class.pm (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Class.pm Sat Jun 25 01:01:48 2011
@@ -38,95 +38,32 @@ sub to_c_header {
     my $methods       = $client->methods;
     my $novel_methods = $client->novel_methods;
     my $inert_vars    = $client->inert_vars;
-    my $vtable_var    = $client->full_vtable_var;
-    my $short_vt_var  = $client->short_vtable_var;
-    my $short_struct  = $client->get_struct_sym;
-    my $full_struct   = $client->full_struct_sym;
-    my $c_file_sym    = "C_" . uc($full_struct);
+    my $c_file_sym    = "C_" . uc($client->full_struct_sym);
     my $struct_def    = _struct_definition($self);
 
     # If class inherits from something, include the parent class's header.
-    my $parent_include = "";
-    if ( my $parent = $client->get_parent ) {
-        $parent_include = $parent->include_h;
-        $parent_include = qq|#include "$parent_include"|;
-    }
+    my $parent_include = _parent_include($self);
 
     # Add a C function definition for each method and each function.
-    my $sub_declarations = "";
-    for my $sub ( @$functions, @$novel_methods ) {
-        $sub_declarations
-            .= Clownfish::Binding::Core::Function->func_declaration($sub)
-            . "\n\n";
-    }
+    my $sub_declarations = _sub_declarations($self);
 
     # Declare class (a.k.a. "inert") variables.
-    my $inert_var_defs = "";
-    for my $inert_var (@$inert_vars) {
-        $inert_var_defs .= "extern " . $inert_var->global_c . ";\n";
-    }
+    my $inert_var_defs = _inert_var_declarations($self);
 
     # Declare typedefs for novel methods, to ease casting.
-    my $method_typedefs = '';
-    for my $method (@$novel_methods) {
-        $method_typedefs
-            .= Clownfish::Binding::Core::Method->typedef_dec($method) . "\n";
-    }
+    my $method_typedefs = _method_typedefs($self);
 
     # Define method invocation syntax.
-    my $method_defs = '';
-    for my $method (@$methods) {
-        $method_defs .= Clownfish::Binding::Core::Method->method_def(
-            method => $method,
-            class  => $self->_get_client,
-        ) . "\n";
-    }
+    my $method_defs = _method_defs($self);
 
     # Declare the virtual table singleton object.
-    my $vt_type = $self->_get_client->full_vtable_type;
-    my $vt      = "extern struct $vt_type ${vtable_var}_vt;";
-    my $vtable_object
-        = "#define $vtable_var ((cfish_VTable*)&${vtable_var}_vt)";
-    my $num_methods = scalar @$methods;
+    my $vt_singleton_def = _vt_singleton_def($self);
 
     # Declare cfish_Callback objects.
-    my $callback_declarations = "";
-    for my $method (@$novel_methods) {
-        next unless $method->public || $method->abstract;
-        $callback_declarations
-            .= Clownfish::Binding::Core::Method->callback_dec($method);
-    }
+    my $callback_declarations = _callback_declarations($self);
 
     # Define short names.
-    my $short_names       = '';
-    my $short_names_macro = _short_names_macro($self);
-    for my $function (@$functions) {
-        my $short_func_sym = $function->short_sym;
-        my $full_func_sym  = $function->full_sym;
-        $short_names .= "  #define $short_func_sym $full_func_sym\n";
-    }
-    for my $inert_var (@$inert_vars) {
-        my $short_sym = $inert_var->short_sym;
-        my $full_sym  = $inert_var->full_sym;
-        $short_names .= "  #define $short_sym $full_sym\n";
-    }
-    if ( !$client->inert ) {
-        for my $method (@$novel_methods) {
-            if ( !$method->isa("Clownfish::Method::Overridden") ) {
-                my $short_typedef = $method->short_typedef;
-                my $full_typedef  = $method->full_typedef;
-                $short_names .= "  #define $short_typedef $full_typedef\n";
-            }
-            my $short_func_sym = $method->short_func_sym;
-            my $full_func_sym  = $method->full_func_sym;
-            $short_names .= "  #define $short_func_sym $full_func_sym\n";
-        }
-        for my $method (@$methods) {
-            my $short_method_sym = $method->short_method_sym($cnick);
-            my $full_method_sym  = $method->full_method_sym($cnick);
-            $short_names .= "  #define $short_method_sym $full_method_sym\n";
-        }
-    }
+    my $short_names = _short_names($self);
 
     # Make the spacing in the file a little more elegant.
     s/\s+$// for ( $method_typedefs, $method_defs, $short_names );
@@ -142,9 +79,7 @@ $inert_var_defs
 
 $sub_declarations
 
-#ifdef $short_names_macro
 $short_names
-#endif /* $short_names_macro */
 
 END_INERT
     }
@@ -169,26 +104,8 @@ $method_typedefs
 
 $method_defs
 
-typedef struct $vt_type {
-    cfish_VTable *vtable;
-    cfish_ref_t ref;
-    cfish_VTable *parent;
-    cfish_CharBuf *name;
-    uint32_t flags;
-    void *x;
-    size_t obj_alloc_size;
-    size_t vt_alloc_size;
-    void *callbacks;
-    cfish_method_t methods[$num_methods];
-} $vt_type;
-$vt
-$vtable_object
-
-#ifdef $short_names_macro
-  #define $short_struct $full_struct
-  #define $short_vt_var $vtable_var
+$vt_singleton_def
 $short_names
-#endif /* $short_names_macro */
 
 END_STUFF
 }

Modified: incubator/lucy/trunk/clownfish/src/CFCBindClass.c
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCBindClass.c?rev=1139475&r1=1139474&r2=1139475&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCBindClass.c (original)
+++ incubator/lucy/trunk/clownfish/src/CFCBindClass.c Sat Jun 25 01:01:48 2011
@@ -19,6 +19,7 @@
 #include <stdio.h>
 #include <string.h>
 #include "CFCBindClass.h"
+#include "CFCBindFunction.h"
 #include "CFCBindMethod.h"
 #include "CFCBase.h"
 #include "CFCClass.h"
@@ -336,3 +337,217 @@ CFCBindClass_short_names_macro(CFCBindCl
     return self->short_names_macro;
 }
 
+// Declare cfish_Callback objects.
+char*
+CFCBindClass_callback_declarations(CFCBindClass *self) {
+    CFCMethod** novel_methods = CFCClass_novel_methods(self->client);
+    char *declarations = CFCUtil_strdup("");
+    for (int i = 0; novel_methods[i] != NULL; i++) {
+        CFCMethod *method = novel_methods[i];
+        if (CFCMethod_public(method) || CFCMethod_abstract(method)) {
+            char *callback = CFCBindMeth_callback_dec(method);
+            declarations = CFCUtil_cat_strings(declarations, callback, NULL);
+            FREEMEM(callback);
+        }
+    }
+    FREEMEM(novel_methods);
+    return declarations;
+}
+
+// Declare typedefs for novel methods, to ease casting.
+char*
+CFCBindClass_method_typedefs(CFCBindClass *self) {
+    CFCMethod** novel_methods = CFCClass_novel_methods(self->client);
+    char *typedefs = CFCUtil_strdup("");
+    for (int i = 0; novel_methods[i] != NULL; i++) {
+        CFCMethod *method = novel_methods[i];
+        char *typedef_str = CFCBindMeth_typdef_dec(method);
+        typedefs = CFCUtil_cat_strings(typedefs, typedef_str, "\n", NULL);
+        FREEMEM(typedef_str);
+    }
+    FREEMEM(novel_methods);
+    return typedefs;
+}
+
+// If class inherits from something, include the parent class's header.
+char*
+CFCBindClass_parent_include(CFCBindClass *self) {
+    char *parent_include = CFCUtil_strdup("");
+    CFCClass *parent = CFCClass_get_parent(self->client);
+    if (parent) {
+        parent_include
+            = CFCUtil_cat_strings(parent_include, "#include \"",
+                                  CFCClass_include_h(parent), "\"", NULL);
+    }
+    return parent_include;
+}
+
+// Add a C function definition for each method and each function.
+char*
+CFCBindClass_sub_declarations(CFCBindClass *self) {
+    CFCFunction **functions = CFCClass_functions(self->client);
+    CFCMethod** novel_methods = CFCClass_novel_methods(self->client);
+    char *declarations = CFCUtil_strdup("");
+    for (int i = 0; functions[i] != NULL; i++) {
+        CFCFunction *func = functions[i];
+        char *dec = CFCBindFunc_func_declaration(func);
+        declarations = CFCUtil_cat_strings(declarations, dec, "\n\n", NULL);
+        FREEMEM(dec);
+    }
+    for (int i = 0; novel_methods[i] != NULL; i++) {
+        CFCMethod *method = novel_methods[i];
+        char *dec = CFCBindFunc_func_declaration((CFCFunction*)method);
+        declarations = CFCUtil_cat_strings(declarations, dec, "\n\n", NULL);
+        FREEMEM(dec);
+    }
+    FREEMEM(novel_methods);
+    return declarations;
+}
+
+// Declare class (a.k.a. "inert") variables.
+char*
+CFCBindClass_inert_var_declarations(CFCBindClass *self) {
+    CFCVariable **inert_vars = CFCClass_inert_vars(self->client);
+    char *declarations = CFCUtil_strdup("");
+    for (int i = 0; inert_vars[i] != NULL; i++) {
+        const char *global_c = CFCVariable_global_c(inert_vars[i]);
+        declarations = CFCUtil_cat_strings(declarations, "extern ", global_c, 
+                                           ";\n", NULL);
+    }
+    return declarations;
+}
+
+// Define method invocation inline functions.
+char*
+CFCBindClass_method_defs(CFCBindClass *self) {
+    CFCMethod **methods = CFCClass_methods(self->client);
+    char *method_defs = CFCUtil_strdup("");
+    for (int i = 0; methods[i] != NULL; i++) {
+        CFCMethod *method = methods[i];
+        char *def = CFCBindMeth_method_def(method, self->client);
+        method_defs = CFCUtil_cat_strings(method_defs, def, "\n", NULL);
+        FREEMEM(def);
+    }
+    return method_defs;
+}
+
+
+// Define the virtual table singleton object.
+char*
+CFCBindClass_vt_singleton_def(CFCBindClass *self) {
+    CFCClass   *client      = self->client;
+    const char *vt_type     = CFCClass_full_vtable_type(client);
+    const char *vt_var      = CFCClass_full_vtable_var(client);
+    const char *vt_hidden   = CFCClass_full_vtable_hidden(client);
+    size_t      num_methods = CFCClass_num_methods(client);
+
+    const char pattern[] = 
+        "typedef struct %s {\n"
+        "    cfish_VTable *vtable;\n"
+        "    cfish_ref_t ref;\n"
+        "    cfish_VTable *parent;\n"
+        "    cfish_CharBuf *name;\n"
+        "    uint32_t flags;\n"
+        "    void *x;\n"
+        "    size_t obj_alloc_size;\n"
+        "    size_t vt_alloc_size;\n"
+        "    void *callbacks;\n"
+        "    cfish_method_t methods[%lu];\n"
+        "} %s;\n"
+        "extern struct %s %s;\n"
+        "#define %s ((cfish_VTable*)&%s)\n";
+
+    size_t size = sizeof(pattern)
+                  + strlen(vt_type)
+                  + 40 // num_methods
+                  + strlen(vt_type)
+                  + strlen(vt_type)
+                  + strlen(vt_hidden)
+                  + strlen(vt_var)
+                  + strlen(vt_hidden)
+                  + 30;
+    char *def = (char*)MALLOCATE(size);
+    sprintf(def, pattern, vt_type, (unsigned long)num_methods, vt_type,
+            vt_type, vt_hidden, vt_var, vt_hidden);
+
+    return def;
+}
+
+// Define short names for all of the symbols associated with this class.
+char*
+CFCBindClass_short_names(CFCBindClass *self) {
+    CFCClass *client = self->client;
+    char *short_names = CFCUtil_strdup("");
+    short_names = CFCUtil_cat_strings(short_names, "#ifdef ",
+                                      self->short_names_macro, "\n", NULL);
+
+    if (!CFCClass_inert(client)) {
+        const char *short_struct = CFCClass_get_struct_sym(client);
+        const char *full_struct  = CFCClass_full_struct_sym(client);
+        const char *short_vt_var = CFCClass_short_vtable_var(client);
+        const char *full_vt_var  = CFCClass_full_vtable_var(client);
+        short_names 
+            = CFCUtil_cat_strings(short_names, "  #define ",
+                                  short_struct, " ", full_struct, "\n",
+                                  "  #define ", short_vt_var, " ", 
+                                  full_vt_var, "\n", NULL);
+    }
+    
+    CFCFunction **functions = CFCClass_functions(client);
+    for (int i = 0; functions[i] != NULL; i++) {
+        CFCFunction *func = functions[i];
+        short_names 
+            = CFCUtil_cat_strings(short_names, "  #define ",
+                                  CFCFunction_short_func_sym(func), " ", 
+                                  CFCFunction_full_func_sym(func), "\n",
+                                  NULL);
+    }
+
+    CFCVariable **inert_vars = CFCClass_inert_vars(client);
+    for (int i = 0; inert_vars[i] != NULL; i++) {
+        CFCVariable *var = inert_vars[i];
+        short_names 
+            = CFCUtil_cat_strings(short_names, "  #define ",
+                                  CFCVariable_short_sym(var), " ", 
+                                  CFCVariable_full_sym(var), "\n", NULL);
+    }
+
+    if (!CFCClass_inert(client)) {
+        CFCMethod **novel_methods = CFCClass_novel_methods(client);
+        for (int i = 0; novel_methods[i] != NULL; i++) {
+            CFCMethod *meth = novel_methods[i];
+            const char *short_typedef = CFCMethod_short_typedef(meth);
+            const char *full_typedef  = CFCMethod_full_typedef(meth);
+            short_names 
+                = CFCUtil_cat_strings(short_names, "  #define ",
+                                      short_typedef, " ", full_typedef, "\n",
+                                      NULL);
+            const char *short_func = CFCMethod_short_implementing_func_sym(meth);
+            const char *full_func  = CFCMethod_implementing_func_sym(meth);
+            short_names 
+                = CFCUtil_cat_strings(short_names, "  #define ", short_func,
+                                      " ", full_func, "\n", NULL);
+        }
+        FREEMEM(novel_methods);
+
+        CFCMethod  **methods = CFCClass_methods(client);
+        const char  *cnick   = CFCClass_get_cnick(client);
+        for (int i = 0; methods[i] != NULL; i++) {
+            CFCMethod *meth = methods[i];
+            size_t size = CFCMethod_short_method_sym(meth, cnick, NULL, 0);
+            char *short_sym = (char*)MALLOCATE(size);
+            CFCMethod_short_method_sym(meth, cnick, short_sym, size);
+            size = CFCMethod_full_method_sym(meth, cnick, NULL, 0);
+            char *full_sym = (char*)MALLOCATE(size);
+            CFCMethod_full_method_sym(meth, cnick, full_sym, size);
+            short_names 
+                = CFCUtil_cat_strings(short_names, "  #define ", short_sym,
+                                      " ", full_sym, "\n", NULL);
+        }
+    }
+    short_names = CFCUtil_cat_strings(short_names, "#endif /* ",
+                                      self->short_names_macro, " */\n", NULL);
+
+    return short_names;
+}
+

Modified: incubator/lucy/trunk/clownfish/src/CFCBindClass.h
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCBindClass.h?rev=1139475&r1=1139474&r2=1139475&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCBindClass.h (original)
+++ incubator/lucy/trunk/clownfish/src/CFCBindClass.h Sat Jun 25 01:01:48 2011
@@ -46,6 +46,30 @@ CFCBindClass_get_client(struct CFCBindCl
 const char*
 CFCBindClass_short_names_macro(CFCBindClass *self);
 
+char*
+CFCBindClass_callback_declarations(CFCBindClass *self);
+
+char*
+CFCBindClass_method_typedefs(CFCBindClass *self);
+
+char*
+CFCBindClass_parent_include(CFCBindClass *self);
+
+char*
+CFCBindClass_sub_declarations(CFCBindClass *self);
+
+char*
+CFCBindClass_inert_var_declarations(CFCBindClass *self);
+
+char*
+CFCBindClass_method_defs(CFCBindClass *self);
+
+char*
+CFCBindClass_vt_singleton_def(CFCBindClass *self);
+
+char*
+CFCBindClass_short_names(CFCBindClass *self);
+
 #ifdef __cplusplus
 }
 #endif