Commit 7199f0e3 authored by Kevin Modzelewski's avatar Kevin Modzelewski

proper dealloc (with free), and imports

parent 3a2c0407
......@@ -133,7 +133,7 @@ PyAPI_DATA(PyTypeObject*) dictvalues_cls;
(PyDictKeys_Check(op) || PyDictItems_Check(op))
PyAPI_FUNC(PyObject *) PyDict_New(void) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key) PYSTON_NOEXCEPT;
PyAPI_FUNC(BORROWED(PyObject *)) PyDict_GetItem(PyObject *mp, PyObject *key) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key) PYSTON_NOEXCEPT;
PyAPI_FUNC(void) PyDict_Clear(PyObject *mp) PYSTON_NOEXCEPT;
......@@ -172,7 +172,7 @@ PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d,
PyObject *seq2,
int override) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key) PYSTON_NOEXCEPT;
PyAPI_FUNC(BORROWED(PyObject *)) PyDict_GetItemString(PyObject *dp, const char *key) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key) PYSTON_NOEXCEPT;
......
......@@ -17,7 +17,7 @@ PyAPI_DATA(PyTypeObject*) module_cls;
#define PyModule_CheckExact(op) (Py_TYPE(op) == &PyModule_Type)
PyAPI_FUNC(PyObject *) PyModule_New(const char *) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyModule_GetDict(PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(BORROWED(PyObject *)) PyModule_GetDict(PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(char *) PyModule_GetName(PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(char *) PyModule_GetFilename(PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(void) _PyModule_Clear(PyObject *) PYSTON_NOEXCEPT;
......
......@@ -42,8 +42,8 @@ PyAPI_DATA(PyTypeObject*) tuple_cls;
PyAPI_FUNC(PyObject *) PyTuple_New(Py_ssize_t size) PYSTON_NOEXCEPT;
PyAPI_FUNC(Py_ssize_t) PyTuple_Size(PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyTuple_GetItem(PyObject *, Py_ssize_t) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(BORROWED(PyObject *)) PyTuple_GetItem(PyObject *, Py_ssize_t) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyTuple_SetItem(PyObject *, Py_ssize_t, STOLEN(PyObject *)) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyTuple_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...) PYSTON_NOEXCEPT;
......
......@@ -2249,12 +2249,17 @@ _PyExc_Init(void)
PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
if (!PyExc_MemoryErrorInst)
Py_FatalError("Cannot pre-allocate MemoryError instance");
// Pyston addition:
PyGC_RegisterStaticConstant(PyExc_MemoryErrorInst);
PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RuntimeError, NULL, NULL);
if (!PyExc_RecursionErrorInst)
Py_FatalError("Cannot pre-allocate RuntimeError instance for "
"recursion errors");
else {
// Pyston addition:
PyGC_RegisterStaticConstant(PyExc_RecursionErrorInst);
PyBaseExceptionObject *err_inst =
(PyBaseExceptionObject *)PyExc_RecursionErrorInst;
PyObject *args_tuple;
......
......@@ -2965,8 +2965,7 @@ static void inherit_slots(PyTypeObject* type, PyTypeObject* base) noexcept {
* didn't define tp_free, and the base uses the
* default non-gc tp_free.
*/
// Pyston change: don't do this:
// type->tp_free = PyObject_GC_Del;
type->tp_free = PyObject_GC_Del;
}
/* else they didn't agree about gc, and there isn't something
* obvious to be done -- the type is on its own.
......@@ -3379,7 +3378,7 @@ extern "C" void PyType_RequestHcAttrs(PyTypeObject* cls, int offset) noexcept {
extern "C" void PyType_GiveHcAttrsDictDescr(PyTypeObject* cls) noexcept {
static BoxedString* dict_str = getStaticString("__dict__");
assert(!cls->hasattr(dict_str));
cls->giveAttr(dict_str, dict_descr);
cls->giveAttr(incref(dict_str), incref(dict_descr));
}
extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
......@@ -3422,7 +3421,7 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
cls->giveAttrBorrowed("__base__", base);
assert(cls->tp_dict == NULL);
cls->tp_dict = cls->getAttrWrapper();
cls->tp_dict = incref(cls->getAttrWrapper());
assert(cls->tp_name);
......
......@@ -661,7 +661,7 @@ public:
void delattr(BoxedString* attr, DelattrRewriteArgs* rewrite_args);
// Only valid for hc-backed instances:
Box* getAttrWrapper();
BORROWED(Box*) getAttrWrapper();
Box* reprIC();
BoxedString* reprICAsString();
......
......@@ -712,8 +712,7 @@ void setupSys() {
sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX));
sys_module->giveAttr("maxsize", boxInt(PY_SSIZE_T_MAX));
sys_flags_cls = new (0)
BoxedClass(object_cls, 0, 0, sizeof(BoxedSysFlags), false, "flags");
sys_flags_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSysFlags), false, "flags");
sys_flags_cls->giveAttr(
"__new__", new BoxedFunction(FunctionMetadata::create((void*)BoxedSysFlags::__new__, UNKNOWN, 1, true, true)));
sys_flags_cls->tp_dealloc = (destructor)BoxedSysFlags::dealloc;
......@@ -730,7 +729,6 @@ void setupSys() {
#ifdef Py_USING_UNICODE
SET_SYS_FROM_STRING("maxunicode", PyInt_FromLong(PyUnicode_GetMax()));
#endif
sys_flags_cls->tp_mro = BoxedTuple::create({ sys_flags_cls, object_cls });
sys_flags_cls->freeze();
for (auto& md : sys_methods) {
......
......@@ -313,7 +313,7 @@ extern "C" int PyDict_SetItemString(PyObject* mp, const char* key, PyObject* ite
abort();
}
return PyDict_SetItem(mp, key_s, item);
return PyDict_SetItem(mp, autoDecref(key_s), item);
}
extern "C" PyObject* PyDict_GetItem(PyObject* dict, PyObject* key) noexcept {
......
......@@ -384,14 +384,14 @@ static Box* getParent(Box* globals, int level, std::string& buf) {
static Box* importSub(const std::string& name, BoxedString* full_name, Box* parent_module) {
BoxedDict* sys_modules = getSysModulesDict();
if (sys_modules->d.find(full_name) != sys_modules->d.end()) {
return sys_modules->d[full_name];
return incref(sys_modules->d[full_name]);
}
BoxedList* path_list;
if (parent_module == NULL || parent_module == None) {
path_list = NULL;
} else {
static BoxedString* path_str = internStringImmortal("__path__");
static BoxedString* path_str = getStaticString("__path__");
path_list = static_cast<BoxedList*>(getattrInternal<ExceptionStyle::CXX>(parent_module, path_str));
if (path_list == NULL || path_list->cls != list_cls) {
return None;
......@@ -472,10 +472,10 @@ static bool loadNext(Box* mod, Box* altmod, std::string& name, std::string& buf,
std::string subname(local_name.substr(0, len));
buf += subname;
result = importSub(subname, boxString(buf), mod);
result = importSub(subname, autoDecref(boxString(buf)), mod);
if (result == None && altmod != mod) {
/* Here, altmod must be None and mod must not be None */
result = importSub(subname, boxString(subname), altmod);
result = importSub(subname, autoDecref(boxString(subname)), altmod);
if (result != NULL && result != None) {
markMiss(buf);
......@@ -566,7 +566,7 @@ extern "C" PyObject* PyImport_ImportModuleLevel(const char* name, PyObject* glob
}
static void ensureFromlist(Box* module, Box* fromlist, std::string& buf, bool recursive) {
static BoxedString* path_str = internStringImmortal("__path__");
static BoxedString* path_str = getStaticString("__path__");
Box* pathlist = NULL;
try {
pathlist = getattrInternal<ExceptionStyle::CXX>(module, path_str);
......@@ -579,6 +579,9 @@ static void ensureFromlist(Box* module, Box* fromlist, std::string& buf, bool re
// If it's not a package, then there's no sub-importing to do
return;
}
Py_DECREF(pathlist);
RELEASE_ASSERT(0, "check the refcounting here");
for (Box* _s : fromlist->pyElements()) {
RELEASE_ASSERT(PyString_Check(_s), "");
......@@ -614,8 +617,8 @@ extern "C" PyObject* PyImport_Import(PyObject* module_name) noexcept {
try {
// TODO: check if this has the same behaviour as the cpython implementation
BoxedList* silly_list = new BoxedList();
listAppendInternal(silly_list, boxString("__doc__"));
return import(0, silly_list, ((BoxedString*)module_name)->s());
listAppendInternal(silly_list, autoDecref(boxString("__doc__")));
return import(0, autoDecref(silly_list), ((BoxedString*)module_name)->s());
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
......@@ -623,7 +626,7 @@ extern "C" PyObject* PyImport_Import(PyObject* module_name) noexcept {
}
extern "C" PyObject* PyImport_ImportModule(const char* name) noexcept {
return PyImport_Import(boxString(name));
return PyImport_Import(autoDecref(boxString(name)));
}
extern "C" PyObject* PyImport_GetModuleDict(void) noexcept {
......
......@@ -189,8 +189,7 @@ bool calliter_hasnext(Box* b) {
void setupIter() {
seqiter_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSeqIter), false,
"iterator");
seqiter_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSeqIter), false, "iterator");
seqiter_cls->giveAttr("next", new BoxedFunction(FunctionMetadata::create((void*)seqiterNext, UNKNOWN, 1)));
seqiter_cls->giveAttr("__hasnext__",
......
This diff is collapsed.
......@@ -382,7 +382,10 @@ extern "C" int PyTuple_SetItem(PyObject* op, Py_ssize_t i, PyObject* newitem) no
BoxedTuple* t = static_cast<BoxedTuple*>(op);
RELEASE_ASSERT(i >= 0 && i < t->size(), "");
auto olditem = t->elts[i];
t->elts[i] = newitem;
Py_XDECREF(olditem);
return 0;
}
......@@ -399,6 +402,7 @@ extern "C" PyObject* PyTuple_Pack(Py_ssize_t n, ...) noexcept {
for (Py_ssize_t i = 0; i < n; i++) {
PyObject* o = va_arg(vargs, PyObject*);
Py_INCREF(o);
PyTuple_SetItem(result, i, o);
}
va_end(vargs);
......
......@@ -2498,11 +2498,13 @@ Box* Box::getAttrWrapper() {
auto new_hcls = hcls->getAttrwrapperChild();
appendNewHCAttr(aw, NULL);
attrs->hcls = new_hcls;
Py_DECREF(aw);
return aw;
} else {
assert(hcls->type == HiddenClass::SINGLETON);
appendNewHCAttr(aw, NULL);
hcls->appendAttrwrapper();
Py_DECREF(aw);
return aw;
}
}
......@@ -3223,12 +3225,6 @@ extern "C" PyUnicodeObject* _PyUnicode_New(Py_ssize_t length) noexcept {
return unicode;
}
// We don't need CPython's version of tp_free since we have GC.
// We still need to set tp_free to something and not a NULL pointer,
// because C extensions might still call tp_free from tp_dealloc.
void default_free(void*) {
}
void dealloc_null(Box* box) {
assert(box->cls->tp_del == NULL);
}
......@@ -3423,6 +3419,10 @@ void BoxedClass::dealloc(Box* b) noexcept {
#endif
}
static void object_dealloc(PyObject* self) {
Py_TYPE(self)->tp_free(self);
}
#ifndef Py_REF_DEBUG
#define PRINT_TOTAL_REFS()
......@@ -3448,15 +3448,14 @@ void setupRuntime() {
type_cls = static_cast<BoxedClass*>(PyObject_MALLOC(sizeof(BoxedClass)));
PyObject_INIT(object_cls, type_cls);
PyObject_INIT(type_cls, type_cls);
::new (object_cls) BoxedClass(NULL, 0, 0, sizeof(Box), false, "object");
::new (object_cls) BoxedClass(NULL, 0, 0, sizeof(Box), false, "object", object_dealloc, PyObject_Del);
object_cls->tp_flags &= ~Py_TPFLAGS_HAVE_GC;
::new (type_cls) BoxedClass(object_cls, offsetof(BoxedClass, attrs),
offsetof(BoxedClass, tp_weaklist), sizeof(BoxedHeapClass), false, "type");
::new (type_cls) BoxedClass(object_cls, offsetof(BoxedClass, attrs), offsetof(BoxedClass, tp_weaklist),
sizeof(BoxedHeapClass), false, "type", BoxedClass::dealloc, PyObject_GC_Del);
type_cls->has_safe_tp_dealloc = false;
type_cls->tp_flags |= Py_TPFLAGS_TYPE_SUBCLASS;
type_cls->tp_itemsize = sizeof(BoxedHeapClass::SlotOffset);
type_cls->tp_dealloc = BoxedClass::dealloc;
// XXX silly that we have to set this again
new (&object_cls->attrs) HCAttrs(HiddenClass::makeSingleton());
......@@ -3468,18 +3467,18 @@ void setupRuntime() {
object_cls->tp_new = object_new;
type_cls->tp_getattro = type_getattro;
none_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(Box), false, "NoneType");
none_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(Box), false, "NoneType", NULL, NULL);
None = new (none_cls) Box();
constants.push_back(None);
assert(None->cls);
// You can't actually have an instance of basestring
basestring_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(Box), false, "basestring");
basestring_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(Box), false, "basestring", NULL, NULL);
// We add 1 to the tp_basicsize of the BoxedString in order to hold the null byte at the end.
// We use offsetof(BoxedString, s_data) as opposed to sizeof(BoxedString) so that we can
// use the extra padding bytes at the end of the BoxedString.
str_cls = new (0) BoxedClass(basestring_cls, 0, 0, offsetof(BoxedString, s_data) + 1, false, "str");
str_cls = new (0) BoxedClass(basestring_cls, 0, 0, offsetof(BoxedString, s_data) + 1, false, "str", NULL, NULL);
str_cls->tp_flags |= Py_TPFLAGS_STRING_SUBCLASS;
str_cls->tp_itemsize = sizeof(char);
......@@ -3498,61 +3497,55 @@ void setupRuntime() {
// Not sure why CPython defines sizeof(PyTupleObject) to include one element,
// but we copy that, which means we have to subtract that extra pointer to get the tp_basicsize:
tuple_cls = new (0)
BoxedClass(object_cls, 0, 0, sizeof(BoxedTuple) - sizeof(Box*), false, "tuple");
BoxedClass(object_cls, 0, 0, sizeof(BoxedTuple) - sizeof(Box*), false, "tuple", (destructor)tupledealloc, NULL);
tuple_cls->tp_dealloc = (destructor)tupledealloc;
tuple_cls->tp_flags |= Py_TPFLAGS_TUPLE_SUBCLASS;
tuple_cls->tp_itemsize = sizeof(Box*);
tuple_cls->tp_mro = BoxedTuple::create({ tuple_cls, object_cls });
EmptyTuple = BoxedTuple::create({});
constants.push_back(EmptyTuple);
list_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(BoxedList), false, "list");
list_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(BoxedList), false, "list", BoxedList::dealloc, NULL);
list_cls->tp_flags |= Py_TPFLAGS_LIST_SUBCLASS;
list_cls->tp_dealloc = BoxedList::dealloc;
pyston_getset_cls = new (0)
BoxedClass(object_cls, 0, 0, sizeof(BoxedGetsetDescriptor), false, "getset_descriptor");
BoxedClass(object_cls, 0, 0, sizeof(BoxedGetsetDescriptor), false, "getset_descriptor", NULL, NULL);
attrwrapper_cls = new (0)
BoxedClass(object_cls, 0, 0, sizeof(AttrWrapper), false, "attrwrapper");
dict_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(BoxedDict), false, "dict");
BoxedClass(object_cls, 0, 0, sizeof(AttrWrapper), false, "attrwrapper", NULL, NULL);
dict_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(BoxedDict), false, "dict", BoxedDict::dealloc, NULL);
dict_cls->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS;
dict_cls->tp_dealloc = BoxedDict::dealloc;
file_cls = new (0) BoxedClass(object_cls, 0, offsetof(BoxedFile, weakreflist),
sizeof(BoxedFile), false, "file");
file_cls->tp_dealloc = file_dealloc;
int_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(BoxedInt), false, "int");
sizeof(BoxedFile), false, "file", file_dealloc, NULL);
int_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(BoxedInt), false, "int", NULL, NULL);
int_cls->tp_flags |= Py_TPFLAGS_INT_SUBCLASS;
int_cls->tp_flags &= ~Py_TPFLAGS_HAVE_GC;
bool_cls = new (0) BoxedClass(int_cls, 0, 0, sizeof(BoxedBool), false, "bool");
bool_cls = new (0) BoxedClass(int_cls, 0, 0, sizeof(BoxedBool), false, "bool", NULL, NULL);
bool_cls->tp_flags &= ~Py_TPFLAGS_HAVE_GC;
complex_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(BoxedComplex), false, "complex");
complex_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(BoxedComplex), false, "complex", NULL, NULL);
complex_cls->tp_flags &= ~Py_TPFLAGS_HAVE_GC;
long_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(BoxedLong), false, "long");
long_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(BoxedLong), false, "long", NULL, NULL);
long_cls->tp_flags |= Py_TPFLAGS_LONG_SUBCLASS;
long_cls->tp_flags &= ~Py_TPFLAGS_HAVE_GC;
float_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(BoxedFloat), false, "float");
float_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(BoxedFloat), false, "float", NULL, NULL);
float_cls->tp_flags &= ~Py_TPFLAGS_HAVE_GC;
function_cls = new (0)
BoxedClass(object_cls, offsetof(BoxedFunction, attrs),
offsetof(BoxedFunction, weakreflist), sizeof(BoxedFunction), false, "function");
offsetof(BoxedFunction, weakreflist), sizeof(BoxedFunction), false, "function", functionDtor, NULL);
builtin_function_or_method_cls = new (0)
BoxedClass(object_cls, 0, offsetof(BoxedBuiltinFunctionOrMethod, weakreflist),
sizeof(BoxedBuiltinFunctionOrMethod), false, "builtin_function_or_method");
function_cls->tp_dealloc = builtin_function_or_method_cls->tp_dealloc = functionDtor;
sizeof(BoxedBuiltinFunctionOrMethod), false, "builtin_function_or_method", functionDtor, NULL);
function_cls->has_safe_tp_dealloc = builtin_function_or_method_cls->has_safe_tp_dealloc = true;
module_cls = new (0) BoxedClass(object_cls, offsetof(BoxedModule, attrs), 0,
sizeof(BoxedModule), false, "module");
module_cls->tp_dealloc = BoxedModule::dealloc;
sizeof(BoxedModule), false, "module", BoxedModule::dealloc, NULL);
member_descriptor_cls = new (0)
BoxedClass(object_cls, 0, 0, sizeof(BoxedMemberDescriptor), false, "member_descriptor");
BoxedClass(object_cls, 0, 0, sizeof(BoxedMemberDescriptor), false, "member_descriptor", NULL, NULL);
capifunc_cls = new (0)
BoxedClass(object_cls, 0, 0, sizeof(BoxedCApiFunction), false, "capifunc");
BoxedClass(object_cls, 0, 0, sizeof(BoxedCApiFunction), false, "capifunc", NULL, NULL);
method_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(BoxedMethodDescriptor),
false, "method_descriptor");
false, "method_descriptor", NULL, NULL);
wrapperobject_cls = new (0) BoxedClass(object_cls, 0, 0, sizeof(BoxedWrapperObject),
false, "method-wrapper");
false, "method-wrapper", NULL, NULL);
wrapperdescr_cls = new (0) BoxedClass(object_cls, 0, 0,
sizeof(BoxedWrapperDescriptor), false, "wrapper_descriptor");
sizeof(BoxedWrapperDescriptor), false, "wrapper_descriptor", NULL, NULL);
EmptyString = new (0) BoxedString("");
constants.push_back(EmptyString);
......@@ -3660,8 +3653,7 @@ void setupRuntime() {
instancemethod_cls = BoxedClass::create(type_cls, object_cls, 0,
offsetof(BoxedInstanceMethod, im_weakreflist), sizeof(BoxedInstanceMethod),
false, "instancemethod");
instancemethod_cls->tp_dealloc = BoxedInstanceMethod::dealloc;
false, "instancemethod", BoxedInstanceMethod::dealloc);
slice_cls
= BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSlice), false, "slice");
......
......@@ -68,7 +68,7 @@ void setupImport();
void setupAST();
void setupSysEnd();
BoxedDict* getSysModulesDict();
BORROWED(BoxedDict*) getSysModulesDict();
BoxedList* getSysPath();
extern "C" Box* getSysStdout();
......@@ -173,7 +173,6 @@ struct ExcInfo;
void setCAPIException(const ExcInfo& e);
// Finalizer-related
void default_free(void*);
void dealloc_null(Box* box);
void file_dealloc(Box*) noexcept;
......@@ -276,11 +275,12 @@ public:
SlotOffset* slotOffsets() { return (BoxedClass::SlotOffset*)((char*)this + this->cls->tp_basicsize); }
// These should only be used for builtin types:
static BoxedClass* create(BoxedClass* metatype, BoxedClass* base, int attrs_offset,
int weaklist_offset, int instance_size, bool is_user_defined, const char* name);
static BoxedClass* create(BoxedClass* metatype, BoxedClass* base, int attrs_offset, int weaklist_offset,
int instance_size, bool is_user_defined, const char* name, destructor dealloc = NULL,
freefunc free = NULL);
BoxedClass(BoxedClass* base, int attrs_offset, int weaklist_offset, int instance_size,
bool is_user_defined, const char* name);
bool is_user_defined, const char* name, destructor dealloc, freefunc free);
DEFAULT_CLASS_VAR(type_cls, sizeof(SlotOffset));
......
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