[pypy-svn] r15511 - in pypy/dist/pypy/translator: . c c/test tool

arigo at codespeak.net arigo at codespeak.net
Tue Aug 2 16:55:05 CEST 2005


Author: arigo
Date: Tue Aug  2 16:55:04 2005
New Revision: 15511

Added:
   pypy/dist/pypy/translator/c/test/test_standalone.py
      - copied, changed from r15510, pypy/dist/pypy/translator/c/test/inprogress_test_standalone.py
Removed:
   pypy/dist/pypy/translator/c/test/inprogress_test_standalone.py
Modified:
   pypy/dist/pypy/translator/c/genc.py
   pypy/dist/pypy/translator/tool/cbuild.py
   pypy/dist/pypy/translator/translator.py
Log:
Finished the CBuilder class, now split in two subclasses as per Holger's suggestion
-- one for building C extension modules and one for standalone executables.

The test pass, at least on Linux.



Modified: pypy/dist/pypy/translator/c/genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/genc.py	(original)
+++ pypy/dist/pypy/translator/c/genc.py	Tue Aug  2 16:55:04 2005
@@ -5,29 +5,24 @@
 from pypy.translator.c.extfunc import pre_include_code_lines
 from pypy.translator.gensupp import uniquemodulename
 from pypy.translator.tool.cbuild import compile_c_module
+from pypy.translator.tool.cbuild import build_executable
 from pypy.translator.tool.cbuild import import_module_from_directory
 from pypy.rpython.rmodel import getfunctionptr
 from pypy.rpython import lltype
 from pypy.tool.udir import udir
 
 class CBuilder: 
-    def __init__(self, translator, standalone=False):
+    c_source_filename = None
+    _compiled = False
+    symboltable = None
+    
+    def __init__(self, translator):
         self.translator = translator
-        self.standalone = standalone
-        self.c_source_filename = None
-        self._compiled = False
-        self.c_ext_module = None
     
     def generate_source(self):
         assert self.c_source_filename is None
         translator = self.translator
-        entrypoint = translator.entrypoint
-        if not self.standalone:
-            pf = lltype.pyobjectptr(entrypoint)
-        else:
-            # XXX check that the entrypoint has the correct
-            # signature:  list-of-strings -> int
-            pf = getfunctionptr(translator, entrypoint)
+        pf = self.getentrypointptr()
         db = LowLevelDatabase(translator, standalone=self.standalone)
         pfname = db.get(pf)
         db.complete()
@@ -44,16 +39,22 @@
                                exports = {translator.entrypoint.func_name: pf},
                                symboltable = self.symboltable)
         else:
-            self.symboltable = None
             cfile = gen_source_standalone(db, modulename, targetdir,
                                           entrypointname = pfname,
                                           defines = defines)
         self.c_source_filename = py.path.local(cfile)
         return cfile 
-        
+
+
+class CExtModuleBuilder(CBuilder):
+    standalone = False
+
+    def getentrypointptr(self):
+        return lltype.pyobjectptr(self.translator.entrypoint)
+
     def compile(self):
         assert self.c_source_filename 
-        assert not self.standalone, "XXX"
+        assert not self._compiled
         compile_c_module(self.c_source_filename, 
                          self.c_source_filename.purebasename,
                          include_dirs = [autopath.this_dir])
@@ -74,6 +75,29 @@
         return getattr(self.c_ext_module, 
                        self.translator.entrypoint.func_name)
 
+
+class CStandaloneBuilder(CBuilder):
+    standalone = True
+    executable_name = None
+
+    def getentrypointptr(self):
+        # XXX check that the entrypoint has the correct
+        # signature:  list-of-strings -> int
+        return getfunctionptr(self.translator, self.translator.entrypoint)
+
+    def compile(self):
+        assert self.c_source_filename
+        assert not self._compiled
+        self.executable_name = build_executable([self.c_source_filename],
+                                         include_dirs = [autopath.this_dir])
+        self._compiled = True
+        return self.executable_name
+
+    def cmdexec(self, args=''):
+        assert self._compiled
+        return py.process.cmdexec('"%s" %s' % (self.executable_name, args))
+
+
 def translator2database(translator):
     pf = pyobjectptr(translator.entrypoint)
     db = LowLevelDatabase(translator)

