[pypy-svn] r15478 - in pypy/dist/pypy/translator/c: . src test

hpk at codespeak.net hpk at codespeak.net
Sun Jul 31 17:16:23 CEST 2005


Author: hpk
Date: Sun Jul 31 17:16:20 2005
New Revision: 15478

Added:
   pypy/dist/pypy/translator/c/src/main.h
   pypy/dist/pypy/translator/c/src/standalone.h
   pypy/dist/pypy/translator/c/test/inprogress_test_standalone.py   (contents, props changed)
Modified:
   pypy/dist/pypy/translator/c/database.py
   pypy/dist/pypy/translator/c/extfunc.py
   pypy/dist/pypy/translator/c/genc.py
   pypy/dist/pypy/translator/c/src/exception.h
   pypy/dist/pypy/translator/c/src/g_include.h
   pypy/dist/pypy/translator/c/src/ll_math.h
   pypy/dist/pypy/translator/c/src/ll_os.h
   pypy/dist/pypy/translator/c/src/support.h
Log:
(hpk, arigo)

Progressing towards generating stand-alone C programs that
don't link against CPython at all.  Mostly works when tested
by hand.  Missing distutils incantations to compile the C
source automatically (the inprogress test is disabled because
of that).



Modified: pypy/dist/pypy/translator/c/database.py
==============================================================================
--- pypy/dist/pypy/translator/c/database.py	(original)
+++ pypy/dist/pypy/translator/c/database.py	Sun Jul 31 17:16:20 2005
@@ -13,14 +13,16 @@
 
 class LowLevelDatabase:
 
-    def __init__(self, translator=None):
+    def __init__(self, translator=None, standalone=False):
         self.translator = translator
+        self.standalone = standalone
         self.structdefnodes = {}
         self.containernodes = {}
         self.containerlist = []
         self.externalfuncs = {}
         self.namespace = CNameManager()
-        self.pyobjmaker = PyObjMaker(self.namespace, self.get, translator)
+        if not standalone:
+            self.pyobjmaker = PyObjMaker(self.namespace, self.get, translator)
 
     def gettypedefnode(self, T, varlength=1):
         if varlength <= 1:
@@ -136,7 +138,8 @@
     def complete(self):
         i = 0
         while True:
-            self.pyobjmaker.collect_initcode()
+            if hasattr(self, 'pyobjmaker'):
+                self.pyobjmaker.collect_initcode()
             if i == len(self.containerlist):
                 break
             node = self.containerlist[i]

Modified: pypy/dist/pypy/translator/c/extfunc.py
==============================================================================
--- pypy/dist/pypy/translator/c/extfunc.py	(original)
+++ pypy/dist/pypy/translator/c/extfunc.py	Sun Jul 31 17:16:20 2005
@@ -3,6 +3,7 @@
 from pypy.translator.c.support import cdecl
 from pypy.rpython.rmodel import getfunctionptr
 from pypy.rpython.rstr import STR
+from pypy.rpython import rlist
 from pypy.rpython.module import ll_os, ll_time, ll_math
 
 
@@ -48,6 +49,7 @@
 def predeclare_common_types(db, rtyper):
     # Common types
     yield ('RPyString', STR)
+    yield ('RPyListOfString', rlist.LIST_OF_STR)
     yield ('RPyFREXP_RESULT', ll_math.FREXP_RESULT)
     yield ('RPyMODF_RESULT', ll_math.MODF_RESULT)
     yield ('RPySTAT_RESULT', ll_os.STAT_RESULT)
@@ -57,6 +59,16 @@
     def RPyString_New(length=lltype.Signed):
         return lltype.malloc(STR, length)
 
+    p = lltype.Ptr(rlist.LIST_OF_STR)
+
+    def RPyListOfString_New(length=lltype.Signed):
+        return rlist.ll_newlist(p, length)
+
+    def RPyListOfString_SetItem(l=p,
+                                index=lltype.Signed,
+                                newstring=lltype.Ptr(STR)):
+        rlist.ll_setitem_nonneg(l, index, newstring)
+
     for fname, f in locals().items():
         if isinstance(f, types.FunctionType):
             # hack: the defaults give the type of the arguments
@@ -87,8 +99,9 @@
 
     yield ('RPYTHON_EXCEPTION_MATCH',  exceptiondata.ll_exception_match)
     yield ('RPYTHON_TYPE_OF_EXC_INST', exceptiondata.ll_type_of_exc_inst)
-    yield ('RPYTHON_PYEXCCLASS2EXC',   exceptiondata.ll_pyexcclass2exc)
     yield ('RAISE_OSERROR',            exceptiondata.ll_raise_OSError)
