[pypy-svn] r45906 - in pypy/branch/pypy-more-rtti-inprogress: rpython/lltypesystem rpython/lltypesystem/test translator/c

fijal at codespeak.net fijal at codespeak.net
Wed Aug 22 14:31:03 CEST 2007


Author: fijal
Date: Wed Aug 22 14:31:01 2007
New Revision: 45906

Modified:
   pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/rffi.py
   pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/test/test_rffi.py
   pypy/branch/pypy-more-rtti-inprogress/translator/c/database.py
   pypy/branch/pypy-more-rtti-inprogress/translator/c/genc.py
Log:
whack, whack, whack until it works.
* move all additional-c-snippets into one .h file, so it could be included
* slight simplification here and there
probably this needs to be simplified at some point :-(


Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/rffi.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/rffi.py	Wed Aug 22 14:31:01 2007
@@ -6,23 +6,11 @@
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.rlib.objectmodel import Symbolic, CDefinedIntSymbolic
 from pypy.rlib import rarithmetic
-import os
-
-class CConstant(Symbolic):
-    """ A C-level constant, maybe #define, rendered directly.
-    """
-    def __init__(self, c_name, TP):
-        self.c_name = c_name
-        self.TP = TP
-
-    def annotation(self):
-        return lltype_to_annotation(self.TP)
-
-    def lltype(self):
-        return self.TP
+import os, py
 
 def llexternal(name, args, result, _callable=None, sources=[], includes=[],
-               libraries=[], include_dirs=[], sandboxsafe=False):
+               libraries=[], include_dirs=[], extra_exports=[],
+               sandboxsafe=False):
     ext_type = lltype.FuncType(args, result)
     if _callable is None:
         _callable = ll2ctypes.LL2CtypesCallable(ext_type)
@@ -119,25 +107,34 @@
 def COpaquePtr(*args, **kwds):
     return lltype.Ptr(COpaque(*args, **kwds))
 
-def CExternVariable(TYPE, name):
+def CExternVariable(TYPE, name, **kwds):
     """Return a pair of functions - a getter and a setter - to access
     the given global C variable.
     """
-    # XXX THIS IS ONLY A QUICK HACK TO MAKE IT WORK
-    # In general, we need to re-think a few things to be more consistent,
-    # e.g. what if a CStruct, COpaque or CExternVariable requires
-    # some #include...
     assert not isinstance(TYPE, lltype.ContainerType)
-    CTYPE = lltype.FixedSizeArray(TYPE, 1)
-    c_variable_ref = CConstant('(&%s)' % (name,), lltype.Ptr(CTYPE))
-    def getter():
-        return c_variable_ref[0]
-    def setter(newvalue):
-        c_variable_ref[0] = newvalue
-    return (func_with_new_name(getter, '%s_getter' % (name,)),
-            func_with_new_name(setter, '%s_setter' % (name,)))
-
-get_errno, set_errno = CExternVariable(lltype.Signed, 'errno')
+    try:
+        tp = lltype_to_c_mapping[TYPE]
+    except KeyError:
+        raise NotImplementedError("Don't know how to handle %s" % TYPE)
+    src = py.code.Source("""
+    #include <errno.h>
+    %(tp)s _rffi_get_%(name)s()
+    {
+       return %(name)s;
+    }
+    void _rffi_set_%(name)s(%(tp)s arg)
+    {
+       %(name)s = arg;
+    }
+    """ % {'name':name, 'tp':tp})
+    kwds = kwds.copy()
+    if 'sources' in kwds:
+        kwds['sources'].append(src)
+    else:
+        kwds['sources'] = [src]
+    getter = llexternal('_rffi_get_' + name, [], TYPE, **kwds)
+    setter = llexternal('_rffi_set_' + name, [TYPE], lltype.Void, **kwds)
+    return getter, setter
 
 # char, represented as a Python character
 # (use SIGNEDCHAR or UCHAR for the small integer types)
@@ -158,6 +155,19 @@
 # double *
 DOUBLEP = lltype.Ptr(lltype.Array(DOUBLE, hints={'nolength': True}))
 
+# char**
+CCHARPP = lltype.Ptr(lltype.Array(CCHARP, hints={'nolength': True}))
+
+# HAAAAAAAAAAAAAACK
+lltype_to_c_mapping = {
+    lltype.Signed: 'int',
+    CCHARP: 'char*',
+    lltype.Char: 'char',
+    CCHARPP: 'char**',
+    }
+
+get_errno, set_errno = CExternVariable(lltype.Signed, 'errno')
+
 # various type mapping
 # str -> char*
 def str2charp(s):
@@ -182,9 +192,6 @@
         i += 1
     return "".join(l)
 
-# char**
-CCHARPP = lltype.Ptr(lltype.Array(CCHARP, hints={'nolength': True}))
-
 def liststr2charpp(l):
     """ list[str] -> char**, NULL terminated
     """
@@ -228,3 +235,4 @@
     if tp is lltype.Signed:
         return ULONG._type.BITS/8
     return tp._type.BITS/8
