[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