[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