[pypy-commit] creflect default: Streamline the declaration of functions.

arigo noreply at buildbot.pypy.org
Tue Nov 18 01:16:52 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r66:9cc3ae087730
Date: 2014-11-18 01:17 +0100
http://bitbucket.org/cffi/creflect/changeset/9cc3ae087730/

Log:	Streamline the declaration of functions.

diff --git a/creflect/cparser.py b/creflect/cparser.py
--- a/creflect/cparser.py
+++ b/creflect/cparser.py
@@ -95,7 +95,7 @@
         if isinstance(node, pycparser.c_ast.FuncDecl):
             tp = self._get_type(node)
             assert isinstance(tp, model.FunctionType)
-            self.declarations.append(model.VarDecl(decl.name, tp))
+            self.declarations.append(model.FuncDecl(decl.name, tp))
         else:
             xxxxxxxxxxxxxx
             const = 'const' in decl.quals
diff --git a/creflect/creflect.h b/creflect/creflect.h
--- a/creflect/creflect.h
+++ b/creflect/creflect.h
@@ -10,7 +10,8 @@
 } crx_field_t;
 
 typedef struct crx_type_s crx_type_t;   /* opaque */
-typedef void (*crx_trampoline_fn)(void *fn, void *args[], void *res);
+typedef void (*crx_trampoline0_fn)(void *args[], void *res);
+typedef void (*crx_trampoline1_fn)(void *fn, void *args[], void *res);
 
 #define CRX_SELF struct _crx_builder_s *
 typedef struct _crx_builder_s {
@@ -24,7 +25,7 @@
     crx_type_t *(*get_float_type)(CRX_SELF, size_t,
                                const char *);
     crx_type_t *(*get_function_type)(CRX_SELF, crx_type_t *,
-                                     crx_type_t *[], int, crx_trampoline_fn);
+                                     crx_type_t *[], int, crx_trampoline1_fn);
     crx_type_t *(*get_ellipsis_function_type)(CRX_SELF, crx_type_t *,
                                               crx_type_t *[], int);
     crx_type_t *(*get_pointer_type)(CRX_SELF, crx_type_t *);
@@ -40,6 +41,8 @@
     void (*define_type)(CRX_SELF, const char *, crx_type_t *);
     void (*define_var)(CRX_SELF, const char *, crx_type_t *,
                        void *);
+    void (*define_func)(CRX_SELF, const char *, crx_type_t *,
+                        crx_type_t *[], int, crx_trampoline0_fn, void *);
     void (*error)(CRX_SELF, const char *);
 } crx_builder_t;
 #undef CRX_SELF
diff --git a/creflect/model.py b/creflect/model.py
--- a/creflect/model.py
+++ b/creflect/model.py
@@ -160,20 +160,14 @@
         # limitations so far:
         assert not self.ellipsis, "XXX"
         assert inspect is not None, "XXX"
-        if inspect.started:
-            assert inspect.levels == ['*'], "XXX"
-
-        if inspect.started:
-            localvar = 'f'
-        else:
-            assert inspect.varname is not None
-            localvar = inspect.varname
+        assert inspect.started, "XXX"
+        assert inspect.levels == ['*'], "XXX"
 
         t1 = self.result.inspect_type(block, None)
         call = ['    ']
         if not isinstance(self.result, VoidType):
             call.append('*(%s)result = ' % (self.result.get_c_name('*'),))
-        call.append('%s(' % localvar)
+        call.append('f(')
         t_args = [arg.inspect_type(block, None) for arg in self.args]
         a2 = block.add_array_crx_types(len(t_args))
         for i, t in enumerate(t_args):
@@ -194,7 +188,7 @@
             crx_func_name,))
         if inspect.started:
             assert inspect.levels == ['*']
-            wrline('    %s %s = func;' % (inspect.typename, localvar))
+            wrline('    %s f = func;' % inspect.typename)
         wrline(''.join(call))
         wrline('}')
         wrline('')
@@ -216,6 +210,34 @@
         wrline('')
         return shadowname
 
+    def write_func_decl(self, block, fnname):
+        # XXX code duplication!
+        t1 = self.result.inspect_type(block, None)
+        call = ['    ']
+        if not isinstance(self.result, VoidType):
+            call.append('*(%s)result = ' % (self.result.get_c_name('*'),))
+        call.append('%s(' % fnname)
+        t_args = [arg.inspect_type(block, None) for arg in self.args]
+        a2 = block.add_array_crx_types(len(t_args))
+        for i, t in enumerate(t_args):
+            block.writeline('%s[%d] = %s;' % (a2, i, t))
+            if i > 0:
+                call.append(', ')
+            call.append('*(%s)args[%d]' % (self.args[i].get_c_name('*'), i))
+        call.append(');')
+        #
+        toplevel = block.crx_top_level
+        crx_func_name = '%s__c_%s' % (toplevel.crx_func_name, fnname)
+        wrline = toplevel.writeline
+        wrline('static void %s(void *args[], void *result) {' % (
+            crx_func_name,))
+        wrline(''.join(call))
+        wrline('}')
+        wrline('')
+        shadow = self.shadow_global_var(toplevel, fnname)
+        block.writeline('cb->define_func(cb, "%s", %s, %s, %d, &%s, &%s);' % (
+            fnname, t1, a2, len(t_args), crx_func_name, shadow))
+
 
 class PointerType(BaseType):
     _attrs_ = ('totype',)
@@ -512,3 +534,14 @@
         block.writeline('cb->define_var(cb, "%s", %s, &%s);' % (
             self.name, t1, shadow))
         funcblock.write_subblock(block)
+
+
+class FuncDecl(object):
+    def __init__(self, name, type):
+        self.name = name
+        self.type = type
+
+    def write_declaration(self, funcblock):
+        block = CodeBlock(funcblock)
+        self.type.write_func_decl(block, self.name)
+        funcblock.write_subblock(block)
diff --git a/test/cgcompile.c b/test/cgcompile.c
--- a/test/cgcompile.c
+++ b/test/cgcompile.c
@@ -80,7 +80,7 @@
 
 static crx_type_t *tst_get_function_type(crx_builder_t *cb, crx_type_t *ret,
                                          crx_type_t *args[], int nargs,
-                                         crx_trampoline_fn trampl)
+                                         crx_trampoline1_fn trampl)
 {
     int i;
     const char *prev = "FUNC( ";
@@ -162,6 +162,17 @@
     printf("VAR %s: %s\n", name, t->text);
 }
 
+static void tst_define_func(crx_builder_t *cb, const char *name,
+                            crx_type_t *ret, crx_type_t *args[], int nargs,
+                            crx_trampoline0_fn trampl, void *directcall)
+{
+    int i;
+    printf("FUNC %s: ", name);
+    for (i = 0; i < nargs; i++)
+        printf("%s -> ", args[i]->text);
+    printf("%s\n", ret->text);
+}
+
 static void tst_error(crx_builder_t *cb, const char *msg)
 {
     printf("ERROR: %s\n", msg);
@@ -187,6 +198,7 @@
     tst_complete_enum,
     tst_define_type,
     tst_define_var,
+    tst_define_func,
     tst_error,
 };
 
diff --git a/test/codegen/func-001.c b/test/codegen/func-001.c
--- a/test/codegen/func-001.c
+++ b/test/codegen/func-001.c
@@ -6,7 +6,7 @@
 
 # ____________________________________________________________
 
-static void testfunc_001__c_f(void *func, void *args[], void *result) {
+static void testfunc_001__c_f(void *args[], void *result) {
     *(int *)result = f();
 }
 
@@ -16,11 +16,10 @@
 
 void testfunc_001(crx_builder_t *cb)
 {
-    crx_type_t *t1, *t2;
+    crx_type_t *t1;
     {
         t1 = cb->get_signed_type(cb, sizeof(int), "int");
-        t2 = cb->get_function_type(cb, t1, 0, 0, &testfunc_001__c_f);
-        cb->define_var(cb, "f", t2, &testfunc_001__d_f);
-#expect VAR f: FUNC( int )
+        cb->define_func(cb, "f", t1, 0, 0, &testfunc_001__c_f, &testfunc_001__d_f);
+#expect FUNC f: int
     }
 }
diff --git a/test/codegen/func-001b.c b/test/codegen/func-001b.c
--- a/test/codegen/func-001b.c
+++ b/test/codegen/func-001b.c
@@ -10,7 +10,7 @@
 
 # ____________________________________________________________
 
-static void testfunc_001b__c_f(void *func, void *args[], void *result) {
+static void testfunc_001b__c_f(void *args[], void *result) {
     *(unsigned int *)result = f(*(long *)args[0]);
 }
 
@@ -18,7 +18,7 @@
     return f(a0);
 }
 
-static void testfunc_001b__c_g(void *func, void *args[], void *result) {
+static void testfunc_001b__c_g(void *args[], void *result) {
     *(long *)result = g(*(int *)args[0], *(int *)args[1]);
 }
 
@@ -26,7 +26,7 @@
     return g(a0, a1);
 }
 
-static void testfunc_001b__c_h(void *func, void *args[], void *result) {
+static void testfunc_001b__c_h(void *args[], void *result) {
     *(long *)result = h(*(int *)args[0], *(int *)args[1]);
 }
 
@@ -36,28 +36,25 @@
 
 void testfunc_001b(crx_builder_t *cb)
 {
-    crx_type_t *t1, *t2, *a3[1], *t4, *t5, *a6[2], *t7, *a8[2], *t9;
+    crx_type_t *t1, *t2, *a3[1], *t4, *a5[2], *a6[2];
     {
         t1 = cb->get_unsigned_type(cb, sizeof(unsigned int), "unsigned int");
         t2 = cb->get_signed_type(cb, sizeof(long), "long");
         a3[0] = t2;
-        t4 = cb->get_function_type(cb, t1, a3, 1, &testfunc_001b__c_f);
-        cb->define_var(cb, "f", t4, &testfunc_001b__d_f);
-#expect VAR f: FUNC( long -> unsigned int )
+        cb->define_func(cb, "f", t1, a3, 1, &testfunc_001b__c_f, &testfunc_001b__d_f);
+#expect FUNC f: long -> unsigned int
     }
     {
-        t5 = cb->get_signed_type(cb, sizeof(int), "int");
-        a6[0] = t5;
-        a6[1] = t5;
-        t7 = cb->get_function_type(cb, t2, a6, 2, &testfunc_001b__c_g);
-        cb->define_var(cb, "g", t7, &testfunc_001b__d_g);
-#expect VAR g: FUNC( int -> int -> long )
+        t4 = cb->get_signed_type(cb, sizeof(int), "int");
+        a5[0] = t4;
+        a5[1] = t4;
+        cb->define_func(cb, "g", t2, a5, 2, &testfunc_001b__c_g, &testfunc_001b__d_g);
+#expect FUNC g: int -> int -> long
     }
     {
-        a8[0] = t5;
-        a8[1] = t5;
-        t9 = cb->get_function_type(cb, t2, a8, 2, &testfunc_001b__c_h);
-        cb->define_var(cb, "h", t9, &testfunc_001b__d_h);
-#expect VAR h: FUNC( int -> int -> long )
+        a6[0] = t4;
+        a6[1] = t4;
+        cb->define_func(cb, "h", t2, a6, 2, &testfunc_001b__c_h, &testfunc_001b__d_h);
+#expect FUNC h: int -> int -> long
     }
 }


More information about the pypy-commit mailing list