Author: Matti Picus <[email protected]>
Branch: call-via-pyobj
Changeset: r85484:5b38ce2c4c11
Date: 2016-07-01 12:53 +0300
http://bitbucket.org/pypy/pypy/changeset/5b38ce2c4c11/
Log: proof of concept using offset-to-function instead of function
diff --git a/pypy/module/cpyext/methodobject.py
b/pypy/module/cpyext/methodobject.py
--- a/pypy/module/cpyext/methodobject.py
+++ b/pypy/module/cpyext/methodobject.py
@@ -10,9 +10,10 @@
from pypy.module.cpyext.api import (
CONST_STRING, METH_CLASS, METH_COEXIST, METH_KEYWORDS, METH_NOARGS, METH_O,
METH_STATIC, METH_VARARGS, PyObject, PyObjectFields, bootstrap_function,
- build_type_checkers, cpython_api, cpython_struct, generic_cpy_call)
+ build_type_checkers, cpython_api, cpython_struct, generic_cpy_call,
+ PyTypeObjectPtr)
from pypy.module.cpyext.pyobject import (
- Py_DecRef, from_ref, make_ref, make_typedescr)
+ Py_DecRef, from_ref, make_ref, as_pyobj, make_typedescr)
PyCFunction_typedef = rffi.COpaquePtr(typedef='PyCFunction')
PyCFunction = lltype.Ptr(lltype.FuncType([PyObject, PyObject], PyObject))
@@ -151,13 +152,14 @@
class W_PyCWrapperObject(W_Root):
def __init__(self, space, pto, method_name, wrapper_func,
- wrapper_func_kwds, doc, func):
+ wrapper_func_kwds, doc, func, offset=-1):
self.space = space
self.method_name = method_name
self.wrapper_func = wrapper_func
self.wrapper_func_kwds = wrapper_func_kwds
self.doc = doc
self.func = func
+ self.offset = offset
pyo = rffi.cast(PyObject, pto)
w_type = from_ref(space, pyo)
assert isinstance(w_type, W_TypeObject)
@@ -172,7 +174,17 @@
raise oefmt(space.w_TypeError,
"wrapper %s doesn't take any keyword arguments",
self.method_name)
- return self.wrapper_func(space, w_self, w_args, self.func)
+ if self.offset >= 0:
+ pto = rffi.cast(PyTypeObjectPtr, as_pyobj(space, self.w_objclass))
+ pto_func_as_int = lltype.cast_ptr_to_int(pto) + self.offset
+ # XXX make pto_func the equivalent of this line
+ #lltype.cast_int_to_ptr(pto_func_as_int)
+ func_to_call = rffi.cast(rffi.VOIDP,
pto.c_tp_as_number.c_nb_multiply)
+ # print '\ncalling', func_to_call, 'not', self.func
+ else:
+ # print 'calling', self.method_name,'with no offset'
+ func_to_call = self.func
+ return self.wrapper_func(space, w_self, w_args, func_to_call)
def descr_method_repr(self):
return self.space.wrap("<slot wrapper '%s' of '%s' objects>" %
@@ -301,12 +313,6 @@
def PyDescr_NewClassMethod(space, w_type, method):
return space.wrap(W_PyCClassMethodObject(space, method, w_type))
-def PyDescr_NewWrapper(space, pto, method_name, wrapper_func,
- wrapper_func_kwds, doc, func):
- # not exactly the API sig
- return space.wrap(W_PyCWrapperObject(space, pto, method_name,
- wrapper_func, wrapper_func_kwds, doc, func))
-
@cpython_api([lltype.Ptr(PyMethodDef), PyObject, CONST_STRING], PyObject)
def Py_FindMethod(space, table, w_obj, name_ptr):
"""Return a bound method object for an extension type implemented in
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -17,9 +17,9 @@
generic_cpy_call, Py_TPFLAGS_READY, Py_TPFLAGS_READYING,
Py_TPFLAGS_HEAPTYPE, METH_VARARGS, METH_KEYWORDS, CANNOT_FAIL,
Py_TPFLAGS_HAVE_GETCHARBUFFER, build_type_checkers, StaticObjectBuilder,
- PyObjectFields, Py_TPFLAGS_BASETYPE)
+ PyObjectFields, Py_TPFLAGS_BASETYPE, PyTypeObject, PyTypeObjectPtr)
from pypy.module.cpyext.methodobject import (W_PyCClassMethodObject,
- PyDescr_NewWrapper, PyCFunction_NewEx, PyCFunction_typedef, PyMethodDef,
+ W_PyCWrapperObject, PyCFunction_NewEx, PyCFunction_typedef, PyMethodDef,
W_PyCMethodObject, W_PyCFunctionObject)
from pypy.module.cpyext.modsupport import convert_method_defs
from pypy.module.cpyext.pyobject import (
@@ -30,7 +30,7 @@
from pypy.module.cpyext.state import State
from pypy.module.cpyext.structmember import PyMember_GetOne, PyMember_SetOne
from pypy.module.cpyext.typeobjectdefs import (
- PyTypeObjectPtr, PyTypeObject, PyGetSetDef, PyMemberDef, newfunc,
+ PyGetSetDef, PyMemberDef, newfunc,
PyNumberMethods, PyMappingMethods, PySequenceMethods, PyBufferProcs)
from pypy.objspace.std.typeobject import W_TypeObject, find_best_base
@@ -296,6 +296,7 @@
for method_name, slot_names, wrapper_func, wrapper_func_kwds, doc in
slotdefs_for_wrappers:
if method_name in dict_w:
continue
+ offset = rffi.offsetof(pto._T, slot_names[0])
if len(slot_names) == 1:
func = getattr(pto, slot_names[0])
else:
@@ -303,14 +304,24 @@
struct = getattr(pto, slot_names[0])
if not struct:
continue
+ offset += rffi.offsetof(struct._T, slot_names[1])
func = getattr(struct, slot_names[1])
func_voidp = rffi.cast(rffi.VOIDP, func)
if not func:
continue
if wrapper_func is None and wrapper_func_kwds is None:
continue
- dict_w[method_name] = PyDescr_NewWrapper(space, pto, method_name,
wrapper_func,
- wrapper_func_kwds, doc, func_voidp)
+ name = rffi.charp2str(pto.c_tp_name)
+ if method_name in ('__mul__', '__rmul__') and 'array' in name:
+ # print '\nsetting', name, method_name, 'from', slot_names
+ # print ' pto is', pto
+ # print ' func_voidp is', func_voidp
+ pass
+ else:
+ offset = -1
+ w_obj = W_PyCWrapperObject(space, pto, method_name, wrapper_func,
+ wrapper_func_kwds, doc, func_voidp, offset=offset)
+ dict_w[method_name] = space.wrap(w_obj)
if pto.c_tp_new:
add_tp_new_wrapper(space, dict_w, pto)
@@ -714,6 +725,8 @@
def py_type_ready(space, pto):
if pto.c_tp_flags & Py_TPFLAGS_READY:
+ name = rffi.charp2str(pto.c_tp_name)
+ print 'py_type_ready',name, 'but PyTP_FLAGS_READY is set'
return
type_realize(space, rffi.cast(PyObject, pto))
@@ -730,6 +743,8 @@
try:
w_obj = _type_realize(space, py_obj)
finally:
+ name = rffi.charp2str(pto.c_tp_name)
+ print '_type_realize done', name
pto.c_tp_flags &= ~Py_TPFLAGS_READYING
pto.c_tp_flags |= Py_TPFLAGS_READY
return w_obj
@@ -811,7 +826,9 @@
base = pto.c_tp_base
base_pyo = rffi.cast(PyObject, pto.c_tp_base)
if base and not base.c_tp_flags & Py_TPFLAGS_READY:
- type_realize(space, rffi.cast(PyObject, base_pyo))
+ name = rffi.charp2str(base.c_tp_name)
+ print 'realizing base while creating child',
+ type_realize(space, base_pyo)
if base and not pto.c_ob_type: # will be filled later
pto.c_ob_type = base.c_ob_type
if not pto.c_tp_bases:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit