Commit 15cb10b0 authored by Boxiang Sun's avatar Boxiang Sun

add ctypes workaround of tp_dict, wrote by kmod

parent 8013893c
......@@ -115,6 +115,9 @@ PyAPI_FUNC(PyObject*) PyObject_GetHcAttrString(PyObject*, const char*) PYSTON_NO
PyAPI_FUNC(int) PyObject_SetHcAttrString(PyObject*, const char*, PyObject*) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyObject_DelHcAttrString(PyObject*, const char*) PYSTON_NOEXCEPT;
// Workaround: call this instead of setting tp_dict.
PyAPI_FUNC(void) PyType_SetDict(PyTypeObject*, PyObject*) PYSTON_NOEXCEPT;
#include "codecs.h"
#include "pyerrors.h"
......
......@@ -425,7 +425,9 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
return NULL;
}
Py_DECREF(result->tp_dict);
result->tp_dict = (PyObject *)dict;
// Pyston change:
//result->tp_dict = (PyObject *)dict;
PyType_SetDict(result, dict);
dict->format = _ctypes_alloc_format_string(NULL, "B");
if (dict->format == NULL) {
Py_DECREF(result);
......@@ -995,7 +997,9 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
}
Py_DECREF(result->tp_dict);
result->tp_dict = (PyObject *)stgdict;
// Pyston change:
//result->tp_dict = (PyObject *)stgdict;
PyType_SetDict(result, stgdict);
return (PyObject *)result;
}
......@@ -1461,7 +1465,9 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
}
Py_DECREF(result->tp_dict);
result->tp_dict = (PyObject *)stgdict;
// Pyston change:
//result->tp_dict = (PyObject *)stgdict;
PyType_SetDict(result, stgdict);
/* Special case for character arrays.
A permanent annoyance: char arrays are also strings!
......@@ -1885,7 +1891,9 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject
return NULL;
}
Py_DECREF(result->tp_dict);
result->tp_dict = (PyObject *)stgdict;
// Pyston change:
//result->tp_dict = (PyObject *)stgdict;
PyType_SetDict(result, stgdict);
return (PyObject *)result;
}
......@@ -2014,7 +2022,9 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
}
Py_DECREF(result->tp_dict);
result->tp_dict = (PyObject *)stgdict;
// Pyston change:
//result->tp_dict = (PyObject *)stgdict;
PyType_SetDict(result, stgdict);
/* Install from_param class methods in ctypes base classes.
Overrides the PyCSimpleType_from_param generic method.
......@@ -2044,21 +2054,14 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
break;
}
// TODO: Pyston change:
// For now, don't run this code path because we don't support some of
// the descriptor CAPI functions.
// We do this to be able to run `import ctypes`, but this will need to be
// enabled again once we want CType to actually work.
// if (ml) {
if (false) {
if (ml) {
#if (PYTHON_API_VERSION >= 1012)
PyObject *meth;
int x;
/*
meth = PyDescr_NewClassMethod(result, ml);
if (!meth)
return NULL;
*/
#else
#error
PyObject *meth, *func;
......@@ -2402,7 +2405,9 @@ PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
}
Py_DECREF(result->tp_dict);
result->tp_dict = (PyObject *)stgdict;
// Pyston change:
//result->tp_dict = (PyObject *)stgdict;
PyType_SetDict(result, stgdict);
if (-1 == make_funcptrtype_dict(stgdict)) {
Py_DECREF(result);
......
......@@ -684,9 +684,14 @@ extern "C" PyObject* PyDescr_NewGetSet(PyTypeObject* x, struct PyGetSetDef* y) n
return new (capi_getset_cls) BoxedGetsetDescriptor(y->get, (void (*)(Box*, Box*, void*))y->set, y->closure);
}
extern "C" PyObject* PyDescr_NewClassMethod(PyTypeObject* x, PyMethodDef* y) noexcept {
Py_FatalError("unimplemented");
return NULL;
extern "C" PyObject* PyDescr_NewClassMethod(PyTypeObject* type, PyMethodDef* method) noexcept {
// Pyston change: we don't have a separate capi classmethod descriptor type, we just use the normal
// one but with the METH_CLASS flag set.
if (!(method->ml_flags & METH_CLASS)) {
method = new PyMethodDef(*method);
method->ml_flags |= METH_CLASS;
}
return new pyston::BoxedMethodDescriptor(method, type);
}
extern "C" PyObject* PyDescr_NewMethod(PyTypeObject* type, PyMethodDef* method) noexcept {
......
......@@ -993,28 +993,36 @@ Box* typeLookup(BoxedClass* cls, BoxedString* attr, GetattrRewriteArgs* rewrite_
obj_saved->addAttrGuard(offsetof(BoxedClass, tp_mro), (intptr_t)mro);
for (auto base : *mro) {
rewrite_args->out_success = false;
if (base == cls) {
// Small optimization: don't have to load the class again since it was given to us in
// a register.
assert(rewrite_args->obj == obj_saved);
} else {
rewrite_args->obj = rewrite_args->rewriter->loadConst((intptr_t)base, Location::any());
// We are passing a constant object, and objects are not allowed to change shape
// (at least the kind of "shape" that Box::getattr is referring to)
rewrite_args->obj_shape_guarded = true;
if (rewrite_args) {
rewrite_args->out_success = false;
if (base == cls) {
// Small optimization: don't have to load the class again since it was given to us in
// a register.
assert(rewrite_args->obj == obj_saved);
} else {
rewrite_args->obj = rewrite_args->rewriter->loadConst((intptr_t)base, Location::any());
// We are passing a constant object, and objects are not allowed to change shape
// (at least the kind of "shape" that Box::getattr is referring to)
rewrite_args->obj_shape_guarded = true;
}
}
val = base->getattr(attr, rewrite_args);
if (rewrite_args && !rewrite_args->out_success)
rewrite_args = NULL;
if (val)
return val;
}
assert(!rewrite_args->out_rtn);
rewrite_args->out_return_convention = GetattrRewriteArgs::NO_RETURN;
if (rewrite_args) {
assert(rewrite_args->out_success);
assert(!rewrite_args->out_rtn);
rewrite_args->out_return_convention = GetattrRewriteArgs::NO_RETURN;
}
return NULL;
} else {
assert(attr->interned_state != SSTATE_NOT_INTERNED);
assert(cls->tp_mro);
assert(cls->tp_mro->cls == tuple_cls);
for (auto b : *static_cast<BoxedTuple*>(cls->tp_mro)) {
......
......@@ -1425,7 +1425,16 @@ static void typeSubSetDict(Box* obj, Box* val, void* context) {
}
if (obj->cls->instancesHaveHCAttrs()) {
obj->setDictBacked(val);
RELEASE_ASSERT(PyDict_Check(val) || val->cls == attrwrapper_cls, "%s", val->cls->tp_name);
auto new_attr_list
= (HCAttrs::AttrList*)gc_alloc(sizeof(HCAttrs::AttrList) + sizeof(Box*), gc::GCKind::PRECISE);
new_attr_list->attrs[0] = val;
HCAttrs* hcattrs = obj->getHCAttrsPtr();
hcattrs->hcls = HiddenClass::dict_backed;
hcattrs->attr_list = new_attr_list;
return;
}
......@@ -1433,6 +1442,11 @@ static void typeSubSetDict(Box* obj, Box* val, void* context) {
abort();
}
extern "C" void PyType_SetDict(PyTypeObject* type, PyObject* dict) {
typeSubSetDict(type, dict, NULL);
type->tp_dict = dict;
}
Box* dict_descr = NULL;
void BoxedInstanceMethod::gcHandler(GCVisitor* v, Box* b) {
......
from ctypes import *
s = "tmp"
ap = create_string_buffer(s)
print type(ap)
print type(c_void_p.from_param(ap))
print type(cast(ap, c_char_p))
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