[pypy-svn] r66015 - in pypy/trunk/pypy/translator/c: . test

fijal at codespeak.net fijal at codespeak.net
Sun Jun 28 20:38:03 CEST 2009


Author: fijal
Date: Sun Jun 28 20:38:02 2009
New Revision: 66015

Added:
   pypy/trunk/pypy/translator/c/dlltool.py   (contents, props changed)
   pypy/trunk/pypy/translator/c/test/test_dlltool.py   (contents, props changed)
Modified:
   pypy/trunk/pypy/translator/c/genc.py
Log:
A minor hack that lets you compile a library using C backend


Added: pypy/trunk/pypy/translator/c/dlltool.py
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/translator/c/dlltool.py	Sun Jun 28 20:38:02 2009
@@ -0,0 +1,50 @@
+
+from pypy.translator.driver import TranslationDriver
+from pypy.translator.c.genc import CBuilder, CCompilerDriver
+from pypy.rpython.typesystem import getfunctionptr
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
+
+class CLibraryBuilder(CBuilder):
+    standalone = False
+
+    def __init__(self, *args, **kwds):
+        self.functions = kwds.pop('functions')
+        self.name = kwds.pop('name')
+        CBuilder.__init__(self, *args, **kwds)
+
+    def getentrypointptr(self):
+        bk = self.translator.annotator.bookkeeper
+        graphs = [bk.getdesc(f).cachedgraph(None) for f, _ in self.functions]
+        return [getfunctionptr(graph) for graph in graphs]
+
+    def gen_makefile(self, targetdir):
+        pass # XXX finish
+
+    def compile(self):
+        export_symbols = ([self.db.get(ep) for ep in self.getentrypointptr()] +
+                          ['RPython_StartupCode'])
+        extsymeci = ExternalCompilationInfo(export_symbols=export_symbols)
+        self.eci = self.eci.merge(extsymeci)
+        files = [self.c_source_filename] + self.extrafiles
+        oname = self.name
+        self.so_name = self.translator.platform.compile(files, self.eci,
+                                                        standalone=False,
+                                                        outputfilename=oname)
+
+    def get_entry_point(self):
+        return self.so_name
+
+class DLLDef(object):
+    def __init__(self, name, functions=[]):
+        self.name = name
+        self.functions = functions # [(function, annotation), ...]
+        self.driver = TranslationDriver()
+        self.driver.setup_library(self)
+
+    def compile(self):
+        self.driver.proceed(['compile_c'])
+        return self.driver.c_entryp
+
+    def getcbuilder(self, translator, config):
+        return CLibraryBuilder(translator, None, config,
+                               functions=self.functions, name=self.name)

Modified: pypy/trunk/pypy/translator/c/genc.py
==============================================================================
--- pypy/trunk/pypy/translator/c/genc.py	(original)
+++ pypy/trunk/pypy/translator/c/genc.py	Sun Jun 28 20:38:02 2009
@@ -105,7 +105,7 @@
     def __init__(self, translator, entrypoint, config, gcpolicy=None):
         self.translator = translator
         self.entrypoint = entrypoint
-        self.entrypoint_name = self.entrypoint.func_name
+        self.entrypoint_name = getattr(self.entrypoint, 'func_name', None)
         self.originalentrypoint = entrypoint
         self.config = config
         self.gcpolicy = gcpolicy    # for tests only, e.g. rpython/memory/
@@ -156,8 +156,13 @@
 
         # build entrypoint and eventually other things to expose
         pf = self.getentrypointptr()
-        pfname = db.get(pf)
-        self.c_entrypoint_name = pfname
+        if isinstance(pf, list):
+            for one_pf in pf:
+                db.get(one_pf)
+            self.c_entrypoint_name = None
+        else:
+            pfname = db.get(pf)
+            self.c_entrypoint_name = pfname
         db.complete()
 
         self.collect_compilation_info(db)
@@ -209,7 +214,6 @@
         if db is None:
             db = self.build_database()
         pf = self.getentrypointptr()
-        pfname = db.get(pf)
         if self.modulename is None:
             self.modulename = uniquemodulename('testing')
         modulename = self.modulename
@@ -229,6 +233,7 @@
                                                 self.eci,
                                                 defines = defines)
         else:
+            pfname = db.get(pf)
             if self.config.translation.instrument:
                 defines['INSTRUMENT'] = 1
             if CBuilder.have___thread:

Added: pypy/trunk/pypy/translator/c/test/test_dlltool.py
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/translator/c/test/test_dlltool.py	Sun Jun 28 20:38:02 2009
@@ -0,0 +1,17 @@
+
+from pypy.translator.c.dlltool import DLLDef
+from ctypes import CDLL
+
+class TestDLLTool(object):
+    def test_basic(self):
+        def f(x):
+            return x
+
+        def b(x):
+            return x + 2
+
+        d = DLLDef('lib', [(f, [int]), (b, [int])])
+        so = d.compile()
+        dll = CDLL(str(so))
+        assert dll.f(3) == 3
+        assert dll.b(10) == 12



More information about the Pypy-commit mailing list