+    if not db.standalone:
+        yield ('RPYTHON_PYEXCCLASS2EXC', exceptiondata.ll_pyexcclass2exc)
 
     for pyexccls in exceptiondata.standardexceptions:
         exc_llvalue = exceptiondata.ll_pyexcclass2exc(

Modified: pypy/dist/pypy/translator/c/genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/genc.py	(original)
+++ pypy/dist/pypy/translator/c/genc.py	Sun Jul 31 17:16:20 2005
@@ -6,7 +6,8 @@
 from pypy.translator.gensupp import uniquemodulename
 from pypy.translator.tool.cbuild import compile_c_module
 from pypy.translator.tool.cbuild import import_module_from_directory
-from pypy.rpython.lltype import pyobjectptr
+from pypy.rpython.rmodel import getfunctionptr
+from pypy.rpython import lltype
 from pypy.tool.udir import udir
 
 class CBuilder: 
@@ -18,21 +19,35 @@
         self.c_ext_module = None
     
     def generate_source(self):
-        assert not self.standalone
         assert self.c_source_filename is None
         translator = self.translator
-        db, pf = translator2database(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)
+        db = LowLevelDatabase(translator, standalone=self.standalone)
+        pfname = db.get(pf)
+        db.complete()
+
         modulename = uniquemodulename('testing')
         targetdir = udir.ensure(modulename, dir=1)
+        defines = {}
+        # defines={'COUNT_OP_MALLOCS': 1}
         if not self.standalone:
             from pypy.translator.c.symboltable import SymbolTable
             self.symboltable = SymbolTable()
+            cfile = gen_source(db, modulename, targetdir,
+                               defines = defines,
+                               exports = {translator.entrypoint.func_name: pf},
+                               symboltable = self.symboltable)
         else:
             self.symboltable = None
-        cfile = gen_source(db, modulename, targetdir,
-                           # defines={'COUNT_OP_MALLOCS': 1},
-                           exports = {translator.entrypoint.func_name: pf},
-                           symboltable = self.symboltable)
+            cfile = gen_source_standalone(db, modulename, targetdir,
+                                          entrypointname = pfname,
+                                          defines = defines)
         self.c_source_filename = py.path.local(cfile)
         return cfile 
         
@@ -115,9 +130,37 @@
             print >> f, line
             blank = True
 
+def gen_source_standalone(database, modulename, targetdir, 
+                          entrypointname, defines={}): 
+    assert database.standalone
+    if isinstance(targetdir, str):
+        targetdir = py.path.local(targetdir)
+    filename = targetdir.join(modulename + '.c')
+    f = filename.open('w')
+
+    #
+    # Header
+    #
+    defines['PYPY_STANDALONE'] = entrypointname
+    for key, value in defines.items():
+        print >> f, '#define %s %s' % (key, value)
+
+    preimplementationlines = list(
+        pre_include_code_lines(database, database.translator.rtyper))
+
+    #
+    # 1) All declarations
+    # 2) Implementation of functions and global structures and arrays
+    #
+    gen_readable_parts_of_main_c_file(f, database, preimplementationlines)
+
+    f.close()
+    return filename
+
 
 def gen_source(database, modulename, targetdir, defines={}, exports={},
-                                                symboltable=None):
+               symboltable=None):
+    assert not database.standalone
     if isinstance(targetdir, str):
         targetdir = py.path.local(targetdir)
     filename = targetdir.join(modulename + '.c')

Modified: pypy/dist/pypy/translator/c/src/exception.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/exception.h	(original)
+++ pypy/dist/pypy/translator/c/src/exception.h	Sun Jul 31 17:16:20 2005
@@ -2,8 +2,9 @@
 /************************************************************/
  /***  C header subsection: exceptions                     ***/
 
-static PyObject *RPythonError;
-
+#ifndef PYPY_STANDALONE
+   static PyObject *RPythonError;
+#endif 
 
 /******************************************************************/
 #ifdef HAVE_RTYPER               /* RPython version of exceptions */
@@ -28,6 +29,7 @@
 #define MatchException(etype)	RPYTHON_EXCEPTION_MATCH(rpython_exc_type,  \
 					(RPYTHON_EXCEPTION_VTABLE) etype)
 
