Author: Armin Rigo <ar...@tunes.org> Branch: share-cpyext-cpython-api Changeset: r84056:e4d93f6ca982 Date: 2016-04-30 12:11 +0100 http://bitbucket.org/pypy/pypy/changeset/e4d93f6ca982/
Log: mess in progress diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -256,7 +256,7 @@ class ApiFunction: def __init__(self, argtypes, restype, callable, error=_NOT_SPECIFIED, - c_name=None, gil=None, result_borrowed=False): + c_name=None, gil=None, result_borrowed=False, result_is_ll=False): self.argtypes = argtypes self.restype = restype self.functype = lltype.Ptr(lltype.FuncType(argtypes, restype)) @@ -277,6 +277,9 @@ assert len(self.argnames) == len(self.argtypes) self.gil = gil self.result_borrowed = result_borrowed + self.result_is_ll = result_is_ll + if result_is_ll: # means 'returns a low-level PyObject pointer' + assert is_PyObject(restype) # def get_llhelper(space): return llhelper(self.functype, self.get_wrapper(space)) @@ -298,7 +301,7 @@ DEFAULT_HEADER = 'pypy_decl.h' def cpython_api(argtypes, restype, error=_NOT_SPECIFIED, header=DEFAULT_HEADER, - gil=None, result_borrowed=False): + gil=None, result_borrowed=False, result_is_ll=False): """ Declares a function to be exported. - `argtypes`, `restype` are lltypes and describe the function signature. @@ -337,7 +340,8 @@ c_name = func_name api_function = ApiFunction(argtypes, restype, func, error, c_name=c_name, gil=gil, - result_borrowed=result_borrowed) + result_borrowed=result_borrowed, + result_is_ll=result_is_ll) func.api_func = api_function if error is _NOT_SPECIFIED: @@ -613,6 +617,9 @@ def is_PyObject(TYPE): if not isinstance(TYPE, lltype.Ptr): return False + if TYPE == PyObject: + return True + assert not isinstance(TYPE.TO, lltype.ForwardReference) return hasattr(TYPE.TO, 'c_ob_refcnt') and hasattr(TYPE.TO, 'c_ob_type') # a pointer to PyObject @@ -710,7 +717,7 @@ argnames = callable.api_func.argnames argtypesw = zip(callable.api_func.argtypes, [_name.startswith("w_") for _name in argnames]) - error_value = callable.api_func.error_value + error_value = getattr(callable.api_func, "error_value", CANNOT_FAIL) if (isinstance(callable.api_func.restype, lltype.Ptr) and error_value is not CANNOT_FAIL): assert lltype.typeOf(error_value) == callable.api_func.restype @@ -720,6 +727,7 @@ signature = (tuple(argtypesw), callable.api_func.restype, callable.api_func.result_borrowed, + callable.api_func.result_is_ll, error_value, gil) @@ -769,7 +777,7 @@ assert False def make_wrapper_second_level(space, callable2name, argtypesw, restype, - result_borrowed, error_value, gil): + result_borrowed, result_is_ll, error_value, gil): from rpython.rlib import rgil argtypes_enum_ui = unrolling_iterable(enumerate(argtypesw)) fatal_value = restype._defl() @@ -862,13 +870,17 @@ elif is_PyObject(restype): if is_pyobj(result): - assert 0, "XXX retval = result" + assert result_is_ll else: + assert not result_is_ll if result_borrowed: result = as_pyobj(space, result) else: result = make_ref(space, result) - retval = rffi.cast(restype, result) + retval = rffi.cast(restype, result) + + elif restype is not lltype.Void: + retval = rffi.cast(restype, result) except Exception, e: unexpected_exception(callable2name[callable], e, tb) diff --git a/pypy/module/cpyext/bytesobject.py b/pypy/module/cpyext/bytesobject.py --- a/pypy/module/cpyext/bytesobject.py +++ b/pypy/module/cpyext/bytesobject.py @@ -124,7 +124,7 @@ #_______________________________________________________________________ -@cpython_api([CONST_STRING, Py_ssize_t], PyObject) +@cpython_api([CONST_STRING, Py_ssize_t], PyObject, result_is_ll=True) def PyString_FromStringAndSize(space, char_p, length): if char_p: s = rffi.charpsize2str(char_p, length) diff --git a/pypy/module/cpyext/frameobject.py b/pypy/module/cpyext/frameobject.py --- a/pypy/module/cpyext/frameobject.py +++ b/pypy/module/cpyext/frameobject.py @@ -67,7 +67,8 @@ track_reference(space, py_obj, w_obj) return w_obj -@cpython_api([PyThreadState, PyCodeObject, PyObject, PyObject], PyFrameObject) +@cpython_api([PyThreadState, PyCodeObject, PyObject, PyObject], PyFrameObject, + result_is_ll=True) def PyFrame_New(space, tstate, w_code, w_globals, w_locals): typedescr = get_typedescr(PyFrame.typedef) py_obj = typedescr.allocate(space, space.gettypeobject(PyFrame.typedef)) diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py --- a/pypy/module/cpyext/object.py +++ b/pypy/module/cpyext/object.py @@ -34,11 +34,11 @@ def PyObject_Free(space, ptr): lltype.free(ptr, flavor='raw') -@cpython_api([PyTypeObjectPtr], PyObject) +@cpython_api([PyTypeObjectPtr], PyObject, result_is_ll=True) def _PyObject_New(space, type): return _PyObject_NewVar(space, type, 0) -@cpython_api([PyTypeObjectPtr, Py_ssize_t], PyObject) +@cpython_api([PyTypeObjectPtr, Py_ssize_t], PyObject, result_is_ll=True) def _PyObject_NewVar(space, type, itemcount): w_type = from_ref(space, rffi.cast(PyObject, type)) assert isinstance(w_type, W_TypeObject) @@ -63,7 +63,7 @@ if pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE: Py_DecRef(space, rffi.cast(PyObject, pto)) -@cpython_api([PyTypeObjectPtr], PyObject) +@cpython_api([PyTypeObjectPtr], PyObject, result_is_ll=True) def _PyObject_GC_New(space, type): return _PyObject_New(space, type) @@ -193,7 +193,7 @@ space.delitem(w_obj, w_key) return 0 -@cpython_api([PyObject, PyTypeObjectPtr], PyObject) +@cpython_api([PyObject, PyTypeObjectPtr], PyObject, result_is_ll=True) def PyObject_Init(space, obj, type): """Initialize a newly-allocated object op with its type and initial reference. Returns the initialized object. If type indicates that the @@ -207,7 +207,7 @@ obj.c_ob_refcnt = 1 return obj -@cpython_api([PyVarObject, PyTypeObjectPtr, Py_ssize_t], PyObject) +@cpython_api([PyVarObject, PyTypeObjectPtr, Py_ssize_t], PyObject, result_is_ll=True) def PyObject_InitVar(space, py_obj, type, size): """This does everything PyObject_Init() does, and also initializes the length information for a variable-size object.""" diff --git a/pypy/module/cpyext/pystate.py b/pypy/module/cpyext/pystate.py --- a/pypy/module/cpyext/pystate.py +++ b/pypy/module/cpyext/pystate.py @@ -168,8 +168,16 @@ state = space.fromcache(InterpreterState) return state.get_thread_state(space) -@cpython_api([], PyObject, error=CANNOT_FAIL) +@cpython_api([], PyObject, result_is_ll=True, error=CANNOT_FAIL) def PyThreadState_GetDict(space): + """Return a dictionary in which extensions can store thread-specific state + information. Each extension should use a unique key to use to store state in + the dictionary. It is okay to call this function when no current thread state + is available. If this function returns NULL, no exception has been raised and + the caller should assume no current thread state is available. + + Previously this could only be called when a current thread is active, and NULL + meant that an exception was raised.""" state = space.fromcache(InterpreterState) return state.get_thread_state(space).c_dict diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py --- a/pypy/module/cpyext/stubs.py +++ b/pypy/module/cpyext/stubs.py @@ -1156,19 +1156,6 @@ PyInterpreterState_Clear().""" raise NotImplementedError -@cpython_api([], PyObject) -def PyThreadState_GetDict(space): - """Return a dictionary in which extensions can store thread-specific state - information. Each extension should use a unique key to use to store state in - the dictionary. It is okay to call this function when no current thread state - is available. If this function returns NULL, no exception has been raised and - the caller should assume no current thread state is available. - - Previously this could only be called when a current thread is active, and NULL - meant that an exception was raised.""" - borrow_from() - raise NotImplementedError - @cpython_api([lltype.Signed, PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyThreadState_SetAsyncExc(space, id, exc): """Asynchronously raise an exception in a thread. The id argument is the thread diff --git a/pypy/module/cpyext/tupleobject.py b/pypy/module/cpyext/tupleobject.py --- a/pypy/module/cpyext/tupleobject.py +++ b/pypy/module/cpyext/tupleobject.py @@ -127,7 +127,7 @@ #_______________________________________________________________________ -@cpython_api([Py_ssize_t], PyObject) +@cpython_api([Py_ssize_t], PyObject, result_is_ll=True) def PyTuple_New(space, size): return rffi.cast(PyObject, new_empty_tuple(space, size)) @@ -150,7 +150,8 @@ decref(space, old_ref) return 0 -@cpython_api([PyObject, Py_ssize_t], PyObject, result_borrowed=True) +@cpython_api([PyObject, Py_ssize_t], PyObject, + result_borrowed=True, result_is_ll=True) def PyTuple_GetItem(space, ref, index): if not tuple_check_ref(space, ref): PyErr_BadInternalCall(space) 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 @@ -752,7 +752,7 @@ w_type2 = from_ref(space, rffi.cast(PyObject, b)) return int(abstract_issubclass_w(space, w_type1, w_type2)) #XXX correct? -@cpython_api([PyTypeObjectPtr, Py_ssize_t], PyObject) +@cpython_api([PyTypeObjectPtr, Py_ssize_t], PyObject, result_is_ll=True) def PyType_GenericAlloc(space, type, nitems): from pypy.module.cpyext.object import _PyObject_NewVar return _PyObject_NewVar(space, type, nitems) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit