[pypy-svn] r34513 - in pypy/dist/pypy: rlib rlib/test rpython

arigo at codespeak.net arigo at codespeak.net
Sat Nov 11 22:52:47 CET 2006


Author: arigo
Date: Sat Nov 11 22:52:45 2006
New Revision: 34513

Modified:
   pypy/dist/pypy/rlib/rctypesobject.py
   pypy/dist/pypy/rlib/test/test_rctypesobject.py
   pypy/dist/pypy/rpython/annlowlevel.py
Log:
rctypesobject.RFuncType.


Modified: pypy/dist/pypy/rlib/rctypesobject.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypesobject.py	(original)
+++ pypy/dist/pypy/rlib/rctypesobject.py	Sat Nov 11 22:52:45 2006
@@ -1,4 +1,5 @@
 from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython import annlowlevel
 from pypy.interpreter.miscutils import InitializedClass
 from pypy.tool.sourcetools import func_with_new_name
 
@@ -19,6 +20,8 @@
     def setkeepalive(self, index, memblock):
         self.keepalives[self.ofs_keepalives + index] = memblock
 
+EMPTY_RAW_MEM_BLOCK = RawMemBlock(0)
+
 class AllocatedRawMemBlock(RawMemBlock):
     def __init__(self, num_keepalives, rawsize):
         RawMemBlock.__init__(self, num_keepalives)
@@ -57,6 +60,9 @@
                     cls.CDATATYPE = cls.LLTYPE
                 else:
                     cls.CDATATYPE = lltype.FixedSizeArray(cls.LLTYPE, 1)
+            if not getattr(cls, 'can_allocate', True):
+                return
+
             if not hasattr(cls, 'rawsize'):
                 cls.rawsize = llmemory.sizeof(cls.CDATATYPE)
 
@@ -397,3 +403,55 @@
 
 
 create_string_buffer = RVarArray(rc_char).allocate
+
+# ____________________________________________________________
+
+_functype_cache = {}
+def RFuncType(args_cls, rescls):
+    """Build and return a new RCTypesFunc class.
+    Note that like lltype, but unlike ctypes, a 'function' type is not
+    automatically a pointer to a function.  Conceptually, it represents
+    the area of memory where the function's machine code is stored."""
+    args_cls = tuple(args_cls)
+    try:
+        return _functype_cache[args_cls, rescls]
+    except KeyError:
+
+        ARGS = [cls.LLTYPE for cls in args_cls]
+        RES  = rescls.LLTYPE
+        FUNCTYPE = lltype.FuncType(ARGS, RES)
+        PTRTYPE  = lltype.Ptr(FUNCTYPE)
+
+        class RCTypesFunc(RCTypesObject):
+            LLTYPE = FUNCTYPE
+            can_allocate = False
+
+            def fromrpython(func):
+                """Return an RCTypes function that references the given
+                RPython function."""
+                p = annlowlevel.llhelper(PTRTYPE, func)
+                addr = llmemory.cast_ptr_to_adr(p)
+                memblock = EMPTY_RAW_MEM_BLOCK
+                return RCTypesFunc(addr, memblock)
+            fromrpython._annspecialcase_ = 'specialize:arg(0)'
+            fromrpython = staticmethod(fromrpython)
+
+            def call(self, *args):
+                assert len(args) == len(ARGS)
+                p = llmemory.cast_adr_to_ptr(self.addr, PTRTYPE)
+                return p(*args)
+
+        _functype_cache[args_cls, rescls] = RCTypesFunc
+        return RCTypesFunc
+RFuncType._annspecialcase_ = 'specialize:memo'
+
+##class RLibrary(object):
+
+##    def __init__(self, c_libname=None, c_includes=None):
+##        self.c_libname = c_libname
+##        self.c_includes = c_includes
+
+##    def link(self, cls, c_name):
+##        assert issubclass(cls, RCTypeObject)
+##        ...
+##    link._annspecialcase_ = 'specialize:arg(1)'

Modified: pypy/dist/pypy/rlib/test/test_rctypesobject.py
==============================================================================
--- pypy/dist/pypy/rlib/test/test_rctypesobject.py	(original)
+++ pypy/dist/pypy/rlib/test/test_rctypesobject.py	Sat Nov 11 22:52:45 2006
@@ -154,6 +154,14 @@
         res = self.do(func)
         assert res == 1
 
+    def test_func(self):
+        def g(x, y):
+            return x - y
+        def func():
+            a = RFuncType((rc_int, rc_int), rc_int).fromrpython(g)
+            return a.call(50, 8)
+        res = self.do(func)
+        assert res == 42
 
 class TestLLInterpreted(TestBasic):
     POLICY = AnnotatorPolicy()

Modified: pypy/dist/pypy/rpython/annlowlevel.py
==============================================================================
--- pypy/dist/pypy/rpython/annlowlevel.py	(original)
+++ pypy/dist/pypy/rpython/annlowlevel.py	Sat Nov 11 22:52:45 2006
@@ -331,7 +331,9 @@
 
 
 def llhelper(F, f):
-    raise NotImplementedError("llhelper")
+    # implementation for the purpose of direct running only
+    # XXX need more cleverness to support translation of prebuilt llhelper ptr
+    return lltype.functionptr(F.TO, f.func_name, _callable=f)
 
 class LLHelperEntry(extregistry.ExtRegistryEntry):
     _about_ = llhelper



More information about the Pypy-commit mailing list