+#ifndef PYPY_STANDALONE
 static void ConvertExceptionFromCPython(void)
 {
 	/* convert the CPython exception to an RPython one */
@@ -64,7 +66,9 @@
 	vanishing = rpython_exc_value;		\
 	rpython_exc_type = NULL;		\
 	rpython_exc_value = NULL;
-        
+
+#endif   /* !PYPY_STANDALONE */
+
 
 #define RaiseSimpleException(exc, msg)				\
 		/* XXX 1. uses officially bad fishing */	\

Modified: pypy/dist/pypy/translator/c/src/g_include.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/g_include.h	(original)
+++ pypy/dist/pypy/translator/c/src/g_include.h	Sun Jul 31 17:16:20 2005
@@ -2,18 +2,25 @@
 /************************************************************/
 /***  C header file for code produced by genc.py          ***/
 
-#include "Python.h"
-#include "compile.h"
-#include "frameobject.h"
-#include "structmember.h"
-#include "traceback.h"
-#include "marshal.h"
-#include "eval.h"
+#ifndef PYPY_STANDALONE
+#  include "Python.h"
+#  include "compile.h"
+#  include "frameobject.h"
+#  include "structmember.h"
+#  include "traceback.h"
+#  include "marshal.h"
+#  include "eval.h"
+#else
+#  include "src/standalone.h"
+#endif
 
 #include "src/exception.h"
 #include "src/trace.h"
 #include "src/support.h"
-#include "src/module.h"
+
+#ifndef PYPY_STANDALONE
+#  include "src/module.h"
+#endif
 
 #include "src/mem.h"
 #include "src/int.h"
@@ -29,3 +36,8 @@
 #  include "src/ll_time.h"
 #  include "src/ll_math.h"
 #endif
+
+#ifdef PYPY_STANDALONE
+#  include "src/main.h"
+#endif
+

Modified: pypy/dist/pypy/translator/c/src/ll_math.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/ll_math.h	(original)
+++ pypy/dist/pypy/translator/c/src/ll_math.h	Sun Jul 31 17:16:20 2005
@@ -1,8 +1,6 @@
 /************************************************************/
 /***  C header subsection: math module                    ***/
 
-#include "math.h"
-
 /* The functions below are mapped to functions from pypy.rpython.module.*
    by the pypy.translator.c.extfunc.EXTERNALS dictionary.
    They should correspond to the functions with the suggested_primitive

Modified: pypy/dist/pypy/translator/c/src/ll_os.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/ll_os.h	(original)
+++ pypy/dist/pypy/translator/c/src/ll_os.h	Sun Jul 31 17:16:20 2005
@@ -1,9 +1,13 @@
 /************************************************************/
  /***  C header subsection: os module                      ***/
 
-/*#include <unistd.h> -- XXX re-enable with lots of #ifdefs */
-/*#include <sys/types.h>*/
-/*#include <sys/stat.h>*/
+#if !(defined(MS_WIN64) || defined(MS_WINDOWS))
+#  include <unistd.h>
+#  include <sys/types.h>
+#  include <sys/stat.h>
+#endif
+
+#include <errno.h>
 #include <fcntl.h>
 #ifndef PATH_MAX
   /* assume windows */
@@ -36,7 +40,7 @@
 {
 	/* XXX unicode_file_names */
 	char buf[PATH_MAX];
-	int fd, error, namelen = RPyString_Size(filename);
+	int fd, namelen = RPyString_Size(filename);
 	if (namelen >= PATH_MAX) {
 		RAISE_OSERROR(ENAMETOOLONG);
 		return -1;

Added: pypy/dist/pypy/translator/c/src/main.h
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/c/src/main.h	Sun Jul 31 17:16:20 2005
@@ -0,0 +1,14 @@
+
+#define STANDALONE_ENTRY_POINT   PYPY_STANDALONE
+
+int main(int argc, char *argv[])
+{
+    int i;
+    RPyListOfString *list = RPyListOfString_New(argc);
+    for (i=0; i<argc; i++) {
+        RPyString *s = RPyString_FromString(argv[i]);
+        RPyListOfString_SetItem(list, i, s);
+    }
+    return STANDALONE_ENTRY_POINT(list);
+}
+

Added: pypy/dist/pypy/translator/c/src/standalone.h
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/c/src/standalone.h	Sun Jul 31 17:16:20 2005
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+#include <limits.h>
+#include <assert.h>
+#include <math.h>
+
+#define PyObject_Malloc malloc
+#define PyObject_Free   free
+

Modified: pypy/dist/pypy/translator/c/src/support.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/support.h	(original)
+++ pypy/dist/pypy/translator/c/src/support.h	Sun Jul 31 17:16:20 2005
@@ -19,6 +19,9 @@
 #define FAIL_ZER(err, msg) FAIL_EXCEPTION(err, Exc_ZeroDivisionError, msg)
 #define CFAIL(err)         { ConvertExceptionFromCPython(); FAIL(err) }
 
+
+#ifndef PYPY_STANDALONE
+
 /* we need a subclass of 'builtin_function_or_method' which can be used
    as methods: builtin function objects that can be bound on instances */
 static PyObject *
@@ -375,3 +378,4 @@
 #define PyString_ToLLCharArray(s, itemsarray)                           \
 		memcpy(itemsarray->items, PyString_AS_STRING(s),        \
                        itemsarray->length)
+#endif /* PYPY_STANDALONE */

Added: pypy/dist/pypy/translator/c/test/inprogress_test_standalone.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/c/test/inprogress_test_standalone.py	Sun Jul 31 17:16:20 2005
@@ -0,0 +1,23 @@
+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 



More information about the Pypy-commit mailing list