Deleted: /pypy/dist/pypy/translator/c/test/inprogress_test_standalone.py
==============================================================================
--- /pypy/dist/pypy/translator/c/test/inprogress_test_standalone.py	Tue Aug  2 16:55:04 2005
+++ (empty file)
@@ -1,23 +0,0 @@
-from pypy.translator.translator import Translator
-from pypy.translator.tool.cbuild import build_executable 
-from pypy.annotation.model import SomeList, SomeString
-from pypy.annotation.listdef import ListDef
-import os
-
-
-def test_hello_world():
-    def entry_point(argv):
-        os.write(1, "hello world\n")
-        os.write(1, "argument count: " + str(len(argv)) + "\n")
-        for s in argv:
-            os.write(1, "   '" + str(s) + "'\n")
-        return 0
-    
-    t = Translator(entry_point)
-    s_list_of_strings = SomeList(ListDef(None, SomeString()))
-    t.annotate([s_list_of_strings])
-    t.specialize()
-    cbuilder = t.cbuilder(standalone=True)
-    cbuilder.generate_source()
-    cbuilder.compile() 
-    XXX 

Copied: pypy/dist/pypy/translator/c/test/test_standalone.py (from r15510, pypy/dist/pypy/translator/c/test/inprogress_test_standalone.py)
==============================================================================
--- pypy/dist/pypy/translator/c/test/inprogress_test_standalone.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_standalone.py	Tue Aug  2 16:55:04 2005
@@ -8,6 +8,7 @@
 def test_hello_world():
     def entry_point(argv):
         os.write(1, "hello world\n")
+        argv = argv[1:]
         os.write(1, "argument count: " + str(len(argv)) + "\n")
         for s in argv:
             os.write(1, "   '" + str(s) + "'\n")
@@ -20,4 +21,5 @@
     cbuilder = t.cbuilder(standalone=True)
     cbuilder.generate_source()
     cbuilder.compile() 
-    XXX 
+    data = cbuilder.cmdexec('hi there')
+    assert data.startswith('''hello world\nargument count: 2\n   'hi'\n   'there'\n''')

Modified: pypy/dist/pypy/translator/tool/cbuild.py
==============================================================================
--- pypy/dist/pypy/translator/tool/cbuild.py	(original)
+++ pypy/dist/pypy/translator/tool/cbuild.py	Tue Aug  2 16:55:04 2005
@@ -226,7 +226,8 @@
     return getattr(mod, func.func_name)
 
 
-def build_executable(cfilenames, outputfilename=None, include_dirs=None):
+def build_executable(cfilenames, outputfilename=None, include_dirs=None,
+                     libraries=['m']):
     from distutils.ccompiler import new_compiler 
     if outputfilename is None: 
         if sys.platform == 'win32': 
@@ -251,6 +252,7 @@
             objects.append(str(cobjfile))
         finally: 
             old.chdir() 
-    compiler.link_executable(objects, str(outputfilename))
+    compiler.link_executable(objects, str(outputfilename),
+                             libraries=libraries)
     return str(outputfilename)
 

Modified: pypy/dist/pypy/translator/translator.py
==============================================================================
--- pypy/dist/pypy/translator/translator.py	(original)
+++ pypy/dist/pypy/translator/translator.py	Tue Aug  2 16:55:04 2005
@@ -268,7 +268,10 @@
 
     def cbuilder(self, standalone=False):
         from pypy.translator.c import genc
-        return genc.CBuilder(self, standalone=standalone)
+        if standalone:
+            return genc.CStandaloneBuilder(self)
+        else:
+            return genc.CExtModuleBuilder(self)
 
     def llvmcompile(self, optimize=True):
         """llvmcompile(self, optimize=True) -> LLVM translation



More information about the Pypy-commit mailing list