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 ...@@ -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_SetHcAttrString(PyObject*, const char*, PyObject*) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyObject_DelHcAttrString(PyObject*, const char*) 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 "codecs.h"
#include "pyerrors.h" #include "pyerrors.h"
......
...@@ -425,7 +425,9 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt ...@@ -425,7 +425,9 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
return NULL; return NULL;
} }
Py_DECREF(result->tp_dict); 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"); dict->format = _ctypes_alloc_format_string(NULL, "B");
if (dict->format == NULL) { if (dict->format == NULL) {
Py_DECREF(result); Py_DECREF(result);
...@@ -995,7 +997,9 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -995,7 +997,9 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL; return NULL;
} }
Py_DECREF(result->tp_dict); Py_DECREF(result->tp_dict);
result->tp_dict = (PyObject *)stgdict; // Pyston change:
//result->tp_dict = (PyObject *)stgdict;
PyType_SetDict(result, stgdict);
return (PyObject *)result; return (PyObject *)result;
} }
...@@ -1461,7 +1465,9 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -1461,7 +1465,9 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL; return NULL;
} }
Py_DECREF(result->tp_dict); 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. /* Special case for character arrays.
A permanent annoyance: char arrays are also strings! A permanent annoyance: char arrays are also strings!
...@@ -1885,7 +1891,9 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject ...@@ -1885,7 +1891,9 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject
return NULL; return NULL;
} }
Py_DECREF(result->tp_dict); Py_DECREF(result->tp_dict);
result->tp_dict = (PyObject *)stgdict; // Pyston change:
//result->tp_dict = (PyObject *)stgdict;
PyType_SetDict(result, stgdict);
return (PyObject *)result; return (PyObject *)result;
} }
...@@ -2014,7 +2022,9 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -2014,7 +2022,9 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL; return NULL;
} }
Py_DECREF(result->tp_dict); 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. /* Install from_param class methods in ctypes base classes.
Overrides the PyCSimpleType_from_param generic method. Overrides the PyCSimpleType_from_param generic method.
...@@ -2044,21 +2054,14 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -2044,21 +2054,14 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
break; break;
} }
// TODO: Pyston change:
// For now, don't run this code path because we don't support some of if (ml) {
// 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 (PYTHON_API_VERSION >= 1012) #if (PYTHON_API_VERSION >= 1012)
PyObject *meth; PyObject *meth;
int x; int x;
/*
meth = PyDescr_NewClassMethod(result, ml); meth = PyDescr_NewClassMethod(result, ml);
if (!meth) if (!meth)
return NULL; return NULL;
*/
#else #else
#error #error
PyObject *meth, *func; PyObject *meth, *func;
...@@ -2402,7 +2405,9 @@ PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -2402,7 +2405,9 @@ PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL; return NULL;
} }
Py_DECREF(result->tp_dict); 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)) { if (-1 == make_funcptrtype_dict(stgdict)) {
Py_DECREF(result); Py_DECREF(result);
......
...@@ -684,9 +684,14 @@ extern "C" PyObject* PyDescr_NewGetSet(PyTypeObject* x, struct PyGetSetDef* y) n ...@@ -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); 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 { extern "C" PyObject* PyDescr_NewClassMethod(PyTypeObject* type, PyMethodDef* method) noexcept {
Py_FatalError("unimplemented"); // Pyston change: we don't have a separate capi classmethod descriptor type, we just use the normal
return NULL; // 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 { extern "C" PyObject* PyDescr_NewMethod(PyTypeObject* type, PyMethodDef* method) noexcept {
......
...@@ -993,28 +993,36 @@ Box* typeLookup(BoxedClass* cls, BoxedString* attr, GetattrRewriteArgs* rewrite_ ...@@ -993,28 +993,36 @@ Box* typeLookup(BoxedClass* cls, BoxedString* attr, GetattrRewriteArgs* rewrite_
obj_saved->addAttrGuard(offsetof(BoxedClass, tp_mro), (intptr_t)mro); obj_saved->addAttrGuard(offsetof(BoxedClass, tp_mro), (intptr_t)mro);
for (auto base : *mro) { for (auto base : *mro) {
rewrite_args->out_success = false; if (rewrite_args) {
if (base == cls) { rewrite_args->out_success = false;
// Small optimization: don't have to load the class again since it was given to us in if (base == cls) {
// a register. // Small optimization: don't have to load the class again since it was given to us in
assert(rewrite_args->obj == obj_saved); // a register.
} else { assert(rewrite_args->obj == obj_saved);
rewrite_args->obj = rewrite_args->rewriter->loadConst((intptr_t)base, Location::any()); } else {
// We are passing a constant object, and objects are not allowed to change shape rewrite_args->obj = rewrite_args->rewriter->loadConst((intptr_t)base, Location::any());
// (at least the kind of "shape" that Box::getattr is referring to) // We are passing a constant object, and objects are not allowed to change shape
rewrite_args->obj_shape_guarded = true; // (at least the kind of "shape" that Box::getattr is referring to)
rewrite_args->obj_shape_guarded = true;
}
} }
val = base->getattr(attr, rewrite_args); val = base->getattr(attr, rewrite_args);
if (rewrite_args && !rewrite_args->out_success)
rewrite_args = NULL;
if (val) if (val)
return val; return val;
} }
assert(!rewrite_args->out_rtn); if (rewrite_args) {
rewrite_args->out_return_convention = GetattrRewriteArgs::NO_RETURN; assert(rewrite_args->out_success);
assert(!rewrite_args->out_rtn);
rewrite_args->out_return_convention = GetattrRewriteArgs::NO_RETURN;
}
return NULL; return NULL;
} else { } else {
assert(attr->interned_state != SSTATE_NOT_INTERNED); assert(attr->interned_state != SSTATE_NOT_INTERNED);
assert(cls->tp_mro); assert(cls->tp_mro);
assert(cls->tp_mro->cls == tuple_cls); assert(cls->tp_mro->cls == tuple_cls);
for (auto b : *static_cast<BoxedTuple*>(cls->tp_mro)) { for (auto b : *static_cast<BoxedTuple*>(cls->tp_mro)) {
......
...@@ -1425,7 +1425,16 @@ static void typeSubSetDict(Box* obj, Box* val, void* context) { ...@@ -1425,7 +1425,16 @@ static void typeSubSetDict(Box* obj, Box* val, void* context) {
} }
if (obj->cls->instancesHaveHCAttrs()) { 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; return;
} }
...@@ -1433,6 +1442,11 @@ static void typeSubSetDict(Box* obj, Box* val, void* context) { ...@@ -1433,6 +1442,11 @@ static void typeSubSetDict(Box* obj, Box* val, void* context) {
abort(); abort();
} }
extern "C" void PyType_SetDict(PyTypeObject* type, PyObject* dict) {
typeSubSetDict(type, dict, NULL);
type->tp_dict = dict;
}
Box* dict_descr = NULL; Box* dict_descr = NULL;
void BoxedInstanceMethod::gcHandler(GCVisitor* v, Box* b) { 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