Commit 3f0b2da2 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Getting pretty far

parent ffffa422
......@@ -653,9 +653,9 @@ public:
// getattr() does the equivalent of PyDict_GetItem(obj->dict, attr): it looks up the attribute's value on the
// object's attribute storage. it doesn't look at other objects or do any descriptor logic.
template <Rewritable rewritable = REWRITABLE>
Box* getattr(BoxedString* attr, GetattrRewriteArgs* rewrite_args);
Box* getattr(BoxedString* attr) { return getattr<NOT_REWRITABLE>(attr, NULL); }
Box* getattrString(const char* attr);
BORROWED(Box*) getattr(BoxedString* attr, GetattrRewriteArgs* rewrite_args);
BORROWED(Box*) getattr(BoxedString* attr) { return getattr<NOT_REWRITABLE>(attr, NULL); }
BORROWED(Box*) getattrString(const char* attr);
bool hasattr(BoxedString* attr) { return getattr(attr) != NULL; }
void delattr(BoxedString* attr, DelattrRewriteArgs* rewrite_args);
......
......@@ -1755,6 +1755,7 @@ Box* processDescriptor(Box* obj, Box* inst, Box* owner) {
template <bool IsType, Rewritable rewritable>
Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rewrite_args, bool cls_only, bool for_call,
Box** bind_obj_out, RewriterVar** r_bind_obj_out) {
RELEASE_ASSERT(0, "need to check the refcounting here\n");
if (rewritable == NOT_REWRITABLE) {
assert(!rewrite_args);
rewrite_args = NULL;
......
......@@ -169,8 +169,8 @@ extern "C" PyObject* type_getattro(PyObject* o, PyObject* name) noexcept;
// This is the equivalent of _PyType_Lookup(), which calls Box::getattr() on each item in the object's MRO in the
// appropriate order. It does not do any descriptor logic.
template <Rewritable rewritable = REWRITABLE>
Box* typeLookup(BoxedClass* cls, BoxedString* attr, GetattrRewriteArgs* rewrite_args);
inline Box* typeLookup(BoxedClass* cls, BoxedString* attr) {
BORROWED(Box*) typeLookup(BoxedClass* cls, BoxedString* attr, GetattrRewriteArgs* rewrite_args);
inline BORROWED(Box*) typeLookup(BoxedClass* cls, BoxedString* attr) {
return typeLookup<NOT_REWRITABLE>(cls, attr, NULL);
}
......
......@@ -280,7 +280,7 @@ Box* Box::hasnextOrNullIC() {
}
extern "C" BoxedFunctionBase::BoxedFunctionBase(FunctionMetadata* md)
: in_weakreflist(NULL),
: weakreflist(NULL),
md(md),
closure(NULL),
defaults(NULL),
......@@ -306,7 +306,7 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(FunctionMetadata* md)
extern "C" BoxedFunctionBase::BoxedFunctionBase(FunctionMetadata* md, std::initializer_list<Box*> defaults,
BoxedClosure* closure, Box* globals, bool can_change_defaults)
: in_weakreflist(NULL),
: weakreflist(NULL),
md(md),
closure(closure),
globals(globals),
......@@ -3349,6 +3349,32 @@ void BoxedModule::dealloc(Box* b) noexcept {
self->clearAttrs();
}
void BoxedInstanceMethod::dealloc(Box* b) noexcept {
BoxedInstanceMethod* im = static_cast<BoxedInstanceMethod*>(b);
im->clearAttrs();
_PyObject_GC_UNTRACK(im);
if (im->im_weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *)im);
Py_DECREF(im->func);
Py_XDECREF(im->obj);
Py_XDECREF(im->im_class);
#if 0
if (numfree < PyMethod_MAXFREELIST) {
im->obj = (PyObject *)free_list;
free_list = im;
numfree++;
}
else {
#endif
PyObject_GC_Del(im);
#if 0
}
#endif
}
void BoxedList::dealloc(Box* b) noexcept {
BoxedList* op = static_cast<BoxedList*>(b);
......@@ -3511,9 +3537,9 @@ void setupRuntime() {
float_cls->tp_flags &= ~Py_TPFLAGS_HAVE_GC;
function_cls = new (0)
BoxedClass(object_cls, offsetof(BoxedFunction, attrs),
offsetof(BoxedFunction, in_weakreflist), sizeof(BoxedFunction), false, "function");
offsetof(BoxedFunction, weakreflist), sizeof(BoxedFunction), false, "function");
builtin_function_or_method_cls = new (0)
BoxedClass(object_cls, 0, offsetof(BoxedBuiltinFunctionOrMethod, in_weakreflist),
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;
function_cls->has_safe_tp_dealloc = builtin_function_or_method_cls->has_safe_tp_dealloc = true;
......@@ -3602,24 +3628,6 @@ void setupRuntime() {
// Weakrefs are used for tp_subclasses:
init_weakref();
// XXX
_Py_ReleaseInternedStrings();
for (auto b : classes)
b->clearAttrs();
for (auto b : constants) {
b->clearAttrs();
Py_DECREF(b);
}
for (auto b : classes) {
if (b->tp_mro) {
Py_DECREF(b->tp_mro);
}
Py_DECREF(b);
}
PRINT_TOTAL_REFS();
exit(0);
// XXX
add_operators(object_cls);
object_cls->finishInitialization();
......@@ -3655,8 +3663,9 @@ void setupRuntime() {
instancemethod_cls = BoxedClass::create(type_cls, object_cls, 0,
offsetof(BoxedInstanceMethod, in_weakreflist), sizeof(BoxedInstanceMethod),
offsetof(BoxedInstanceMethod, im_weakreflist), sizeof(BoxedInstanceMethod),
false, "instancemethod");
instancemethod_cls->tp_dealloc = BoxedInstanceMethod::dealloc;
slice_cls
= BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSlice), false, "slice");
......@@ -3694,8 +3703,8 @@ void setupRuntime() {
object_cls->giveAttr("__repr__",
new BoxedFunction(FunctionMetadata::create((void*)objectRepr, UNKNOWN, 1, false, false)));
object_cls->giveAttr("__subclasshook__", boxInstanceMethod(object_cls, new BoxedFunction(FunctionMetadata::create(
(void*)objectSubclasshook, UNKNOWN, 2)),
object_cls->giveAttr("__subclasshook__", boxInstanceMethod(object_cls, autoDecref(new BoxedFunction(FunctionMetadata::create(
(void*)objectSubclasshook, UNKNOWN, 2))),
object_cls));
// __setattr__ was already set to a WrapperDescriptor; it'd be nice to set this to a faster BoxedFunction
// object_cls->setattr("__setattr__", new BoxedFunction(FunctionMetadata::create((void*)objectSetattr, UNKNOWN, 3)),
......@@ -3726,6 +3735,26 @@ void setupRuntime() {
type_cls->tp_richcompare = type_richcompare;
add_operators(type_cls);
type_cls->freeze();
// XXX
PyType_ClearCache();
_Py_ReleaseInternedStrings();
for (auto b : classes)
b->clearAttrs();
for (auto b : constants) {
b->clearAttrs();
Py_DECREF(b);
}
for (auto b : classes) {
if (b->tp_mro) {
Py_DECREF(b->tp_mro);
}
Py_DECREF(b);
}
PRINT_TOTAL_REFS();
exit(0);
// XXX
type_cls->tp_new = type_new;
type_cls->tpp_call.capi_val = &typeTppCall<CAPI>;
type_cls->tpp_call.cxx_val = &typeTppCall<CXX>;
......
......@@ -483,15 +483,21 @@ extern "C" int64_t hashUnboxed(Box* obj);
class BoxedInstanceMethod : public Box {
public:
Box** in_weakreflist;
Box** im_weakreflist;
// obj is NULL for unbound instancemethod
Box* obj, *func, *im_class;
BoxedInstanceMethod(Box* obj, Box* func, Box* im_class) __attribute__((visibility("default")))
: in_weakreflist(NULL), obj(obj), func(func), im_class(im_class) {}
: im_weakreflist(NULL), obj(obj), func(func), im_class(im_class) {
Py_INCREF(func);
Py_XINCREF(obj);
Py_XINCREF(im_class);
}
DEFAULT_CLASS_SIMPLE(instancemethod_cls, true);
static void dealloc(Box* self) noexcept;
};
class GCdArray {
......@@ -823,7 +829,7 @@ static_assert(sizeof(BoxedDict) == sizeof(PyDictObject), "");
class BoxedFunctionBase : public Box {
public:
Box** in_weakreflist;
Box** weakreflist;
FunctionMetadata* md;
......
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