+

Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/test/test_rffi.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/test/test_rffi.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/test/test_rffi.py	Wed Aug 22 14:31:01 2007
@@ -103,11 +103,14 @@
 
 def test_struct():
     h_source = """
+    #ifndef _STRUCT_XX
+    #define _STRUCT_XX
     struct xx {
        int one;
        char two;
        int three;
     };
+    #endif
     """
     h_file = udir.join("structxx.h")
     h_file.write(h_source)
@@ -260,3 +263,38 @@
     assert not size_and_sign(lltype.Signed)[1]
     assert not size_and_sign(lltype.Char)[1]
     assert size_and_sign(UINT)[1]
+
+def test_prebuild_constant():
+    h_source = py.code.Source("""
+    #ifndef _CONSTANTS
+    #define _CONSTANTS
+    int x = 3;
+    char** z = NULL;
+    #endif
+    """)
+    h_include = udir.join('constants.h')
+    h_include.write(h_source)
+
+    kwds = {'includes':['constants.h'], 'include_dirs':[str(udir)]}
+    get_x, set_x = CExternVariable(lltype.Signed, 'x', **kwds)
+    get_z, set_z = CExternVariable(CCHARPP, 'z', **kwds)
+
+    def f():
+        one = get_x()
+        set_x(13)
+        return one + get_x()
+
+    def g():
+        l = liststr2charpp(["a", "b", "c"])
+        try:
+            set_z(l)
+            return charp2str(get_z()[2])
+        finally:
+            free_charpp(l)
+
+    fn = compile(f, [])
+    assert fn() == 16
+    gn = compile(g, [])
+    assert gn() == "c"
+    
+

Modified: pypy/branch/pypy-more-rtti-inprogress/translator/c/database.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/translator/c/database.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/translator/c/database.py	Wed Aug 22 14:31:01 2007
@@ -4,7 +4,6 @@
      ContainerType, OpaqueType, FixedSizeArray, _uninitialized
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.lltypesystem.llmemory import Address
-from pypy.rpython.lltypesystem.rffi import CConstant
 from pypy.tool.sourcetools import valid_identifier
 from pypy.translator.c.primitive import PrimitiveName, PrimitiveType
 from pypy.translator.c.primitive import PrimitiveErrorValue
@@ -169,8 +168,6 @@
             else:
                 raise Exception("don't know about %r" % (T,))
         else:
-            if isinstance(obj, CConstant):
-                return obj.c_name  # without further checks
             T = typeOf(obj)
             if isinstance(T, Primitive):
                 return PrimitiveName[T](obj, self)

Modified: pypy/branch/pypy-more-rtti-inprogress/translator/c/genc.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/translator/c/genc.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/translator/c/genc.py	Wed Aug 22 14:31:01 2007
@@ -374,13 +374,22 @@
 #        self.funcnodes = graph.ordered_funcnodes()
 
     def write_extra_sources(self, sources):
-        basename = 'additional_node.c'
-        retval = []
+        name = 'additional_source.h'
+
+        includes = {}
         for source in sorted(sources.keys()):
-            f = self.makefile(self.uniquecname(basename))
             for include in sources[source]:
-                print >>f, "#include <%s>" % (include,)
-            print >>f, str(source)
+                includes[include] = True
+
+        f = self.path.join(name).open("w")
+        print >>f, "#ifndef _ADDITIONAL_SOURCE"
+        print >>f, "#define _ADDITIONAL_SOURCE"
+        for include in includes.keys():
+            print >>f, "#include <%s>" % (include,)
+        if sources:
+            print >>f, str(py.code.Source(*sources))
+        print >>f, "#endif"
+        f.close()
 
     def uniquecname(self, name):
         assert name.endswith('.c')
@@ -624,17 +633,14 @@
     sources = {}
     include_dirs = {}
     for node in database.globalcontainers():
-        if hasattr(node, 'includes'):
-            for include in node.includes:
-                includes[include] = True
-        if hasattr(node, 'sources'):
-            for source in node.sources:
-                sources[source] = getattr(node, 'includes', [])
-        if hasattr(node, 'include_dirs'):
-            for include_dir in node.include_dirs:
-                include_dirs[include_dir] = True
-    includes = includes.keys()
-    includes.sort()
+        for include in getattr(node, 'includes', []):
+            includes[include] = True
+        for source in getattr(node, 'sources', []):
+            sources[source] = getattr(node, 'includes', [])
+        for include_dir in getattr(node, 'include_dirs', []):
+            include_dirs[include_dir] = True
+    includes = sorted(includes.keys())
+    includes.append("additional_source.h")
     return includes, sources, include_dirs
 
 def gen_source_standalone(database, modulename, targetdir, 
@@ -668,7 +674,7 @@
 
     includes, sources, include_dirs = extra_information(database)
     for include in includes:
-        print >> fi, '#include <%s>' % (include,)
+        print >> fi, '#include "%s"' % (include,)
     fi.close()
 
     preimplementationlines = list(
@@ -727,7 +733,7 @@
 
     includes, sources, include_dirs = extra_information(database)
     for include in includes:
-        print >> fi, '#include <%s>' % (include,)
+        print >> fi, '#include "%s"' % (include,)
     fi.close()
 
     if database.translator is None or database.translator.rtyper is None:



More information about the Pypy-commit mailing list