Commit 03cd0cbc authored by Rudi Chen's avatar Rudi Chen

Make gc visitors (gcHandler) static methods on the type being visited.

This serves two purposes.
1) Improve naming consistency (follow the format TYPENAME::gcHandler)
2) In the source file, the visit function declaration is closer to the
   fields of the objects. If a field is added, hopefully it will be
   easier to remember to update the GC visit function.
parent 7ca763c7
...@@ -682,7 +682,24 @@ extern "C" Box* dictInit(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) { ...@@ -682,7 +682,24 @@ extern "C" Box* dictInit(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) {
return None; return None;
} }
static void BoxedDictIterator:::gcHandler(GCVisitor* v, Box* b) { void BoxedDict::gcHandler(GCVisitor* v, Box* b) {
assert(isSubclass(b->cls, dict_cls));
boxGCHandler(v, b);
BoxedDict* d = (BoxedDict*)b;
// This feels like a cludge, but we need to find anything that
// the unordered_map might have allocated.
// Another way to handle this would be to rt_alloc the unordered_map
// as well, though that incurs extra memory dereferences which would
// be nice to avoid.
void** start = (void**)&d->d;
void** end = start + (sizeof(d->d) / 8);
v->visitPotentialRange(start, end);
}
void BoxedDictIterator::gcHandler(GCVisitor* v, Box* b) {
assert(b->cls == dict_iterator_cls); assert(b->cls == dict_iterator_cls);
boxGCHandler(v, b); boxGCHandler(v, b);
...@@ -690,7 +707,7 @@ static void BoxedDictIterator:::gcHandler(GCVisitor* v, Box* b) { ...@@ -690,7 +707,7 @@ static void BoxedDictIterator:::gcHandler(GCVisitor* v, Box* b) {
v->visit(it->d); v->visit(it->d);
} }
static void BoxedDictView::gcHandler(GCVisitor* v, Box* b) { void BoxedDictView::gcHandler(GCVisitor* v, Box* b) {
assert(b->cls == dict_items_cls); assert(b->cls == dict_items_cls);
boxGCHandler(v, b); boxGCHandler(v, b);
...@@ -723,12 +740,12 @@ void setupDict() { ...@@ -723,12 +740,12 @@ void setupDict() {
dict_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedDictIterator::gcHandler, 0, 0, dict_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedDictIterator::gcHandler, 0, 0,
sizeof(BoxedDictIterator), false, "dictionary-itemiterator"); sizeof(BoxedDictIterator), false, "dictionary-itemiterator");
dict_keys_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedDictView::gcHandler, 0, 0, sizeof(BoxedDictView), false, dict_keys_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedDictView::gcHandler, 0, 0, sizeof(BoxedDictView),
"dict_keys"); false, "dict_keys");
dict_values_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedDictView::gcHandler, 0, 0, sizeof(BoxedDictView), dict_values_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedDictView::gcHandler, 0, 0,
false, "dict_values"); sizeof(BoxedDictView), false, "dict_values");
dict_items_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedDictView::gcHandler, 0, 0, sizeof(BoxedDictView), dict_items_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedDictView::gcHandler, 0, 0,
false, "dict_items"); sizeof(BoxedDictView), false, "dict_items");
dict_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)dictLen, BOXED_INT, 1))); dict_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)dictLen, BOXED_INT, 1)));
dict_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)dictNew, UNKNOWN, 1, 0, true, true))); dict_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)dictNew, UNKNOWN, 1, 0, true, true)));
......
...@@ -378,7 +378,7 @@ extern "C" BoxedGenerator::BoxedGenerator(BoxedFunctionBase* function, Box* arg1 ...@@ -378,7 +378,7 @@ extern "C" BoxedGenerator::BoxedGenerator(BoxedFunctionBase* function, Box* arg1
context = makeContext(stack_begin, (void (*)(intptr_t))generatorEntry); context = makeContext(stack_begin, (void (*)(intptr_t))generatorEntry);
} }
extern "C" void generatorGCHandler(GCVisitor* v, Box* b) { void BoxedGenerator::gcHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b); boxGCHandler(v, b);
BoxedGenerator* g = (BoxedGenerator*)b; BoxedGenerator* g = (BoxedGenerator*)b;
...@@ -434,8 +434,8 @@ void generatorDestructor(Box* b) { ...@@ -434,8 +434,8 @@ void generatorDestructor(Box* b) {
void setupGenerator() { void setupGenerator() {
generator_cls generator_cls
= BoxedHeapClass::create(type_cls, object_cls, &generatorGCHandler, 0, offsetof(BoxedGenerator, weakreflist), = BoxedHeapClass::create(type_cls, object_cls, &BoxedGenerator::gcHandler, 0,
sizeof(BoxedGenerator), false, "generator"); offsetof(BoxedGenerator, weakreflist), sizeof(BoxedGenerator), false, "generator");
generator_cls->tp_dealloc = generatorDestructor; generator_cls->tp_dealloc = generatorDestructor;
generator_cls->has_safe_tp_dealloc = true; generator_cls->has_safe_tp_dealloc = true;
generator_cls->giveAttr("__iter__", generator_cls->giveAttr("__iter__",
......
...@@ -118,7 +118,7 @@ public: ...@@ -118,7 +118,7 @@ public:
return boxInt(xrangeIteratorNextUnboxed(s)); return boxInt(xrangeIteratorNextUnboxed(s));
} }
static void xrangeIteratorGCHandler(GCVisitor* v, Box* b) { static void gcHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b); boxGCHandler(v, b);
BoxedXrangeIterator* it = (BoxedXrangeIterator*)b; BoxedXrangeIterator* it = (BoxedXrangeIterator*)b;
...@@ -195,8 +195,8 @@ Box* xrangeLen(Box* self) { ...@@ -195,8 +195,8 @@ Box* xrangeLen(Box* self) {
void setupXrange() { void setupXrange() {
xrange_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, 0, sizeof(BoxedXrange), false, "xrange"); xrange_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, 0, sizeof(BoxedXrange), false, "xrange");
xrange_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedXrangeIterator::xrangeIteratorGCHandler, 0, xrange_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedXrangeIterator::gcHandler, 0, 0,
0, sizeof(BoxedXrangeIterator), false, "rangeiterator"); sizeof(BoxedXrangeIterator), false, "rangeiterator");
xrange_cls->giveAttr( xrange_cls->giveAttr(
"__new__", "__new__",
......
...@@ -112,7 +112,7 @@ Box* seqiterNext(Box* s) { ...@@ -112,7 +112,7 @@ Box* seqiterNext(Box* s) {
return r; return r;
} }
static void seqiterGCVisit(GCVisitor* v, Box* b) { void BoxedSeqIter::gcHandler(GCVisitor* v, Box* b) {
assert(b->cls == seqiter_cls || b->cls == seqreviter_cls); assert(b->cls == seqiter_cls || b->cls == seqreviter_cls);
boxGCHandler(v, b); boxGCHandler(v, b);
...@@ -122,7 +122,7 @@ static void seqiterGCVisit(GCVisitor* v, Box* b) { ...@@ -122,7 +122,7 @@ static void seqiterGCVisit(GCVisitor* v, Box* b) {
v->visit(si->next); v->visit(si->next);
} }
static void iterwrapperGCVisit(GCVisitor* v, Box* b) { void BoxedIterWrapper::gcHandler(GCVisitor* v, Box* b) {
assert(b->cls == iterwrapper_cls); assert(b->cls == iterwrapper_cls);
boxGCHandler(v, b); boxGCHandler(v, b);
...@@ -182,8 +182,8 @@ bool calliter_hasnext(Box* b) { ...@@ -182,8 +182,8 @@ bool calliter_hasnext(Box* b) {
void setupIter() { void setupIter() {
seqiter_cls seqiter_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedSeqIter::gcHandler, 0, 0, sizeof(BoxedSeqIter),
= BoxedHeapClass::create(type_cls, object_cls, seqiterGCVisit, 0, 0, sizeof(BoxedSeqIter), false, "iterator"); false, "iterator");
seqiter_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)seqiterNext, UNKNOWN, 1))); seqiter_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)seqiterNext, UNKNOWN, 1)));
seqiter_cls->giveAttr("__hasnext__", new BoxedFunction(boxRTFunction((void*)seqiterHasnext, BOXED_BOOL, 1))); seqiter_cls->giveAttr("__hasnext__", new BoxedFunction(boxRTFunction((void*)seqiterHasnext, BOXED_BOOL, 1)));
...@@ -192,8 +192,8 @@ void setupIter() { ...@@ -192,8 +192,8 @@ void setupIter() {
seqiter_cls->freeze(); seqiter_cls->freeze();
seqiter_cls->tpp_hasnext = seqiterHasnextUnboxed; seqiter_cls->tpp_hasnext = seqiterHasnextUnboxed;
seqreviter_cls seqreviter_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedSeqIter::gcHandler, 0, 0, sizeof(BoxedSeqIter),
= BoxedHeapClass::create(type_cls, object_cls, seqiterGCVisit, 0, 0, sizeof(BoxedSeqIter), false, "reversed"); false, "reversed");
seqreviter_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)seqiterNext, UNKNOWN, 1))); seqreviter_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)seqiterNext, UNKNOWN, 1)));
seqreviter_cls->giveAttr("__hasnext__", new BoxedFunction(boxRTFunction((void*)seqreviterHasnext, BOXED_BOOL, 1))); seqreviter_cls->giveAttr("__hasnext__", new BoxedFunction(boxRTFunction((void*)seqreviterHasnext, BOXED_BOOL, 1)));
...@@ -201,8 +201,8 @@ void setupIter() { ...@@ -201,8 +201,8 @@ void setupIter() {
seqreviter_cls->freeze(); seqreviter_cls->freeze();
iterwrapper_cls = BoxedHeapClass::create(type_cls, object_cls, iterwrapperGCVisit, 0, 0, sizeof(BoxedIterWrapper), iterwrapper_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedIterWrapper::gcHandler, 0, 0,
false, "iterwrapper"); sizeof(BoxedIterWrapper), false, "iterwrapper");
iterwrapper_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)iterwrapperNext, UNKNOWN, 1))); iterwrapper_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)iterwrapperNext, UNKNOWN, 1)));
iterwrapper_cls->giveAttr("__hasnext__", iterwrapper_cls->giveAttr("__hasnext__",
......
...@@ -36,6 +36,8 @@ public: ...@@ -36,6 +36,8 @@ public:
BoxedSeqIter(Box* b, int64_t start) : b(b), idx(start), next(NULL) {} BoxedSeqIter(Box* b, int64_t start) : b(b), idx(start), next(NULL) {}
DEFAULT_CLASS(seqiter_cls); DEFAULT_CLASS(seqiter_cls);
static void gcHandler(GCVisitor* v, Box* b);
}; };
extern BoxedClass* iterwrapper_cls; extern BoxedClass* iterwrapper_cls;
...@@ -49,6 +51,8 @@ public: ...@@ -49,6 +51,8 @@ public:
BoxedIterWrapper(Box* iter) : iter(iter), next(NULL) {} BoxedIterWrapper(Box* iter) : iter(iter), next(NULL) {}
DEFAULT_CLASS(iterwrapper_cls); DEFAULT_CLASS(iterwrapper_cls);
static void gcHandler(GCVisitor* v, Box* b);
}; };
bool calliter_hasnext(Box* b); bool calliter_hasnext(Box* b);
......
...@@ -917,12 +917,6 @@ Box* listRemove(BoxedList* self, Box* elt) { ...@@ -917,12 +917,6 @@ Box* listRemove(BoxedList* self, Box* elt) {
BoxedClass* list_iterator_cls = NULL; BoxedClass* list_iterator_cls = NULL;
BoxedClass* list_reverse_iterator_cls = NULL; BoxedClass* list_reverse_iterator_cls = NULL;
extern "C" void listIteratorGCHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b);
BoxedListIterator* it = (BoxedListIterator*)b;
v->visit(it->l);
}
Box* listNew(BoxedClass* cls, Box* container) { Box* listNew(BoxedClass* cls, Box* container) {
assert(isSubclass(cls->cls, type_cls)); assert(isSubclass(cls->cls, type_cls));
assert(isSubclass(cls, list_cls)); assert(isSubclass(cls, list_cls));
...@@ -1097,10 +1091,31 @@ extern "C" int PyList_SetSlice(PyObject* a, Py_ssize_t ilow, Py_ssize_t ihigh, P ...@@ -1097,10 +1091,31 @@ extern "C" int PyList_SetSlice(PyObject* a, Py_ssize_t ilow, Py_ssize_t ihigh, P
} }
} }
void BoxedListIterator::gcHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b);
BoxedListIterator* it = (BoxedListIterator*)b;
v->visit(it->l);
}
void BoxedList::gcHandler(GCVisitor* v, Box* b) {
assert(isSubclass(b->cls, list_cls));
boxGCHandler(v, b);
BoxedList* l = (BoxedList*)b;
int size = l->size;
int capacity = l->capacity;
assert(capacity >= size);
if (capacity)
v->visit(l->elts);
if (size)
v->visitRange((void**)&l->elts->elts[0], (void**)&l->elts->elts[size]);
}
void setupList() { void setupList() {
list_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &listIteratorGCHandler, 0, 0, list_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedListIterator::gcHandler, 0, 0,
sizeof(BoxedListIterator), false, "listiterator"); sizeof(BoxedListIterator), false, "listiterator");
list_reverse_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &listIteratorGCHandler, 0, 0, list_reverse_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedListIterator::gcHandler, 0, 0,
sizeof(BoxedListIterator), false, "listreverseiterator"); sizeof(BoxedListIterator), false, "listreverseiterator");
list_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)listLen, BOXED_INT, 1))); list_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)listLen, BOXED_INT, 1)));
......
...@@ -29,6 +29,8 @@ public: ...@@ -29,6 +29,8 @@ public:
BoxedListIterator(BoxedList* l, int start); BoxedListIterator(BoxedList* l, int start);
DEFAULT_CLASS(list_iterator_cls); DEFAULT_CLASS(list_iterator_cls);
static void gcHandler(GCVisitor* v, Box* b);
}; };
Box* listIter(Box* self) noexcept; Box* listIter(Box* self) noexcept;
......
...@@ -25,6 +25,21 @@ extern "C" Box* createSet() { ...@@ -25,6 +25,21 @@ extern "C" Box* createSet() {
return new BoxedSet(); return new BoxedSet();
} }
void BoxedSet::gcHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b);
BoxedSet* s = (BoxedSet*)b;
// This feels like a cludge, but we need to find anything that
// the unordered_map might have allocated.
// Another way to handle this would be to rt_alloc the unordered_map
// as well, though that incurs extra memory dereferences which would
// be nice to avoid.
void** start = (void**)&s->s;
void** end = start + (sizeof(s->s) / 8);
v->visitPotentialRange(start, end);
}
namespace set { namespace set {
class BoxedSetIterator : public Box { class BoxedSetIterator : public Box {
...@@ -43,15 +58,15 @@ public: ...@@ -43,15 +58,15 @@ public:
++it; ++it;
return rtn; return rtn;
} }
};
extern "C" void setIteratorGCHandler(GCVisitor* v, Box* b) { static void gcHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b); boxGCHandler(v, b);
BoxedSetIterator* it = (BoxedSetIterator*)b; BoxedSetIterator* it = (BoxedSetIterator*)b;
v->visit(it->s); v->visit(it->s);
} }
};
Box* setiteratorHasnext(BoxedSetIterator* self) { Box* setiteratorHasnext(BoxedSetIterator* self) {
RELEASE_ASSERT(self->cls == set_iterator_cls, ""); RELEASE_ASSERT(self->cls == set_iterator_cls, "");
...@@ -509,7 +524,7 @@ extern "C" PyObject* PyFrozenSet_New(PyObject* iterable) noexcept { ...@@ -509,7 +524,7 @@ extern "C" PyObject* PyFrozenSet_New(PyObject* iterable) noexcept {
using namespace pyston::set; using namespace pyston::set;
void setupSet() { void setupSet() {
set_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &setIteratorGCHandler, 0, 0, set_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedSetIterator::gcHandler, 0, 0,
sizeof(BoxedSetIterator), false, "setiterator"); sizeof(BoxedSetIterator), false, "setiterator");
set_iterator_cls->giveAttr( set_iterator_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)setiteratorIter, typeFromClass(set_iterator_cls), 1))); "__iter__", new BoxedFunction(boxRTFunction((void*)setiteratorIter, typeFromClass(set_iterator_cls), 1)));
......
...@@ -38,6 +38,8 @@ public: ...@@ -38,6 +38,8 @@ public:
template <typename T> __attribute__((visibility("default"))) BoxedSet(T&& s) : s(std::forward<T>(s)) {} template <typename T> __attribute__((visibility("default"))) BoxedSet(T&& s) : s(std::forward<T>(s)) {}
DEFAULT_CLASS(set_cls); DEFAULT_CLASS(set_cls);
static void gcHandler(GCVisitor* v, Box* b);
}; };
} }
......
...@@ -2311,13 +2311,13 @@ public: ...@@ -2311,13 +2311,13 @@ public:
++self->it; ++self->it;
return characters[c & UCHAR_MAX]; return characters[c & UCHAR_MAX];
} }
};
extern "C" void strIteratorGCHandler(GCVisitor* v, Box* b) { static void gcHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b); boxGCHandler(v, b);
BoxedStringIterator* it = (BoxedStringIterator*)b; BoxedStringIterator* it = (BoxedStringIterator*)b;
v->visit(it->s); v->visit(it->s);
} }
};
Box* strIter(BoxedString* self) noexcept { Box* strIter(BoxedString* self) noexcept {
assert(PyString_Check(self)); assert(PyString_Check(self));
...@@ -2698,7 +2698,7 @@ static PyMethodDef string_methods[] = { ...@@ -2698,7 +2698,7 @@ static PyMethodDef string_methods[] = {
void setupStr() { void setupStr() {
str_cls->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER; str_cls->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
str_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &strIteratorGCHandler, 0, 0, str_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedStringIterator::gcHandler, 0, 0,
sizeof(BoxedStringIterator), false, "striterator"); sizeof(BoxedStringIterator), false, "striterator");
str_iterator_cls->giveAttr("__hasnext__", str_iterator_cls->giveAttr("__hasnext__",
new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::hasnext, BOXED_BOOL, 1))); new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::hasnext, BOXED_BOOL, 1)));
......
...@@ -412,12 +412,6 @@ extern "C" PyObject* PyTuple_New(Py_ssize_t size) noexcept { ...@@ -412,12 +412,6 @@ extern "C" PyObject* PyTuple_New(Py_ssize_t size) noexcept {
BoxedClass* tuple_iterator_cls = NULL; BoxedClass* tuple_iterator_cls = NULL;
extern "C" void tupleIteratorGCHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b);
BoxedTupleIterator* it = (BoxedTupleIterator*)b;
v->visit(it->t);
}
static int64_t tuple_hash(BoxedTuple* v) noexcept { static int64_t tuple_hash(BoxedTuple* v) noexcept {
long x, y; long x, y;
Py_ssize_t len = Py_SIZE(v); Py_ssize_t len = Py_SIZE(v);
...@@ -564,8 +558,21 @@ static Py_ssize_t tuplelength(PyTupleObject* a) { ...@@ -564,8 +558,21 @@ static Py_ssize_t tuplelength(PyTupleObject* a) {
return Py_SIZE(a); return Py_SIZE(a);
} }
void BoxedTuple::gcHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b);
BoxedTuple* t = (BoxedTuple*)b;
v->visitRange((void* const*)&t->elts[0], (void* const*)&t->elts[t->size()]);
}
extern "C" void BoxedTupleIterator::gcHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b);
BoxedTupleIterator* it = (BoxedTupleIterator*)b;
v->visit(it->t);
}
void setupTuple() { void setupTuple() {
tuple_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &tupleIteratorGCHandler, 0, 0, tuple_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedTupleIterator::gcHandler, 0, 0,
sizeof(BoxedTupleIterator), false, "tuple"); sizeof(BoxedTupleIterator), false, "tuple");
tuple_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)tupleNew, UNKNOWN, 1, 0, true, true))); tuple_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)tupleNew, UNKNOWN, 1, 0, true, true)));
......
...@@ -28,6 +28,8 @@ public: ...@@ -28,6 +28,8 @@ public:
BoxedTupleIterator(BoxedTuple* t); BoxedTupleIterator(BoxedTuple* t);
DEFAULT_CLASS(tuple_iterator_cls); DEFAULT_CLASS(tuple_iterator_cls);
static void gcHandler(GCVisitor* v, Box* _o);
}; };
Box* tupleIter(Box* self) noexcept; Box* tupleIter(Box* self) noexcept;
......
...@@ -408,23 +408,7 @@ BoxedFunction::BoxedFunction(CLFunction* f, std::initializer_list<Box*> defaults ...@@ -408,23 +408,7 @@ BoxedFunction::BoxedFunction(CLFunction* f, std::initializer_list<Box*> defaults
} }
} }
BoxedBuiltinFunctionOrMethod::BoxedBuiltinFunctionOrMethod(CLFunction* f, const char* name, const char* doc) void BoxedFunction::gcHandler(GCVisitor* v, Box* b) {
: BoxedBuiltinFunctionOrMethod(f, name, {}) {
this->doc = doc ? boxString(doc) : None;
}
BoxedBuiltinFunctionOrMethod::BoxedBuiltinFunctionOrMethod(CLFunction* f, const char* name,
std::initializer_list<Box*> defaults, BoxedClosure* closure,
const char* doc)
: BoxedFunctionBase(f, defaults, closure) {
assert(name);
this->name = static_cast<BoxedString*>(boxString(name));
this->doc = doc ? boxString(doc) : None;
}
extern "C" void functionGCHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b); boxGCHandler(v, b);
BoxedFunction* f = (BoxedFunction*)b; BoxedFunction* f = (BoxedFunction*)b;
...@@ -456,6 +440,22 @@ extern "C" void functionGCHandler(GCVisitor* v, Box* b) { ...@@ -456,6 +440,22 @@ extern "C" void functionGCHandler(GCVisitor* v, Box* b) {
} }
} }
BoxedBuiltinFunctionOrMethod::BoxedBuiltinFunctionOrMethod(CLFunction* f, const char* name, const char* doc)
: BoxedBuiltinFunctionOrMethod(f, name, {}) {
this->doc = doc ? boxString(doc) : None;
}
BoxedBuiltinFunctionOrMethod::BoxedBuiltinFunctionOrMethod(CLFunction* f, const char* name,
std::initializer_list<Box*> defaults, BoxedClosure* closure,
const char* doc)
: BoxedFunctionBase(f, defaults, closure) {
assert(name);
this->name = static_cast<BoxedString*>(boxString(name));
this->doc = doc ? boxString(doc) : None;
}
static void functionDtor(Box* b) { static void functionDtor(Box* b) {
assert(isSubclass(b->cls, function_cls) || isSubclass(b->cls, builtin_function_or_method_cls)); assert(isSubclass(b->cls, function_cls) || isSubclass(b->cls, builtin_function_or_method_cls));
...@@ -1131,7 +1131,7 @@ Box* typeCall(Box* obj, BoxedTuple* vararg, BoxedDict* kwargs) { ...@@ -1131,7 +1131,7 @@ Box* typeCall(Box* obj, BoxedTuple* vararg, BoxedDict* kwargs) {
return typeCallInternal(NULL, NULL, ArgPassSpec(n + 1, 0, false, pass_kwargs), arg1, arg2, arg3, args, NULL); return typeCallInternal(NULL, NULL, ArgPassSpec(n + 1, 0, false, pass_kwargs), arg1, arg2, arg3, args, NULL);
} }
extern "C" void typeGCHandler(GCVisitor* v, Box* b) { void BoxedHeapClass::gcHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b); boxGCHandler(v, b);
BoxedClass* cls = (BoxedClass*)b; BoxedClass* cls = (BoxedClass*)b;
...@@ -1195,7 +1195,7 @@ static void typeSubSetDict(Box* obj, Box* val, void* context) { ...@@ -1195,7 +1195,7 @@ static void typeSubSetDict(Box* obj, Box* val, void* context) {
Box* dict_descr = NULL; Box* dict_descr = NULL;
extern "C" void instancemethodGCHandler(GCVisitor* v, Box* b) { void BoxedInstanceMethod::gcHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b); boxGCHandler(v, b);
BoxedInstanceMethod* im = (BoxedInstanceMethod*)b; BoxedInstanceMethod* im = (BoxedInstanceMethod*)b;
...@@ -1205,7 +1205,7 @@ extern "C" void instancemethodGCHandler(GCVisitor* v, Box* b) { ...@@ -1205,7 +1205,7 @@ extern "C" void instancemethodGCHandler(GCVisitor* v, Box* b) {
v->visit(im->im_class); v->visit(im->im_class);
} }
extern "C" void propertyGCHandler(GCVisitor* v, Box* b) { void BoxedProperty::gcHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b); boxGCHandler(v, b);
BoxedProperty* prop = (BoxedProperty*)b; BoxedProperty* prop = (BoxedProperty*)b;
...@@ -1220,7 +1220,7 @@ extern "C" void propertyGCHandler(GCVisitor* v, Box* b) { ...@@ -1220,7 +1220,7 @@ extern "C" void propertyGCHandler(GCVisitor* v, Box* b) {
v->visit(prop->prop_doc); v->visit(prop->prop_doc);
} }
extern "C" void staticmethodGCHandler(GCVisitor* v, Box* b) { void BoxedStaticmethod::gcHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b); boxGCHandler(v, b);
BoxedStaticmethod* sm = (BoxedStaticmethod*)b; BoxedStaticmethod* sm = (BoxedStaticmethod*)b;
...@@ -1229,7 +1229,7 @@ extern "C" void staticmethodGCHandler(GCVisitor* v, Box* b) { ...@@ -1229,7 +1229,7 @@ extern "C" void staticmethodGCHandler(GCVisitor* v, Box* b) {
v->visit(sm->sm_callable); v->visit(sm->sm_callable);
} }
extern "C" void classmethodGCHandler(GCVisitor* v, Box* b) { void BoxedClassmethod::gcHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b); boxGCHandler(v, b);
BoxedClassmethod* cm = (BoxedClassmethod*)b; BoxedClassmethod* cm = (BoxedClassmethod*)b;
...@@ -1238,40 +1238,12 @@ extern "C" void classmethodGCHandler(GCVisitor* v, Box* b) { ...@@ -1238,40 +1238,12 @@ extern "C" void classmethodGCHandler(GCVisitor* v, Box* b) {
v->visit(cm->cm_callable); v->visit(cm->cm_callable);
} }
// This probably belongs in list.cpp? void BoxedSlice::gcHandler(GCVisitor* v, Box* b) {
extern "C" void listGCHandler(GCVisitor* v, Box* b) { assert(b->cls == slice_cls);
boxGCHandler(v, b);
BoxedList* l = (BoxedList*)b;
int size = l->size;
int capacity = l->capacity;
assert(capacity >= size);
if (capacity)
v->visit(l->elts);
if (size)
v->visitRange((void**)&l->elts->elts[0], (void**)&l->elts->elts[size]);
}
extern "C" void setGCHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b);
BoxedSet* s = (BoxedSet*)b;
// This feels like a cludge, but we need to find anything that
// the unordered_map might have allocated.
// Another way to handle this would be to rt_alloc the unordered_map
// as well, though that incurs extra memory dereferences which would
// be nice to avoid.
void** start = (void**)&s->s;
void** end = start + (sizeof(s->s) / 8);
v->visitPotentialRange(start, end);
}
extern "C" void sliceGCHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b); boxGCHandler(v, b);
BoxedSlice* sl = static_cast<BoxedSlice*>(b); BoxedSlice* sl = static_cast<BoxedSlice*>(b);
assert(sl->cls == slice_cls);
v->visit(sl->start); v->visit(sl->start);
v->visit(sl->stop); v->visit(sl->stop);
...@@ -1293,31 +1265,9 @@ static void proxy_to_tp_traverse(GCVisitor* v, Box* b) { ...@@ -1293,31 +1265,9 @@ static void proxy_to_tp_traverse(GCVisitor* v, Box* b) {
b->cls->tp_traverse(b, call_gc_visit, v); b->cls->tp_traverse(b, call_gc_visit, v);
} }
// This probably belongs in tuple.cpp? void BoxedClosure::gcHandler(GCVisitor* v, Box* b) {
extern "C" void tupleGCHandler(GCVisitor* v, Box* b) { assert(isSubclass(b->cls, closure_cls));
boxGCHandler(v, b);
BoxedTuple* t = (BoxedTuple*)b;
v->visitRange((void* const*)&t->elts[0], (void* const*)&t->elts[t->size()]);
}
// This probably belongs in dict.cpp?
extern "C" void dictGCHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b);
BoxedDict* d = (BoxedDict*)b;
// This feels like a cludge, but we need to find anything that
// the unordered_map might have allocated.
// Another way to handle this would be to rt_alloc the unordered_map
// as well, though that incurs extra memory dereferences which would
// be nice to avoid.
void** start = (void**)&d->d;
void** end = start + (sizeof(d->d) / 8);
v->visitPotentialRange(start, end);
}
extern "C" void closureGCHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b); boxGCHandler(v, b);
BoxedClosure* c = (BoxedClosure*)b; BoxedClosure* c = (BoxedClosure*)b;
...@@ -3245,7 +3195,7 @@ void setupRuntime() { ...@@ -3245,7 +3195,7 @@ void setupRuntime() {
void* mem = gc_alloc(sizeof(BoxedClass), gc::GCKind::PYTHON); void* mem = gc_alloc(sizeof(BoxedClass), gc::GCKind::PYTHON);
object_cls = ::new (mem) BoxedClass(NULL, &boxGCHandler, 0, 0, sizeof(Box), false); object_cls = ::new (mem) BoxedClass(NULL, &boxGCHandler, 0, 0, sizeof(Box), false);
mem = gc_alloc(sizeof(BoxedHeapClass), gc::GCKind::PYTHON); mem = gc_alloc(sizeof(BoxedHeapClass), gc::GCKind::PYTHON);
type_cls = ::new (mem) BoxedHeapClass(object_cls, &typeGCHandler, offsetof(BoxedClass, attrs), type_cls = ::new (mem) BoxedHeapClass(object_cls, &BoxedHeapClass::gcHandler, offsetof(BoxedClass, attrs),
offsetof(BoxedClass, tp_weaklist), sizeof(BoxedHeapClass), false, NULL); offsetof(BoxedClass, tp_weaklist), sizeof(BoxedHeapClass), false, NULL);
type_cls->tp_flags |= Py_TPFLAGS_TYPE_SUBCLASS; type_cls->tp_flags |= Py_TPFLAGS_TYPE_SUBCLASS;
type_cls->tp_itemsize = sizeof(BoxedHeapClass::SlotOffset); type_cls->tp_itemsize = sizeof(BoxedHeapClass::SlotOffset);
...@@ -3297,20 +3247,21 @@ void setupRuntime() { ...@@ -3297,20 +3247,21 @@ void setupRuntime() {
// Not sure why CPython defines sizeof(PyTupleObject) to include one element, // 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: // but we copy that, which means we have to subtract that extra pointer to get the tp_basicsize:
tuple_cls = new (0) tuple_cls = new (0) BoxedHeapClass(object_cls, &BoxedTuple::gcHandler, 0, 0, sizeof(BoxedTuple) - sizeof(Box*),
BoxedHeapClass(object_cls, &tupleGCHandler, 0, 0, sizeof(BoxedTuple) - sizeof(Box*), false, boxString("tuple")); false, boxString("tuple"));
tuple_cls->tp_flags |= Py_TPFLAGS_TUPLE_SUBCLASS; tuple_cls->tp_flags |= Py_TPFLAGS_TUPLE_SUBCLASS;
tuple_cls->tp_itemsize = sizeof(Box*); tuple_cls->tp_itemsize = sizeof(Box*);
tuple_cls->tp_mro = BoxedTuple::create({ tuple_cls, object_cls }); tuple_cls->tp_mro = BoxedTuple::create({ tuple_cls, object_cls });
EmptyTuple = BoxedTuple::create({}); EmptyTuple = BoxedTuple::create({});
gc::registerPermanentRoot(EmptyTuple); gc::registerPermanentRoot(EmptyTuple);
list_cls = new (0) BoxedHeapClass(object_cls, &listGCHandler, 0, 0, sizeof(BoxedList), false, boxString("list")); list_cls = new (0)
BoxedHeapClass(object_cls, &BoxedList::gcHandler, 0, 0, sizeof(BoxedList), false, boxString("list"));
list_cls->tp_flags |= Py_TPFLAGS_LIST_SUBCLASS; list_cls->tp_flags |= Py_TPFLAGS_LIST_SUBCLASS;
pyston_getset_cls = new (0) pyston_getset_cls = new (0)
BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedGetsetDescriptor), false, boxString("getset_descriptor")); BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedGetsetDescriptor), false, boxString("getset_descriptor"));
attrwrapper_cls = new (0) BoxedHeapClass(object_cls, &AttrWrapper::gcHandler, 0, 0, sizeof(AttrWrapper), false, attrwrapper_cls = new (0) BoxedHeapClass(object_cls, &AttrWrapper::gcHandler, 0, 0, sizeof(AttrWrapper), false,
static_cast<BoxedString*>(boxString("attrwrapper"))); static_cast<BoxedString*>(boxString("attrwrapper")));
dict_cls = new (0) BoxedHeapClass(object_cls, &dictGCHandler, 0, 0, sizeof(BoxedDict), false, dict_cls = new (0) BoxedHeapClass(object_cls, &BoxedDict::gcHandler, 0, 0, sizeof(BoxedDict), false,
static_cast<BoxedString*>(boxString("dict"))); static_cast<BoxedString*>(boxString("dict")));
dict_cls->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS; dict_cls->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS;
file_cls = new (0) BoxedHeapClass(object_cls, &BoxedFile::gcHandler, 0, offsetof(BoxedFile, weakreflist), file_cls = new (0) BoxedHeapClass(object_cls, &BoxedFile::gcHandler, 0, offsetof(BoxedFile, weakreflist),
...@@ -3327,11 +3278,11 @@ void setupRuntime() { ...@@ -3327,11 +3278,11 @@ void setupRuntime() {
long_cls->tp_flags |= Py_TPFLAGS_LONG_SUBCLASS; long_cls->tp_flags |= Py_TPFLAGS_LONG_SUBCLASS;
float_cls = new (0) BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedFloat), false, float_cls = new (0) BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedFloat), false,
static_cast<BoxedString*>(boxString("float"))); static_cast<BoxedString*>(boxString("float")));
function_cls = new (0) BoxedHeapClass(object_cls, &functionGCHandler, offsetof(BoxedFunction, attrs), function_cls = new (0) BoxedHeapClass(object_cls, &BoxedFunction::gcHandler, offsetof(BoxedFunction, attrs),
offsetof(BoxedFunction, in_weakreflist), sizeof(BoxedFunction), false, offsetof(BoxedFunction, in_weakreflist), sizeof(BoxedFunction), false,
static_cast<BoxedString*>(boxString("function"))); static_cast<BoxedString*>(boxString("function")));
builtin_function_or_method_cls = new (0) builtin_function_or_method_cls = new (0)
BoxedHeapClass(object_cls, &functionGCHandler, 0, offsetof(BoxedBuiltinFunctionOrMethod, in_weakreflist), BoxedHeapClass(object_cls, &BoxedFunction::gcHandler, 0, offsetof(BoxedBuiltinFunctionOrMethod, in_weakreflist),
sizeof(BoxedBuiltinFunctionOrMethod), false, sizeof(BoxedBuiltinFunctionOrMethod), false,
static_cast<BoxedString*>(boxString("builtin_function_or_method"))); static_cast<BoxedString*>(boxString("builtin_function_or_method")));
function_cls->tp_dealloc = builtin_function_or_method_cls->tp_dealloc = functionDtor; function_cls->tp_dealloc = builtin_function_or_method_cls->tp_dealloc = functionDtor;
...@@ -3455,24 +3406,25 @@ void setupRuntime() { ...@@ -3455,24 +3406,25 @@ void setupRuntime() {
type_cls->giveAttr("__dict__", new (pyston_getset_cls) BoxedGetsetDescriptor(typeDict, NULL, NULL)); type_cls->giveAttr("__dict__", new (pyston_getset_cls) BoxedGetsetDescriptor(typeDict, NULL, NULL));
instancemethod_cls = BoxedHeapClass::create(type_cls, object_cls, &instancemethodGCHandler, 0, instancemethod_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedInstanceMethod::gcHandler, 0,
offsetof(BoxedInstanceMethod, in_weakreflist), offsetof(BoxedInstanceMethod, in_weakreflist),
sizeof(BoxedInstanceMethod), false, "instancemethod"); sizeof(BoxedInstanceMethod), false, "instancemethod");
slice_cls = BoxedHeapClass::create(type_cls, object_cls, &sliceGCHandler, 0, 0, sizeof(BoxedSlice), false, "slice"); slice_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedSlice::gcHandler, 0, 0, sizeof(BoxedSlice), false,
set_cls = BoxedHeapClass::create(type_cls, object_cls, &setGCHandler, 0, offsetof(BoxedSet, weakreflist), "slice");
set_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedSet::gcHandler, 0, offsetof(BoxedSet, weakreflist),
sizeof(BoxedSet), false, "set"); sizeof(BoxedSet), false, "set");
frozenset_cls = BoxedHeapClass::create(type_cls, object_cls, &setGCHandler, 0, offsetof(BoxedSet, weakreflist), frozenset_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedSet::gcHandler, 0,
sizeof(BoxedSet), false, "frozenset"); offsetof(BoxedSet, weakreflist), sizeof(BoxedSet), false, "frozenset");
capi_getset_cls capi_getset_cls
= BoxedHeapClass::create(type_cls, object_cls, NULL, 0, 0, sizeof(BoxedGetsetDescriptor), false, "getset"); = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, 0, sizeof(BoxedGetsetDescriptor), false, "getset");
closure_cls closure_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedClosure::gcHandler, 0, 0, sizeof(BoxedClosure),
= BoxedHeapClass::create(type_cls, object_cls, &closureGCHandler, 0, 0, sizeof(BoxedClosure), false, "closure"); false, "closure");
property_cls = BoxedHeapClass::create(type_cls, object_cls, &propertyGCHandler, 0, 0, sizeof(BoxedProperty), false, property_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedProperty::gcHandler, 0, 0, sizeof(BoxedProperty),
"property"); false, "property");
staticmethod_cls = BoxedHeapClass::create(type_cls, object_cls, &staticmethodGCHandler, 0, 0, staticmethod_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedStaticmethod::gcHandler, 0, 0,
sizeof(BoxedStaticmethod), false, "staticmethod"); sizeof(BoxedStaticmethod), false, "staticmethod");
classmethod_cls = BoxedHeapClass::create(type_cls, object_cls, &classmethodGCHandler, 0, 0, classmethod_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedClassmethod::gcHandler, 0, 0,
sizeof(BoxedClassmethod), false, "classmethod"); sizeof(BoxedClassmethod), false, "classmethod");
attrwrapperiter_cls = BoxedHeapClass::create(type_cls, object_cls, &AttrWrapperIter::gcHandler, 0, 0, attrwrapperiter_cls = BoxedHeapClass::create(type_cls, object_cls, &AttrWrapperIter::gcHandler, 0, 0,
sizeof(AttrWrapperIter), false, "attrwrapperiter"); sizeof(AttrWrapperIter), false, "attrwrapperiter");
......
...@@ -298,6 +298,8 @@ public: ...@@ -298,6 +298,8 @@ public:
static BoxedHeapClass* create(BoxedClass* metatype, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, static BoxedHeapClass* create(BoxedClass* metatype, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset,
int weaklist_offset, int instance_size, bool is_user_defined, llvm::StringRef name); int weaklist_offset, int instance_size, bool is_user_defined, llvm::StringRef name);
static void gcHandler(GCVisitor* v, Box* b);
private: private:
// These functions are not meant for external callers and will mostly just be called // These functions are not meant for external callers and will mostly just be called
// by BoxedHeapClass::create(), but setupRuntime() also needs to do some manual class // by BoxedHeapClass::create(), but setupRuntime() also needs to do some manual class
...@@ -471,6 +473,8 @@ public: ...@@ -471,6 +473,8 @@ public:
: in_weakreflist(NULL), obj(obj), func(func), im_class(im_class) {} : in_weakreflist(NULL), obj(obj), func(func), im_class(im_class) {}
DEFAULT_CLASS_SIMPLE(instancemethod_cls); DEFAULT_CLASS_SIMPLE(instancemethod_cls);
static void gcHandler(GCVisitor* v, Box* b);
}; };
class GCdArray { class GCdArray {
...@@ -505,6 +509,8 @@ public: ...@@ -505,6 +509,8 @@ public:
static const int INITIAL_CAPACITY; static const int INITIAL_CAPACITY;
DEFAULT_CLASS_SIMPLE(list_cls); DEFAULT_CLASS_SIMPLE(list_cls);
static void gcHandler(GCVisitor* v, Box* b);
}; };
static_assert(sizeof(BoxedList) <= sizeof(PyListObject), ""); static_assert(sizeof(BoxedList) <= sizeof(PyListObject), "");
static_assert(sizeof(BoxedList) >= sizeof(PyListObject), ""); static_assert(sizeof(BoxedList) >= sizeof(PyListObject), "");
...@@ -639,6 +645,8 @@ public: ...@@ -639,6 +645,8 @@ public:
return rtn; return rtn;
} }
static void gcHandler(GCVisitor* v, Box* b);
private: private:
BoxedTuple() {} BoxedTuple() {}
...@@ -697,6 +705,8 @@ public: ...@@ -697,6 +705,8 @@ public:
return p->second; return p->second;
return NULL; return NULL;
} }
static void gcHandler(GCVisitor* v, Box* b);
}; };
static_assert(sizeof(BoxedDict) == sizeof(PyDictObject), ""); static_assert(sizeof(BoxedDict) == sizeof(PyDictObject), "");
...@@ -737,6 +747,8 @@ public: ...@@ -737,6 +747,8 @@ public:
Box* globals = NULL); Box* globals = NULL);
DEFAULT_CLASS(function_cls); DEFAULT_CLASS(function_cls);
static void gcHandler(GCVisitor* v, Box* b);
}; };
class BoxedBuiltinFunctionOrMethod : public BoxedFunctionBase { class BoxedBuiltinFunctionOrMethod : public BoxedFunctionBase {
...@@ -790,6 +802,8 @@ public: ...@@ -790,6 +802,8 @@ public:
BoxedSlice(Box* lower, Box* upper, Box* step) : start(lower), stop(upper), step(step) {} BoxedSlice(Box* lower, Box* upper, Box* step) : start(lower), stop(upper), step(step) {}
DEFAULT_CLASS_SIMPLE(slice_cls); DEFAULT_CLASS_SIMPLE(slice_cls);
static void gcHandler(GCVisitor* v, Box* b);
}; };
static_assert(sizeof(BoxedSlice) == sizeof(PySliceObject), ""); static_assert(sizeof(BoxedSlice) == sizeof(PySliceObject), "");
static_assert(offsetof(BoxedSlice, start) == offsetof(PySliceObject, start), ""); static_assert(offsetof(BoxedSlice, start) == offsetof(PySliceObject, start), "");
...@@ -855,6 +869,8 @@ public: ...@@ -855,6 +869,8 @@ public:
: prop_get(get), prop_set(set), prop_del(del), prop_doc(doc) {} : prop_get(get), prop_set(set), prop_del(del), prop_doc(doc) {}
DEFAULT_CLASS_SIMPLE(property_cls); DEFAULT_CLASS_SIMPLE(property_cls);
static void gcHandler(GCVisitor* v, Box* b);
}; };
class BoxedStaticmethod : public Box { class BoxedStaticmethod : public Box {
...@@ -864,6 +880,8 @@ public: ...@@ -864,6 +880,8 @@ public:
BoxedStaticmethod(Box* callable) : sm_callable(callable){}; BoxedStaticmethod(Box* callable) : sm_callable(callable){};
DEFAULT_CLASS_SIMPLE(staticmethod_cls); DEFAULT_CLASS_SIMPLE(staticmethod_cls);
static void gcHandler(GCVisitor* v, Box* b);
}; };
class BoxedClassmethod : public Box { class BoxedClassmethod : public Box {
...@@ -873,6 +891,8 @@ public: ...@@ -873,6 +891,8 @@ public:
BoxedClassmethod(Box* callable) : cm_callable(callable){}; BoxedClassmethod(Box* callable) : cm_callable(callable){};
DEFAULT_CLASS_SIMPLE(classmethod_cls); DEFAULT_CLASS_SIMPLE(classmethod_cls);
static void gcHandler(GCVisitor* v, Box* b);
}; };
// TODO is there any particular reason to make this a Box, i.e. a python-level object? // TODO is there any particular reason to make this a Box, i.e. a python-level object?
...@@ -896,6 +916,8 @@ public: ...@@ -896,6 +916,8 @@ public:
memset((void*)rtn->elts, 0, sizeof(Box*) * nelts); memset((void*)rtn->elts, 0, sizeof(Box*) * nelts);
return rtn; return rtn;
} }
static void gcHandler(GCVisitor* v, Box* b);
}; };
class BoxedGenerator : public Box { class BoxedGenerator : public Box {
...@@ -923,6 +945,8 @@ public: ...@@ -923,6 +945,8 @@ public:
BoxedGenerator(BoxedFunctionBase* function, Box* arg1, Box* arg2, Box* arg3, Box** args); BoxedGenerator(BoxedFunctionBase* function, Box* arg1, Box* arg2, Box* arg3, Box** args);
DEFAULT_CLASS(generator_cls); DEFAULT_CLASS(generator_cls);
static void gcHandler(GCVisitor* v, Box* b);
}; };
struct wrapper_def { struct wrapper_def {
......
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