[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