Commit 0c20808b authored by Kevin Modzelewski's avatar Kevin Modzelewski

Large refactor for basic tp_alloc support

Use operator new() to get access to tp_alloc in a C++-ish way.

Instead of passing the object's class to the constructor, pass
it to new().  We need to do this since the class gets to pick how
the object gets allocated, including how large it will end up being.

Unfortunately it looks like defining an operator new on a subclass
hides the operator new from a superclass, even if they have different
signatures.  Macros to the rescue.
parent 91321622
......@@ -44,7 +44,9 @@ private:
public:
BoxedCApiFunction(int ml_flags, Box* passthrough, const char* name, PyCFunction func)
: Box(capifunc_cls), ml_flags(ml_flags), passthrough(passthrough), name(name), func(func) {}
: ml_flags(ml_flags), passthrough(passthrough), name(name), func(func) {}
DEFAULT_CLASS(capifunc_cls);
static BoxedString* __repr__(BoxedCApiFunction* self) {
assert(self->cls == capifunc_cls);
......@@ -88,7 +90,9 @@ public:
BoxedClass* type;
void* wrapped;
BoxedWrapperDescriptor(const wrapper_def* wrapper, BoxedClass* type, void* wrapped)
: Box(wrapperdescr_cls), wrapper(wrapper), type(type), wrapped(wrapped) {}
: wrapper(wrapper), type(type), wrapped(wrapped) {}
DEFAULT_CLASS(wrapperdescr_cls);
static Box* __get__(BoxedWrapperDescriptor* self, Box* inst, Box* owner);
};
......@@ -98,7 +102,9 @@ public:
BoxedWrapperDescriptor* descr;
Box* obj;
BoxedWrapperObject(BoxedWrapperDescriptor* descr, Box* obj) : Box(wrapperobject_cls), descr(descr), obj(obj) {}
BoxedWrapperObject(BoxedWrapperDescriptor* descr, Box* obj) : descr(descr), obj(obj) {}
DEFAULT_CLASS(wrapperobject_cls);
static Box* __call__(BoxedWrapperObject* self, Box* args, Box* kwds) {
assert(self->cls == wrapperobject_cls);
......@@ -128,7 +134,9 @@ public:
PyMethodDef* method;
BoxedClass* type;
BoxedMethodDescriptor(PyMethodDef* method, BoxedClass* type) : Box(method_cls), method(method), type(type) {}
BoxedMethodDescriptor(PyMethodDef* method, BoxedClass* type) : method(method), type(type) {}
DEFAULT_CLASS(method_cls);
static Box* __get__(BoxedMethodDescriptor* self, Box* inst, Box* owner) {
RELEASE_ASSERT(self->cls == method_cls, "");
......
......@@ -986,7 +986,7 @@ Value ASTInterpreter::visit_set(AST_Set* node) {
for (AST_expr* e : node->elts)
set.insert(visit_expr(e).o);
return new BoxedSet(std::move(set), set_cls);
return new BoxedSet(std::move(set));
}
Value ASTInterpreter::visit_str(AST_Str* node) {
......
......@@ -354,14 +354,6 @@ enum class GCKind : uint8_t {
extern "C" void* gc_alloc(size_t nbytes, GCKind kind);
}
class PythonGCObject {
public:
void* operator new(size_t size) __attribute__((visibility("default"))) {
return gc_alloc(size, gc::GCKind::PYTHON);
}
void operator delete(void* ptr) __attribute__((visibility("default"))) { abort(); }
};
class ConservativeGCObject {
public:
void* operator new(size_t size) __attribute__((visibility("default"))) {
......@@ -370,14 +362,6 @@ public:
void operator delete(void* ptr) __attribute__((visibility("default"))) { abort(); }
};
class UntrackedGCObject {
public:
void* operator new(size_t size) __attribute__((visibility("default"))) {
return gc_alloc(size, gc::GCKind::UNTRACKED);
}
void operator delete(void* ptr) __attribute__((visibility("default"))) { abort(); }
};
class HiddenClass;
extern HiddenClass* root_hcls;
......@@ -399,26 +383,16 @@ public:
class BoxedString;
class Box : public PythonGCObject {
class Box {
public:
void* operator new(size_t size, BoxedClass* cls) __attribute__((visibility("default")));
void operator delete(void* ptr) __attribute__((visibility("default"))) { abort(); }
// Note: cls gets initialized in the new() function.
BoxedClass* cls;
llvm::iterator_range<BoxIterator> pyElements();
Box(BoxedClass* cls) : cls(cls) {
// if (TRACK_ALLOCATIONS) {
// int id = Stats::getStatId("allocated_" + *getNameOfClass(c));
// Stats::log(id);
//}
// the only way cls should be NULL is if we're creating the type_cls
// object itself:
if (cls == NULL) {
ASSERT(type_cls == NULL, "should pass a non-null cls here");
} else {
}
}
HCAttrs* getAttrsPtr();
void setattr(const std::string& attr, Box* val, SetattrRewriteArgs* rewrite_args);
......@@ -439,12 +413,20 @@ public:
};
static_assert(offsetof(Box, cls) == offsetof(struct _object, ob_type), "");
#define DEFAULT_CLASS(default_cls) \
void* operator new(size_t size, BoxedClass * cls) __attribute__((visibility("default"))) { \
return Box::operator new(size, cls); \
} \
void* operator new(size_t size) __attribute__((visibility("default"))) { \
return Box::operator new(size, default_cls); \
}
// CPython C API compatibility class:
class BoxVar : public Box {
public:
Py_ssize_t ob_size;
BoxVar(BoxedClass* cls, Py_ssize_t ob_size) : Box(cls), ob_size(ob_size) {}
BoxVar(Py_ssize_t ob_size) : ob_size(ob_size) {}
};
static_assert(offsetof(BoxVar, ob_size) == offsetof(struct _varobject, ob_size), "");
......
......@@ -533,7 +533,7 @@ Box* exceptionNew1(BoxedClass* cls) {
class BoxedException : public Box {
public:
HCAttrs attrs;
BoxedException(BoxedClass* cls) : Box(cls) {}
BoxedException() {}
};
Box* exceptionNew2(BoxedClass* cls, Box* message) {
......@@ -548,11 +548,7 @@ Box* exceptionNew(BoxedClass* cls, BoxedTuple* args) {
raiseExcHelper(TypeError, "BaseException.__new__(%s): %s is not a subtype of BaseException",
getNameOfClass(cls)->c_str(), getNameOfClass(cls)->c_str());
assert(cls->tp_basicsize >= sizeof(BoxedException));
void* mem = gc_alloc(cls->tp_basicsize, gc::GCKind::PYTHON);
memset((char*)mem + sizeof(BoxedException), 0, cls->tp_basicsize - sizeof(BoxedException));
BoxedException* rtn = ::new (mem) BoxedException(cls);
initUserAttrs(rtn, cls);
BoxedException* rtn = new (cls) BoxedException();
// TODO: this should be a MemberDescriptor and set during init
if (args->elts.size() == 1)
......@@ -587,7 +583,7 @@ static BoxedClass* makeBuiltinException(BoxedClass* base, const char* name, int
if (size == 0)
size = base->tp_basicsize;
BoxedClass* cls = new BoxedHeapClass(type_cls, base, NULL, offsetof(BoxedException, attrs), size, false);
BoxedClass* cls = new BoxedHeapClass(base, NULL, offsetof(BoxedException, attrs), size, false);
cls->giveAttr("__name__", boxStrConstant(name));
cls->giveAttr("__module__", boxStrConstant("exceptions"));
......@@ -609,8 +605,7 @@ extern "C" PyObject* PyErr_NewException(char* name, PyObject* _base, PyObject* d
try {
BoxedClass* base = Exception;
BoxedClass* cls
= new BoxedHeapClass(type_cls, base, NULL, offsetof(BoxedException, attrs), sizeof(BoxedException), true);
BoxedClass* cls = new BoxedHeapClass(base, NULL, offsetof(BoxedException, attrs), sizeof(BoxedException), true);
char* dot_pos = strchr(name, '.');
RELEASE_ASSERT(dot_pos, "");
......@@ -634,7 +629,9 @@ private:
public:
BoxedEnumerate(BoxIterator iterator_begin, BoxIterator iterator_end, int64_t idx)
: Box(enumerate_cls), iterator(iterator_begin), iterator_end(iterator_end), idx(idx) {}
: iterator(iterator_begin), iterator_end(iterator_end), idx(idx) {}
DEFAULT_CLASS(enumerate_cls);
static Box* new_(Box* cls, Box* obj, Box* start) {
RELEASE_ASSERT(cls == enumerate_cls, "");
......@@ -906,11 +903,11 @@ void setupBuiltins() {
builtins_module->giveAttr("print", new BoxedFunction(boxRTFunction((void*)print, NONE, 0, 0, true, true)));
notimplemented_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(Box), false);
notimplemented_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(Box), false);
notimplemented_cls->giveAttr("__name__", boxStrConstant("NotImplementedType"));
notimplemented_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)notimplementedRepr, STR, 1)));
notimplemented_cls->freeze();
NotImplemented = new Box(notimplemented_cls);
NotImplemented = new (notimplemented_cls) Box();
gc::registerPermanentRoot(NotImplemented);
builtins_module->giveAttr("NotImplemented", NotImplemented);
......@@ -1015,8 +1012,7 @@ void setupBuiltins() {
builtins_module->giveAttr("__import__", new BoxedFunction(boxRTFunction((void*)bltinImport, UNKNOWN, 1)));
enumerate_cls
= new BoxedHeapClass(type_cls, object_cls, &BoxedEnumerate::gcHandler, 0, sizeof(BoxedEnumerate), false);
enumerate_cls = new BoxedHeapClass(object_cls, &BoxedEnumerate::gcHandler, 0, sizeof(BoxedEnumerate), false);
enumerate_cls->giveAttr("__name__", boxStrConstant("enumerate"));
enumerate_cls->giveAttr(
"__new__",
......@@ -1091,9 +1087,9 @@ void setupBuiltins() {
builtins_module->giveAttr("classmethod", classmethod_cls);
PyExc_RecursionErrorInst = new BoxedException(RuntimeError);
PyExc_RecursionErrorInst = new (RuntimeError) BoxedException();
gc::registerPermanentRoot(PyExc_RecursionErrorInst);
PyExc_MemoryErrorInst = new BoxedException(MemoryError);
PyExc_MemoryErrorInst = new (MemoryError) BoxedException();
gc::registerPermanentRoot(PyExc_MemoryErrorInst);
}
}
......@@ -158,13 +158,15 @@ class BoxedSysFlags : public Box {
public:
Box* division_warning, *bytes_warning, *no_user_site;
BoxedSysFlags() : Box(sys_flags_cls) {
BoxedSysFlags() {
auto zero = boxInt(0);
division_warning = zero;
bytes_warning = zero;
no_user_site = zero;
}
DEFAULT_CLASS(sys_flags_cls);
static void gcHandler(GCVisitor* v, Box* _b) {
assert(_b->cls == sys_flags_cls);
boxGCHandler(v, _b);
......@@ -235,7 +237,7 @@ void setupSys() {
sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX));
sys_flags_cls = new BoxedHeapClass(type_cls, object_cls, BoxedSysFlags::gcHandler, 0, sizeof(BoxedSysFlags), false);
sys_flags_cls = new BoxedHeapClass(object_cls, BoxedSysFlags::gcHandler, 0, sizeof(BoxedSysFlags), false);
sys_flags_cls->giveAttr("__name__", boxStrConstant("flags"));
sys_flags_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)BoxedSysFlags::__new__, UNKNOWN, 1, 0, true, true)));
......
......@@ -142,26 +142,6 @@ extern "C" void _PyErr_BadInternalCall(const char* filename, int lineno) noexcep
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyObject_Init(PyObject* op, PyTypeObject* tp) noexcept {
RELEASE_ASSERT(op, "");
RELEASE_ASSERT(tp, "");
assert(gc::isValidGCObject(op));
assert(gc::isValidGCObject(tp));
Py_TYPE(op) = tp;
// I think CPython defers the dict creation (equivalent of our initUserAttrs) to the
// first time that an attribute gets set.
// Our HCAttrs object already includes this optimization of no-allocation-if-empty,
// but it's nice to initialize the hcls here so we don't have to check it on every getattr/setattr.
// TODO It does mean that anything not defering to this function will have to call
// initUserAttrs themselves, though.
initUserAttrs(op, tp);
return op;
}
extern "C" PyVarObject* PyObject_InitVar(PyVarObject* op, PyTypeObject* tp, Py_ssize_t size) noexcept {
assert(gc::isValidGCObject(op));
assert(gc::isValidGCObject(tp));
......@@ -1342,7 +1322,7 @@ BoxedModule* importTestExtension(const std::string& name) {
}
void setupCAPI() {
capifunc_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedCApiFunction), false);
capifunc_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedCApiFunction), false);
capifunc_cls->giveAttr("__name__", boxStrConstant("capifunc"));
capifunc_cls->giveAttr("__repr__",
......@@ -1354,7 +1334,7 @@ void setupCAPI() {
capifunc_cls->freeze();
method_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedMethodDescriptor), false);
method_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedMethodDescriptor), false);
method_cls->giveAttr("__name__", boxStrConstant("method"));
method_cls->giveAttr("__get__",
new BoxedFunction(boxRTFunction((void*)BoxedMethodDescriptor::__get__, UNKNOWN, 3)));
......@@ -1362,13 +1342,13 @@ void setupCAPI() {
0, true, true)));
method_cls->freeze();
wrapperdescr_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedWrapperDescriptor), false);
wrapperdescr_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedWrapperDescriptor), false);
wrapperdescr_cls->giveAttr("__name__", boxStrConstant("wrapper_descriptor"));
wrapperdescr_cls->giveAttr("__get__",
new BoxedFunction(boxRTFunction((void*)BoxedWrapperDescriptor::__get__, UNKNOWN, 3)));
wrapperdescr_cls->freeze();
wrapperobject_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedWrapperObject), false);
wrapperobject_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedWrapperObject), false);
wrapperobject_cls->giveAttr("__name__", boxStrConstant("method-wrapper"));
wrapperobject_cls->giveAttr(
"__call__", new BoxedFunction(boxRTFunction((void*)BoxedWrapperObject::__call__, UNKNOWN, 1, 0, true, true)));
......
......@@ -83,7 +83,7 @@ Box* classobjNew(Box* _cls, Box* _name, Box* _bases, Box** _args) {
raiseExcHelper(TypeError, "PyClass_New: bases must be a tuple");
BoxedTuple* bases = static_cast<BoxedTuple*>(_bases);
BoxedClassobj* made = new BoxedClassobj(cls, name, bases);
BoxedClassobj* made = new (cls) BoxedClassobj(name, bases);
made->giveAttr("__module__", boxString(getCurrentModule()->name()));
made->giveAttr("__doc__", None);
......@@ -270,9 +270,9 @@ Box* instanceSetitem(Box* _inst, Box* key, Box* value) {
}
void setupClassobj() {
classobj_cls = new BoxedHeapClass(type_cls, object_cls, &BoxedClassobj::gcHandler, offsetof(BoxedClassobj, attrs),
classobj_cls = new BoxedHeapClass(object_cls, &BoxedClassobj::gcHandler, offsetof(BoxedClassobj, attrs),
sizeof(BoxedClassobj), false);
instance_cls = new BoxedHeapClass(type_cls, object_cls, &BoxedInstance::gcHandler, offsetof(BoxedInstance, attrs),
instance_cls = new BoxedHeapClass(object_cls, &BoxedInstance::gcHandler, offsetof(BoxedInstance, attrs),
sizeof(BoxedInstance), false);
classobj_cls->giveAttr("__name__", boxStrConstant("classobj"));
......
......@@ -38,8 +38,7 @@ public:
BoxedTuple* bases;
BoxedString* name;
BoxedClassobj(BoxedClass* metaclass, BoxedString* name, BoxedTuple* bases)
: Box(metaclass), bases(bases), name(name) {}
BoxedClassobj(BoxedString* name, BoxedTuple* bases) : bases(bases), name(name) {}
static void gcHandler(GCVisitor* v, Box* _o) {
assert(_o->cls == classobj_cls);
......@@ -55,7 +54,9 @@ public:
BoxedClassobj* inst_cls;
BoxedInstance(BoxedClassobj* inst_cls) : Box(instance_cls), inst_cls(inst_cls) {}
BoxedInstance(BoxedClassobj* inst_cls) : inst_cls(inst_cls) {}
DEFAULT_CLASS(instance_cls);
static void gcHandler(GCVisitor* v, Box* _o) {
assert(_o->cls == instance_cls);
......
......@@ -95,7 +95,7 @@ Box* dictViewKeys(BoxedDict* self) {
raiseExcHelper(TypeError, "descriptor 'viewkeys' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
}
BoxedDictView* rtn = new BoxedDictView(self, dict_keys_cls);
BoxedDictView* rtn = new (dict_keys_cls) BoxedDictView(self);
return rtn;
}
......@@ -104,7 +104,7 @@ Box* dictViewValues(BoxedDict* self) {
raiseExcHelper(TypeError, "descriptor 'viewvalues' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
}
BoxedDictView* rtn = new BoxedDictView(self, dict_values_cls);
BoxedDictView* rtn = new (dict_values_cls) BoxedDictView(self);
return rtn;
}
......@@ -113,7 +113,7 @@ Box* dictViewItems(BoxedDict* self) {
raiseExcHelper(TypeError, "descriptor 'viewitems' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
}
BoxedDictView* rtn = new BoxedDictView(self, dict_items_cls);
BoxedDictView* rtn = new (dict_items_cls) BoxedDictView(self);
return rtn;
}
......@@ -465,11 +465,11 @@ extern "C" void dictViewGCHandler(GCVisitor* v, Box* b) {
}
void setupDict() {
dict_iterator_cls = new BoxedHeapClass(type_cls, object_cls, &dictIteratorGCHandler, 0, sizeof(BoxedDict), false);
dict_iterator_cls = new BoxedHeapClass(object_cls, &dictIteratorGCHandler, 0, sizeof(BoxedDict), false);
dict_keys_cls = new BoxedHeapClass(type_cls, object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false);
dict_values_cls = new BoxedHeapClass(type_cls, object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false);
dict_items_cls = new BoxedHeapClass(type_cls, object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false);
dict_keys_cls = new BoxedHeapClass(object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false);
dict_values_cls = new BoxedHeapClass(object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false);
dict_items_cls = new BoxedHeapClass(object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false);
dict_cls->giveAttr("__name__", boxStrConstant("dict"));
dict_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)dictLen, BOXED_INT, 1)));
......
......@@ -34,6 +34,8 @@ public:
const IteratorType type;
BoxedDictIterator(BoxedDict* d, IteratorType type);
DEFAULT_CLASS(dict_iterator_cls);
};
Box* dictGetitem(BoxedDict* self, Box* k);
......@@ -49,7 +51,7 @@ Box* dictIterNext(Box* self);
class BoxedDictView : public Box {
public:
BoxedDict* d;
BoxedDictView(BoxedDict* d, BoxedClass* view_cls);
BoxedDictView(BoxedDict* d);
};
Box* dictViewKeysIter(Box* self);
......
......@@ -548,21 +548,21 @@ BoxedFloat* _floatNew(Box* a) {
if (a->cls == float_cls) {
return static_cast<BoxedFloat*>(a);
} else if (isSubclass(a->cls, float_cls)) {
return new BoxedFloat(float_cls, static_cast<BoxedFloat*>(a)->d);
return new BoxedFloat(static_cast<BoxedFloat*>(a)->d);
} else if (isSubclass(a->cls, int_cls)) {
return new BoxedFloat(float_cls, static_cast<BoxedInt*>(a)->n);
return new BoxedFloat(static_cast<BoxedInt*>(a)->n);
} else if (a->cls == str_cls) {
const std::string& s = static_cast<BoxedString*>(a)->s;
if (s == "nan")
return new BoxedFloat(float_cls, NAN);
return new BoxedFloat(NAN);
if (s == "-nan")
return new BoxedFloat(float_cls, -NAN);
return new BoxedFloat(-NAN);
if (s == "inf")
return new BoxedFloat(float_cls, INFINITY);
return new BoxedFloat(INFINITY);
if (s == "-inf")
return new BoxedFloat(float_cls, -INFINITY);
return new BoxedFloat(-INFINITY);
return new BoxedFloat(float_cls, strtod(s.c_str(), NULL));
return new BoxedFloat(strtod(s.c_str(), NULL));
} else {
static const std::string float_str("__float__");
Box* r = callattr(a, &float_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }),
......@@ -596,13 +596,7 @@ Box* floatNew(BoxedClass* _cls, Box* a) {
BoxedFloat* f = _floatNew(a);
assert(cls->tp_basicsize >= sizeof(BoxedFloat));
void* mem = gc_alloc(cls->tp_basicsize, gc::GCKind::PYTHON);
BoxedFloat* rtn = ::new (mem) BoxedFloat(cls, 0);
initUserAttrs(rtn, cls);
rtn->d = f->d;
return rtn;
return new (cls) BoxedFloat(f->d);
}
Box* floatStr(BoxedFloat* self) {
......
......@@ -145,8 +145,8 @@ extern "C" BoxedGenerator* createGenerator(BoxedFunction* function, Box* arg1, B
extern "C" BoxedGenerator::BoxedGenerator(BoxedFunction* function, Box* arg1, Box* arg2, Box* arg3, Box** args)
: Box(generator_cls), function(function), arg1(arg1), arg2(arg2), arg3(arg3), args(nullptr), entryExited(false),
running(false), returnValue(nullptr), exception(nullptr) {
: function(function), arg1(arg1), arg2(arg2), arg3(arg3), args(nullptr), entryExited(false), running(false),
returnValue(nullptr), exception(nullptr) {
giveAttr("__name__", boxString(function->f->source->getName()));
......@@ -231,7 +231,7 @@ extern "C" void generatorGCHandler(GCVisitor* v, Box* b) {
void setupGenerator() {
generator_cls = new BoxedHeapClass(type_cls, object_cls, &generatorGCHandler, offsetof(BoxedGenerator, attrs),
generator_cls = new BoxedHeapClass(object_cls, &generatorGCHandler, offsetof(BoxedGenerator, attrs),
sizeof(BoxedGenerator), false);
generator_cls->giveAttr("__name__", boxStrConstant("generator"));
generator_cls->giveAttr("__iter__",
......
......@@ -62,7 +62,7 @@ Box* boxInt(int64_t n) {
if (0 <= n && n < NUM_INTERNED_INTS) {
return interned_ints[n];
}
return new BoxedInt(int_cls, n);
return new BoxedInt(n);
}
// BoxedInt::BoxedInt(int64_t n) : Box(int_cls), n(n) {}
......
......@@ -23,7 +23,7 @@ namespace pyston {
extern "C" inline Box* boxFloat(double d) __attribute__((visibility("default")));
extern "C" inline Box* boxFloat(double d) {
return new BoxedFloat(float_cls, d);
return new BoxedFloat(d);
}
extern "C" inline Box* boxComplex(double r, double i) __attribute__((visibility("default")));
......
......@@ -19,7 +19,7 @@
namespace pyston {
BoxedDictIterator::BoxedDictIterator(BoxedDict* d, IteratorType type)
: Box(dict_iterator_cls), d(d), it(d->d.begin()), itEnd(d->d.end()), type(type) {
: d(d), it(d->d.begin()), itEnd(d->d.end()), type(type) {
}
Box* dictIterKeys(Box* s) {
......@@ -72,7 +72,7 @@ Box* dictIterNext(Box* s) {
return rtn;
}
BoxedDictView::BoxedDictView(BoxedDict* d, BoxedClass* view_cls) : Box(view_cls), d(d) {
BoxedDictView::BoxedDictView(BoxedDict* d) : d(d) {
}
Box* dictViewKeysIter(Box* s) {
......
......@@ -20,7 +20,7 @@
namespace pyston {
BoxedListIterator::BoxedListIterator(BoxedList* l) : Box(list_iterator_cls), l(l), pos(0) {
BoxedListIterator::BoxedListIterator(BoxedList* l) : l(l), pos(0) {
}
......
......@@ -19,7 +19,7 @@
namespace pyston {
BoxedTupleIterator::BoxedTupleIterator(BoxedTuple* t) : Box(tuple_iterator_cls), t(t), pos(0) {
BoxedTupleIterator::BoxedTupleIterator(BoxedTuple* t) : t(t), pos(0) {
}
Box* tupleIterIter(Box* s) {
......
......@@ -26,9 +26,11 @@ private:
const int64_t start, stop, step;
public:
BoxedXrange(i64 start, i64 stop, i64 step) : Box(xrange_cls), start(start), stop(stop), step(step) {}
BoxedXrange(i64 start, i64 stop, i64 step) : start(start), stop(stop), step(step) {}
friend class BoxedXrangeIterator;
DEFAULT_CLASS(xrange_cls);
};
class BoxedXrangeIterator : public Box {
......@@ -37,7 +39,9 @@ private:
int64_t cur;
public:
BoxedXrangeIterator(BoxedXrange* xrange) : Box(xrange_iterator_cls), xrange(xrange), cur(xrange->start) {}
BoxedXrangeIterator(BoxedXrange* xrange) : xrange(xrange), cur(xrange->start) {}
DEFAULT_CLASS(xrange_iterator_cls);
static bool xrangeIteratorHasnextUnboxed(Box* s) __attribute__((visibility("default"))) {
assert(s->cls == xrange_iterator_cls);
......@@ -113,9 +117,9 @@ Box* xrangeIter(Box* self) {
}
void setupXrange() {
xrange_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedXrange), false);
xrange_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedXrange), false);
xrange_cls->giveAttr("__name__", boxStrConstant("xrange"));
xrange_iterator_cls = new BoxedHeapClass(type_cls, object_cls, &BoxedXrangeIterator::xrangeIteratorGCHandler, 0,
xrange_iterator_cls = new BoxedHeapClass(object_cls, &BoxedXrangeIterator::xrangeIteratorGCHandler, 0,
sizeof(BoxedXrangeIterator), false);
xrange_iterator_cls->giveAttr("__name__", boxStrConstant("rangeiterator"));
......
......@@ -758,17 +758,17 @@ BoxedInt* _intNew(Box* val) {
BoxedInt* n = static_cast<BoxedInt*>(val);
if (val->cls == int_cls)
return n;
return new BoxedInt(int_cls, n->n);
return new BoxedInt(n->n);
} else if (val->cls == str_cls) {
BoxedString* s = static_cast<BoxedString*>(val);
std::istringstream ss(s->s);
int64_t n;
ss >> n;
return new BoxedInt(int_cls, n);
return new BoxedInt(n);
} else if (val->cls == float_cls) {
double d = static_cast<BoxedFloat*>(val)->d;
return new BoxedInt(int_cls, d);
return new BoxedInt(d);
} else {
static const std::string int_str("__int__");
Box* r = callattr(val, &int_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }),
......@@ -801,13 +801,7 @@ extern "C" Box* intNew(Box* _cls, Box* val) {
BoxedInt* n = _intNew(val);
assert(cls->tp_basicsize >= sizeof(BoxedInt));
void* mem = gc_alloc(cls->tp_basicsize, gc::GCKind::PYTHON);
BoxedInt* rtn = ::new (mem) BoxedInt(cls, 0);
initUserAttrs(rtn, cls);
rtn->n = n->n;
return rtn;
return new (cls) BoxedInt(n->n);
}
extern "C" Box* intInit(BoxedInt* self, Box* val, Box* args) {
......@@ -849,7 +843,7 @@ static void _addFuncIntUnknown(const char* name, ConcreteCompilerType* rtn_type,
void setupInt() {
for (int i = 0; i < NUM_INTERNED_INTS; i++) {
interned_ints[i] = new BoxedInt(int_cls, i);
interned_ints[i] = new BoxedInt(i);
gc::registerPermanentRoot(interned_ints[i]);
}
......
......@@ -57,7 +57,7 @@ Box* seqiterNext(Box* s) {
}
void setupIter() {
seqiter_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedSeqIter), false);
seqiter_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedSeqIter), false);
seqiter_cls->giveAttr("__name__", boxStrConstant("iterator"));
seqiter_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)seqiterNext, UNKNOWN, 1)));
......
......@@ -29,7 +29,9 @@ public:
int64_t idx;
Box* next;
BoxedSeqIter(Box* b) : Box(seqiter_cls), b(b), idx(0), next(NULL) {}
BoxedSeqIter(Box* b) : b(b), idx(0), next(NULL) {}
DEFAULT_CLASS(seqiter_cls);
};
void setupIter();
......
......@@ -579,7 +579,7 @@ Box* listNe(BoxedList* self, Box* rhs) {
}
void setupList() {
list_iterator_cls = new BoxedHeapClass(type_cls, object_cls, &listIteratorGCHandler, 0, sizeof(BoxedList), false);
list_iterator_cls = new BoxedHeapClass(object_cls, &listIteratorGCHandler, 0, sizeof(BoxedList), false);
list_cls->giveAttr("__name__", boxStrConstant("list"));
......
......@@ -26,6 +26,8 @@ public:
BoxedList* l;
int pos;
BoxedListIterator(BoxedList* l);
DEFAULT_CLASS(list_iterator_cls);
};
Box* listIter(Box* self);
......
This diff is collapsed.
......@@ -30,7 +30,9 @@ class BoxedLong : public Box {
public:
mpz_t n;
BoxedLong(BoxedClass* cls) __attribute__((visibility("default"))) : Box(cls) {}
BoxedLong() __attribute__((visibility("default"))) {}
DEFAULT_CLASS(long_cls);
};
extern "C" Box* createLong(const std::string* s);
......
......@@ -343,10 +343,9 @@ void BoxedClass::freeze() {
is_constant = true;
}
BoxedClass::BoxedClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset,
int instance_size, bool is_user_defined)
: BoxVar(metaclass, 0), gc_visit(gc_visit), attrs_offset(attrs_offset), is_constant(false),
is_user_defined(is_user_defined) {
BoxedClass::BoxedClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size,
bool is_user_defined)
: BoxVar(0), gc_visit(gc_visit), attrs_offset(attrs_offset), is_constant(false), is_user_defined(is_user_defined) {
// Zero out the CPython tp_* slots:
memset(&tp_name, 0, (char*)(&tp_version_tag + 1) - (char*)(&tp_name));
......@@ -358,10 +357,12 @@ BoxedClass::BoxedClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_
tp_base = base;
if (metaclass == NULL) {
tp_alloc = PyType_GenericAlloc;
if (cls == NULL) {
assert(type_cls == NULL);
} else {
assert(isSubclass(metaclass, type_cls));
assert(isSubclass(cls, type_cls));
}
assert(tp_dealloc == NULL);
......@@ -396,10 +397,9 @@ BoxedClass::BoxedClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_
gc::registerPermanentRoot(this);
}
BoxedHeapClass::BoxedHeapClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset,
int instance_size, bool is_user_defined)
: BoxedClass(metaclass, base, gc_visit, attrs_offset, instance_size, is_user_defined), ht_name(NULL),
ht_slots(NULL) {
BoxedHeapClass::BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size,
bool is_user_defined)
: BoxedClass(base, gc_visit, attrs_offset, instance_size, is_user_defined), ht_name(NULL), ht_slots(NULL) {
tp_as_number = &as_number;
tp_as_mapping = &as_mapping;
......@@ -3314,10 +3314,10 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
BoxedClass* made;
if (base->instancesHaveAttrs()) {
made = new BoxedHeapClass(cls, base, NULL, base->attrs_offset, base->tp_basicsize, true);
made = new (cls) BoxedHeapClass(base, NULL, base->attrs_offset, base->tp_basicsize, true);
} else {
assert(base->tp_basicsize % sizeof(void*) == 0);
made = new BoxedHeapClass(cls, base, NULL, base->tp_basicsize, base->tp_basicsize + sizeof(HCAttrs), true);
made = new (cls) BoxedHeapClass(base, NULL, base->tp_basicsize, base->tp_basicsize + sizeof(HCAttrs), true);
}
made->giveAttr("__module__", boxString(getCurrentModule()->name()));
......
......@@ -25,7 +25,7 @@ BoxedClass* set_cls, *set_iterator_cls;
BoxedClass* frozenset_cls;
extern "C" Box* createSet() {
return new BoxedSet(set_cls);
return new BoxedSet();
}
namespace set {
......@@ -35,7 +35,9 @@ public:
BoxedSet* s;
decltype(BoxedSet::s)::iterator it;
BoxedSetIterator(BoxedSet* s) : Box(set_iterator_cls), s(s), it(s->s.begin()) {}
BoxedSetIterator(BoxedSet* s) : s(s), it(s->s.begin()) {}
DEFAULT_CLASS(set_iterator_cls);
bool hasNext() { return it != s->s.end(); }
......@@ -77,10 +79,11 @@ Box* setNew(Box* _cls, Box* container) {
BoxedClass* cls = static_cast<BoxedClass*>(_cls);
assert(cls == set_cls || cls == frozenset_cls);
Box* rtn = new (cls) BoxedSet();
if (container == None)
return new BoxedSet(cls);
return rtn;
Box* rtn = new BoxedSet(cls);
for (Box* e : container->pyElements()) {
setAdd2(rtn, e);
}
......@@ -118,7 +121,7 @@ Box* setOrSet(BoxedSet* lhs, BoxedSet* rhs) {
assert(lhs->cls == set_cls || lhs->cls == frozenset_cls);
assert(rhs->cls == set_cls || rhs->cls == frozenset_cls);
BoxedSet* rtn = new BoxedSet(lhs->cls);
BoxedSet* rtn = new (lhs->cls) BoxedSet();
for (Box* elt : lhs->s) {
rtn->s.insert(elt);
......@@ -133,7 +136,7 @@ Box* setAndSet(BoxedSet* lhs, BoxedSet* rhs) {
assert(lhs->cls == set_cls || lhs->cls == frozenset_cls);
assert(rhs->cls == set_cls || rhs->cls == frozenset_cls);
BoxedSet* rtn = new BoxedSet(lhs->cls);
BoxedSet* rtn = new (lhs->cls) BoxedSet();
for (Box* elt : lhs->s) {
if (rhs->s.count(elt))
......@@ -146,7 +149,7 @@ Box* setSubSet(BoxedSet* lhs, BoxedSet* rhs) {
assert(lhs->cls == set_cls || lhs->cls == frozenset_cls);
assert(rhs->cls == set_cls || rhs->cls == frozenset_cls);
BoxedSet* rtn = new BoxedSet(lhs->cls);
BoxedSet* rtn = new (lhs->cls) BoxedSet();
for (Box* elt : lhs->s) {
// TODO if len(rhs) << len(lhs), it might be more efficient
......@@ -161,7 +164,7 @@ Box* setXorSet(BoxedSet* lhs, BoxedSet* rhs) {
assert(lhs->cls == set_cls || lhs->cls == frozenset_cls);
assert(rhs->cls == set_cls || rhs->cls == frozenset_cls);
BoxedSet* rtn = new BoxedSet(lhs->cls);
BoxedSet* rtn = new (lhs->cls) BoxedSet();
for (Box* elt : lhs->s) {
if (rhs->s.count(elt) == 0)
......@@ -216,7 +219,7 @@ void setupSet() {
set_cls->giveAttr("__name__", boxStrConstant("set"));
frozenset_cls->giveAttr("__name__", boxStrConstant("frozenset"));
set_iterator_cls = new BoxedHeapClass(type_cls, object_cls, &setIteratorGCHandler, 0, sizeof(BoxedSet), false);
set_iterator_cls = new BoxedHeapClass(object_cls, &setIteratorGCHandler, 0, sizeof(BoxedSet), false);
set_iterator_cls->giveAttr("__name__", boxStrConstant("setiterator"));
set_iterator_cls->giveAttr("__hasnext__",
new BoxedFunction(boxRTFunction((void*)setiteratorHasnext, BOXED_BOOL, 1)));
......
......@@ -34,11 +34,11 @@ public:
typedef std::unordered_set<Box*, PyHasher, PyEq, StlCompatAllocator<Box*>> Set;
Set s;
BoxedSet(BoxedClass* cls) __attribute__((visibility("default"))) : Box(cls) {}
BoxedSet() __attribute__((visibility("default"))) {}
template <typename T>
__attribute__((visibility("default"))) BoxedSet(T&& s, BoxedClass* cls)
: Box(cls), s(std::forward<T>(s)) {}
template <typename T> __attribute__((visibility("default"))) BoxedSet(T&& s) : s(std::forward<T>(s)) {}
DEFAULT_CLASS(set_cls);
};
}
......
......@@ -1604,7 +1604,9 @@ public:
BoxedString* s;
std::string::const_iterator it, end;
BoxedStringIterator(BoxedString* s) : Box(str_iterator_cls), s(s), it(s->s.begin()), end(s->s.end()) {}
BoxedStringIterator(BoxedString* s) : it(s->s.begin()), end(s->s.end()) {}
DEFAULT_CLASS(str_iterator_cls);
static bool hasnextUnboxed(BoxedStringIterator* self) {
assert(self->cls == str_iterator_cls);
......@@ -1742,7 +1744,7 @@ static PyBufferProcs string_as_buffer = {
};
void setupStr() {
str_iterator_cls = new BoxedHeapClass(type_cls, object_cls, &strIteratorGCHandler, 0, sizeof(BoxedString), false);
str_iterator_cls = new BoxedHeapClass(object_cls, &strIteratorGCHandler, 0, sizeof(BoxedString), false);
str_iterator_cls->giveAttr("__name__", boxStrConstant("striterator"));
str_iterator_cls->giveAttr("__hasnext__",
new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::hasnext, BOXED_BOOL, 1)));
......
......@@ -32,8 +32,9 @@ public:
Box* obj; // "the instance invoking super(); make be None"
BoxedClass* obj_type; // "the type of the instance invoking super(); may be None"
BoxedSuper(BoxedClass* type, Box* obj, BoxedClass* obj_type)
: Box(super_cls), type(type), obj(obj), obj_type(obj_type) {}
BoxedSuper(BoxedClass* type, Box* obj, BoxedClass* obj_type) : type(type), obj(obj), obj_type(obj_type) {}
DEFAULT_CLASS(super_cls);
static void gcHandler(GCVisitor* v, Box* _o) {
assert(_o->cls == super_cls);
......@@ -131,7 +132,7 @@ Box* superInit(Box* _self, Box* _type, Box* obj) {
}
void setupSuper() {
super_cls = new BoxedHeapClass(type_cls, object_cls, &BoxedSuper::gcHandler, 0, sizeof(BoxedSuper), false);
super_cls = new BoxedHeapClass(object_cls, &BoxedSuper::gcHandler, 0, sizeof(BoxedSuper), false);
super_cls->giveAttr("__name__", boxStrConstant("super"));
......
......@@ -382,8 +382,7 @@ extern "C" void tupleIteratorGCHandler(GCVisitor* v, Box* b) {
void setupTuple() {
tuple_iterator_cls
= new BoxedHeapClass(type_cls, object_cls, &tupleIteratorGCHandler, 0, sizeof(BoxedTuple), false);
tuple_iterator_cls = new BoxedHeapClass(object_cls, &tupleIteratorGCHandler, 0, sizeof(BoxedTuple), false);
tuple_cls->giveAttr("__name__", boxStrConstant("tuple"));
......
......@@ -26,6 +26,8 @@ public:
BoxedTuple* t;
int pos;
BoxedTupleIterator(BoxedTuple* t);
DEFAULT_CLASS(tuple_iterator_cls);
};
Box* tupleIter(Box* self);
......
This diff is collapsed.
......@@ -216,8 +216,9 @@ public:
void freeze();
BoxedClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size,
bool is_user_defined);
BoxedClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size, bool is_user_defined);
DEFAULT_CLASS(type_cls);
};
class BoxedHeapClass : public BoxedClass {
......@@ -228,8 +229,7 @@ public:
PyBufferProcs as_buffer;
PyObject* ht_name, *ht_slots;
BoxedHeapClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size,
bool is_user_defined);
BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size, bool is_user_defined);
};
static_assert(sizeof(pyston::Box) == sizeof(struct _object), "");
......@@ -278,19 +278,22 @@ public:
HiddenClass* delAttrToMakeHC(const std::string& attr);
};
class BoxedInt : public Box {
public:
int64_t n;
BoxedInt(BoxedClass* cls, int64_t n) __attribute__((visibility("default"))) : Box(cls), n(n) {}
BoxedInt(int64_t n) __attribute__((visibility("default"))) : n(n) {}
DEFAULT_CLASS(int_cls);
};
class BoxedFloat : public Box {
public:
double d;
BoxedFloat(BoxedClass* cls, double d) __attribute__((visibility("default"))) : Box(cls), d(d) {}
BoxedFloat(double d) __attribute__((visibility("default"))) : d(d) {}
DEFAULT_CLASS(float_cls);
};
class BoxedComplex : public Box {
......@@ -298,12 +301,16 @@ public:
double real;
double imag;
BoxedComplex(double r, double i) __attribute__((visibility("default"))) : Box(complex_cls), real(r), imag(i) {}
BoxedComplex(double r, double i) __attribute__((visibility("default"))) : real(r), imag(i) {}
DEFAULT_CLASS(complex_cls);
};
class BoxedBool : public BoxedInt {
public:
BoxedBool(bool b) __attribute__((visibility("default"))) : BoxedInt(bool_cls, b ? 1 : 0) {}
BoxedBool(bool b) __attribute__((visibility("default"))) : BoxedInt(b ? 1 : 0) {}
DEFAULT_CLASS(bool_cls);
};
class BoxedString : public Box {
......@@ -311,9 +318,11 @@ public:
// const std::basic_string<char, std::char_traits<char>, StlCompatAllocator<char> > s;
std::string s;
BoxedString(const char* s, size_t n) __attribute__((visibility("default"))) : Box(str_cls), s(s, n) {}
BoxedString(const std::string&& s) __attribute__((visibility("default"))) : Box(str_cls), s(std::move(s)) {}
BoxedString(const std::string& s) __attribute__((visibility("default"))) : Box(str_cls), s(s) {}
BoxedString(const char* s, size_t n) __attribute__((visibility("default"))) : s(s, n) {}
BoxedString(const std::string&& s) __attribute__((visibility("default"))) : s(std::move(s)) {}
BoxedString(const std::string& s) __attribute__((visibility("default"))) : s(s) {}
DEFAULT_CLASS(str_cls);
};
class BoxedUnicode : public Box {
......@@ -325,8 +334,9 @@ public:
// obj is NULL for unbound instancemethod
Box* obj, *func;
BoxedInstanceMethod(Box* obj, Box* func) __attribute__((visibility("default")))
: Box(instancemethod_cls), obj(obj), func(func) {}
BoxedInstanceMethod(Box* obj, Box* func) __attribute__((visibility("default"))) : obj(obj), func(func) {}
DEFAULT_CLASS(instancemethod_cls);
};
class GCdArray {
......@@ -352,11 +362,13 @@ public:
DS_DEFINE_MUTEX(lock);
BoxedList() __attribute__((visibility("default"))) : Box(list_cls), size(0), capacity(0) {}
BoxedList() __attribute__((visibility("default"))) : size(0), capacity(0) {}
void ensure(int space);
void shrink();
static const int INITIAL_CAPACITY;
DEFAULT_CLASS(list_cls);
};
class BoxedTuple : public Box {
......@@ -364,8 +376,10 @@ public:
typedef std::vector<Box*, StlCompatAllocator<Box*>> GCVector;
GCVector elts;
BoxedTuple(GCVector& elts) __attribute__((visibility("default"))) : Box(tuple_cls), elts(elts) {}
BoxedTuple(GCVector&& elts) __attribute__((visibility("default"))) : Box(tuple_cls), elts(std::move(elts)) {}
BoxedTuple(GCVector& elts) __attribute__((visibility("default"))) : elts(elts) {}
BoxedTuple(GCVector&& elts) __attribute__((visibility("default"))) : elts(std::move(elts)) {}
DEFAULT_CLASS(tuple_cls);
};
extern "C" BoxedTuple* EmptyTuple;
......@@ -377,7 +391,9 @@ public:
bool closed;
bool softspace;
BoxedFile(FILE* f, std::string fname, std::string fmode) __attribute__((visibility("default")))
: Box(file_cls), f(f), fname(fname), fmode(fmode), closed(false), softspace(false) {}
: f(f), fname(fname), fmode(fmode), closed(false), softspace(false) {}
DEFAULT_CLASS(file_cls);
};
struct PyHasher {
......@@ -398,7 +414,9 @@ public:
DictMap d;
BoxedDict() __attribute__((visibility("default"))) : Box(dict_cls) {}
BoxedDict() __attribute__((visibility("default"))) {}
DEFAULT_CLASS(dict_cls);
Box* getOrNull(Box* k) {
const auto& p = d.find(k);
......@@ -424,6 +442,8 @@ public:
BoxedFunction(CLFunction* f);
BoxedFunction(CLFunction* f, std::initializer_list<Box*> defaults, BoxedClosure* closure = NULL,
bool isGenerator = false);
DEFAULT_CLASS(function_cls);
};
class BoxedModule : public Box {
......@@ -434,12 +454,16 @@ public:
BoxedModule(const std::string& name, const std::string& fn);
std::string name();
DEFAULT_CLASS(module_cls);
};
class BoxedSlice : public Box {
public:
Box* start, *stop, *step;
BoxedSlice(Box* lower, Box* upper, Box* step) : Box(slice_cls), start(lower), stop(upper), step(step) {}
BoxedSlice(Box* lower, Box* upper, Box* step) : start(lower), stop(upper), step(step) {}
DEFAULT_CLASS(slice_cls);
};
class BoxedMemberDescriptor : public Box {
......@@ -468,9 +492,10 @@ public:
int offset;
BoxedMemberDescriptor(MemberType type, int offset) : Box(member_cls), type(type), offset(offset) {}
BoxedMemberDescriptor(PyMemberDef* member)
: Box(member_cls), type((MemberType)member->type), offset(member->offset) {}
BoxedMemberDescriptor(MemberType type, int offset) : type(type), offset(offset) {}
BoxedMemberDescriptor(PyMemberDef* member) : type((MemberType)member->type), offset(member->offset) {}
DEFAULT_CLASS(member_cls);
};
class BoxedProperty : public Box {
......@@ -481,21 +506,27 @@ public:
Box* prop_doc;
BoxedProperty(Box* get, Box* set, Box* del, Box* doc)
: Box(property_cls), 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(property_cls);
};
class BoxedStaticmethod : public Box {
public:
Box* sm_callable;
BoxedStaticmethod(Box* callable) : Box(staticmethod_cls), sm_callable(callable){};
BoxedStaticmethod(Box* callable) : sm_callable(callable){};
DEFAULT_CLASS(staticmethod_cls);
};
class BoxedClassmethod : public Box {
public:
Box* cm_callable;
BoxedClassmethod(Box* callable) : Box(classmethod_cls), cm_callable(callable){};
BoxedClassmethod(Box* callable) : cm_callable(callable){};
DEFAULT_CLASS(classmethod_cls);
};
// TODO is there any particular reason to make this a Box, ie a python-level object?
......@@ -504,7 +535,9 @@ public:
HCAttrs attrs;
BoxedClosure* parent;
BoxedClosure(BoxedClosure* parent) : Box(closure_cls), parent(parent) {}
BoxedClosure(BoxedClosure* parent) : parent(parent) {}
DEFAULT_CLASS(closure_cls);
};
class BoxedGenerator : public Box {
......@@ -523,6 +556,8 @@ public:
void* stack_begin;
BoxedGenerator(BoxedFunction* function, Box* arg1, Box* arg2, Box* arg3, Box** args);
DEFAULT_CLASS(generator_cls);
};
extern "C" void boxGCHandler(GCVisitor* v, Box* b);
......@@ -535,16 +570,6 @@ extern "C" BoxedClass* Exception, *AssertionError, *AttributeError, *TypeError,
*IOError, *OSError, *ZeroDivisionError, *ValueError, *UnboundLocalError, *RuntimeError, *ImportError,
*StopIteration, *GeneratorExit, *SyntaxError;
// cls should be obj->cls.
// Added as parameter because it should typically be available
inline void initUserAttrs(Box* obj, BoxedClass* cls) {
assert(obj->cls == cls);
if (cls->attrs_offset) {
HCAttrs* attrs = obj->getAttrsPtr();
attrs = new ((void*)attrs) HCAttrs();
}
}
Box* makeAttrWrapper(Box* b);
}
#endif
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