Commit 790f24d2 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge branch 'tp_alloc'

parents 91321622 1ee311d6
......@@ -160,12 +160,17 @@ PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t) PYSTON_NO
#define PyObject_NewVar(type, typeobj, n) \
( (type *) _PyObject_NewVar((typeobj), (n)) )
// Pyston change: these are function calls now
#if 0
/* Macros trading binary compatibility for speed. See also pymem.h.
Note that these macros expect non-NULL object pointers.*/
#define PyObject_INIT(op, typeobj) \
( Py_TYPE(op) = (typeobj), (op) )
#define PyObject_INIT_VAR(op, typeobj, size) \
( Py_SIZE(op) = (size), PyObject_INIT((op), (typeobj)) )
#endif
#define PyObject_INIT(op, typeobj) PyObject_Init((PyObject*)(op), (PyTypeObject*)(typeobj))
#define PyObject_INIT_VAR(op, typeobj, size) PyObject_InitVar((PyObject*)(op), (PyTypeObject*)(typeobj), size)
#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize )
......
......@@ -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,19 @@ public:
class BoxedString;
class Box : public PythonGCObject {
class Box {
public:
// Add a no-op constructor to make sure that we don't zero-initialize cls
Box() {}
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 +416,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), "");
......
......@@ -26,6 +26,7 @@
#include "core/ast.h"
#include "core/types.h"
#include "gc/collector.h"
#include "runtime/capi.h"
#include "runtime/classobj.h"
#include "runtime/ics.h"
#include "runtime/import.h"
......@@ -262,8 +263,11 @@ Box* open(Box* arg1, Box* arg2) {
const std::string& mode = static_cast<BoxedString*>(arg2)->s;
FILE* f = fopen(fn.c_str(), mode.c_str());
if (!f)
raiseExcHelper(IOError, "[Errno %d] %s: '%s'", errno, strerror(errno), fn.c_str());
if (!f) {
PyErr_SetFromErrnoWithFilename(IOError, fn.c_str());
checkAndThrowCAPIException();
abort(); // unreachable;
}
return new BoxedFile(f, fn, mode);
}
......@@ -533,7 +537,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 +552,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 +587,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 +609,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 +633,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 +907,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 +1016,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 +1091,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)));
......
......@@ -63,17 +63,6 @@ int Py_Py3kWarningFlag;
BoxedClass* capifunc_cls;
extern "C" PyObject* PyType_GenericAlloc(PyTypeObject* cls, Py_ssize_t nitems) noexcept {
RELEASE_ASSERT(nitems == 0, "unimplemented");
RELEASE_ASSERT(cls->tp_itemsize == 0, "unimplemented");
auto rtn = (PyObject*)gc_alloc(cls->tp_basicsize, gc::GCKind::PYTHON);
memset(rtn, 0, cls->tp_basicsize);
PyObject_Init(rtn, cls);
return rtn;
}
BoxedClass* wrapperdescr_cls, *wrapperobject_cls;
Box* BoxedWrapperDescriptor::__get__(BoxedWrapperDescriptor* self, Box* inst, Box* owner) {
......@@ -142,26 +131,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 +1311,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 +1323,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 +1331,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(BoxedStringIterator), 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