Commit 9ebfc95f authored by Kevin Modzelewski's avatar Kevin Modzelewski

Add cobject.c

parent 949dfeb1
......@@ -366,6 +366,7 @@ STDOBJECT_SRCS := \
memoryobject.c \
iterobject.c \
bufferobject.c \
cobject.c \
$(EXTRA_STDOBJECT_SRCS)
STDPYTHON_SRCS := \
......
......@@ -76,6 +76,7 @@ file(GLOB_RECURSE STDOBJECT_SRCS Objects
bytearrayobject.c
bytes_methods.c
capsule.c
cobject.c
exceptions.c
iterobject.c
memoryobject.c
......
......@@ -75,6 +75,7 @@
#include "methodobject.h"
#include "moduleobject.h"
#include "classobject.h"
#include "cobject.h"
#include "fileobject.h"
#include "pycapsule.h"
#include "traceback.h"
......
// This file is originally from CPython 2.7, with modifications for Pyston
/*
CObjects are marked Pending Deprecation as of Python 2.7.
The full schedule for 2.x is as follows:
- CObjects are marked Pending Deprecation in Python 2.7.
- CObjects will be marked Deprecated in Python 2.8
(if there is one).
- CObjects will be removed in Python 2.9 (if there is one).
Additionally, for the Python 3.x series:
- CObjects were marked Deprecated in Python 3.1.
- CObjects will be removed in Python 3.2.
You should switch all use of CObjects to capsules. Capsules
have a safer and more consistent API. For more information,
see Include/pycapsule.h, or read the "Capsules" topic in
the "Python/C API Reference Manual".
Python 2.7 no longer uses CObjects itself; all objects which
were formerly CObjects are now capsules. Note that this change
does not by itself break binary compatibility with extensions
built for previous versions of Python--PyCObject_AsVoidPtr()
has been changed to also understand capsules.
*/
/* original file header comment follows: */
/* C objects to be exported from one extension module to another.
C objects are used for communication between extension modules.
They provide a way for an extension module to export a C interface
to other extension modules, so that extension modules can use the
Python import mechanism to link to one another.
*/
#ifndef Py_COBJECT_H
#define Py_COBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
PyAPI_DATA(PyTypeObject) PyCObject_Type;
#define PyCObject_Check(op) (Py_TYPE(op) == &PyCObject_Type)
/* Create a PyCObject from a pointer to a C object and an optional
destructor function. If the second argument is non-null, then it
will be called with the first argument if and when the PyCObject is
destroyed.
*/
PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtr(
void *cobj, void (*destruct)(void*)) PYSTON_NOEXCEPT;
/* Create a PyCObject from a pointer to a C object, a description object,
and an optional destructor function. If the third argument is non-null,
then it will be called with the first and second arguments if and when
the PyCObject is destroyed.
*/
PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtrAndDesc(
void *cobj, void *desc, void (*destruct)(void*,void*)) PYSTON_NOEXCEPT;
/* Retrieve a pointer to a C object from a PyCObject. */
PyAPI_FUNC(void *) PyCObject_AsVoidPtr(PyObject *) PYSTON_NOEXCEPT;
/* Retrieve a pointer to a description object from a PyCObject. */
PyAPI_FUNC(void *) PyCObject_GetDesc(PyObject *) PYSTON_NOEXCEPT;
/* Import a pointer to a C object from a module using a PyCObject. */
PyAPI_FUNC(void *) PyCObject_Import(char *module_name, char *cobject_name) PYSTON_NOEXCEPT;
/* Modify a C object. Fails (==0) if object has a destructor. */
PyAPI_FUNC(int) PyCObject_SetVoidPtr(PyObject *self, void *cobj) PYSTON_NOEXCEPT;
typedef struct {
PyObject_HEAD
void *cobject;
void *desc;
void (*destructor)(void *);
} PyCObject;
#ifdef __cplusplus
}
#endif
#endif /* !Py_COBJECT_H */
// This file is originally from CPython 2.7, with modifications for Pyston
/* Wrap void* pointers to be passed between C modules */
#include "Python.h"
/* Declarations for objects of type PyCObject */
typedef void (*destructor1)(void *);
typedef void (*destructor2)(void *, void*);
static int cobject_deprecation_warning(void)
{
return PyErr_WarnPy3k("CObject type is not supported in 3.x. "
"Please use capsule objects instead.", 1);
}
PyObject *
PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
{
PyCObject *self;
if (cobject_deprecation_warning()) {
return NULL;
}
self = PyObject_NEW(PyCObject, &PyCObject_Type);
if (self == NULL)
return NULL;
self->cobject=cobj;
self->destructor=destr;
self->desc=NULL;
return (PyObject *)self;
}
PyObject *
PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
void (*destr)(void *, void *))
{
PyCObject *self;
if (cobject_deprecation_warning()) {
return NULL;
}
if (!desc) {
PyErr_SetString(PyExc_TypeError,
"PyCObject_FromVoidPtrAndDesc called with null"
" description");
return NULL;
}
self = PyObject_NEW(PyCObject, &PyCObject_Type);
if (self == NULL)
return NULL;
self->cobject = cobj;
self->destructor = (destructor1)destr;
self->desc = desc;
return (PyObject *)self;
}
void *
PyCObject_AsVoidPtr(PyObject *self)
{
if (self) {
if (PyCapsule_CheckExact(self)) {
const char *name = PyCapsule_GetName(self);
return (void *)PyCapsule_GetPointer(self, name);
}
if (self->ob_type == &PyCObject_Type)
return ((PyCObject *)self)->cobject;
PyErr_SetString(PyExc_TypeError,
"PyCObject_AsVoidPtr with non-C-object");
}
if (!PyErr_Occurred())
PyErr_SetString(PyExc_TypeError,
"PyCObject_AsVoidPtr called with null pointer");
return NULL;
}
void *
PyCObject_GetDesc(PyObject *self)
{
if (self) {
if (self->ob_type == &PyCObject_Type)
return ((PyCObject *)self)->desc;
PyErr_SetString(PyExc_TypeError,
"PyCObject_GetDesc with non-C-object");
}
if (!PyErr_Occurred())
PyErr_SetString(PyExc_TypeError,
"PyCObject_GetDesc called with null pointer");
return NULL;
}
void *
PyCObject_Import(char *module_name, char *name)
{
PyObject *m, *c;
void *r = NULL;
if ((m = PyImport_ImportModule(module_name))) {
if ((c = PyObject_GetAttrString(m,name))) {
r = PyCObject_AsVoidPtr(c);
Py_DECREF(c);
}
Py_DECREF(m);
}
return r;
}
int
PyCObject_SetVoidPtr(PyObject *self, void *cobj)
{
PyCObject* cself = (PyCObject*)self;
if (cself == NULL || !PyCObject_Check(cself) ||
cself->destructor != NULL) {
PyErr_SetString(PyExc_TypeError,
"Invalid call to PyCObject_SetVoidPtr");
return 0;
}
cself->cobject = cobj;
return 1;
}
static void
PyCObject_dealloc(PyCObject *self)
{
if (self->destructor) {
if(self->desc)
((destructor2)(self->destructor))(self->cobject, self->desc);
else
(self->destructor)(self->cobject);
}
PyObject_DEL(self);
}
PyDoc_STRVAR(PyCObject_Type__doc__,
"C objects to be exported from one extension module to another\n\
\n\
C objects are used for communication between extension modules. They\n\
provide a way for an extension module to export a C interface to other\n\
extension modules, so that extension modules can use the Python import\n\
mechanism to link to one another.");
PyTypeObject PyCObject_Type = {
PyVarObject_HEAD_INIT(/* Pyston change: &PyType_Type */ NULL, 0)
"PyCObject", /*tp_name*/
sizeof(PyCObject), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor)PyCObject_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
0, /*tp_flags*/
PyCObject_Type__doc__ /*tp_doc*/
};
......@@ -2596,8 +2596,6 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
// unhandled fields:
RELEASE_ASSERT(cls->tp_compare == NULL, "");
RELEASE_ASSERT(cls->tp_getattro == NULL || cls->tp_getattro == PyObject_GenericGetAttr, "");
int ALLOWABLE_FLAGS = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES
| Py_TPFLAGS_HAVE_NEWBUFFER;
ALLOWABLE_FLAGS |= Py_TPFLAGS_INT_SUBCLASS | Py_TPFLAGS_LONG_SUBCLASS | Py_TPFLAGS_LIST_SUBCLASS
......
......@@ -105,7 +105,7 @@ public:
RELEASE_ASSERT(_self->cls == thread_lock_cls, "");
BoxedThreadLock* self = static_cast<BoxedThreadLock*>(_self);
RELEASE_ASSERT(_waitflag->cls == int_cls, "");
RELEASE_ASSERT(isSubclass(_waitflag->cls, int_cls), "");
int waitflag = static_cast<BoxedInt*>(_waitflag)->n;
// Copied + adapted from CPython:
......
......@@ -2273,6 +2273,7 @@ void setupRuntime() {
PyType_Ready(&PyByteArrayIter_Type);
PyType_Ready(&PyCapsule_Type);
PyType_Ready(&PyCallIter_Type);
PyType_Ready(&PyCObject_Type);
initerrno();
init_sha();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment