[pypy-svn] r34514 - in pypy/dist/pypy/rlib: . test

arigo at codespeak.net arigo at codespeak.net
Sat Nov 11 23:10:36 CET 2006


Author: arigo
Date: Sat Nov 11 23:10:35 2006
New Revision: 34514

Modified:
   pypy/dist/pypy/rlib/rctypesobject.py
   pypy/dist/pypy/rlib/test/test_rctypesobject.py
Log:
Yay!  Calls to external C functions.


Modified: pypy/dist/pypy/rlib/rctypesobject.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypesobject.py	(original)
+++ pypy/dist/pypy/rlib/rctypesobject.py	Sat Nov 11 23:10:35 2006
@@ -426,16 +426,35 @@
             LLTYPE = FUNCTYPE
             can_allocate = False
 
+            def fromllptr(p):
+                addr = llmemory.cast_ptr_to_adr(p)
+                memblock = EMPTY_RAW_MEM_BLOCK
+                return RCTypesFunc(addr, memblock)
+            fromllptr = staticmethod(fromllptr)
+
             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)
+                return RCTypesFunc.fromllptr(p)
             fromrpython._annspecialcase_ = 'specialize:arg(0)'
             fromrpython = staticmethod(fromrpython)
 
+            def fromlib(rlib, c_funcname, llinterp_friendly_version=None):
+                flags = {'external': 'C'}
+                if rlib.pythonapi:
+                    pass   # no 'includes': hack to trigger
+                           # in GenC a PyErr_Occurred() check
+                else:
+                    flags['includes']  = rlib.c_includes
+                    flags['libraries'] = rlib.c_libs
+                if llinterp_friendly_version:
+                    flags['_callable'] = llinterp_friendly_version
+                p = lltype.functionptr(FUNCTYPE, c_funcname, **flags)
+                return RCTypesFunc.fromllptr(p)
+            fromlib._annspecialcase_ = 'specialize:memo'
+            fromlib = staticmethod(fromlib)
+
             def call(self, *args):
                 assert len(args) == len(ARGS)
                 p = llmemory.cast_adr_to_ptr(self.addr, PTRTYPE)
@@ -445,13 +464,22 @@
         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)'
+class RLibrary(object):
+    """A C library.  Use to create references to external functions.
+    """
+    # XXX for now, lltype only supports functions imported from external
+    # libraries, not variables
+
+    pythonapi = False
+
+    def __init__(self, c_libs=(), c_includes=()):
+        if isinstance(c_libs,     str): c_libs     = (c_libs,)
+        if isinstance(c_includes, str): c_includes = (c_includes,)
+        self.c_libs = c_libs
+        self.c_includes = c_includes
+
+    def _freeze_(self):
+        return True
+
+LIBC = RLibrary()

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 23:10:35 2006
@@ -1,5 +1,6 @@
 from pypy.rlib.rctypesobject import *
 from pypy.rpython.test.test_llinterp import interpret
+from pypy.translator.c.test.test_genc import compile
 from pypy.annotation.policy import AnnotatorPolicy
 
 
@@ -163,9 +164,27 @@
         res = self.do(func)
         assert res == 42
 
+    def test_labs(self):
+        def ll_labs(n):
+            return abs(n)
+        labs = RFuncType((rc_int,), rc_int).fromlib(LIBC, 'labs', ll_labs)
+        def func():
+            return labs.call(-7)
+        res = self.do(func)
+        assert res == 7
+
+
+POLICY = AnnotatorPolicy()
+POLICY.allow_someobjects = False
+
 class TestLLInterpreted(TestBasic):
-    POLICY = AnnotatorPolicy()
-    POLICY.allow_someobjects = False
 
     def do(self, func):
-        return interpret(func, [], policy=self.POLICY)
+        return interpret(func, [], policy=POLICY)
+
+
+class TestCompiled(TestBasic):
+
+    def do(self, func):
+        fn = compile(func, [], annotatorpolicy=POLICY)
+        return fn()



More information about the Pypy-commit mailing list