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