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/11/13 02:50:10 UTC

[lucy-commits] [1/7] git commit: refs/heads/kill_clownfish_host - Refactor callbacks for compiled object size.

Updated Branches:
  refs/heads/kill_clownfish_host [created] 0712b3f3b


Refactor callbacks for compiled object size.

Execute significant amounts of perlcall code within shared static
routines, in order to save on compiled object size.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/0712b3f3
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/0712b3f3
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/0712b3f3

Branch: refs/heads/kill_clownfish_host
Commit: 0712b3f3b11dc391ff80cfff7f142e85afd0ce91
Parents: 6d4c932
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Sat Nov 10 20:05:36 2012 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Mon Nov 12 17:33:20 2012 -0800

----------------------------------------------------------------------
 clownfish/compiler/src/CFCPerl.c       |   73 +++++++++++++++++++++-
 clownfish/compiler/src/CFCPerlMethod.c |   93 +++++----------------------
 2 files changed, 89 insertions(+), 77 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/0712b3f3/clownfish/compiler/src/CFCPerl.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCPerl.c b/clownfish/compiler/src/CFCPerl.c
index 7e15e21..5f664e3 100644
--- a/clownfish/compiler/src/CFCPerl.c
+++ b/clownfish/compiler/src/CFCPerl.c
@@ -522,8 +522,79 @@ CFCPerl_write_callbacks(CFCPerl *self) {
     "\n"
     "#include \"XSBind.h\"\n"
     "#include \"parcel.h\"\n"
-    "#include \"Clownfish/Host.h\"\n"
+    "\n"
+    "static void\n"
+    "S_finish_callback_void(const char *meth_name) {\n"
+    "    int count = call_method(meth_name, G_VOID | G_DISCARD);\n"
+    "    if (count != 0) {\n"
+    "        CFISH_THROW(CFISH_ERR, \"Bad callback to '%%s': %%i32\",\n"
+    "                    \"%s\", (int32_t)count);\n"
+    "    }\n"
+    "    FREETMPS;\n"
+    "    LEAVE;\n"
+    "}\n"
+    "\n"
+    "static CHY_INLINE SV*\n"
+    "SI_do_callback_sv(const char *meth_name) {\n"
+    "    int count = call_method(meth_name, G_SCALAR);\n"
+    "    if (count != 1) {\n"
+    "        CFISH_THROW(CFISH_ERR, \"Bad callback to '%%s': %%i32\",\n"
+    "                    \"%s\", (int32_t)count);\n"
+    "    }\n"
+    "    dSP;\n"
+    "    SV *return_sv = POPs;\n"
+    "    PUTBACK;\n"
+    "    return return_sv;\n"
+    "}\n"
+    "\n"
+    "static int64_t\n"
+    "S_finish_callback_i64(const char *meth_name) {\n"
+    "    SV *return_sv = SI_do_callback_sv(meth_name);\n"
+    "    int64_t retval;\n"
+    "    if (sizeof(IV) == 8) {\n"
+    "        retval = (int64_t)SvIV(return_sv);\n"
+    "    }\n"
+    "    else {\n"
+    "        if (SvIOK(return_sv)) {\n"
+    "            // It's already no more than 32 bits, so don't convert.\n"
+    "            retval = SvIV(return_sv);\n"
+    "        }\n"
+    "        else {\n"
+    "            // Maybe lossy.\n"
+    "            double temp = SvNV(return_sv);\n"
+    "            retval = (int64_t)temp;\n"
+    "        }\n"
+    "    }\n"
+    "    FREETMPS;\n"
+    "    LEAVE;\n"
+    "    return retval;\n"
+    "}\n"
+    "\n"
+    "static double\n"
+    "S_finish_callback_f64(const char *meth_name) {\n"
+    "    SV *return_sv = SI_do_callback_sv(meth_name);\n"
+    "    double retval = SvNV(return_sv);\n"
+    "    FREETMPS;\n"
+    "    LEAVE;\n"
+    "    return retval;\n"
+    "}\n"
+    "\n"
+    "static cfish_Obj*\n"
+    "S_finish_callback_obj(void *vself, const char *meth_name,\n"
+    "                      int nullable) {\n"
+    "    SV *return_sv = SI_do_callback_sv(meth_name);\n"
+    "    cfish_Obj *retval = XSBind_perl_to_cfish(return_sv);\n"
+    "    FREETMPS;\n"
+    "    LEAVE;\n"
+    "    if (!nullable && !retval) {\n"
+    "        CFISH_THROW(CFISH_ERR, \"%%o#%%s cannot return NULL\",\n"
+    "                    Cfish_Obj_Get_Class_Name((cfish_Obj*)vself),\n"
+    "                    meth_name);\n"
+    "    }\n"
+    "    return retval;\n"
+    "}\n"
     "\n";
+
     char *content = CFCUtil_strdup(start);
 
     for (size_t i = 0; ordered[i] != NULL; i++) {

http://git-wip-us.apache.org/repos/asf/lucy/blob/0712b3f3/clownfish/compiler/src/CFCPerlMethod.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCPerlMethod.c b/clownfish/compiler/src/CFCPerlMethod.c
index 7596e73..a0cb4db 100644
--- a/clownfish/compiler/src/CFCPerlMethod.c
+++ b/clownfish/compiler/src/CFCPerlMethod.c
@@ -651,13 +651,7 @@ S_void_callback_def(CFCMethod *method, const char *callback_start,
         "void\n"
         "%s(%s) {\n"
         "%s"
-        "    int _count = call_method(\"%s\", G_VOID | G_DISCARD);\n"
-        "    if (_count != 0) {\n"
-        "        CFISH_THROW(CFISH_ERR, \"callback '%%s' returned too many values: %%i32\",\n"
-        "                    \"%s\", (int32_t)_count);\n"
-        "    }\n"
-        "    FREETMPS;\n"
-        "    LEAVE;%s\n"
+        "    S_finish_callback_void(\"%s\");%s\n"
         "}\n";
 
     size_t size = sizeof(pattern)
@@ -665,12 +659,11 @@ S_void_callback_def(CFCMethod *method, const char *callback_start,
                   + strlen(params)
                   + strlen(callback_start)
                   + strlen(micro_sym)
-                  + strlen(micro_sym)
                   + strlen(refcount_mods)
                   + 20;
     char *callback_def = (char*)MALLOCATE(size);
     sprintf(callback_def, pattern, override_sym, params, callback_start,
-            micro_sym, micro_sym, refcount_mods);
+            micro_sym, refcount_mods);
 
     return callback_def;
 }
@@ -683,31 +676,13 @@ S_primitive_callback_def(CFCMethod *method, const char *callback_start,
     CFCType *return_type = CFCMethod_get_return_type(method);
     const char *ret_type_str = CFCType_to_c(return_type);
     const char *micro_sym = CFCMethod_micro_sym(method);
-    char *assign_retval = NULL;
+    char callback_func[50];
 
     if (CFCType_is_integer(return_type)) {
-        int width = CFCType_get_width(return_type);
-        if (width != 0 && width <= 4) {
-            char pattern[] = "    %s retval = (%s)SvIV(return_sv);\n";
-            size_t size = sizeof(pattern) + (2 * strlen(ret_type_str)) + 20;
-            assign_retval = (char*)MALLOCATE(size);
-            sprintf(assign_retval, pattern, ret_type_str, ret_type_str);
-        }
-        else {
-            char pattern[] =
-            "    %s retval = (sizeof(IV) >= sizeof(%s))\n"
-            "                ? (%s)SvIV(return_sv) : (%s)SvNV(return_sv);\n";
-            size_t size = sizeof(pattern) + (4 * strlen(ret_type_str)) + 20;
-            assign_retval = (char*)MALLOCATE(size);
-            sprintf(assign_retval, pattern, ret_type_str, ret_type_str,
-                    ret_type_str, ret_type_str);
-        }
+        strcpy(callback_func, "S_finish_callback_i64");
     }
     else if (CFCType_is_floating(return_type)) {
-        char pattern[] = "    %s retval = (%s)SvNV(return_sv);\n";
-        size_t size = sizeof(pattern) + (2 * strlen(ret_type_str)) + 20;
-        assign_retval = (char*)MALLOCATE(size);
-        sprintf(assign_retval, pattern, ret_type_str, ret_type_str);
+        strcpy(callback_func, "S_finish_callback_f64");
     }
     else {
         CFCUtil_die("Unexpected type: %s", ret_type_str);
@@ -717,36 +692,25 @@ S_primitive_callback_def(CFCMethod *method, const char *callback_start,
         "%s\n"
         "%s(%s) {\n"
         "%s"
-        "    int _count = call_method(\"%s\", G_SCALAR);\n"
-        "    if (_count != 1) {\n"
-        "        CFISH_THROW(CFISH_ERR, \"Bad number of return vals from '%%s': %%i32\",\n"
-        "                    \"%s\", (int32_t)_count);\n"
-        "    }\n"
-        "    SPAGAIN;\n"
-        "    SV *return_sv = POPs;\n"
-        "    PUTBACK;\n"
-        "%s"
-        "    FREETMPS;\n"
-        "    LEAVE;%s\n"
+        "    %s retval = (%s)%s(\"%s\");%s\n"
         "    return retval;\n"
         "}\n";
-
     size_t size = sizeof(pattern)
                   + strlen(ret_type_str)
                   + strlen(override_sym)
                   + strlen(params)
                   + strlen(callback_start)
+                  + strlen(ret_type_str)
+                  + strlen(ret_type_str)
+                  + strlen(callback_func)
                   + strlen(micro_sym)
-                  + strlen(micro_sym)
-                  + strlen(assign_retval)
                   + strlen(refcount_mods)
                   + 30;
     char *callback_def = (char*)MALLOCATE(size);
     sprintf(callback_def, pattern, ret_type_str, override_sym, params,
-            callback_start, micro_sym, micro_sym, assign_retval,
-            refcount_mods);
+            callback_start, ret_type_str, ret_type_str, callback_func,
+            micro_sym, refcount_mods);
 
-    FREEMEM(assign_retval);
     return callback_def;
 }
 
@@ -758,34 +722,13 @@ S_obj_callback_def(CFCMethod *method, const char *callback_start,
     CFCType *return_type = CFCMethod_get_return_type(method);
     const char *ret_type_str = CFCType_to_c(return_type);
     const char *micro_sym = CFCMethod_micro_sym(method);
-
-    char *nullable_check = CFCUtil_strdup("");
-    if (!CFCType_nullable(return_type)) {
-        const char *macro_sym = CFCMethod_get_macro_sym(method);
-        char pattern[] =
-            "\n    if (!retval) { CFISH_THROW(CFISH_ERR, "
-            "\"%s() for class '%%o' cannot return NULL\", "
-            "Cfish_Obj_Get_Class_Name((cfish_Obj*)self)); }";
-        size_t size = sizeof(pattern) + strlen(macro_sym) + 30;
-        nullable_check = (char*)REALLOCATE(nullable_check, size);
-        sprintf(nullable_check, pattern, macro_sym);
-    }
+    const char *nullable  = CFCType_nullable(return_type) ? "true" : "false";
 
     char pattern[] =
         "%s\n"
         "%s(%s) {\n"
         "%s"
-        "    int _count = call_method(\"%s\", G_SCALAR);\n"
-        "    if (_count != 1) {\n"
-        "        CFISH_THROW(CFISH_ERR, \"Bad number of return vals from '%%s': %%i32\",\n"
-        "                    \"%s\", (int32_t)_count);\n"
-        "    }\n"
-        "    SPAGAIN;\n"
-        "    SV *return_sv = POPs;\n"
-        "    PUTBACK;\n"
-        "    %s retval = (%s)XSBind_perl_to_cfish(return_sv);\n"
-        "    FREETMPS;\n"
-        "    LEAVE;%s%s\n"
+        "    %s retval = (%s)S_finish_callback_obj(self, \"%s\", %s);%s\n"
         "    return retval;\n"
         "}\n";
 
@@ -794,19 +737,17 @@ S_obj_callback_def(CFCMethod *method, const char *callback_start,
                   + strlen(override_sym)
                   + strlen(params)
                   + strlen(callback_start)
-                  + strlen(micro_sym)
-                  + strlen(micro_sym)
                   + strlen(ret_type_str)
                   + strlen(ret_type_str)
-                  + strlen(nullable_check)
+                  + strlen(micro_sym)
+                  + strlen(nullable)
                   + strlen(refcount_mods)
                   + 30;
     char *callback_def = (char*)MALLOCATE(size);
     sprintf(callback_def, pattern, ret_type_str, override_sym, params,
-            callback_start, micro_sym, micro_sym, ret_type_str, ret_type_str,
-            refcount_mods, nullable_check);
+            callback_start, ret_type_str, ret_type_str, micro_sym, nullable,
+            refcount_mods);
 
-    FREEMEM(nullable_check);
     return callback_def;
 }