Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit