[pypy-svn] r26321 - in pypy/dist/pypy: objspace/cpy objspace/cpy/test rpython/rctypes

arigo at codespeak.net arigo at codespeak.net
Tue Apr 25 12:25:15 CEST 2006


Author: arigo
Date: Tue Apr 25 12:25:12 2006
New Revision: 26321

Modified:
   pypy/dist/pypy/objspace/cpy/test/test_compile.py
   pypy/dist/pypy/objspace/cpy/wrappable.py
   pypy/dist/pypy/rpython/rctypes/apyobject.py
   pypy/dist/pypy/rpython/rctypes/implementation.py
Log:
A possibly dead-end check-in: trying to compile built-in functions via a
'builder' attribute on W_Objects that specify how the Python object
should be created.  The builder's intent is to be called when the
compiled extension module is first imported, but this is not implemented
and I think I will try another approach instead.



Modified: pypy/dist/pypy/objspace/cpy/test/test_compile.py
==============================================================================
--- pypy/dist/pypy/objspace/cpy/test/test_compile.py	(original)
+++ pypy/dist/pypy/objspace/cpy/test/test_compile.py	Tue Apr 25 12:25:12 2006
@@ -4,6 +4,7 @@
 from pypy.translator.translator import TranslationContext, graphof
 from pypy.objspace.cpy.ann_policy import CPyAnnotatorPolicy
 from pypy.objspace.cpy.objspace import CPyObjSpace
+from pypy.objspace.cpy import wrappable, capi
 import pypy.rpython.rctypes.implementation
 from pypy.interpreter.function import BuiltinFunction
 from pypy.interpreter.gateway import interp2app, ObjSpace, W_Root
@@ -55,6 +56,12 @@
     assert s.knowntype == CPyObjSpace.W_Object
     s = a.binding(graph.getreturnvar())
     assert s.knowntype == CPyObjSpace.W_Object
+    graph = graphof(t, wrappable.builtin_function_builder)
+    assert len(graph.getargs()) == 2
+    s = a.binding(graph.getargs()[0])
+    assert s.knowntype == capi.PyMethodDef
+    s = a.binding(graph.getreturnvar())
+    assert s.knowntype == CPyObjSpace.W_Object
 
 def test_compile_bltinfunc():
     py.test.skip("in-progress")

Modified: pypy/dist/pypy/objspace/cpy/wrappable.py
==============================================================================
--- pypy/dist/pypy/objspace/cpy/wrappable.py	(original)
+++ pypy/dist/pypy/objspace/cpy/wrappable.py	Tue Apr 25 12:25:12 2006
@@ -11,6 +11,14 @@
 from pypy.interpreter.gateway import BuiltinCode, ObjSpace, W_Root
 
 
+def builtin_function_builder(ml, w_module):
+    """Build and initialize a real CPython built-in function object.
+    Compiled into the extension module and called when it is
+    first imported.
+    """
+    return PyCFunction_NewEx(byref(ml), None, w_module)
+
+
 class __extend__(pairtype(CPyObjSpace, BuiltinFunction)):
 
     def wrap((space, func)):
@@ -22,9 +30,21 @@
 
         assert unwrap_spec == [ObjSpace, W_Root]    # XXX for now
 
-        # make a real CPython built-in function from a PyMethodDef
+        # argh! callbacks of mode PyDLL are not supported by ctypes so far
+        # (as of 0.9.9.4).  XXX hack.  I am not happy.
+
+        # as a workaround, we use an interface that lets us return a normal
+        # Python function used for testing, with an attached 'builder'
+        # function that is executed at start-up to construct the object
+
+        def trampoline(*args):
+            # only called during testing; not compiled
+            args_w = [space.W_Object(a) for a in args]
+            w_result = bltin(space, *args_w)
+            return w_result.value
+
         def callback(w_self, w_args):
-            "XXX minimalistic"
+            # only called when compiled into the extension module
             w_a = PyObject_GetItem(w_args, 0)
             w_result = bltin(space, w_a)
             return w_result
@@ -34,17 +54,7 @@
                          ml_flags = METH_VARARGS,
                          #ml_doc  = ...,
                          )
-        w_result = PyCFunction_NewEx(byref(ml), None, func.w_module)
-        w_result.ml = ml   # keep ml alive as long as w_result is around
-
-        # argh! callbacks of mode PyDLL are not supported by ctypes so far
-        # (as of 0.9.9.4).  XXX hack.  I am not happy.
-
-        def hackish_trampoline(*args):
-            args_w = [space.W_Object(a) for a in args]
-            w_result = bltin(space, *args_w)
-            return w_result.value
 
-        w_pseudoresult = W_Object(hackish_trampoline)
-        w_pseudoresult._hack_replace_with_ = w_result
-        return w_pseudoresult
+        w_result = W_Object(trampoline)
+        w_result.builder = builtin_function_builder, (ml, func.w_module)
+        return w_result

Modified: pypy/dist/pypy/rpython/rctypes/apyobject.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/apyobject.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/apyobject.py	Tue Apr 25 12:25:12 2006
@@ -1,7 +1,8 @@
 from ctypes import py_object
-from pypy.annotation.model import SomeCTypesObject
+from pypy.annotation.model import SomeCTypesObject, SomeImpossibleValue
 from pypy.rpython.rctypes.implementation import CTypesCallEntry, CTypesObjEntry
 from pypy.rpython.lltypesystem import lltype
+from pypy.tool.uid import Hashable
 
 
 class CallEntry(CTypesCallEntry):
@@ -22,6 +23,22 @@
     "Annotation and rtyping of py_object instances."
     _type_ = py_object
 
+    def object_seen(self, bookkeeper):
+        "Called when the annotator sees this py_object."
+        # extension: if the py_object instance has a 'builder' attribute,
+        # it must be a pair (callable, args) which is meant to be called
+        # at initialization-time when the compiled extension module is
+        # first imported.  It returns the "real" Python object.
+        if hasattr(self.instance, 'builder'):
+            # emulate a call so that the callable is properly annotated
+            callable, args = self.instance.builder
+            s_callable = bookkeeper.immutablevalue(callable)
+            args_s = [bookkeeper.immutablevalue(a) for a in args]
+            uniquekey = Hashable(self.instance)
+            s_res = bookkeeper.emulate_pbc_call(uniquekey, s_callable, args_s)
+            assert (issubclass(s_res.knowntype, py_object) or
+                    isinstance(s_res, SomeImpossibleValue))
+
     def get_repr(self, rtyper, s_pyobject):
         from pypy.rpython.rctypes.rpyobject import CTypesPyObjRepr
         lowleveltype = lltype.Ptr(lltype.PyObject)

Modified: pypy/dist/pypy/rpython/rctypes/implementation.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/implementation.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/implementation.py	Tue Apr 25 12:25:12 2006
@@ -76,6 +76,9 @@
             if isinstance(o, dict):
                 for x in o.itervalues():
                     recfind(x)
+            elif isinstance(o, (list, tuple)):
+                for x in o:
+                    recfind(x)
             elif extregistry.is_registered(o):
                 entry = extregistry.lookup(o)
                 if isinstance(entry, CTypesEntry):



More information about the Pypy-commit mailing list