Commit d4d92177 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Let the attributes live at various offsets in an object.

Similar to the location of the dict attribute in CPython,
the 'hc attrs list' in Pyston will end up being located at
different offsets, depending on the class that's being subclassed
from.

This commit removes the HCBox class, which assumes that it always lives
at the same offset and so can be statically described with a C++ class,
and instead uses a runtime lookup.

This should hopefully make things a fair bit closer to supporting inheritance.
parent e7a250a0
...@@ -117,6 +117,7 @@ COMMON_CXXFLAGS += -std=c++11 ...@@ -117,6 +117,7 @@ COMMON_CXXFLAGS += -std=c++11
COMMON_CXXFLAGS += -Wextra -Wno-sign-compare COMMON_CXXFLAGS += -Wextra -Wno-sign-compare
COMMON_CXXFLAGS += -Wno-unused-parameter # should use the "unused" attribute COMMON_CXXFLAGS += -Wno-unused-parameter # should use the "unused" attribute
COMMON_CXXFLAGS += -fexceptions -fno-rtti COMMON_CXXFLAGS += -fexceptions -fno-rtti
COMMON_CXXFLAGS += -Wno-invalid-offsetof # allow the use of "offsetof", and we'll just have to make sure to only use it legally.
ifeq ($(ENABLE_VALGRIND),0) ifeq ($(ENABLE_VALGRIND),0)
COMMON_CXXFLAGS += -DNVALGRIND COMMON_CXXFLAGS += -DNVALGRIND
......
...@@ -840,8 +840,8 @@ public: ...@@ -840,8 +840,8 @@ public:
virtual bool isFitBy(BoxedClass* c) { return c == cls; } virtual bool isFitBy(BoxedClass* c) { return c == cls; }
virtual CompilerType* getattrType(const std::string* attr, bool cls_only) { virtual CompilerType* getattrType(const std::string* attr, bool cls_only) {
if (cls->is_constant && !cls->hasattrs && cls->hasGenericGetattr()) { if (cls->is_constant && !cls->instancesHaveAttrs() && cls->hasGenericGetattr()) {
Box* rtattr = cls->peekattr(*attr); Box* rtattr = cls->getattr(*attr);
if (rtattr == NULL) if (rtattr == NULL)
return UNDEF; return UNDEF;
...@@ -861,8 +861,8 @@ public: ...@@ -861,8 +861,8 @@ public:
CompilerVariable* getattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var, CompilerVariable* getattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var,
const std::string* attr, bool cls_only) { const std::string* attr, bool cls_only) {
// printf("%s.getattr %s\n", debugName().c_str(), attr->c_str()); // printf("%s.getattr %s\n", debugName().c_str(), attr->c_str());
if (cls->is_constant && !cls->hasattrs && cls->hasGenericGetattr()) { if (cls->is_constant && !cls->instancesHaveAttrs() && cls->hasGenericGetattr()) {
Box* rtattr = cls->peekattr(*attr); Box* rtattr = cls->getattr(*attr);
if (rtattr == NULL) { if (rtattr == NULL) {
llvm::CallSite call = emitter.createCall2(info.exc_info, g.funcs.raiseAttributeErrorStr, llvm::CallSite call = emitter.createCall2(info.exc_info, g.funcs.raiseAttributeErrorStr,
getStringConstantPtr(*getNameOfClass(cls) + "\0"), getStringConstantPtr(*getNameOfClass(cls) + "\0"),
...@@ -927,8 +927,8 @@ public: ...@@ -927,8 +927,8 @@ public:
virtual CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var, virtual CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var,
const std::string* attr, bool clsonly, const std::string* attr, bool clsonly,
const std::vector<CompilerVariable*>& args) { const std::vector<CompilerVariable*>& args) {
if (cls->is_constant && !cls->hasattrs && cls->hasGenericGetattr()) { if (cls->is_constant && !cls->instancesHaveAttrs() && cls->hasGenericGetattr()) {
Box* rtattr = cls->peekattr(*attr); Box* rtattr = cls->getattr(*attr);
if (rtattr == NULL) { if (rtattr == NULL) {
llvm::CallSite call = emitter.createCall2(info.exc_info, g.funcs.raiseAttributeErrorStr, llvm::CallSite call = emitter.createCall2(info.exc_info, g.funcs.raiseAttributeErrorStr,
getStringConstantPtr(*getNameOfClass(cls) + "\0"), getStringConstantPtr(*getNameOfClass(cls) + "\0"),
......
...@@ -37,9 +37,6 @@ using namespace llvm; ...@@ -37,9 +37,6 @@ using namespace llvm;
namespace pyston { namespace pyston {
#define CLS_HASATTRS_OFFSET ((const char*)&(((BoxedClass*)0x01)->hasattrs) - (const char*)0x1)
#define FLAVOR_KINDID_OFFSET ((const char*)&(((ObjectFlavor*)0x01)->kind_id) - (const char*)0x1)
class ConstClassesPass : public FunctionPass { class ConstClassesPass : public FunctionPass {
private: private:
void* getGVAddr(GlobalVariable* gv) { void* getGVAddr(GlobalVariable* gv) {
...@@ -84,7 +81,7 @@ private: ...@@ -84,7 +81,7 @@ private:
assert(success); assert(success);
int64_t offset = ap_offset.getSExtValue(); int64_t offset = ap_offset.getSExtValue();
if (offset == FLAVOR_KINDID_OFFSET) { if (offset == offsetof(ObjectFlavor, kind_id)) {
ObjectFlavor* flavor = getFlavorFromGV(cast<GlobalVariable>(gepce->getOperand(0))); ObjectFlavor* flavor = getFlavorFromGV(cast<GlobalVariable>(gepce->getOperand(0)));
replaceUsesWithConstant(li, flavor->kind_id); replaceUsesWithConstant(li, flavor->kind_id);
return true; return true;
...@@ -150,9 +147,13 @@ private: ...@@ -150,9 +147,13 @@ private:
errs() << "Found a load: " << *gep_load << '\n'; errs() << "Found a load: " << *gep_load << '\n';
if (offset == CLS_HASATTRS_OFFSET) { if (offset == offsetof(BoxedClass, attrs_offset)) {
errs() << "Hasattrs; replacing with " << cls->hasattrs << "\n"; errs() << "attrs_offset; replacing with " << cls->attrs_offset << "\n";
replaceUsesWithConstant(gep_load, cls->hasattrs); replaceUsesWithConstant(gep_load, cls->attrs_offset);
changed = true;
} else if (offset == offsetof(BoxedClass, instance_size)) {
errs() << "instance_size; replacing with " << cls->instance_size << "\n";
replaceUsesWithConstant(gep_load, cls->instance_size);
changed = true; changed = true;
} }
} }
......
...@@ -140,15 +140,15 @@ PatchpointSetupInfo* createSetattrPatchpoint(CompiledFunction* parent_cf, TypeRe ...@@ -140,15 +140,15 @@ PatchpointSetupInfo* createSetattrPatchpoint(CompiledFunction* parent_cf, TypeRe
} }
PatchpointSetupInfo* createCallsitePatchpoint(CompiledFunction* parent_cf, TypeRecorder* type_recorder, int num_args) { PatchpointSetupInfo* createCallsitePatchpoint(CompiledFunction* parent_cf, TypeRecorder* type_recorder, int num_args) {
return PatchpointSetupInfo::initialize(true, 3, 256 + 36 * num_args, parent_cf, Callsite, type_recorder); return PatchpointSetupInfo::initialize(true, 3, 320 + 36 * num_args, parent_cf, Callsite, type_recorder);
} }
PatchpointSetupInfo* createGetGlobalPatchpoint(CompiledFunction* parent_cf, TypeRecorder* type_recorder) { PatchpointSetupInfo* createGetGlobalPatchpoint(CompiledFunction* parent_cf, TypeRecorder* type_recorder) {
return PatchpointSetupInfo::initialize(true, 1, 80, parent_cf, GetGlobal, type_recorder); return PatchpointSetupInfo::initialize(true, 1, 128, parent_cf, GetGlobal, type_recorder);
} }
PatchpointSetupInfo* createBinexpPatchpoint(CompiledFunction* parent_cf, TypeRecorder* type_recorder) { PatchpointSetupInfo* createBinexpPatchpoint(CompiledFunction* parent_cf, TypeRecorder* type_recorder) {
return PatchpointSetupInfo::initialize(true, 4, 196, parent_cf, Binexp, type_recorder); return PatchpointSetupInfo::initialize(true, 4, 256, parent_cf, Binexp, type_recorder);
} }
PatchpointSetupInfo* createNonzeroPatchpoint(CompiledFunction* parent_cf, TypeRecorder* type_recorder) { PatchpointSetupInfo* createNonzeroPatchpoint(CompiledFunction* parent_cf, TypeRecorder* type_recorder) {
......
...@@ -302,67 +302,63 @@ private: ...@@ -302,67 +302,63 @@ private:
}; };
extern bool TRACK_ALLOCATIONS;
class Box : public GCObject {
public:
BoxedClass* cls;
llvm::iterator_range<BoxIterator> pyElements();
constexpr Box(const ObjectFlavor* flavor, BoxedClass* c) __attribute__((visibility("default")))
: GCObject(flavor), cls(c) {
// if (TRACK_ALLOCATIONS) {
// int id = Stats::getStatId("allocated_" + *getNameOfClass(c));
// Stats::log(id);
//}
}
};
class SetattrRewriteArgs; class SetattrRewriteArgs;
class SetattrRewriteArgs2; class SetattrRewriteArgs2;
class GetattrRewriteArgs; class GetattrRewriteArgs;
class GetattrRewriteArgs2; class GetattrRewriteArgs2;
// I expect that most things will end up being represented by HCBox's rather than boxes,
// but I'm not putting these into Box so that things that don't have any python-level instance struct HCAttrs {
// attributes (ex: integers) don't need to allocate the extra space.
class HCBox : public Box {
public: public:
struct AttrList : GCObject { struct AttrList : GCObject {
Box* attrs[0]; Box* attrs[0];
}; };
HiddenClass* hcls; HiddenClass* hcls;
// Python-level attributes:
AttrList* attr_list; AttrList* attr_list;
HCBox(const ObjectFlavor* flavor, BoxedClass* cls); HCAttrs() : hcls(HiddenClass::getRoot()), attr_list(nullptr) {}
};
class Box : public GCObject {
public:
BoxedClass* cls;
llvm::iterator_range<BoxIterator> pyElements();
Box(const ObjectFlavor* flavor, BoxedClass* cls);
HCAttrs* getAttrs();
void setattr(const std::string& attr, Box* val, SetattrRewriteArgs* rewrite_args, void setattr(const std::string& attr, Box* val, SetattrRewriteArgs* rewrite_args,
SetattrRewriteArgs2* rewrite_args2); SetattrRewriteArgs2* rewrite_args2);
void giveAttr(const std::string& attr, Box* val); void giveAttr(const std::string& attr, Box* val) {
Box* getattr(const std::string& attr, GetattrRewriteArgs* rewrite_args, GetattrRewriteArgs2* rewrite_args2); assert(this->getattr(attr) == NULL);
Box* peekattr(const std::string& attr) { this->setattr(attr, val, NULL, NULL);
int offset = hcls->getOffset(attr);
if (offset == -1)
return NULL;
return attr_list->attrs[offset];
} }
Box* getattr(const std::string& attr, GetattrRewriteArgs* rewrite_args, GetattrRewriteArgs2* rewrite_args2);
Box* getattr(const std::string& attr) { return getattr(attr, NULL, NULL); }
}; };
class BoxedClass : public HCBox {
class BoxedClass : public Box {
public: public:
HCAttrs attrs;
// If the user sets __getattribute__ or __getattr__, we will have to invalidate // If the user sets __getattribute__ or __getattr__, we will have to invalidate
// all getattr IC entries that relied on the fact that those functions didn't exist. // all getattr IC entries that relied on the fact that those functions didn't exist.
// Doing this via invalidation means that instance attr lookups don't have // Doing this via invalidation means that instance attr lookups don't have
// to guard on anything about the class. // to guard on anything about the class.
ICInvalidator dependent_icgetattrs; ICInvalidator dependent_icgetattrs;
// whether or not instances of this class are subclasses of HCBox, // Offset of the HCAttrs object or 0 if there are no hcattrs.
// ie they have python-level instance attributes: // Analogous to tp_dictoffset
const bool hasattrs; const int attrs_offset;
// Analogous to tp_basicsize
const int instance_size;
bool instancesHaveAttrs() { return attrs_offset != 0; }
// Whether this class object is constant or not, ie whether or not class-level // Whether this class object is constant or not, ie whether or not class-level
// attributes can be changed or added. // attributes can be changed or added.
...@@ -377,7 +373,7 @@ public: ...@@ -377,7 +373,7 @@ public:
// will need to update this once we support tp_getattr-style overriding: // will need to update this once we support tp_getattr-style overriding:
bool hasGenericGetattr() { return true; } bool hasGenericGetattr() { return true; }
BoxedClass(bool hasattrs, bool is_user_defined); BoxedClass(int attrs_offset, int instance_size, bool is_user_defined);
void freeze() { void freeze() {
assert(!is_constant); assert(!is_constant);
is_constant = true; is_constant = true;
......
...@@ -65,7 +65,7 @@ void setupBool() { ...@@ -65,7 +65,7 @@ void setupBool() {
bool_cls->giveAttr("__neg__", new BoxedFunction(boxRTFunction((void*)boolNeg, NULL, 1, false))); bool_cls->giveAttr("__neg__", new BoxedFunction(boxRTFunction((void*)boolNeg, NULL, 1, false)));
bool_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)boolNonzero, NULL, 1, false))); bool_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)boolNonzero, NULL, 1, false)));
bool_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)boolRepr, NULL, 1, false))); bool_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)boolRepr, NULL, 1, false)));
bool_cls->setattr("__str__", bool_cls->peekattr("__repr__"), NULL, NULL); bool_cls->setattr("__str__", bool_cls->getattr("__repr__"), NULL, NULL);
CLFunction* __new__ = boxRTFunction((void*)boolNew1, NULL, 1, false); CLFunction* __new__ = boxRTFunction((void*)boolNew1, NULL, 1, false);
addRTFunction(__new__, (void*)boolNew2, NULL, 2, false); addRTFunction(__new__, (void*)boolNew2, NULL, 2, false);
......
...@@ -335,17 +335,22 @@ Box* exceptionNew1(BoxedClass* cls) { ...@@ -335,17 +335,22 @@ Box* exceptionNew1(BoxedClass* cls) {
return exceptionNew2(cls, boxStrConstant("")); return exceptionNew2(cls, boxStrConstant(""));
} }
class BoxedException : public Box {
public:
HCAttrs attrs;
BoxedException(BoxedClass* cls) : Box(&exception_flavor, cls) {}
};
Box* exceptionNew2(BoxedClass* cls, Box* message) { Box* exceptionNew2(BoxedClass* cls, Box* message) {
HCBox* r = new HCBox(&exception_flavor, cls); assert(cls->instance_size == sizeof(BoxedException));
Box* r = new BoxedException(cls);
r->giveAttr("message", message); r->giveAttr("message", message);
return r; return r;
} }
Box* exceptionStr(Box* b) { Box* exceptionStr(Box* b) {
HCBox* hcb = static_cast<HCBox*>(b);
// TODO In CPython __str__ and __repr__ pull from an internalized message field, but for now do this: // TODO In CPython __str__ and __repr__ pull from an internalized message field, but for now do this:
Box* message = hcb->peekattr("message"); Box* message = b->getattr("message");
assert(message); assert(message);
message = str(message); message = str(message);
assert(message->cls == str_cls); assert(message->cls == str_cls);
...@@ -354,10 +359,8 @@ Box* exceptionStr(Box* b) { ...@@ -354,10 +359,8 @@ Box* exceptionStr(Box* b) {
} }
Box* exceptionRepr(Box* b) { Box* exceptionRepr(Box* b) {
HCBox* hcb = static_cast<HCBox*>(b);
// TODO In CPython __str__ and __repr__ pull from an internalized message field, but for now do this: // TODO In CPython __str__ and __repr__ pull from an internalized message field, but for now do this:
Box* message = hcb->peekattr("message"); Box* message = b->getattr("message");
assert(message); assert(message);
message = repr(message); message = repr(message);
assert(message->cls == str_cls); assert(message->cls == str_cls);
...@@ -367,7 +370,7 @@ Box* exceptionRepr(Box* b) { ...@@ -367,7 +370,7 @@ Box* exceptionRepr(Box* b) {
} }
static BoxedClass* makeBuiltinException(const char* name) { static BoxedClass* makeBuiltinException(const char* name) {
BoxedClass* cls = new BoxedClass(true, false); BoxedClass* cls = new BoxedClass(offsetof(BoxedException, attrs), sizeof(BoxedException), false);
cls->giveAttr("__name__", boxStrConstant(name)); cls->giveAttr("__name__", boxStrConstant(name));
// TODO these should be on the base Exception class: // TODO these should be on the base Exception class:
...@@ -385,7 +388,7 @@ void setupBuiltins() { ...@@ -385,7 +388,7 @@ void setupBuiltins() {
builtins_module->setattr("None", None, NULL, NULL); builtins_module->setattr("None", None, NULL, NULL);
notimplemented_cls = new BoxedClass(false, false); notimplemented_cls = new BoxedClass(0, sizeof(Box), false);
notimplemented_cls->giveAttr("__name__", boxStrConstant("NotImplementedType")); notimplemented_cls->giveAttr("__name__", boxStrConstant("NotImplementedType"));
notimplemented_cls->giveAttr("__repr__", notimplemented_cls->giveAttr("__repr__",
new BoxedFunction(boxRTFunction((void*)notimplementedRepr, NULL, 1, false))); new BoxedFunction(boxRTFunction((void*)notimplementedRepr, NULL, 1, false)));
......
...@@ -28,7 +28,7 @@ BoxedDict* sys_modules_dict; ...@@ -28,7 +28,7 @@ BoxedDict* sys_modules_dict;
BoxedDict* getSysModulesDict() { BoxedDict* getSysModulesDict() {
// PyPy's behavior: fetch from sys.modules each time: // PyPy's behavior: fetch from sys.modules each time:
// Box *_sys_modules = sys_module->peekattr("modules"); // Box *_sys_modules = sys_module->getattr("modules");
// assert(_sys_modules); // assert(_sys_modules);
// assert(_sys_modules->cls == dict_cls); // assert(_sys_modules->cls == dict_cls);
// return static_cast<BoxedDict*>(_sys_modules); // return static_cast<BoxedDict*>(_sys_modules);
...@@ -39,7 +39,7 @@ BoxedDict* getSysModulesDict() { ...@@ -39,7 +39,7 @@ BoxedDict* getSysModulesDict() {
BoxedList* getSysPath() { BoxedList* getSysPath() {
// Unlike sys.modules, CPython handles sys.path by fetching it each time: // Unlike sys.modules, CPython handles sys.path by fetching it each time:
Box* _sys_path = sys_module->peekattr("path"); Box* _sys_path = sys_module->getattr("path");
assert(_sys_path); assert(_sys_path);
if (_sys_path->cls != list_cls) { if (_sys_path->cls != list_cls) {
...@@ -52,7 +52,7 @@ BoxedList* getSysPath() { ...@@ -52,7 +52,7 @@ BoxedList* getSysPath() {
} }
void addToSysArgv(const char* str) { void addToSysArgv(const char* str) {
Box* sys_argv = sys_module->peekattr("argv"); Box* sys_argv = sys_module->getattr("argv");
assert(sys_argv); assert(sys_argv);
assert(sys_argv->cls == list_cls); assert(sys_argv->cls == list_cls);
listAppendInternal(sys_argv, boxStrConstant(str)); listAppendInternal(sys_argv, boxStrConstant(str));
......
...@@ -120,12 +120,12 @@ BoxedModule* getTestModule() { ...@@ -120,12 +120,12 @@ BoxedModule* getTestModule() {
} }
void setupCAPI() { void setupCAPI() {
capifunc_cls = new BoxedClass(false, false); capifunc_cls = new BoxedClass(0, sizeof(BoxedCApiFunction), false);
capifunc_cls->giveAttr("__name__", boxStrConstant("capifunc")); capifunc_cls->giveAttr("__name__", boxStrConstant("capifunc"));
capifunc_cls->giveAttr("__repr__", capifunc_cls->giveAttr("__repr__",
new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__repr__, NULL, 1, false))); new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__repr__, NULL, 1, false)));
capifunc_cls->setattr("__str__", capifunc_cls->peekattr("__repr__"), NULL, NULL); capifunc_cls->setattr("__str__", capifunc_cls->getattr("__repr__"), NULL, NULL);
capifunc_cls->giveAttr("__call__", capifunc_cls->giveAttr("__call__",
new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__call__, NULL, 1, true))); new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__call__, NULL, 1, true)));
......
...@@ -152,16 +152,16 @@ void setupDict() { ...@@ -152,16 +152,16 @@ void setupDict() {
// dict_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)dictNew, NULL, 1, false))); // dict_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)dictNew, NULL, 1, false)));
// dict_cls->giveAttr("__init__", new BoxedFunction(boxRTFunction((void*)dictInit, NULL, 1, false))); // dict_cls->giveAttr("__init__", new BoxedFunction(boxRTFunction((void*)dictInit, NULL, 1, false)));
dict_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)dictRepr, NULL, 1, false))); dict_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)dictRepr, NULL, 1, false)));
dict_cls->setattr("__str__", dict_cls->peekattr("__repr__"), NULL, NULL); dict_cls->setattr("__str__", dict_cls->getattr("__repr__"), NULL, NULL);
dict_cls->giveAttr("items", new BoxedFunction(boxRTFunction((void*)dictItems, NULL, 1, false))); dict_cls->giveAttr("items", new BoxedFunction(boxRTFunction((void*)dictItems, NULL, 1, false)));
dict_cls->setattr("iteritems", dict_cls->peekattr("items"), NULL, NULL); dict_cls->setattr("iteritems", dict_cls->getattr("items"), NULL, NULL);
dict_cls->giveAttr("values", new BoxedFunction(boxRTFunction((void*)dictValues, NULL, 1, false))); dict_cls->giveAttr("values", new BoxedFunction(boxRTFunction((void*)dictValues, NULL, 1, false)));
dict_cls->setattr("itervalues", dict_cls->peekattr("values"), NULL, NULL); dict_cls->setattr("itervalues", dict_cls->getattr("values"), NULL, NULL);
dict_cls->giveAttr("keys", new BoxedFunction(boxRTFunction((void*)dictKeys, NULL, 1, false))); dict_cls->giveAttr("keys", new BoxedFunction(boxRTFunction((void*)dictKeys, NULL, 1, false)));
dict_cls->setattr("iterkeys", dict_cls->peekattr("keys"), NULL, NULL); dict_cls->setattr("iterkeys", dict_cls->getattr("keys"), NULL, NULL);
CLFunction* pop = boxRTFunction((void*)dictPop2, UNKNOWN, 2, false); CLFunction* pop = boxRTFunction((void*)dictPop2, UNKNOWN, 2, false);
addRTFunction(pop, (void*)dictPop3, UNKNOWN, 3, false); addRTFunction(pop, (void*)dictPop3, UNKNOWN, 3, false);
......
...@@ -182,7 +182,7 @@ void setupFile() { ...@@ -182,7 +182,7 @@ void setupFile() {
file_cls->giveAttr("close", new BoxedFunction(boxRTFunction((void*)fileClose, NULL, 1, false))); file_cls->giveAttr("close", new BoxedFunction(boxRTFunction((void*)fileClose, NULL, 1, false)));
file_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)fileRepr, NULL, 1, false))); file_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)fileRepr, NULL, 1, false)));
file_cls->setattr("__str__", file_cls->peekattr("__repr__"), NULL, NULL); file_cls->setattr("__str__", file_cls->getattr("__repr__"), NULL, NULL);
file_cls->giveAttr("__enter__", new BoxedFunction(boxRTFunction((void*)fileEnter, NULL, 1, false))); file_cls->giveAttr("__enter__", new BoxedFunction(boxRTFunction((void*)fileEnter, NULL, 1, false)));
file_cls->giveAttr("__exit__", new BoxedFunction(boxRTFunction((void*)fileExit, NULL, 4, false))); file_cls->giveAttr("__exit__", new BoxedFunction(boxRTFunction((void*)fileExit, NULL, 4, false)));
......
...@@ -565,7 +565,7 @@ void setupFloat() { ...@@ -565,7 +565,7 @@ void setupFloat() {
float_cls->giveAttr("__name__", boxStrConstant("float")); float_cls->giveAttr("__name__", boxStrConstant("float"));
_addFunc("__add__", BOXED_FLOAT, (void*)floatAddFloat, (void*)floatAddInt, (void*)floatAdd); _addFunc("__add__", BOXED_FLOAT, (void*)floatAddFloat, (void*)floatAddInt, (void*)floatAdd);
float_cls->setattr("__radd__", float_cls->peekattr("__add__"), NULL, NULL); float_cls->setattr("__radd__", float_cls->getattr("__add__"), NULL, NULL);
_addFunc("__div__", BOXED_FLOAT, (void*)floatDivFloat, (void*)floatDivInt, (void*)floatDiv); _addFunc("__div__", BOXED_FLOAT, (void*)floatDivFloat, (void*)floatDivInt, (void*)floatDiv);
_addFunc("__rdiv__", BOXED_FLOAT, (void*)floatRDivFloat, (void*)floatRDivInt, (void*)floatRDiv); _addFunc("__rdiv__", BOXED_FLOAT, (void*)floatRDivFloat, (void*)floatRDivInt, (void*)floatRDiv);
...@@ -581,7 +581,7 @@ void setupFloat() { ...@@ -581,7 +581,7 @@ void setupFloat() {
_addFunc("__mod__", BOXED_FLOAT, (void*)floatModFloat, (void*)floatModInt, (void*)floatMod); _addFunc("__mod__", BOXED_FLOAT, (void*)floatModFloat, (void*)floatModInt, (void*)floatMod);
_addFunc("__rmod__", BOXED_FLOAT, (void*)floatRModFloat, (void*)floatRModInt, (void*)floatRMod); _addFunc("__rmod__", BOXED_FLOAT, (void*)floatRModFloat, (void*)floatRModInt, (void*)floatRMod);
_addFunc("__mul__", BOXED_FLOAT, (void*)floatMulFloat, (void*)floatMulInt, (void*)floatMul); _addFunc("__mul__", BOXED_FLOAT, (void*)floatMulFloat, (void*)floatMulInt, (void*)floatMul);
float_cls->setattr("__rmul__", float_cls->peekattr("__mul__"), NULL, NULL); float_cls->setattr("__rmul__", float_cls->getattr("__mul__"), NULL, NULL);
_addFunc("__pow__", BOXED_FLOAT, (void*)floatPowFloat, (void*)floatPowInt, (void*)floatPow); _addFunc("__pow__", BOXED_FLOAT, (void*)floatPowFloat, (void*)floatPowInt, (void*)floatPow);
_addFunc("__sub__", BOXED_FLOAT, (void*)floatSubFloat, (void*)floatSubInt, (void*)floatSub); _addFunc("__sub__", BOXED_FLOAT, (void*)floatSubFloat, (void*)floatSubInt, (void*)floatSub);
......
...@@ -120,9 +120,9 @@ Box* xrangeIter(Box* self) { ...@@ -120,9 +120,9 @@ Box* xrangeIter(Box* self) {
} }
void setupXrange() { void setupXrange() {
xrange_cls = new BoxedClass(false, false); xrange_cls = new BoxedClass(0, sizeof(BoxedXrange), false);
xrange_cls->giveAttr("__name__", boxStrConstant("xrange")); xrange_cls->giveAttr("__name__", boxStrConstant("xrange"));
xrange_iterator_cls = new BoxedClass(false, false); xrange_iterator_cls = new BoxedClass(0, sizeof(BoxedXrangeIterator), false);
xrange_iterator_cls->giveAttr("__name__", boxStrConstant("rangeiterator")); xrange_iterator_cls->giveAttr("__name__", boxStrConstant("rangeiterator"));
CLFunction* xrange_clf = boxRTFunction((void*)xrange1, NULL, 2, false); CLFunction* xrange_clf = boxRTFunction((void*)xrange1, NULL, 2, false);
......
...@@ -533,7 +533,7 @@ void setupInt() { ...@@ -533,7 +533,7 @@ void setupInt() {
int_cls->giveAttr("__neg__", new BoxedFunction(boxRTFunction((void*)intNeg, BOXED_INT, 1, false))); int_cls->giveAttr("__neg__", new BoxedFunction(boxRTFunction((void*)intNeg, BOXED_INT, 1, false)));
int_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)intNonzero, BOXED_BOOL, 1, false))); int_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)intNonzero, BOXED_BOOL, 1, false)));
int_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)intRepr, STR, 1, false))); int_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)intRepr, STR, 1, false)));
int_cls->setattr("__str__", int_cls->peekattr("__repr__"), NULL, NULL); int_cls->setattr("__str__", int_cls->getattr("__repr__"), NULL, NULL);
int_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)intHash, BOXED_INT, 1, false))); int_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)intHash, BOXED_INT, 1, false)));
int_cls->giveAttr("__divmod__", new BoxedFunction(boxRTFunction((void*)intDivmod, BOXED_TUPLE, 2, false))); int_cls->giveAttr("__divmod__", new BoxedFunction(boxRTFunction((void*)intDivmod, BOXED_TUPLE, 2, false)));
......
...@@ -433,7 +433,7 @@ extern "C" Box* listNew2(Box* cls, Box* container) { ...@@ -433,7 +433,7 @@ extern "C" Box* listNew2(Box* cls, Box* container) {
} }
void setupList() { void setupList() {
list_iterator_cls = new BoxedClass(false, false); list_iterator_cls = new BoxedClass(0, sizeof(BoxedList), false);
list_cls->giveAttr("__name__", boxStrConstant("list")); list_cls->giveAttr("__name__", boxStrConstant("list"));
...@@ -449,7 +449,7 @@ void setupList() { ...@@ -449,7 +449,7 @@ void setupList() {
new BoxedFunction(boxRTFunction((void*)listIter, typeFromClass(list_iterator_cls), 1, false))); new BoxedFunction(boxRTFunction((void*)listIter, typeFromClass(list_iterator_cls), 1, false)));
list_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)listRepr, STR, 1, false))); list_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)listRepr, STR, 1, false)));
list_cls->setattr("__str__", list_cls->peekattr("__repr__"), NULL, NULL); list_cls->setattr("__str__", list_cls->getattr("__repr__"), NULL, NULL);
list_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)listNonzero, BOXED_BOOL, 1, false))); list_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)listNonzero, BOXED_BOOL, 1, false)));
CLFunction* pop = boxRTFunction((void*)listPop1, NULL, 1, false); CLFunction* pop = boxRTFunction((void*)listPop1, NULL, 1, false);
......
This diff is collapsed.
...@@ -176,7 +176,7 @@ using namespace pyston::set; ...@@ -176,7 +176,7 @@ using namespace pyston::set;
void setupSet() { void setupSet() {
set_cls->giveAttr("__name__", boxStrConstant("set")); set_cls->giveAttr("__name__", boxStrConstant("set"));
set_iterator_cls = new BoxedClass(false, false); set_iterator_cls = new BoxedClass(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, false))); new BoxedFunction(boxRTFunction((void*)setiteratorHasnext, BOXED_BOOL, 1, false)));
......
...@@ -138,9 +138,8 @@ void raiseExcHelper(BoxedClass* cls, const char* msg, ...) { ...@@ -138,9 +138,8 @@ void raiseExcHelper(BoxedClass* cls, const char* msg, ...) {
std::string formatException(Box* b) { std::string formatException(Box* b) {
const std::string* name = getTypeName(b); const std::string* name = getTypeName(b);
HCBox* hcb = static_cast<HCBox*>(b);
Box* attr = hcb->peekattr("message"); Box* attr = b->getattr("message");
if (attr == nullptr) if (attr == nullptr)
return *name; return *name;
......
...@@ -524,7 +524,7 @@ Box* strCount2(BoxedString* self, Box* elt) { ...@@ -524,7 +524,7 @@ Box* strCount2(BoxedString* self, Box* elt) {
} }
void setupStr() { void setupStr() {
str_iterator_cls = new BoxedClass(false, false); str_iterator_cls = new BoxedClass(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, NULL, 1, false))); new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::hasnext, NULL, 1, false)));
...@@ -558,7 +558,7 @@ void setupStr() { ...@@ -558,7 +558,7 @@ void setupStr() {
CLFunction* strSplit = boxRTFunction((void*)strSplit1, LIST, 1, false); CLFunction* strSplit = boxRTFunction((void*)strSplit1, LIST, 1, false);
addRTFunction(strSplit, (void*)strSplit2, LIST, 2, false); addRTFunction(strSplit, (void*)strSplit2, LIST, 2, false);
str_cls->giveAttr("split", new BoxedFunction(strSplit)); str_cls->giveAttr("split", new BoxedFunction(strSplit));
str_cls->giveAttr("rsplit", str_cls->peekattr("split")); str_cls->giveAttr("rsplit", str_cls->getattr("split"));
CLFunction* count = boxRTFunction((void*)strCount2Unboxed, INT, 2, false); CLFunction* count = boxRTFunction((void*)strCount2Unboxed, INT, 2, false);
addRTFunction(count, (void*)strCount2, BOXED_INT, 2, false); addRTFunction(count, (void*)strCount2, BOXED_INT, 2, false);
......
...@@ -203,7 +203,7 @@ void setupTuple() { ...@@ -203,7 +203,7 @@ void setupTuple() {
tuple_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)tupleHash, BOXED_INT, 1, false))); tuple_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)tupleHash, BOXED_INT, 1, false)));
tuple_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)tupleLen, NULL, 1, false))); tuple_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)tupleLen, NULL, 1, false)));
tuple_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)tupleRepr, NULL, 1, false))); tuple_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)tupleRepr, NULL, 1, false)));
tuple_cls->setattr("__str__", tuple_cls->peekattr("__repr__"), NULL, NULL); tuple_cls->setattr("__str__", tuple_cls->getattr("__repr__"), NULL, NULL);
tuple_cls->freeze(); tuple_cls->freeze();
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "runtime/types.h" #include "runtime/types.h"
#include <cassert> #include <cassert>
#include <cstddef>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
...@@ -63,7 +64,7 @@ llvm::iterator_range<BoxIterator> Box::pyElements() { ...@@ -63,7 +64,7 @@ llvm::iterator_range<BoxIterator> Box::pyElements() {
raiseExcHelper(TypeError, "'%s' object is not iterable", getTypeName(this)->c_str()); raiseExcHelper(TypeError, "'%s' object is not iterable", getTypeName(this)->c_str());
} }
extern "C" BoxedFunction::BoxedFunction(CLFunction* f) : HCBox(&function_flavor, function_cls), f(f) { extern "C" BoxedFunction::BoxedFunction(CLFunction* f) : Box(&function_flavor, function_cls), f(f) {
if (f->source) { if (f->source) {
assert(f->source->ast); assert(f->source->ast);
// this->giveAttr("__name__", boxString(&f->source->ast->name)); // this->giveAttr("__name__", boxString(&f->source->ast->name));
...@@ -74,13 +75,13 @@ extern "C" BoxedFunction::BoxedFunction(CLFunction* f) : HCBox(&function_flavor, ...@@ -74,13 +75,13 @@ extern "C" BoxedFunction::BoxedFunction(CLFunction* f) : HCBox(&function_flavor,
} }
} }
BoxedModule::BoxedModule(const std::string& name, const std::string& fn) : HCBox(&module_flavor, module_cls), fn(fn) { BoxedModule::BoxedModule(const std::string& name, const std::string& fn) : Box(&module_flavor, module_cls), fn(fn) {
this->giveAttr("__name__", boxString(name)); this->giveAttr("__name__", boxString(name));
this->giveAttr("__file__", boxString(fn)); this->giveAttr("__file__", boxString(fn));
} }
std::string BoxedModule::name() { std::string BoxedModule::name() {
Box* name = this->peekattr("__name__"); Box* name = this->getattr("__name__");
if (!name || name->cls != str_cls) { if (!name || name->cls != str_cls) {
return "?"; return "?";
} else { } else {
...@@ -102,27 +103,26 @@ extern "C" void boxGCHandler(GCVisitor* v, void* p) { ...@@ -102,27 +103,26 @@ extern "C" void boxGCHandler(GCVisitor* v, void* p) {
if (b->cls) { if (b->cls) {
v->visit(b->cls); v->visit(b->cls);
if (b->cls->instancesHaveAttrs()) {
HCAttrs* attrs = b->getAttrs();
v->visit(attrs->hcls);
int nattrs = attrs->hcls->attr_offsets.size();
if (nattrs) {
HCAttrs::AttrList* attr_list = attrs->attr_list;
assert(attr_list);
v->visit(attr_list);
v->visitRange((void**)&attr_list->attrs[0], (void**)&attr_list->attrs[nattrs]);
}
}
} else { } else {
assert(type_cls == NULL || p == type_cls); assert(type_cls == NULL || p == type_cls);
} }
} }
extern "C" void hcBoxGCHandler(GCVisitor* v, void* p) {
boxGCHandler(v, p);
HCBox* b = (HCBox*)p;
v->visit(b->hcls);
int nattrs = b->hcls->attr_offsets.size();
if (nattrs) {
HCBox::AttrList* attr_list = b->attr_list;
assert(attr_list);
v->visit(attr_list);
v->visitRange((void**)&attr_list->attrs[0], (void**)&attr_list->attrs[nattrs]);
}
}
extern "C" void typeGCHandler(GCVisitor* v, void* p) { extern "C" void typeGCHandler(GCVisitor* v, void* p) {
hcBoxGCHandler(v, p); boxGCHandler(v, p);
BoxedClass* b = (BoxedClass*)p; BoxedClass* b = (BoxedClass*)p;
} }
...@@ -213,15 +213,15 @@ const ObjectFlavor bool_flavor(&boxGCHandler, NULL); ...@@ -213,15 +213,15 @@ const ObjectFlavor bool_flavor(&boxGCHandler, NULL);
const ObjectFlavor int_flavor(&boxGCHandler, NULL); const ObjectFlavor int_flavor(&boxGCHandler, NULL);
const ObjectFlavor float_flavor(&boxGCHandler, NULL); const ObjectFlavor float_flavor(&boxGCHandler, NULL);
const ObjectFlavor str_flavor(&boxGCHandler, NULL); const ObjectFlavor str_flavor(&boxGCHandler, NULL);
const ObjectFlavor function_flavor(&hcBoxGCHandler, NULL); const ObjectFlavor function_flavor(&boxGCHandler, NULL);
const ObjectFlavor instancemethod_flavor(&instancemethodGCHandler, NULL); const ObjectFlavor instancemethod_flavor(&instancemethodGCHandler, NULL);
const ObjectFlavor list_flavor(&listGCHandler, NULL); const ObjectFlavor list_flavor(&listGCHandler, NULL);
const ObjectFlavor slice_flavor(&sliceGCHandler, NULL); const ObjectFlavor slice_flavor(&sliceGCHandler, NULL);
const ObjectFlavor module_flavor(&hcBoxGCHandler, NULL); const ObjectFlavor module_flavor(&boxGCHandler, NULL);
const ObjectFlavor dict_flavor(&dictGCHandler, NULL); const ObjectFlavor dict_flavor(&dictGCHandler, NULL);
const ObjectFlavor tuple_flavor(&tupleGCHandler, NULL); const ObjectFlavor tuple_flavor(&tupleGCHandler, NULL);
const ObjectFlavor file_flavor(&boxGCHandler, NULL); const ObjectFlavor file_flavor(&boxGCHandler, NULL);
const ObjectFlavor user_flavor(&hcBoxGCHandler, NULL); const ObjectFlavor user_flavor(&boxGCHandler, NULL);
const ObjectFlavor member_flavor(&boxGCHandler, NULL); const ObjectFlavor member_flavor(&boxGCHandler, NULL);
const AllocationKind untracked_kind(NULL, NULL); const AllocationKind untracked_kind(NULL, NULL);
...@@ -230,7 +230,7 @@ const AllocationKind conservative_kind(&conservativeGCHandler, NULL); ...@@ -230,7 +230,7 @@ const AllocationKind conservative_kind(&conservativeGCHandler, NULL);
} }
extern "C" Box* createUserClass(std::string* name, BoxedModule* parent_module) { extern "C" Box* createUserClass(std::string* name, BoxedModule* parent_module) {
BoxedClass* rtn = new BoxedClass(true, true); BoxedClass* rtn = new BoxedClass(offsetof(BoxedUserObject, attrs), sizeof(BoxedUserObject), true);
rtn->giveAttr("__name__", boxString(*name)); rtn->giveAttr("__name__", boxString(*name));
Box* modname = parent_module->getattr("__name__", NULL, NULL); Box* modname = parent_module->getattr("__name__", NULL, NULL);
...@@ -329,14 +329,14 @@ Box* typeRepr(BoxedClass* self) { ...@@ -329,14 +329,14 @@ Box* typeRepr(BoxedClass* self) {
std::ostringstream os; std::ostringstream os;
os << "<class '"; os << "<class '";
Box* m = self->peekattr("__module__"); Box* m = self->getattr("__module__");
RELEASE_ASSERT(m, ""); RELEASE_ASSERT(m, "");
if (m->cls == str_cls) { if (m->cls == str_cls) {
BoxedString* sm = static_cast<BoxedString*>(m); BoxedString* sm = static_cast<BoxedString*>(m);
os << sm->s << '.'; os << sm->s << '.';
} }
Box* n = self->peekattr("__name__"); Box* n = self->getattr("__name__");
RELEASE_ASSERT(n, ""); RELEASE_ASSERT(n, "");
RELEASE_ASSERT(n->cls == str_cls, "should have prevented you from setting __name__ to non-string"); RELEASE_ASSERT(n->cls == str_cls, "should have prevented you from setting __name__ to non-string");
BoxedString* sn = static_cast<BoxedString*>(n); BoxedString* sn = static_cast<BoxedString*>(n);
...@@ -375,31 +375,31 @@ bool TRACK_ALLOCATIONS = false; ...@@ -375,31 +375,31 @@ bool TRACK_ALLOCATIONS = false;
void setupRuntime() { void setupRuntime() {
HiddenClass::getRoot(); HiddenClass::getRoot();
type_cls = new BoxedClass(true, false); type_cls = new BoxedClass(offsetof(BoxedClass, attrs), sizeof(BoxedClass), false);
type_cls->cls = type_cls; type_cls->cls = type_cls;
none_cls = new BoxedClass(false, false); none_cls = new BoxedClass(0, sizeof(Box), false);
None = new Box(&none_flavor, none_cls); None = new Box(&none_flavor, none_cls);
gc::registerStaticRootObj(None); gc::registerStaticRootObj(None);
module_cls = new BoxedClass(true, false); module_cls = new BoxedClass(offsetof(BoxedModule, attrs), sizeof(BoxedModule), false);
// TODO it'd be nice to be able to do these in the respective setupType methods, // TODO it'd be nice to be able to do these in the respective setupType methods,
// but those setup methods probably want access to these objects. // but those setup methods probably want access to these objects.
// We could have a multi-stage setup process, but that seems overkill for now. // We could have a multi-stage setup process, but that seems overkill for now.
bool_cls = new BoxedClass(false, false); bool_cls = new BoxedClass(0, sizeof(BoxedBool), false);
int_cls = new BoxedClass(false, false); int_cls = new BoxedClass(0, sizeof(BoxedInt), false);
float_cls = new BoxedClass(false, false); float_cls = new BoxedClass(0, sizeof(BoxedFloat), false);
str_cls = new BoxedClass(false, false); str_cls = new BoxedClass(0, sizeof(BoxedString), false);
function_cls = new BoxedClass(true, false); function_cls = new BoxedClass(offsetof(BoxedFunction, attrs), sizeof(BoxedFunction), false);
instancemethod_cls = new BoxedClass(false, false); instancemethod_cls = new BoxedClass(0, sizeof(BoxedInstanceMethod), false);
list_cls = new BoxedClass(false, false); list_cls = new BoxedClass(0, sizeof(BoxedList), false);
slice_cls = new BoxedClass(false, false); slice_cls = new BoxedClass(0, sizeof(BoxedSlice), false);
dict_cls = new BoxedClass(false, false); dict_cls = new BoxedClass(0, sizeof(BoxedDict), false);
tuple_cls = new BoxedClass(false, false); tuple_cls = new BoxedClass(0, sizeof(BoxedTuple), false);
file_cls = new BoxedClass(false, false); file_cls = new BoxedClass(0, sizeof(BoxedFile), false);
set_cls = new BoxedClass(false, false); set_cls = new BoxedClass(0, sizeof(BoxedSet), false);
member_cls = new BoxedClass(false, false); member_cls = new BoxedClass(0, sizeof(BoxedMemberDescriptor), false);
STR = typeFromClass(str_cls); STR = typeFromClass(str_cls);
BOXED_INT = typeFromClass(int_cls); BOXED_INT = typeFromClass(int_cls);
...@@ -417,17 +417,17 @@ void setupRuntime() { ...@@ -417,17 +417,17 @@ void setupRuntime() {
type_cls->giveAttr("__call__", new BoxedFunction(boxRTFunction((void*)typeCall, NULL, 1, true))); type_cls->giveAttr("__call__", new BoxedFunction(boxRTFunction((void*)typeCall, NULL, 1, true)));
type_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)typeNew, NULL, 2, true))); type_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)typeNew, NULL, 2, true)));
type_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)typeRepr, NULL, 1, true))); type_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)typeRepr, NULL, 1, true)));
type_cls->setattr("__str__", type_cls->peekattr("__repr__"), NULL, NULL); type_cls->setattr("__str__", type_cls->getattr("__repr__"), NULL, NULL);
type_cls->freeze(); type_cls->freeze();
none_cls->giveAttr("__name__", boxStrConstant("NoneType")); none_cls->giveAttr("__name__", boxStrConstant("NoneType"));
none_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)noneRepr, NULL, 1, false))); none_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)noneRepr, NULL, 1, false)));
none_cls->setattr("__str__", none_cls->peekattr("__repr__"), NULL, NULL); none_cls->setattr("__str__", none_cls->getattr("__repr__"), NULL, NULL);
none_cls->freeze(); none_cls->freeze();
module_cls->giveAttr("__name__", boxStrConstant("module")); module_cls->giveAttr("__name__", boxStrConstant("module"));
module_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)moduleRepr, NULL, 1, false))); module_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)moduleRepr, NULL, 1, false)));
module_cls->setattr("__str__", module_cls->peekattr("__repr__"), NULL, NULL); module_cls->setattr("__str__", module_cls->getattr("__repr__"), NULL, NULL);
module_cls->freeze(); module_cls->freeze();
member_cls->giveAttr("__name__", boxStrConstant("member")); member_cls->giveAttr("__name__", boxStrConstant("member"));
...@@ -445,7 +445,7 @@ void setupRuntime() { ...@@ -445,7 +445,7 @@ void setupRuntime() {
function_cls->giveAttr("__name__", boxStrConstant("function")); function_cls->giveAttr("__name__", boxStrConstant("function"));
function_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)functionRepr, NULL, 1, false))); function_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)functionRepr, NULL, 1, false)));
function_cls->setattr("__str__", function_cls->peekattr("__repr__"), NULL, NULL); function_cls->setattr("__str__", function_cls->getattr("__repr__"), NULL, NULL);
function_cls->freeze(); function_cls->freeze();
instancemethod_cls->giveAttr("__name__", boxStrConstant("instancemethod")); instancemethod_cls->giveAttr("__name__", boxStrConstant("instancemethod"));
...@@ -459,7 +459,7 @@ void setupRuntime() { ...@@ -459,7 +459,7 @@ void setupRuntime() {
addRTFunction(slice_new, (void*)sliceNew4, NULL, 4, false); addRTFunction(slice_new, (void*)sliceNew4, NULL, 4, false);
slice_cls->giveAttr("__new__", new BoxedFunction(slice_new)); slice_cls->giveAttr("__new__", new BoxedFunction(slice_new));
slice_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)sliceRepr, NULL, 1, true))); slice_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)sliceRepr, NULL, 1, true)));
slice_cls->setattr("__str__", slice_cls->peekattr("__repr__"), NULL, NULL); slice_cls->setattr("__str__", slice_cls->getattr("__repr__"), NULL, NULL);
slice_cls->giveAttr("start", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, SLICE_START_OFFSET)); slice_cls->giveAttr("start", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, SLICE_START_OFFSET));
slice_cls->giveAttr("stop", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, SLICE_STOP_OFFSET)); slice_cls->giveAttr("stop", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, SLICE_STOP_OFFSET));
slice_cls->giveAttr("step", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, SLICE_STEP_OFFSET)); slice_cls->giveAttr("step", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, SLICE_STEP_OFFSET));
......
...@@ -260,15 +260,25 @@ public: ...@@ -260,15 +260,25 @@ public:
BoxedDict() __attribute__((visibility("default"))) : Box(&dict_flavor, dict_cls) {} BoxedDict() __attribute__((visibility("default"))) : Box(&dict_flavor, dict_cls) {}
}; };
class BoxedFunction : public HCBox { class BoxedFunction : public Box {
public: public:
HCAttrs attrs;
CLFunction* f; CLFunction* f;
BoxedFunction(CLFunction* f); BoxedFunction(CLFunction* f);
}; };
class BoxedModule : public HCBox { // TODO hack
class BoxedUserObject : public Box {
public: public:
HCAttrs attrs;
BoxedUserObject(BoxedClass* cls) : Box(&user_flavor, cls) {}
};
class BoxedModule : public Box {
public:
HCAttrs attrs;
const std::string fn; // for traceback purposes; not the same as __file__ const std::string fn; // for traceback purposes; not the same as __file__
BoxedModule(const std::string& name, const std::string& fn); BoxedModule(const std::string& name, const std::string& fn);
......
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