Commit ee548408 authored by Travis Hance's avatar Travis Hance

getset descriptors, __name__ for type and functions

parent c250a77e
......@@ -1337,15 +1337,6 @@ void fixup_slot_dispatchers(BoxedClass* self) noexcept {
const slotdef* p = slotdefs;
while (p->name)
p = update_one_slot(self, p);
// TODO: CPython handles this by having the __name__ attribute wrap (via a getset object)
// the tp_name field, whereas we're (needlessly?) doing the opposite.
if (!self->tp_name) {
Box* b = self->getattr("__name__");
assert(b);
assert(b->cls == str_cls);
self->tp_name = static_cast<BoxedString*>(b)->s.c_str();
}
}
static PyObject* tp_new_wrapper(PyTypeObject* self, BoxedTuple* args, Box* kwds) noexcept {
......@@ -1771,7 +1762,6 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
cls->tp_dict = makeAttrWrapper(cls);
assert(cls->tp_name);
cls->giveAttr("__name__", boxStrConstant(cls->tp_name));
// tp_name
// tp_basicsize, tp_itemsize
// tp_doc
......
......@@ -1219,7 +1219,7 @@ private:
KnownClassobjType(BoxedClass* cls) : cls(cls) { assert(cls); }
public:
std::string debugName() override { return "class '" + *getNameOfClass(cls) + "'"; }
std::string debugName() override { return "class '" + std::string(getNameOfClass(cls)) + "'"; }
void assertMatches(BoxedClass* cls) override { assert(cls == this->cls); }
......@@ -1276,7 +1276,7 @@ public:
assert(cls);
// TODO add getTypeName
return "NormalType(" + *getNameOfClass(cls) + ")";
return "NormalType(" + std::string(getNameOfClass(cls)) + ")";
}
ConcreteCompilerVariable* makeConverted(IREmitter& emitter, ConcreteCompilerVariable* var,
ConcreteCompilerType* other_type) override {
......@@ -1332,7 +1332,7 @@ public:
Box* rtattr = cls->getattr(*attr);
if (rtattr == NULL) {
llvm::CallSite call = emitter.createCall2(info.unw_info, g.funcs.raiseAttributeErrorStr,
getStringConstantPtr(*getNameOfClass(cls) + "\0"),
getStringConstantPtr(std::string(getNameOfClass(cls)) + "\0"),
getStringConstantPtr(*attr + '\0'));
call.setDoesNotReturn();
return undefVariable();
......@@ -1383,7 +1383,7 @@ public:
*no_attribute = true;
} else {
llvm::CallSite call = emitter.createCall2(info.unw_info, g.funcs.raiseAttributeErrorStr,
getStringConstantPtr(*getNameOfClass(cls) + "\0"),
getStringConstantPtr(std::string(getNameOfClass(cls)) + "\0"),
getStringConstantPtr(*attr + '\0'));
call.setDoesNotReturn();
}
......
......@@ -324,7 +324,7 @@ EffortLevel::EffortLevel initialEffort();
typedef bool i1;
typedef int64_t i64;
extern "C" const std::string* getNameOfClass(BoxedClass* cls);
const char* getNameOfClass(BoxedClass* cls);
std::string getFullNameOfClass(BoxedClass* cls);
class Rewriter;
......@@ -446,10 +446,8 @@ public:
};
static_assert(offsetof(BoxVar, ob_size) == offsetof(struct _varobject, ob_size), "");
extern "C" const std::string* getTypeName(Box* o);
std::string getFullTypeName(Box* o);
const char* getTypeName(Box* b);
class BoxedClass;
......
......@@ -232,7 +232,7 @@ static void markPhase() {
BoxedClass* cls = b->cls;
if (cls) {
ASSERT(cls->gc_visit, "%s", getTypeName(b)->c_str());
ASSERT(cls->gc_visit, "%s", getTypeName(b));
cls->gc_visit(&visitor, b);
}
}
......@@ -268,7 +268,7 @@ static void markPhase() {
// An arbitrary amount of stuff can happen between the 'new' and
// the call to the constructor (ie the args get evaluated), which
// can trigger a collection.
ASSERT(cls->gc_visit, "%s", getTypeName(b)->c_str());
ASSERT(cls->gc_visit, "%s", getTypeName(b));
cls->gc_visit(&visitor, b);
}
} else if (kind_id == GCKind::HIDDEN_CLASS) {
......
......@@ -300,7 +300,7 @@ static void _doFree(GCAllocation* al) {
if (al->kind_id == GCKind::PYTHON) {
Box* b = (Box*)al->user_data;
ASSERT(b->cls->tp_dealloc == NULL, "%s", getTypeName(b)->c_str());
ASSERT(b->cls->tp_dealloc == NULL, "%s", getTypeName(b));
}
}
......
......@@ -48,8 +48,6 @@ extern "C" Box* boolNew(Box* cls, Box* val) {
}
void setupBool() {
bool_cls->giveAttr("__name__", boxStrConstant("bool"));
bool_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)boolNonzero, BOXED_BOOL, 1)));
bool_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)boolRepr, STR, 1)));
bool_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)boolHash, BOXED_INT, 1)));
......
......@@ -331,13 +331,11 @@ Box* open(Box* arg1, Box* arg2) {
assert(arg2);
if (arg1->cls != str_cls) {
fprintf(stderr, "TypeError: coercing to Unicode: need string of buffer, %s found\n",
getTypeName(arg1)->c_str());
fprintf(stderr, "TypeError: coercing to Unicode: need string of buffer, %s found\n", getTypeName(arg1));
raiseExcHelper(TypeError, "");
}
if (arg2->cls != str_cls) {
fprintf(stderr, "TypeError: coercing to Unicode: need string of buffer, %s found\n",
getTypeName(arg2)->c_str());
fprintf(stderr, "TypeError: coercing to Unicode: need string of buffer, %s found\n", getTypeName(arg2));
raiseExcHelper(TypeError, "");
}
......@@ -368,7 +366,7 @@ extern "C" Box* chr(Box* arg) {
extern "C" Box* ord(Box* arg) {
if (arg->cls != str_cls) {
raiseExcHelper(TypeError, "ord() expected string of length 1, but %s found", getTypeName(arg)->c_str());
raiseExcHelper(TypeError, "ord() expected string of length 1, but %s found", getTypeName(arg));
}
const std::string& s = static_cast<BoxedString*>(arg)->s;
......@@ -381,22 +379,22 @@ extern "C" Box* ord(Box* arg) {
Box* range(Box* start, Box* stop, Box* step) {
i64 istart, istop, istep;
if (stop == NULL) {
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start));
istart = 0;
istop = static_cast<BoxedInt*>(start)->n;
istep = 1;
} else if (step == NULL) {
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(isSubclass(stop->cls, int_cls), "%s", getTypeName(stop)->c_str());
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start));
RELEASE_ASSERT(isSubclass(stop->cls, int_cls), "%s", getTypeName(stop));
istart = static_cast<BoxedInt*>(start)->n;
istop = static_cast<BoxedInt*>(stop)->n;
istep = 1;
} else {
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(isSubclass(stop->cls, int_cls), "%s", getTypeName(stop)->c_str());
RELEASE_ASSERT(isSubclass(step->cls, int_cls), "%s", getTypeName(step)->c_str());
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start));
RELEASE_ASSERT(isSubclass(stop->cls, int_cls), "%s", getTypeName(stop));
RELEASE_ASSERT(isSubclass(step->cls, int_cls), "%s", getTypeName(step));
istart = static_cast<BoxedInt*>(start)->n;
istop = static_cast<BoxedInt*>(stop)->n;
......@@ -481,7 +479,7 @@ Box* issubclass_func(Box* child, Box* parent) {
Box* bltinImport(Box* arg) {
if (arg->cls != str_cls) {
raiseExcHelper(TypeError, "__import__() argument 1 must be string, not %s", getTypeName(arg)->c_str());
raiseExcHelper(TypeError, "__import__() argument 1 must be string, not %s", getTypeName(arg));
}
return import(-1, new BoxedTuple({}), &static_cast<BoxedString*>(arg)->s);
......@@ -506,8 +504,7 @@ Box* getattrFunc(Box* obj, Box* _str, Box* default_value) {
if (default_value)
return default_value;
else
raiseExcHelper(AttributeError, "'%s' object has no attribute '%s'", getTypeName(obj)->c_str(),
str->s.c_str());
raiseExcHelper(AttributeError, "'%s' object has no attribute '%s'", getTypeName(obj), str->s.c_str());
}
return rtn;
......@@ -635,11 +632,11 @@ Box* exceptionNew2(BoxedClass* cls, Box* message) {
Box* exceptionNew(BoxedClass* cls, BoxedTuple* args) {
if (!isSubclass(cls->cls, type_cls))
raiseExcHelper(TypeError, "exceptions.__new__(X): X is not a type object (%s)", getTypeName(cls)->c_str());
raiseExcHelper(TypeError, "exceptions.__new__(X): X is not a type object (%s)", getTypeName(cls));
if (!isSubclass(cls, BaseException))
raiseExcHelper(TypeError, "BaseException.__new__(%s): %s is not a subtype of BaseException",
getNameOfClass(cls)->c_str(), getNameOfClass(cls)->c_str());
getNameOfClass(cls), getNameOfClass(cls));
BoxedException* rtn = new (cls) BoxedException();
......@@ -669,15 +666,14 @@ Box* exceptionRepr(Box* b) {
assert(message->cls == str_cls);
BoxedString* message_s = static_cast<BoxedString*>(message);
return boxString(*getTypeName(b) + "(" + message_s->s + ",)");
return boxString(std::string(getTypeName(b)) + "(" + message_s->s + ",)");
}
static BoxedClass* makeBuiltinException(BoxedClass* base, const char* name, int size = 0) {
if (size == 0)
size = base->tp_basicsize;
BoxedClass* cls = new BoxedHeapClass(base, NULL, offsetof(BoxedException, attrs), size, false);
cls->giveAttr("__name__", boxStrConstant(name));
BoxedClass* cls = new BoxedHeapClass(base, NULL, offsetof(BoxedException, attrs), size, false, name);
cls->giveAttr("__module__", boxStrConstant("exceptions"));
if (base == object_cls) {
......@@ -697,15 +693,16 @@ extern "C" PyObject* PyErr_NewException(char* name, PyObject* _base, PyObject* d
RELEASE_ASSERT(dict == NULL, "unimplemented");
try {
BoxedClass* base = Exception;
BoxedClass* cls = new BoxedHeapClass(base, NULL, offsetof(BoxedException, attrs), sizeof(BoxedException), true);
char* dot_pos = strchr(name, '.');
RELEASE_ASSERT(dot_pos, "");
int n = strlen(name);
BoxedString* boxedName = boxStrConstantSize(dot_pos + 1, n - (dot_pos - name) - 1);
BoxedClass* base = Exception;
BoxedClass* cls
= new BoxedHeapClass(base, NULL, offsetof(BoxedException, attrs), sizeof(BoxedException), true, boxedName);
cls->giveAttr("__module__", boxStrConstantSize(name, dot_pos - name));
cls->giveAttr("__name__", boxStrConstantSize(dot_pos + 1, n - (dot_pos - name) - 1));
// TODO Not sure if this should be called here
fixup_slot_dispatchers(cls);
return cls;
......@@ -781,7 +778,7 @@ Box* divmod(Box* lhs, Box* rhs) {
Box* execfile(Box* _fn) {
// The "globals" and "locals" arguments aren't implemented for now
if (!isSubclass(_fn->cls, str_cls)) {
raiseExcHelper(TypeError, "must be string, not %s", getTypeName(_fn)->c_str());
raiseExcHelper(TypeError, "must be string, not %s", getTypeName(_fn));
}
BoxedString* fn = static_cast<BoxedString*>(_fn);
......@@ -991,8 +988,7 @@ void setupBuiltins() {
builtins_module->giveAttr("print", new BoxedFunction(boxRTFunction((void*)print, NONE, 0, 0, true, true)));
notimplemented_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(Box), false);
notimplemented_cls->giveAttr("__name__", boxStrConstant("NotImplementedType"));
notimplemented_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(Box), false, "NotImplementedType");
notimplemented_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)notimplementedRepr, STR, 1)));
notimplemented_cls->freeze();
NotImplemented = new (notimplemented_cls) Box();
......@@ -1101,8 +1097,8 @@ void setupBuiltins() {
builtins_module->giveAttr("__import__", new BoxedFunction(boxRTFunction((void*)bltinImport, UNKNOWN, 1)));
enumerate_cls = new BoxedHeapClass(object_cls, &BoxedEnumerate::gcHandler, 0, sizeof(BoxedEnumerate), false);
enumerate_cls->giveAttr("__name__", boxStrConstant("enumerate"));
enumerate_cls
= new BoxedHeapClass(object_cls, &BoxedEnumerate::gcHandler, 0, sizeof(BoxedEnumerate), false, "enumerate");
enumerate_cls->giveAttr(
"__new__",
new BoxedFunction(boxRTFunction((void*)BoxedEnumerate::new_, UNKNOWN, 3, 1, false, false), { boxInt(0) }));
......
......@@ -254,8 +254,7 @@ void setupSys() {
sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX));
sys_flags_cls = new BoxedHeapClass(object_cls, BoxedSysFlags::gcHandler, 0, sizeof(BoxedSysFlags), false);
sys_flags_cls->giveAttr("__name__", boxStrConstant("flags"));
sys_flags_cls = new BoxedHeapClass(object_cls, BoxedSysFlags::gcHandler, 0, sizeof(BoxedSysFlags), false, "flags");
sys_flags_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)BoxedSysFlags::__new__, UNKNOWN, 1, 0, true, true)));
#define ADD(name) \
......
......@@ -144,8 +144,7 @@ void setupThread() {
thread_module->giveAttr("get_ident", new BoxedFunction(boxRTFunction((void*)getIdent, BOXED_INT, 0)));
thread_module->giveAttr("stack_size", new BoxedFunction(boxRTFunction((void*)stackSize, BOXED_INT, 0)));
thread_lock_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedThreadLock), false);
thread_lock_cls->giveAttr("__name__", boxStrConstant("lock"));
thread_lock_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedThreadLock), false, "lock");
thread_lock_cls->giveAttr("__module__", boxStrConstant("thread"));
thread_lock_cls->giveAttr(
"acquire",
......@@ -157,15 +156,13 @@ void setupThread() {
thread_lock_cls->giveAttr("__exit__", new BoxedFunction(boxRTFunction((void*)BoxedThreadLock::exit, NONE, 4)));
thread_lock_cls->freeze();
thread_local_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedThreadLocal), false);
thread_local_cls->giveAttr("__name__", boxStrConstant("_local"));
thread_local_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedThreadLocal), false, "_local");
thread_local_cls->giveAttr("__module__", boxStrConstant("thread"));
thread_local_cls->freeze();
thread_module->giveAttr("_local", thread_local_cls);
BoxedClass* ThreadError
= new BoxedHeapClass(Exception, NULL, Exception->attrs_offset, Exception->tp_basicsize, false);
ThreadError->giveAttr("__name__", boxStrConstant("error"));
= new BoxedHeapClass(Exception, NULL, Exception->attrs_offset, Exception->tp_basicsize, false, "error");
ThreadError->giveAttr("__module__", boxStrConstant("thread"));
ThreadError->freeze();
......
......@@ -1467,8 +1467,7 @@ Box* BoxedCApiFunction::callInternal(BoxedFunction* func, CallRewriteArgs* rewri
}
void setupCAPI() {
capifunc_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedCApiFunction), false);
capifunc_cls->giveAttr("__name__", boxStrConstant("capifunc"));
capifunc_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedCApiFunction), false, "capifunc");
capifunc_cls->giveAttr("__repr__",
new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__repr__, UNKNOWN, 1)));
......@@ -1479,22 +1478,20 @@ void setupCAPI() {
capifunc_cls->freeze();
method_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedMethodDescriptor), false);
method_cls->giveAttr("__name__", boxStrConstant("method"));
method_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedMethodDescriptor), false, "method");
method_cls->giveAttr("__get__",
new BoxedFunction(boxRTFunction((void*)BoxedMethodDescriptor::__get__, UNKNOWN, 3)));
method_cls->giveAttr("__call__", new BoxedFunction(boxRTFunction((void*)BoxedMethodDescriptor::__call__, UNKNOWN, 2,
0, true, true)));
method_cls->freeze();
wrapperdescr_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedWrapperDescriptor), false);
wrapperdescr_cls->giveAttr("__name__", boxStrConstant("wrapper_descriptor"));
wrapperdescr_cls
= new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedWrapperDescriptor), false, "wrapper_descriptor");
wrapperdescr_cls->giveAttr("__get__",
new BoxedFunction(boxRTFunction((void*)BoxedWrapperDescriptor::__get__, UNKNOWN, 3)));
wrapperdescr_cls->freeze();
wrapperobject_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedWrapperObject), false);
wrapperobject_cls->giveAttr("__name__", boxStrConstant("method-wrapper"));
wrapperobject_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedWrapperObject), false, "method-wrapper");
wrapperobject_cls->giveAttr(
"__call__", new BoxedFunction(boxRTFunction((void*)BoxedWrapperObject::__call__, UNKNOWN, 1, 0, true, true)));
wrapperobject_cls->freeze();
......
......@@ -63,12 +63,12 @@ extern "C" int PyClass_IsSubclass(PyObject* klass, PyObject* base) noexcept {
Box* classobjNew(Box* _cls, Box* _name, Box* _bases, Box** _args) {
if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "classobj.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
raiseExcHelper(TypeError, "classobj.__new__(X): X is not a type object (%s)", getTypeName(_cls));
BoxedClass* cls = static_cast<BoxedClass*>(_cls);
if (!isSubclass(cls, classobj_cls))
raiseExcHelper(TypeError, "classobj.__new__(%s): %s is not a subtype of classobj", getNameOfClass(cls)->c_str(),
getNameOfClass(cls)->c_str());
raiseExcHelper(TypeError, "classobj.__new__(%s): %s is not a subtype of classobj", getNameOfClass(cls),
getNameOfClass(cls));
if (_name->cls != str_cls)
raiseExcHelper(TypeError, "argument 1 must be string, not %s", getTypeName(_name));
......@@ -129,7 +129,7 @@ Box* classobjCall(Box* _cls, Box* _args, Box* _kwargs) {
Box* classobjStr(Box* _obj) {
if (!isSubclass(_obj->cls, classobj_cls)) {
raiseExcHelper(TypeError, "descriptor '__str__' requires a 'classobj' object but received an '%s'",
getTypeName(_obj)->c_str());
getTypeName(_obj));
}
BoxedClassobj* cls = static_cast<BoxedClassobj*>(_obj);
......@@ -271,11 +271,9 @@ Box* instanceSetitem(Box* _inst, Box* key, Box* value) {
void setupClassobj() {
classobj_cls = new BoxedHeapClass(object_cls, &BoxedClassobj::gcHandler, offsetof(BoxedClassobj, attrs),
sizeof(BoxedClassobj), false);
sizeof(BoxedClassobj), false, "classobj");
instance_cls = new BoxedHeapClass(object_cls, &BoxedInstance::gcHandler, offsetof(BoxedInstance, attrs),
sizeof(BoxedInstance), false);
classobj_cls->giveAttr("__name__", boxStrConstant("classobj"));
sizeof(BoxedInstance), false, "instance");
classobj_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)classobjNew, UNKNOWN, 4, 0, false, false)));
......@@ -288,8 +286,6 @@ void setupClassobj() {
classobj_cls->freeze();
instance_cls->giveAttr("__name__", boxStrConstant("instance"));
instance_cls->giveAttr("__getattribute__",
new BoxedFunction(boxRTFunction((void*)instanceGetattribute, UNKNOWN, 2)));
instance_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)instanceStr, UNKNOWN, 1)));
......
......@@ -252,8 +252,6 @@ Box* complexNew(Box* _cls, Box* real, Box* imag) {
}
void setupComplex() {
complex_cls->giveAttr("__name__", boxStrConstant("complex"));
complex_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)complexNew, UNKNOWN, 3, 2, false, false),
{ boxInt(0), boxInt(0) }));
......
......@@ -168,11 +168,9 @@ static Box* classmethodGet(Box* self, Box* obj, Box* type) {
}
void setupDescr() {
member_cls->giveAttr("__name__", boxStrConstant("member"));
member_cls->giveAttr("__get__", new BoxedFunction(boxRTFunction((void*)memberGet, UNKNOWN, 3)));
member_cls->freeze();
property_cls->giveAttr("__name__", boxStrConstant("property"));
property_cls->giveAttr(
"__init__",
new BoxedFunction(boxRTFunction((void*)propertyInit, UNKNOWN, 5, 4, false, false), { NULL, NULL, NULL, NULL }));
......@@ -192,7 +190,6 @@ void setupDescr() {
new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedProperty, prop_doc)));
property_cls->freeze();
staticmethod_cls->giveAttr("__name__", boxStrConstant("staticmethod"));
staticmethod_cls->giveAttr("__init__",
new BoxedFunction(boxRTFunction((void*)staticmethodInit, UNKNOWN, 5, 4, false, false),
{ None, None, None, None }));
......@@ -201,7 +198,6 @@ void setupDescr() {
staticmethod_cls->freeze();
classmethod_cls->giveAttr("__name__", boxStrConstant("classmethod"));
classmethod_cls->giveAttr("__init__",
new BoxedFunction(boxRTFunction((void*)classmethodInit, UNKNOWN, 5, 4, false, false),
{ None, None, None, None }));
......
......@@ -49,8 +49,7 @@ Box* dictRepr(BoxedDict* self) {
Box* dictClear(BoxedDict* self) {
if (!isSubclass(self->cls, dict_cls))
raiseExcHelper(TypeError, "descriptor 'clear' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
raiseExcHelper(TypeError, "descriptor 'clear' requires a 'dict' object but received a '%s'", getTypeName(self));
self->d.clear();
return None;
......@@ -58,8 +57,7 @@ Box* dictClear(BoxedDict* self) {
Box* dictCopy(BoxedDict* self) {
if (!isSubclass(self->cls, dict_cls))
raiseExcHelper(TypeError, "descriptor 'copy' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
raiseExcHelper(TypeError, "descriptor 'copy' requires a 'dict' object but received a '%s'", getTypeName(self));
BoxedDict* r = new BoxedDict();
r->d.insert(self->d.begin(), self->d.end());
......@@ -113,7 +111,7 @@ extern "C" PyObject* PyDict_Keys(PyObject* mp) noexcept {
Box* dictViewKeys(BoxedDict* self) {
if (!isSubclass(self->cls, dict_cls)) {
raiseExcHelper(TypeError, "descriptor 'viewkeys' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
}
BoxedDictView* rtn = new (dict_keys_cls) BoxedDictView(self);
return rtn;
......@@ -122,7 +120,7 @@ Box* dictViewKeys(BoxedDict* self) {
Box* dictViewValues(BoxedDict* self) {
if (!isSubclass(self->cls, dict_cls)) {
raiseExcHelper(TypeError, "descriptor 'viewvalues' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
}
BoxedDictView* rtn = new (dict_values_cls) BoxedDictView(self);
return rtn;
......@@ -131,7 +129,7 @@ Box* dictViewValues(BoxedDict* self) {
Box* dictViewItems(BoxedDict* self) {
if (!isSubclass(self->cls, dict_cls)) {
raiseExcHelper(TypeError, "descriptor 'viewitems' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
}
BoxedDictView* rtn = new (dict_items_cls) BoxedDictView(self);
return rtn;
......@@ -140,7 +138,7 @@ Box* dictViewItems(BoxedDict* self) {
Box* dictLen(BoxedDict* self) {
if (!isSubclass(self->cls, dict_cls))
raiseExcHelper(TypeError, "descriptor '__len__' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
return boxInt(self->d.size());
}
......@@ -172,7 +170,7 @@ extern "C" int PyDict_Update(PyObject* a, PyObject* b) noexcept {
Box* dictGetitem(BoxedDict* self, Box* k) {
if (!isSubclass(self->cls, dict_cls))
raiseExcHelper(TypeError, "descriptor '__getitem__' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
auto it = self->d.find(k);
if (it == self->d.end()) {
......@@ -198,7 +196,7 @@ extern "C" PyObject* PyDict_New() noexcept {
// The performance should hopefully be comparable to the CPython fast case, since we can use
// runtimeICs.
extern "C" int PyDict_SetItem(PyObject* mp, PyObject* _key, PyObject* _item) noexcept {
ASSERT(mp->cls == dict_cls || mp->cls == attrwrapper_cls, "%s", getTypeName(mp)->c_str());
ASSERT(mp->cls == dict_cls || mp->cls == attrwrapper_cls, "%s", getTypeName(mp));
assert(mp);
Box* b = static_cast<Box*>(mp);
......@@ -226,7 +224,7 @@ extern "C" int PyDict_SetItemString(PyObject* mp, const char* key, PyObject* ite
}
extern "C" PyObject* PyDict_GetItem(PyObject* dict, PyObject* key) noexcept {
ASSERT(dict->cls == dict_cls || dict->cls == attrwrapper_cls, "%s", getTypeName(dict)->c_str());
ASSERT(dict->cls == dict_cls || dict->cls == attrwrapper_cls, "%s", getTypeName(dict));
try {
return getitem(dict, key);
} catch (ExcInfo e) {
......@@ -304,7 +302,7 @@ Box* dictSetitem(BoxedDict* self, Box* k, Box* v) {
Box* dictDelitem(BoxedDict* self, Box* k) {
if (!isSubclass(self->cls, dict_cls))
raiseExcHelper(TypeError, "descriptor '__delitem__' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
auto it = self->d.find(k);
if (it == self->d.end()) {
......@@ -333,8 +331,7 @@ extern "C" int PyDict_DelItem(PyObject* op, PyObject* key) noexcept {
}
Box* dictPop(BoxedDict* self, Box* k, Box* d) {
if (!isSubclass(self->cls, dict_cls))
raiseExcHelper(TypeError, "descriptor 'pop' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
raiseExcHelper(TypeError, "descriptor 'pop' requires a 'dict' object but received a '%s'", getTypeName(self));
auto it = self->d.find(k);
if (it == self->d.end()) {
......@@ -357,7 +354,7 @@ Box* dictPop(BoxedDict* self, Box* k, Box* d) {
Box* dictPopitem(BoxedDict* self) {
if (!isSubclass(self->cls, dict_cls))
raiseExcHelper(TypeError, "descriptor 'popitem' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
auto it = self->d.begin();
if (it == self->d.end()) {
......@@ -374,8 +371,7 @@ Box* dictPopitem(BoxedDict* self) {
Box* dictGet(BoxedDict* self, Box* k, Box* d) {
if (!isSubclass(self->cls, dict_cls))
raiseExcHelper(TypeError, "descriptor 'get' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
raiseExcHelper(TypeError, "descriptor 'get' requires a 'dict' object but received a '%s'", getTypeName(self));
auto it = self->d.find(k);
if (it == self->d.end())
......@@ -387,7 +383,7 @@ Box* dictGet(BoxedDict* self, Box* k, Box* d) {
Box* dictSetdefault(BoxedDict* self, Box* k, Box* v) {
if (!isSubclass(self->cls, dict_cls))
raiseExcHelper(TypeError, "descriptor 'setdefault' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
auto it = self->d.find(k);
if (it != self->d.end())
......@@ -400,7 +396,7 @@ Box* dictSetdefault(BoxedDict* self, Box* k, Box* v) {
Box* dictContains(BoxedDict* self, Box* k) {
if (!isSubclass(self->cls, dict_cls))
raiseExcHelper(TypeError, "descriptor '__contains__' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
return boxBool(self->d.count(k) != 0);
}
......@@ -412,7 +408,7 @@ Box* dictNonzero(BoxedDict* self) {
Box* dictFromkeys(BoxedDict* self, Box* iterable, Box* default_value) {
if (!isSubclass(self->cls, dict_cls))
raiseExcHelper(TypeError, "descriptor 'fromkeys' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
auto rtn = new BoxedDict();
for (Box* e : iterable->pyElements()) {
......@@ -426,12 +422,12 @@ Box* dictFromkeys(BoxedDict* self, Box* iterable, Box* default_value) {
extern "C" Box* dictNew(Box* _cls, BoxedTuple* args, BoxedDict* kwargs) {
if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "dict.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
raiseExcHelper(TypeError, "dict.__new__(X): X is not a type object (%s)", getTypeName(_cls));
BoxedClass* cls = static_cast<BoxedClass*>(_cls);
if (!isSubclass(cls, dict_cls))
raiseExcHelper(TypeError, "dict.__new__(%s): %s is not a subtype of dict", getNameOfClass(cls)->c_str(),
getNameOfClass(cls)->c_str());
raiseExcHelper(TypeError, "dict.__new__(%s): %s is not a subtype of dict", getNameOfClass(cls),
getNameOfClass(cls));
return new (cls) BoxedDict();
}
......@@ -582,13 +578,14 @@ extern "C" void dictViewGCHandler(GCVisitor* v, Box* b) {
}
void setupDict() {
dict_iterator_cls = new BoxedHeapClass(object_cls, &dictIteratorGCHandler, 0, sizeof(BoxedDict), false);
dict_iterator_cls = new BoxedHeapClass(object_cls, &dictIteratorGCHandler, 0, sizeof(BoxedDict), false,
"dictionary-itemiterator");
dict_keys_cls = new BoxedHeapClass(object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false);
dict_values_cls = new BoxedHeapClass(object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false);
dict_items_cls = new BoxedHeapClass(object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false);
dict_keys_cls = new BoxedHeapClass(object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false, "dict_keys");
dict_values_cls
= new BoxedHeapClass(object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false, "dict_values");
dict_items_cls = new BoxedHeapClass(object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false, "dict_items");
dict_cls->giveAttr("__name__", boxStrConstant("dict"));
dict_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)dictLen, BOXED_INT, 1)));
dict_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)dictNew, UNKNOWN, 1, 0, true, true)));
dict_cls->giveAttr("__init__", new BoxedFunction(boxRTFunction((void*)dictInit, NONE, 1, 0, true, true)));
......@@ -638,8 +635,6 @@ void setupDict() {
dict_cls->freeze();
dict_iterator_cls->giveAttr("__name__", boxStrConstant("dictiterator"));
CLFunction* hasnext = boxRTFunction((void*)dictIterHasnextUnboxed, BOOL, 1);
addRTFunction(hasnext, (void*)dictIterHasnext, BOXED_BOOL);
dict_iterator_cls->giveAttr("__hasnext__", new BoxedFunction(hasnext));
......@@ -649,15 +644,12 @@ void setupDict() {
dict_iterator_cls->freeze();
dict_keys_cls->giveAttr("__name__", boxStrConstant("dictkeys"));
dict_keys_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)dictViewKeysIter, typeFromClass(dict_iterator_cls), 1)));
dict_keys_cls->freeze();
dict_values_cls->giveAttr("__name__", boxStrConstant("dictvalues"));
dict_values_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)dictViewValuesIter, typeFromClass(dict_iterator_cls), 1)));
dict_values_cls->freeze();
dict_items_cls->giveAttr("__name__", boxStrConstant("dictitems"));
dict_items_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)dictViewItemsIter, typeFromClass(dict_iterator_cls), 1)));
dict_items_cls->freeze();
......
......@@ -367,8 +367,6 @@ extern "C" int PyFile_SoftSpace(PyObject* f, int newflag) noexcept {
}
void setupFile() {
file_cls->giveAttr("__name__", boxStrConstant("file"));
file_cls->giveAttr("read",
new BoxedFunction(boxRTFunction((void*)fileRead, STR, 2, 1, false, false), { boxInt(-1) }));
......
......@@ -569,8 +569,7 @@ BoxedFloat* _floatNew(Box* a) {
ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
if (!r) {
fprintf(stderr, "TypeError: float() argument must be a string or a number, not '%s'\n",
getTypeName(a)->c_str());
fprintf(stderr, "TypeError: float() argument must be a string or a number, not '%s'\n", getTypeName(a));
raiseExcHelper(TypeError, "");
}
......@@ -583,12 +582,12 @@ BoxedFloat* _floatNew(Box* a) {
Box* floatNew(BoxedClass* _cls, Box* a) {
if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "float.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
raiseExcHelper(TypeError, "float.__new__(X): X is not a type object (%s)", getTypeName(_cls));
BoxedClass* cls = static_cast<BoxedClass*>(_cls);
if (!isSubclass(cls, float_cls))
raiseExcHelper(TypeError, "float.__new__(%s): %s is not a subtype of float", getNameOfClass(cls)->c_str(),
getNameOfClass(cls)->c_str());
raiseExcHelper(TypeError, "float.__new__(%s): %s is not a subtype of float", getNameOfClass(cls),
getNameOfClass(cls));
if (cls == float_cls)
......@@ -602,7 +601,7 @@ Box* floatNew(BoxedClass* _cls, Box* a) {
Box* floatStr(BoxedFloat* self) {
if (!isSubclass(self->cls, float_cls))
raiseExcHelper(TypeError, "descriptor '__str__' requires a 'float' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
return boxString(floatFmt(self->d, 12, 'g'));
}
......@@ -635,8 +634,6 @@ static void _addFunc(const char* name, ConcreteCompilerType* rtn_type, void* flo
}
void setupFloat() {
float_cls->giveAttr("__name__", boxStrConstant("float"));
_addFunc("__add__", BOXED_FLOAT, (void*)floatAddFloat, (void*)floatAddInt, (void*)floatAdd);
float_cls->giveAttr("__radd__", float_cls->getattr("__add__"));
......
......@@ -237,8 +237,7 @@ extern "C" void generatorGCHandler(GCVisitor* v, Box* b) {
void setupGenerator() {
generator_cls = new BoxedHeapClass(object_cls, &generatorGCHandler, offsetof(BoxedGenerator, attrs),
sizeof(BoxedGenerator), false);
generator_cls->giveAttr("__name__", boxStrConstant("generator"));
sizeof(BoxedGenerator), false, "generator");
generator_cls->giveAttr("__iter__",
new BoxedFunction(boxRTFunction((void*)generatorIter, typeFromClass(generator_cls), 1)));
......
......@@ -48,13 +48,13 @@ Box* boxString(std::string&& s) {
}
extern "C" double unboxFloat(Box* b) {
ASSERT(b->cls == float_cls, "%s", getTypeName(b)->c_str());
ASSERT(b->cls == float_cls, "%s", getTypeName(b));
BoxedFloat* f = (BoxedFloat*)b;
return f->d;
}
i64 unboxInt(Box* b) {
ASSERT(b->cls == int_cls, "%s", getTypeName(b)->c_str());
ASSERT(b->cls == int_cls, "%s", getTypeName(b));
return ((BoxedInt*)b)->n;
}
......
......@@ -88,21 +88,21 @@ Box* xrange(Box* cls, Box* start, Box* stop, Box** args) {
Box* step = args[0];
if (stop == NULL) {
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start));
i64 istop = static_cast<BoxedInt*>(start)->n;
return new BoxedXrange(0, istop, 1);
} else if (step == NULL) {
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(isSubclass(stop->cls, int_cls), "%s", getTypeName(stop)->c_str());
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start));
RELEASE_ASSERT(isSubclass(stop->cls, int_cls), "%s", getTypeName(stop));
i64 istart = static_cast<BoxedInt*>(start)->n;
i64 istop = static_cast<BoxedInt*>(stop)->n;
return new BoxedXrange(istart, istop, 1);
} else {
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(isSubclass(stop->cls, int_cls), "%s", getTypeName(stop)->c_str());
RELEASE_ASSERT(isSubclass(step->cls, int_cls), "%s", getTypeName(step)->c_str());
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start));
RELEASE_ASSERT(isSubclass(stop->cls, int_cls), "%s", getTypeName(stop));
RELEASE_ASSERT(isSubclass(step->cls, int_cls), "%s", getTypeName(step));
i64 istart = static_cast<BoxedInt*>(start)->n;
i64 istop = static_cast<BoxedInt*>(stop)->n;
......@@ -120,11 +120,9 @@ Box* xrangeIter(Box* self) {
}
void setupXrange() {
xrange_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedXrange), false);
xrange_cls->giveAttr("__name__", boxStrConstant("xrange"));
xrange_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedXrange), false, "xrange");
xrange_iterator_cls = new BoxedHeapClass(object_cls, &BoxedXrangeIterator::xrangeIteratorGCHandler, 0,
sizeof(BoxedXrangeIterator), false);
xrange_iterator_cls->giveAttr("__name__", boxStrConstant("rangeiterator"));
sizeof(BoxedXrangeIterator), false, "rangeiterator");
xrange_cls->giveAttr(
"__new__",
......
......@@ -235,8 +235,7 @@ extern "C" Box* intAddFloat(BoxedInt* lhs, BoxedFloat* rhs) {
extern "C" Box* intAdd(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__add__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__add__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (isSubclass(rhs->cls, int_cls)) {
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
......@@ -257,8 +256,7 @@ extern "C" Box* intAndInt(BoxedInt* lhs, BoxedInt* rhs) {
extern "C" Box* intAnd(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__and__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__and__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) {
return NotImplemented;
......@@ -275,8 +273,7 @@ extern "C" Box* intOrInt(BoxedInt* lhs, BoxedInt* rhs) {
extern "C" Box* intOr(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__or__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__or__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) {
return NotImplemented;
......@@ -293,8 +290,7 @@ extern "C" Box* intXorInt(BoxedInt* lhs, BoxedInt* rhs) {
extern "C" Box* intXor(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__xor__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__xor__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) {
return NotImplemented;
......@@ -321,8 +317,7 @@ extern "C" Box* intDivFloat(BoxedInt* lhs, BoxedFloat* rhs) {
extern "C" Box* intDiv(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__div__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__div__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (isSubclass(rhs->cls, int_cls)) {
return intDivInt(lhs, static_cast<BoxedInt*>(rhs));
......@@ -352,7 +347,7 @@ extern "C" Box* intFloordivFloat(BoxedInt* lhs, BoxedFloat* rhs) {
extern "C" Box* intFloordiv(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__floordiv__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
getTypeName(lhs));
if (isSubclass(rhs->cls, int_cls)) {
return intFloordivInt(lhs, static_cast<BoxedInt*>(rhs));
......@@ -386,7 +381,7 @@ extern "C" Box* intTruedivFloat(BoxedInt* lhs, BoxedFloat* rhs) {
extern "C" Box* intTruediv(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__truediv__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
getTypeName(lhs));
if (isSubclass(rhs->cls, int_cls)) {
return intTruedivInt(lhs, static_cast<BoxedInt*>(rhs));
......@@ -405,8 +400,7 @@ extern "C" Box* intEqInt(BoxedInt* lhs, BoxedInt* rhs) {
extern "C" Box* intEq(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__eq__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__eq__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (isSubclass(rhs->cls, int_cls)) {
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
......@@ -424,8 +418,7 @@ extern "C" Box* intNeInt(BoxedInt* lhs, BoxedInt* rhs) {
extern "C" Box* intNe(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__ne__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__ne__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) {
return NotImplemented;
......@@ -442,8 +435,7 @@ extern "C" Box* intLtInt(BoxedInt* lhs, BoxedInt* rhs) {
extern "C" Box* intLt(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__lt__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__lt__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) {
return NotImplemented;
......@@ -460,8 +452,7 @@ extern "C" Box* intLeInt(BoxedInt* lhs, BoxedInt* rhs) {
extern "C" Box* intLe(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__le__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__le__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) {
return NotImplemented;
......@@ -478,8 +469,7 @@ extern "C" Box* intGtInt(BoxedInt* lhs, BoxedInt* rhs) {
extern "C" Box* intGt(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__gt__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__gt__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) {
return NotImplemented;
......@@ -496,8 +486,7 @@ extern "C" Box* intGeInt(BoxedInt* lhs, BoxedInt* rhs) {
extern "C" Box* intGe(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__ge__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__ge__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) {
return NotImplemented;
......@@ -520,7 +509,7 @@ extern "C" Box* intLShiftInt(BoxedInt* lhs, BoxedInt* rhs) {
extern "C" Box* intLShift(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__lshift__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
getTypeName(lhs));
if (rhs->cls != int_cls) {
return NotImplemented;
......@@ -537,8 +526,7 @@ extern "C" Box* intModInt(BoxedInt* lhs, BoxedInt* rhs) {
extern "C" Box* intMod(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__mod__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__mod__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) {
return NotImplemented;
......@@ -550,7 +538,7 @@ extern "C" Box* intMod(BoxedInt* lhs, Box* rhs) {
extern "C" Box* intDivmod(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__divmod__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
getTypeName(lhs));
Box* divResult = intDiv(lhs, rhs);
......@@ -583,8 +571,7 @@ extern "C" Box* intMulFloat(BoxedInt* lhs, BoxedFloat* rhs) {
extern "C" Box* intMul(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__mul__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__mul__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (isSubclass(rhs->cls, int_cls)) {
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
......@@ -612,8 +599,7 @@ extern "C" Box* intPowFloat(BoxedInt* lhs, BoxedFloat* rhs) {
extern "C" Box* intPow(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__pow__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__pow__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (isSubclass(rhs->cls, int_cls)) {
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
......@@ -639,7 +625,7 @@ extern "C" Box* intRShiftInt(BoxedInt* lhs, BoxedInt* rhs) {
extern "C" Box* intRShift(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__rshift__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
getTypeName(lhs));
if (rhs->cls != int_cls) {
return NotImplemented;
......@@ -662,8 +648,7 @@ extern "C" Box* intSubFloat(BoxedInt* lhs, BoxedFloat* rhs) {
extern "C" Box* intSub(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__sub__' requires a 'int' object but received a '%s'",
getTypeName(lhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__sub__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (isSubclass(rhs->cls, int_cls)) {
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
......@@ -679,15 +664,14 @@ extern "C" Box* intSub(BoxedInt* lhs, Box* rhs) {
extern "C" Box* intInvert(BoxedInt* v) {
if (!isSubclass(v->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__invert__' requires a 'int' object but received a '%s'",
getTypeName(v)->c_str());
getTypeName(v));
return boxInt(~v->n);
}
extern "C" Box* intPos(BoxedInt* v) {
if (!isSubclass(v->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__pos__' requires a 'int' object but received a '%s'",
getTypeName(v)->c_str());
raiseExcHelper(TypeError, "descriptor '__pos__' requires a 'int' object but received a '%s'", getTypeName(v));
if (v->cls == int_cls)
return v;
......@@ -696,8 +680,7 @@ extern "C" Box* intPos(BoxedInt* v) {
extern "C" Box* intNeg(BoxedInt* v) {
if (!isSubclass(v->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__neg__' requires a 'int' object but received a '%s'",
getTypeName(v)->c_str());
raiseExcHelper(TypeError, "descriptor '__neg__' requires a 'int' object but received a '%s'", getTypeName(v));
// It's possible for this to overflow:
......@@ -715,15 +698,14 @@ extern "C" Box* intNeg(BoxedInt* v) {
extern "C" Box* intNonzero(BoxedInt* v) {
if (!isSubclass(v->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__nonzer__' requires a 'int' object but received a '%s'",
getTypeName(v)->c_str());
getTypeName(v));
return boxBool(v->n != 0);
}
extern "C" BoxedString* intRepr(BoxedInt* v) {
if (!isSubclass(v->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__repr__' requires a 'int' object but received a '%s'",
getTypeName(v)->c_str());
raiseExcHelper(TypeError, "descriptor '__repr__' requires a 'int' object but received a '%s'", getTypeName(v));
char buf[80];
int len = snprintf(buf, 80, "%ld", v->n);
......@@ -733,7 +715,7 @@ extern "C" BoxedString* intRepr(BoxedInt* v) {
extern "C" Box* intHash(BoxedInt* self) {
if (!isSubclass(self->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__hash__' requires a 'int' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
if (self->cls == int_cls)
return self;
......@@ -743,7 +725,7 @@ extern "C" Box* intHash(BoxedInt* self) {
extern "C" Box* intHex(BoxedInt* self) {
if (!isSubclass(self->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__hex__' requires a 'int' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
char buf[80];
int len = snprintf(buf, sizeof(buf), "0x%lx", self->n);
......@@ -753,7 +735,7 @@ extern "C" Box* intHex(BoxedInt* self) {
extern "C" Box* intOct(BoxedInt* self) {
if (!isSubclass(self->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__oct__' requires a 'int' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
char buf[80];
int len = snprintf(buf, sizeof(buf), "%#lo", self->n);
......@@ -782,8 +764,7 @@ BoxedInt* _intNew(Box* val) {
ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
if (!r) {
fprintf(stderr, "TypeError: int() argument must be a string or a number, not '%s'\n",
getTypeName(val)->c_str());
fprintf(stderr, "TypeError: int() argument must be a string or a number, not '%s'\n", getTypeName(val));
raiseExcHelper(TypeError, "");
}
......@@ -796,12 +777,12 @@ BoxedInt* _intNew(Box* val) {
extern "C" Box* intNew(Box* _cls, Box* val) {
if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "int.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
raiseExcHelper(TypeError, "int.__new__(X): X is not a type object (%s)", getTypeName(_cls));
BoxedClass* cls = static_cast<BoxedClass*>(_cls);
if (!isSubclass(cls, int_cls))
raiseExcHelper(TypeError, "int.__new__(%s): %s is not a subtype of int", getNameOfClass(cls)->c_str(),
getNameOfClass(cls)->c_str());
raiseExcHelper(TypeError, "int.__new__(%s): %s is not a subtype of int", getNameOfClass(cls),
getNameOfClass(cls));
if (cls == int_cls)
return _intNew(val);
......@@ -854,8 +835,6 @@ void setupInt() {
gc::registerPermanentRoot(interned_ints[i]);
}
int_cls->giveAttr("__name__", boxStrConstant("int"));
_addFuncIntFloatUnknown("__add__", (void*)intAddInt, (void*)intAddFloat, (void*)intAdd);
_addFuncIntUnknown("__and__", BOXED_INT, (void*)intAndInt, (void*)intAnd);
_addFuncIntUnknown("__or__", BOXED_INT, (void*)intOrInt, (void*)intOr);
......
......@@ -107,16 +107,15 @@ extern "C" PyObject* PySeqIter_New(PyObject* seq) noexcept {
}
void setupIter() {
seqiter_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedSeqIter), false);
seqiter_cls->giveAttr("__name__", boxStrConstant("iterator"));
seqiter_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedSeqIter), false, "iterator");
seqiter_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)seqiterNext, UNKNOWN, 1)));
seqiter_cls->giveAttr("__hasnext__", new BoxedFunction(boxRTFunction((void*)seqiterHasnext, BOXED_BOOL, 1)));
seqiter_cls->freeze();
iterwrapper_cls = new BoxedHeapClass(object_cls, iterwrapperGCVisit, 0, sizeof(BoxedIterWrapper), false);
iterwrapper_cls->giveAttr("__name__", boxStrConstant("iterwrapper"));
iterwrapper_cls
= new BoxedHeapClass(object_cls, iterwrapperGCVisit, 0, sizeof(BoxedIterWrapper), false, "iterwrapper");
iterwrapper_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)iterwrapperNext, UNKNOWN, 1)));
iterwrapper_cls->giveAttr("__hasnext__",
......
......@@ -172,7 +172,7 @@ extern "C" Box* listGetitem(BoxedList* self, Box* slice) {
} else if (slice->cls == slice_cls) {
return listGetitemSlice(self, static_cast<BoxedSlice*>(slice));
} else {
raiseExcHelper(TypeError, "list indices must be integers, not %s", getTypeName(slice)->c_str());
raiseExcHelper(TypeError, "list indices must be integers, not %s", getTypeName(slice));
}
}
......@@ -254,7 +254,7 @@ extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) {
assert(0 <= start && start <= stop && stop <= self->size);
RELEASE_ASSERT(v->cls == list_cls, "unsupported %s", getTypeName(v)->c_str());
RELEASE_ASSERT(v->cls == list_cls, "unsupported %s", getTypeName(v));
BoxedList* lv = static_cast<BoxedList*>(v);
RELEASE_ASSERT(self->elts != lv->elts, "Slice self-assignment currently unsupported");
......@@ -281,7 +281,7 @@ extern "C" Box* listSetitem(BoxedList* self, Box* slice, Box* v) {
} else if (slice->cls == slice_cls) {
return listSetitemSlice(self, static_cast<BoxedSlice*>(slice), v);
} else {
raiseExcHelper(TypeError, "list indices must be integers, not %s", getTypeName(slice)->c_str());
raiseExcHelper(TypeError, "list indices must be integers, not %s", getTypeName(slice));
}
}
......@@ -329,7 +329,7 @@ extern "C" Box* listDelitem(BoxedList* self, Box* slice) {
} else if (slice->cls == slice_cls) {
rtn = listDelitemSlice(self, static_cast<BoxedSlice*>(slice));
} else {
raiseExcHelper(TypeError, "list indices must be integers, not %s", getTypeName(slice)->c_str());
raiseExcHelper(TypeError, "list indices must be integers, not %s", getTypeName(slice));
}
self->shrink();
return rtn;
......@@ -365,7 +365,7 @@ extern "C" Box* listInsert(BoxedList* self, Box* idx, Box* v) {
Box* listMul(BoxedList* self, Box* rhs) {
if (rhs->cls != int_cls) {
raiseExcHelper(TypeError, "can't multiply sequence by non-int of type '%s'", getTypeName(rhs)->c_str());
raiseExcHelper(TypeError, "can't multiply sequence by non-int of type '%s'", getTypeName(rhs));
}
LOCK_REGION(self->lock.asRead());
......@@ -414,7 +414,7 @@ Box* listIAdd(BoxedList* self, Box* _rhs) {
Box* listAdd(BoxedList* self, Box* _rhs) {
if (_rhs->cls != list_cls) {
raiseExcHelper(TypeError, "can only concatenate list (not \"%s\") to list", getTypeName(_rhs)->c_str());
raiseExcHelper(TypeError, "can only concatenate list (not \"%s\") to list", getTypeName(_rhs));
}
LOCK_REGION(self->lock.asRead());
......@@ -691,9 +691,8 @@ extern "C" int PyList_SetSlice(PyObject* a, Py_ssize_t ilow, Py_ssize_t ihigh, P
}
void setupList() {
list_iterator_cls = new BoxedHeapClass(object_cls, &listIteratorGCHandler, 0, sizeof(BoxedList), false);
list_cls->giveAttr("__name__", boxStrConstant("list"));
list_iterator_cls
= new BoxedHeapClass(object_cls, &listIteratorGCHandler, 0, sizeof(BoxedList), false, "listiterator");
list_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)listLen, BOXED_INT, 1)));
......@@ -748,9 +747,6 @@ void setupList() {
list_cls->giveAttr("reverse", new BoxedFunction(boxRTFunction((void*)listReverse, NONE, 1)));
list_cls->freeze();
list_iterator_cls->giveAttr("__name__", boxStrConstant("listiterator"));
CLFunction* hasnext = boxRTFunction((void*)listiterHasnextUnboxed, BOOL, 1);
addRTFunction(hasnext, (void*)listiterHasnext, BOXED_BOOL);
list_iterator_cls->giveAttr("__hasnext__", new BoxedFunction(hasnext));
......
......@@ -358,7 +358,7 @@ BoxedLong* _longNew(Box* val, Box* _base) {
if (!r) {
fprintf(stderr, "TypeError: long() argument must be a string or a number, not '%s'\n",
getTypeName(val)->c_str());
getTypeName(val));
raiseExcHelper(TypeError, "");
}
......@@ -376,12 +376,12 @@ BoxedLong* _longNew(Box* val, Box* _base) {
extern "C" Box* longNew(Box* _cls, Box* val, Box* _base) {
if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "long.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
raiseExcHelper(TypeError, "long.__new__(X): X is not a type object (%s)", getTypeName(_cls));
BoxedClass* cls = static_cast<BoxedClass*>(_cls);
if (!isSubclass(cls, long_cls))
raiseExcHelper(TypeError, "long.__new__(%s): %s is not a subtype of long", getNameOfClass(cls)->c_str(),
getNameOfClass(cls)->c_str());
raiseExcHelper(TypeError, "long.__new__(%s): %s is not a subtype of long", getNameOfClass(cls),
getNameOfClass(cls));
BoxedLong* l = _longNew(val, _base);
if (cls == long_cls)
......@@ -395,8 +395,7 @@ extern "C" Box* longNew(Box* _cls, Box* val, Box* _base) {
Box* longRepr(BoxedLong* v) {
if (!isSubclass(v->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__repr__' requires a 'long' object but received a '%s'",
getTypeName(v)->c_str());
raiseExcHelper(TypeError, "descriptor '__repr__' requires a 'long' object but received a '%s'", getTypeName(v));
int space_required = mpz_sizeinbase(v->n, 10) + 2; // basic size
space_required += 1; // 'L' suffix
......@@ -412,8 +411,7 @@ Box* longRepr(BoxedLong* v) {
Box* longStr(BoxedLong* v) {
if (!isSubclass(v->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__str__' requires a 'long' object but received a '%s'",
getTypeName(v)->c_str());
raiseExcHelper(TypeError, "descriptor '__str__' requires a 'long' object but received a '%s'", getTypeName(v));
int space_required = mpz_sizeinbase(v->n, 10) + 2;
char* buf = (char*)malloc(space_required);
mpz_get_str(buf, 10, v->n);
......@@ -426,8 +424,7 @@ Box* longStr(BoxedLong* v) {
Box* longNeg(BoxedLong* v1) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__neg__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
raiseExcHelper(TypeError, "descriptor '__neg__' requires a 'long' object but received a '%s'", getTypeName(v1));
BoxedLong* r = new BoxedLong();
mpz_init(r->n);
......@@ -445,8 +442,7 @@ Box* longAbs(BoxedLong* v1) {
Box* longAdd(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__add__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
raiseExcHelper(TypeError, "descriptor '__add__' requires a 'long' object but received a '%s'", getTypeName(v1));
if (isSubclass(_v2->cls, long_cls)) {
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
......@@ -472,8 +468,7 @@ Box* longAdd(BoxedLong* v1, Box* _v2) {
extern "C" Box* longAnd(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__and__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
raiseExcHelper(TypeError, "descriptor '__and__' requires a 'long' object but received a '%s'", getTypeName(v1));
if (isSubclass(_v2->cls, long_cls)) {
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
BoxedLong* r = new BoxedLong();
......@@ -499,8 +494,7 @@ extern "C" Box* longAnd(BoxedLong* v1, Box* _v2) {
extern "C" Box* longXor(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__xor__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
raiseExcHelper(TypeError, "descriptor '__xor__' requires a 'long' object but received a '%s'", getTypeName(v1));
if (isSubclass(_v2->cls, long_cls)) {
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
BoxedLong* r = new BoxedLong();
......@@ -527,8 +521,7 @@ extern "C" Box* longXor(BoxedLong* v1, Box* _v2) {
// TODO reduce duplication between these 6 functions, and add double support
Box* longGt(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__gt__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
raiseExcHelper(TypeError, "descriptor '__gt__' requires a 'long' object but received a '%s'", getTypeName(v1));
if (isSubclass(_v2->cls, long_cls)) {
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
......@@ -545,8 +538,7 @@ Box* longGt(BoxedLong* v1, Box* _v2) {
Box* longGe(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__ge__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
raiseExcHelper(TypeError, "descriptor '__ge__' requires a 'long' object but received a '%s'", getTypeName(v1));
if (isSubclass(_v2->cls, long_cls)) {
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
......@@ -563,8 +555,7 @@ Box* longGe(BoxedLong* v1, Box* _v2) {
Box* longLt(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__lt__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
raiseExcHelper(TypeError, "descriptor '__lt__' requires a 'long' object but received a '%s'", getTypeName(v1));
if (isSubclass(_v2->cls, long_cls)) {
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
......@@ -581,8 +572,7 @@ Box* longLt(BoxedLong* v1, Box* _v2) {
Box* longLe(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__le__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
raiseExcHelper(TypeError, "descriptor '__le__' requires a 'long' object but received a '%s'", getTypeName(v1));
if (isSubclass(_v2->cls, long_cls)) {
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
......@@ -599,8 +589,7 @@ Box* longLe(BoxedLong* v1, Box* _v2) {
Box* longEq(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__eq__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
raiseExcHelper(TypeError, "descriptor '__eq__' requires a 'long' object but received a '%s'", getTypeName(v1));
if (isSubclass(_v2->cls, long_cls)) {
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
......@@ -617,8 +606,7 @@ Box* longEq(BoxedLong* v1, Box* _v2) {
Box* longNe(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__ne__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
raiseExcHelper(TypeError, "descriptor '__ne__' requires a 'long' object but received a '%s'", getTypeName(v1));
if (isSubclass(_v2->cls, long_cls)) {
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
......@@ -636,7 +624,7 @@ Box* longNe(BoxedLong* v1, Box* _v2) {
Box* longLshift(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__lshift__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
getTypeName(v1));
if (isSubclass(_v2->cls, long_cls)) {
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
......@@ -666,7 +654,7 @@ Box* longLshift(BoxedLong* v1, Box* _v2) {
Box* longRshift(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__rshift__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
getTypeName(v1));
if (isSubclass(_v2->cls, long_cls)) {
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
......@@ -695,8 +683,7 @@ Box* longRshift(BoxedLong* v1, Box* _v2) {
Box* longSub(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__sub__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
raiseExcHelper(TypeError, "descriptor '__sub__' requires a 'long' object but received a '%s'", getTypeName(v1));
if (isSubclass(_v2->cls, long_cls)) {
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
......@@ -723,15 +710,14 @@ Box* longSub(BoxedLong* v1, Box* _v2) {
Box* longRsub(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__rsub__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
getTypeName(v1));
return longAdd(static_cast<BoxedLong*>(longNeg(v1)), _v2);
}
Box* longMul(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__mul__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
raiseExcHelper(TypeError, "descriptor '__mul__' requires a 'long' object but received a '%s'", getTypeName(v1));
if (isSubclass(_v2->cls, long_cls)) {
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
......@@ -754,8 +740,7 @@ Box* longMul(BoxedLong* v1, Box* _v2) {
Box* longDiv(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__div__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
raiseExcHelper(TypeError, "descriptor '__div__' requires a 'long' object but received a '%s'", getTypeName(v1));
if (isSubclass(_v2->cls, long_cls)) {
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
......@@ -785,7 +770,7 @@ Box* longDiv(BoxedLong* v1, Box* _v2) {
extern "C" Box* longDivmod(BoxedLong* lhs, Box* _rhs) {
if (!isSubclass(lhs->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__div__' requires a 'long' object but received a '%s'",
getTypeName(lhs)->c_str());
getTypeName(lhs));
if (isSubclass(_rhs->cls, long_cls)) {
BoxedLong* rhs = static_cast<BoxedLong*>(_rhs);
......@@ -818,8 +803,7 @@ extern "C" Box* longDivmod(BoxedLong* lhs, Box* _rhs) {
Box* longRdiv(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__div__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
raiseExcHelper(TypeError, "descriptor '__div__' requires a 'long' object but received a '%s'", getTypeName(v1));
if (mpz_cmp_si(v1->n, 0) == 0)
raiseExcHelper(ZeroDivisionError, "long division or modulo by zero");
......@@ -845,8 +829,7 @@ Box* longRdiv(BoxedLong* v1, Box* _v2) {
Box* longPow(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__pow__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
raiseExcHelper(TypeError, "descriptor '__pow__' requires a 'long' object but received a '%s'", getTypeName(v1));
if (!isSubclass(_v2->cls, long_cls))
return NotImplemented;
......@@ -866,7 +849,7 @@ Box* longPow(BoxedLong* v1, Box* _v2) {
Box* longNonzero(BoxedLong* self) {
if (!isSubclass(self->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__pow__' requires a 'long' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
if (mpz_cmp_si(self->n, 0) == 0)
return False;
......@@ -876,7 +859,7 @@ Box* longNonzero(BoxedLong* self) {
Box* longHash(BoxedLong* self) {
if (!isSubclass(self->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__pow__' requires a 'long' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
// Not sure if this is a good hash function or not;
// simple, but only includes top bits:
......@@ -903,8 +886,6 @@ void customised_free(void* ptr, size_t size) {
void setupLong() {
mp_set_memory_functions(customised_allocation, customised_realloc, customised_free);
long_cls->giveAttr("__name__", boxStrConstant("long"));
long_cls->giveAttr(
"__new__", new BoxedFunction(boxRTFunction((void*)longNew, UNKNOWN, 3, 2, false, false), { boxInt(0), NULL }));
......
......@@ -234,9 +234,9 @@ extern "C" void raiseAttributeError(Box* obj, const char* attr) {
if (obj->cls == type_cls) {
// Slightly different error message:
raiseExcHelper(AttributeError, "type object '%s' has no attribute '%s'",
getNameOfClass(static_cast<BoxedClass*>(obj))->c_str(), attr);
getNameOfClass(static_cast<BoxedClass*>(obj)), attr);
} else {
raiseAttributeErrorStr(getTypeName(obj)->c_str(), attr);
raiseAttributeErrorStr(getTypeName(obj), attr);
}
}
......@@ -286,7 +286,7 @@ extern "C" Box** unpackIntoArray(Box* obj, int64_t expected_size) {
void BoxedClass::freeze() {
assert(!is_constant);
assert(getattr("__name__")); // otherwise debugging will be very hard
assert(tp_name); // otherwise debugging will be very hard
fixup_slot_dispatchers(this);
......@@ -356,10 +356,21 @@ BoxedClass::BoxedClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset
gc::registerPermanentRoot(this);
}
BoxedHeapClass::BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size,
bool is_user_defined, const std::string& name)
: BoxedHeapClass(base, gc_visit, attrs_offset, instance_size, is_user_defined, new BoxedString(name)) {
}
BoxedHeapClass::BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size,
bool is_user_defined)
: BoxedClass(base, gc_visit, attrs_offset, instance_size, is_user_defined), ht_name(NULL), ht_slots(NULL) {
// This constructor is only used for bootstrapping purposes to be called for types that
// are initialized before str_cls.
// Therefore, we assert that str_cls is uninitialized to make sure this isn't called at
// an inappropriate time.
assert(str_cls == NULL);
tp_as_number = &as_number;
tp_as_mapping = &as_mapping;
tp_as_sequence = &as_sequence;
......@@ -371,38 +382,45 @@ BoxedHeapClass::BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attr
memset(&as_buffer, 0, sizeof(as_buffer));
}
std::string getFullNameOfClass(BoxedClass* cls) {
Box* b = cls->getattr("__name__");
assert(b);
ASSERT(b->cls == str_cls, "%p", b->cls);
BoxedString* name = static_cast<BoxedString*>(b);
BoxedHeapClass::BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size,
bool is_user_defined, BoxedString* name)
: BoxedClass(base, gc_visit, attrs_offset, instance_size, is_user_defined), ht_name(name), ht_slots(NULL) {
b = cls->getattr("__module__");
tp_as_number = &as_number;
tp_as_mapping = &as_mapping;
tp_as_sequence = &as_sequence;
tp_as_buffer = &as_buffer;
tp_name = ht_name->s.c_str();
memset(&as_number, 0, sizeof(as_number));
memset(&as_mapping, 0, sizeof(as_mapping));
memset(&as_sequence, 0, sizeof(as_sequence));
memset(&as_buffer, 0, sizeof(as_buffer));
}
std::string getFullNameOfClass(BoxedClass* cls) {
Box* b = cls->getattr("__module__");
if (!b)
return name->s;
return cls->tp_name;
assert(b);
if (b->cls != str_cls)
return name->s;
return cls->tp_name;
BoxedString* module = static_cast<BoxedString*>(b);
return module->s + "." + name->s;
return module->s + "." + cls->tp_name;
}
std::string getFullTypeName(Box* o) {
return getFullNameOfClass(o->cls);
}
extern "C" const std::string* getNameOfClass(BoxedClass* cls) {
Box* b = cls->getattr("__name__");
assert(b);
ASSERT(b->cls == str_cls, "%p", b->cls);
BoxedString* sb = static_cast<BoxedString*>(b);
return &sb->s;
const char* getTypeName(Box* b) {
return b->cls->tp_name;
}
extern "C" const std::string* getTypeName(Box* o) {
return getNameOfClass(o->cls);
const char* getNameOfClass(BoxedClass* cls) {
return cls->tp_name;
}
HiddenClass* HiddenClass::getOrMakeChild(const std::string& attr) {
......@@ -965,6 +983,38 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, const
return runtimeCallInternal1(prop->prop_get, NULL, ArgPassSpec(1), obj);
}
// Special case: data descriptor: getset descriptor
else if (descr->cls == getset_cls) {
BoxedGetsetDescriptor* getset_descr = static_cast<BoxedGetsetDescriptor*>(descr);
// TODO some more checks should go here
// getset descriptors (and some other types of builtin descriptors I think) should have
// a field which gives the type that the descriptor should apply to. We need to check that obj
// is of that type.
if (getset_descr->get == NULL) {
raiseExcHelper(AttributeError, "attribute '%s' of '%s' object is not readable", attr_name.c_str(),
getTypeName(getset_descr));
}
// Abort because right now we can't call twice in a rewrite
if (for_call) {
rewrite_args = NULL;
}
if (rewrite_args) {
// hmm, maybe we should write assembly which can look up the function address and call any function
r_descr->addAttrGuard(offsetof(BoxedGetsetDescriptor, get), (intptr_t)getset_descr->get);
RewriterVar* r_closure = r_descr->getAttr(offsetof(BoxedGetsetDescriptor, closure));
rewrite_args->out_rtn = rewrite_args->rewriter->call(
/* can_call_into_python */ true, (void*)getset_descr->get, rewrite_args->obj, r_closure);
rewrite_args->out_success = true;
}
return getset_descr->get(obj, getset_descr->closure);
}
return NULL;
}
......@@ -1009,7 +1059,7 @@ extern "C" Box* getclsattr(Box* obj, const char* attr) {
else {
gotten = getclsattr_internal(obj, attr, NULL);
}
RELEASE_ASSERT(gotten, "%s:%s", getTypeName(obj)->c_str(), attr);
RELEASE_ASSERT(gotten, "%s:%s", getTypeName(obj), attr);
return gotten;
}
......@@ -1567,8 +1617,7 @@ extern "C" void setattr(Box* obj, const char* attr, Box* attr_val) {
if (obj->cls == type_cls) {
BoxedClass* cobj = static_cast<BoxedClass*>(obj);
if (!isUserDefined(cobj)) {
raiseExcHelper(TypeError, "can't set attributes of built-in/extension type '%s'",
getNameOfClass(cobj)->c_str());
raiseExcHelper(TypeError, "can't set attributes of built-in/extension type '%s'", getNameOfClass(cobj));
}
}
......@@ -1660,7 +1709,7 @@ extern "C" bool nonzero(Box* obj) {
ASSERT(isUserDefined(obj->cls) || obj->cls == classobj_cls || obj->cls == type_cls
|| isSubclass(obj->cls, Exception) || obj->cls == file_cls,
"%s.__nonzero__",
getTypeName(obj)->c_str()); // TODO
getTypeName(obj)); // TODO
return true;
}
......@@ -1675,7 +1724,7 @@ extern "C" bool nonzero(Box* obj) {
bool rtn = b->n != 0;
return rtn;
} else {
raiseExcHelper(TypeError, "__nonzero__ should return bool or int, returned %s", getTypeName(r)->c_str());
raiseExcHelper(TypeError, "__nonzero__ should return bool or int, returned %s", getTypeName(r));
}
}
......@@ -1766,7 +1815,7 @@ extern "C" BoxedInt* hash(Box* obj) {
Box* hash = getclsattr_internal(obj, "__hash__", NULL);
if (hash == NULL) {
ASSERT(isUserDefined(obj->cls), "%s.__hash__", getTypeName(obj)->c_str());
ASSERT(isUserDefined(obj->cls), "%s.__hash__", getTypeName(obj));
// TODO not the best way to handle this...
return static_cast<BoxedInt*>(boxInt((i64)obj));
}
......@@ -1792,7 +1841,7 @@ extern "C" BoxedInt* lenInternal(Box* obj, LenRewriteArgs* rewrite_args) {
}
if (rtn == NULL) {
raiseExcHelper(TypeError, "object of type '%s' has no len()", getTypeName(obj)->c_str());
raiseExcHelper(TypeError, "object of type '%s' has no len()", getTypeName(obj));
}
if (rtn->cls != int_cls) {
......@@ -2076,7 +2125,7 @@ extern "C" Box* callattrInternal(Box* obj, const std::string* attr, LookupScope
}
if (!rtn) {
raiseExcHelper(TypeError, "'%s' object is not callable", getTypeName(val)->c_str());
raiseExcHelper(TypeError, "'%s' object is not callable", getTypeName(val));
}
if (rewrite_args)
......@@ -2598,7 +2647,7 @@ Box* runtimeCallInternal(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec ar
rtn = callattrInternal(obj, &call_str, CLASS_ONLY, NULL, argspec, arg1, arg2, arg3, args, keyword_names);
}
if (!rtn)
raiseExcHelper(TypeError, "'%s' object is not callable", getTypeName(obj)->c_str());
raiseExcHelper(TypeError, "'%s' object is not callable", getTypeName(obj));
return rtn;
}
......@@ -2850,24 +2899,23 @@ extern "C" Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, Bin
if (inplace) {
std::string iop_name = getInplaceOpName(op_type);
if (irtn)
fprintf(stderr, "%s has %s, but returned NotImplemented\n", getTypeName(lhs)->c_str(),
iop_name.c_str());
fprintf(stderr, "%s has %s, but returned NotImplemented\n", getTypeName(lhs), iop_name.c_str());
else
fprintf(stderr, "%s does not have %s\n", getTypeName(lhs)->c_str(), iop_name.c_str());
fprintf(stderr, "%s does not have %s\n", getTypeName(lhs), iop_name.c_str());
}
if (lrtn)
fprintf(stderr, "%s has %s, but returned NotImplemented\n", getTypeName(lhs)->c_str(), op_name.c_str());
fprintf(stderr, "%s has %s, but returned NotImplemented\n", getTypeName(lhs), op_name.c_str());
else
fprintf(stderr, "%s does not have %s\n", getTypeName(lhs)->c_str(), op_name.c_str());
fprintf(stderr, "%s does not have %s\n", getTypeName(lhs), op_name.c_str());
if (rrtn)
fprintf(stderr, "%s has %s, but returned NotImplemented\n", getTypeName(rhs)->c_str(), rop_name.c_str());
fprintf(stderr, "%s has %s, but returned NotImplemented\n", getTypeName(rhs), rop_name.c_str());
else
fprintf(stderr, "%s does not have %s\n", getTypeName(rhs)->c_str(), rop_name.c_str());
fprintf(stderr, "%s does not have %s\n", getTypeName(rhs), rop_name.c_str());
}
raiseExcHelper(TypeError, "unsupported operand type(s) for %s%s: '%s' and '%s'", op_sym.data(), op_sym_suffix,
getTypeName(lhs)->c_str(), getTypeName(rhs)->c_str());
getTypeName(lhs), getTypeName(rhs));
}
extern "C" Box* binop(Box* lhs, Box* rhs, int op_type) {
......@@ -2962,15 +3010,15 @@ Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrit
if (contained == NULL) {
Box* iter = callattrInternal0(rhs, &iter_str, CLASS_ONLY, NULL, ArgPassSpec(0));
if (iter)
ASSERT(isUserDefined(rhs->cls), "%s should probably have a __contains__", getTypeName(rhs)->c_str());
ASSERT(isUserDefined(rhs->cls), "%s should probably have a __contains__", getTypeName(rhs));
RELEASE_ASSERT(iter == NULL, "need to try iterating");
Box* getitem = typeLookup(rhs->cls, getitem_str, NULL);
if (getitem)
ASSERT(isUserDefined(rhs->cls), "%s should probably have a __contains__", getTypeName(rhs)->c_str());
ASSERT(isUserDefined(rhs->cls), "%s should probably have a __contains__", getTypeName(rhs));
RELEASE_ASSERT(getitem == NULL, "need to try old iteration protocol");
raiseExcHelper(TypeError, "argument of type '%s' is not iterable", getTypeName(rhs)->c_str());
raiseExcHelper(TypeError, "argument of type '%s' is not iterable", getTypeName(rhs));
}
bool b = nonzero(contained);
......@@ -3111,7 +3159,7 @@ extern "C" Box* unaryop(Box* operand, int op_type) {
Box* attr_func = getclsattr_internal(operand, op_name, NULL);
ASSERT(attr_func, "%s.%s", getTypeName(operand)->c_str(), op_name.c_str());
ASSERT(attr_func, "%s.%s", getTypeName(operand), op_name.c_str());
Box* rtn = runtimeCall0(attr_func, ArgPassSpec(0));
return rtn;
......@@ -3146,14 +3194,13 @@ extern "C" Box* getitem(Box* value, Box* slice) {
if (rtn == NULL) {
// different versions of python give different error messages for this:
if (PYTHON_VERSION_MAJOR == 2 && PYTHON_VERSION_MINOR < 7) {
raiseExcHelper(TypeError, "'%s' object is unsubscriptable", getTypeName(value)->c_str()); // tested on 2.6.6
raiseExcHelper(TypeError, "'%s' object is unsubscriptable", getTypeName(value)); // tested on 2.6.6
} else if (PYTHON_VERSION_MAJOR == 2 && PYTHON_VERSION_MINOR == 7 && PYTHON_VERSION_MICRO < 3) {
raiseExcHelper(TypeError, "'%s' object is not subscriptable",
getTypeName(value)->c_str()); // tested on 2.7.1
raiseExcHelper(TypeError, "'%s' object is not subscriptable", getTypeName(value)); // tested on 2.7.1
} else {
// Changed to this in 2.7.3:
raiseExcHelper(TypeError, "'%s' object has no attribute '__getitem__'",
getTypeName(value)->c_str()); // tested on 2.7.3
getTypeName(value)); // tested on 2.7.3
}
}
......@@ -3184,7 +3231,7 @@ extern "C" void setitem(Box* target, Box* slice, Box* value) {
}
if (rtn == NULL) {
raiseExcHelper(TypeError, "'%s' object does not support item assignment", getTypeName(target)->c_str());
raiseExcHelper(TypeError, "'%s' object does not support item assignment", getTypeName(target));
}
if (rewriter.get()) {
......@@ -3216,7 +3263,7 @@ extern "C" void delitem(Box* target, Box* slice) {
}
if (rtn == NULL) {
raiseExcHelper(TypeError, "'%s' object does not support item deletion", getTypeName(target)->c_str());
raiseExcHelper(TypeError, "'%s' object does not support item deletion", getTypeName(target));
}
if (rewriter.get()) {
......@@ -3286,8 +3333,7 @@ extern "C" void delattr_internal(Box* obj, const std::string& attr, bool allow_c
} else {
// the exception cpthon throws is different when the class contains the attribute
if (clsAttr != NULL) {
raiseExcHelper(AttributeError, "'%s' object attribute '%s' is read-only", getTypeName(obj)->c_str(),
attr.c_str());
raiseExcHelper(AttributeError, "'%s' object attribute '%s' is read-only", getTypeName(obj), attr.c_str());
} else {
raiseAttributeError(obj, attr.c_str());
}
......@@ -3302,8 +3348,7 @@ extern "C" void delattr(Box* obj, const char* attr) {
if (obj->cls == type_cls) {
BoxedClass* cobj = static_cast<BoxedClass*>(obj);
if (!isUserDefined(cobj)) {
raiseExcHelper(TypeError, "can't set attributes of built-in/extension type '%s'\n",
getNameOfClass(cobj)->c_str());
raiseExcHelper(TypeError, "can't set attributes of built-in/extension type '%s'\n", getNameOfClass(cobj));
}
}
......@@ -3328,7 +3373,7 @@ Box* getiter(Box* o) {
return new BoxedSeqIter(o);
}
raiseExcHelper(TypeError, "'%s' object is not iterable", getTypeName(o)->c_str());
raiseExcHelper(TypeError, "'%s' object is not iterable", getTypeName(o));
}
llvm::iterator_range<BoxIterator> Box::pyElements() {
......@@ -3341,7 +3386,7 @@ llvm::iterator_range<BoxIterator> Box::pyElements() {
// For use on __init__ return values
static void assertInitNone(Box* obj) {
if (obj != None) {
raiseExcHelper(TypeError, "__init__() should return None, not '%s'", getTypeName(obj)->c_str());
raiseExcHelper(TypeError, "__init__() should return None, not '%s'", getTypeName(obj));
}
}
......@@ -3349,12 +3394,12 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
Box* arg3 = _args[0];
if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "type.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
raiseExcHelper(TypeError, "type.__new__(X): X is not a type object (%s)", getTypeName(_cls));
BoxedClass* cls = static_cast<BoxedClass*>(_cls);
if (!isSubclass(cls, type_cls))
raiseExcHelper(TypeError, "type.__new__(%s): %s is not a subtype of type", getNameOfClass(cls)->c_str(),
getNameOfClass(cls)->c_str());
raiseExcHelper(TypeError, "type.__new__(%s): %s is not a subtype of type", getNameOfClass(cls),
getNameOfClass(cls));
if (arg2 == NULL) {
assert(arg3 == NULL);
......@@ -3362,7 +3407,7 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
return rtn;
}
RELEASE_ASSERT(arg3->cls == dict_cls, "%s", getTypeName(arg3)->c_str());
RELEASE_ASSERT(arg3->cls == dict_cls, "%s", getTypeName(arg3));
BoxedDict* attr_dict = static_cast<BoxedDict*>(arg3);
RELEASE_ASSERT(arg2->cls == tuple_cls, "");
......@@ -3388,10 +3433,11 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
BoxedClass* made;
if (base->instancesHaveDictAttrs() || base->instancesHaveHCAttrs()) {
made = new (cls) BoxedHeapClass(base, NULL, base->attrs_offset, base->tp_basicsize, true);
made = new (cls) BoxedHeapClass(base, NULL, base->attrs_offset, base->tp_basicsize, true, name);
} else {
assert(base->tp_basicsize % sizeof(void*) == 0);
made = new (cls) BoxedHeapClass(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, name);
}
made->tp_dictoffset = base->tp_dictoffset;
......@@ -3403,9 +3449,6 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
made->setattr(static_cast<BoxedString*>(p.first)->s, p.second, NULL);
}
// Note: make sure to do this after assigning the attrs, since it will overwrite any defined __name__
made->setattr("__name__", name, NULL);
made->tp_new = base->tp_new;
PystonType_Ready(made);
......@@ -3471,7 +3514,7 @@ Box* typeCallInternal(BoxedFunction* f, CallRewriteArgs* rewrite_args, ArgPassSp
if (!isSubclass(_cls->cls, type_cls)) {
raiseExcHelper(TypeError, "descriptor '__call__' requires a 'type' object but received an '%s'",
getTypeName(_cls)->c_str());
getTypeName(_cls));
}
BoxedClass* cls = static_cast<BoxedClass*>(_cls);
......@@ -3831,7 +3874,7 @@ extern "C" Box* importStar(Box* _from_module, BoxedModule* to_module) {
if (all) {
Box* all_getitem = typeLookup(all->cls, getitem_str, NULL);
if (!all_getitem)
raiseExcHelper(TypeError, "'%s' object does not support indexing", getTypeName(all)->c_str());
raiseExcHelper(TypeError, "'%s' object does not support indexing", getTypeName(all));
int idx = 0;
while (true) {
......@@ -3846,7 +3889,7 @@ extern "C" Box* importStar(Box* _from_module, BoxedModule* to_module) {
idx++;
if (attr_name->cls != str_cls)
raiseExcHelper(TypeError, "attribute name must be string, not '%s'", getTypeName(attr_name)->c_str());
raiseExcHelper(TypeError, "attribute name must be string, not '%s'", getTypeName(attr_name));
BoxedString* casted_attr_name = static_cast<BoxedString*>(attr_name);
Box* attr_value = from_module->getattr(casted_attr_name->s);
......
......@@ -251,11 +251,7 @@ Box* setNonzero(BoxedSet* self) {
using namespace pyston::set;
void setupSet() {
set_cls->giveAttr("__name__", boxStrConstant("set"));
frozenset_cls->giveAttr("__name__", boxStrConstant("frozenset"));
set_iterator_cls = new BoxedHeapClass(object_cls, &setIteratorGCHandler, 0, sizeof(BoxedSet), false);
set_iterator_cls->giveAttr("__name__", boxStrConstant("setiterator"));
set_iterator_cls = new BoxedHeapClass(object_cls, &setIteratorGCHandler, 0, sizeof(BoxedSet), false, "setiterator");
set_iterator_cls->giveAttr("__hasnext__",
new BoxedFunction(boxRTFunction((void*)setiteratorHasnext, BOXED_BOOL, 1)));
set_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)setiteratorNext, UNKNOWN, 1)));
......
......@@ -233,14 +233,14 @@ void raise0() {
ExcInfo::ExcInfo(Box* type, Box* value, Box* traceback) : type(type), value(value), traceback(traceback) {
if (this->type && this->type != None)
RELEASE_ASSERT(isSubclass(this->type->cls, type_cls), "throwing old-style objects not supported yet (%s)",
getTypeName(this->type)->c_str());
getTypeName(this->type));
}
#endif
bool ExcInfo::matches(BoxedClass* cls) const {
assert(this->type);
RELEASE_ASSERT(isSubclass(this->type->cls, type_cls), "throwing old-style objects not supported yet (%s)",
getTypeName(this->type)->c_str());
getTypeName(this->type));
return isSubclass(static_cast<BoxedClass*>(this->type), cls);
}
......@@ -267,7 +267,7 @@ void raise3(Box* arg0, Box* arg1, Box* arg2) {
}
raiseExcHelper(TypeError, "exceptions must be old-style classes or derived from BaseException, not %s",
getTypeName(arg0)->c_str());
getTypeName(arg0));
}
void raiseExcHelper(BoxedClass* cls, const char* msg, ...) {
......@@ -295,16 +295,16 @@ void raiseExcHelper(BoxedClass* cls, const char* msg, ...) {
}
std::string formatException(Box* b) {
const std::string* name = getTypeName(b);
std::string name = getTypeName(b);
BoxedString* r = strOrNull(b);
if (!r)
return *name;
return name;
assert(r->cls == str_cls);
const std::string* msg = &r->s;
if (msg->size())
return *name + ": " + *msg;
return *name;
return name + ": " + *msg;
return name;
}
}
......@@ -274,7 +274,7 @@ extern "C" BoxedString* strAdd(BoxedString* lhs, Box* _rhs) {
assert(lhs->cls == str_cls);
if (_rhs->cls != str_cls) {
raiseExcHelper(TypeError, "cannot concatenate 'str' and '%s' objects", getTypeName(_rhs)->c_str());
raiseExcHelper(TypeError, "cannot concatenate 'str' and '%s' objects", getTypeName(_rhs));
}
BoxedString* rhs = static_cast<BoxedString*>(_rhs);
......@@ -1537,7 +1537,7 @@ Box* strSwapcase(BoxedString* self) {
Box* strContains(BoxedString* self, Box* elt) {
assert(self->cls == str_cls);
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "'in <string>' requires string as left operand, not %s", getTypeName(elt)->c_str());
raiseExcHelper(TypeError, "'in <string>' requires string as left operand, not %s", getTypeName(elt));
BoxedString* sub = static_cast<BoxedString*>(elt);
......@@ -1552,7 +1552,7 @@ Box* strStartswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
if (self->cls != str_cls)
raiseExcHelper(TypeError, "descriptor 'startswith' requires a 'str' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
......@@ -1597,7 +1597,7 @@ Box* strEndswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
if (self->cls != str_cls)
raiseExcHelper(TypeError, "descriptor 'endswith' requires a 'str' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
......@@ -1641,8 +1641,7 @@ Box* strEndswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
Box* strFind(BoxedString* self, Box* elt, Box* _start) {
if (self->cls != str_cls)
raiseExcHelper(TypeError, "descriptor 'find' requires a 'str' object but received a '%s'",
getTypeName(self)->c_str());
raiseExcHelper(TypeError, "descriptor 'find' requires a 'str' object but received a '%s'", getTypeName(self));
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
......@@ -1669,8 +1668,7 @@ Box* strFind(BoxedString* self, Box* elt, Box* _start) {
Box* strRfind(BoxedString* self, Box* elt) {
if (self->cls != str_cls)
raiseExcHelper(TypeError, "descriptor 'rfind' requires a 'str' object but received a '%s'",
getTypeName(self)->c_str());
raiseExcHelper(TypeError, "descriptor 'rfind' requires a 'str' object but received a '%s'", getTypeName(self));
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
......@@ -1707,7 +1705,7 @@ extern "C" Box* strGetitem(BoxedString* self, Box* slice) {
parseSlice(sslice, self->s.size(), &start, &stop, &step, &length);
return _strSlice(self, start, stop, step, length);
} else {
raiseExcHelper(TypeError, "string indices must be integers, not %s", getTypeName(slice)->c_str());
raiseExcHelper(TypeError, "string indices must be integers, not %s", getTypeName(slice));
}
}
......@@ -1868,8 +1866,8 @@ static PyBufferProcs string_as_buffer = {
};
void setupStr() {
str_iterator_cls = new BoxedHeapClass(object_cls, &strIteratorGCHandler, 0, sizeof(BoxedStringIterator), false);
str_iterator_cls->giveAttr("__name__", boxStrConstant("striterator"));
str_iterator_cls
= new BoxedHeapClass(object_cls, &strIteratorGCHandler, 0, sizeof(BoxedStringIterator), false, "striterator");
str_iterator_cls->giveAttr("__hasnext__",
new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::hasnext, BOXED_BOOL, 1)));
str_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::next, STR, 1)));
......@@ -1877,8 +1875,6 @@ void setupStr() {
str_cls->tp_as_buffer = &string_as_buffer;
str_cls->giveAttr("__name__", boxStrConstant("str"));
str_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)strLen, BOXED_INT, 1)));
str_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)strStr, STR, 1)));
str_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)strRepr, STR, 1)));
......@@ -1970,7 +1966,6 @@ void setupStr() {
"__doc__", boxStrConstant("Type basestring cannot be instantiated; it is the base for str and unicode."));
basestring_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)basestringNew, UNKNOWN, 1, 0, true, true)));
basestring_cls->giveAttr("__name__", boxStrConstant("basestring"));
basestring_cls->freeze();
}
......
......@@ -84,10 +84,10 @@ Box* superRepr(Box* _s) {
BoxedSuper* s = static_cast<BoxedSuper*>(_s);
if (s->obj_type) {
return boxString("<super: <class '" + (s->type ? *getNameOfClass(s->type) : "NULL") + "'>, <"
+ *getNameOfClass(s->obj_type) + " object>>");
return boxString("<super: <class '" + std::string(s->type ? getNameOfClass(s->type) : "NULL") + "'>, <"
+ std::string(getNameOfClass(s->obj_type)) + " object>>");
} else {
return boxString("<super: <class '" + (s->type ? *getNameOfClass(s->type) : "NULL") + "'>, <NULL>>");
return boxString("<super: <class '" + std::string(s->type ? getNameOfClass(s->type) : "NULL") + "'>, <NULL>>");
}
}
......@@ -115,7 +115,7 @@ Box* superInit(Box* _self, Box* _type, Box* obj) {
BoxedSuper* self = static_cast<BoxedSuper*>(_self);
if (!isSubclass(_type->cls, type_cls))
raiseExcHelper(TypeError, "must be type, not %s", getTypeName(_type)->c_str());
raiseExcHelper(TypeError, "must be type, not %s", getTypeName(_type));
BoxedClass* type = static_cast<BoxedClass*>(_type);
BoxedClass* obj_type = NULL;
......@@ -132,9 +132,7 @@ Box* superInit(Box* _self, Box* _type, Box* obj) {
}
void setupSuper() {
super_cls = new BoxedHeapClass(object_cls, &BoxedSuper::gcHandler, 0, sizeof(BoxedSuper), false);
super_cls->giveAttr("__name__", boxStrConstant("super"));
super_cls = new BoxedHeapClass(object_cls, &BoxedSuper::gcHandler, 0, sizeof(BoxedSuper), false, "super");
super_cls->giveAttr("__getattribute__", new BoxedFunction(boxRTFunction((void*)superGetattribute, UNKNOWN, 2)));
super_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)superRepr, STR, 1)));
......
......@@ -113,7 +113,7 @@ Box* tupleGetitem(BoxedTuple* self, Box* slice) {
else if (slice->cls == slice_cls)
return tupleGetitemSlice(self, static_cast<BoxedSlice*>(slice));
else
raiseExcHelper(TypeError, "tuple indices must be integers, not %s", getTypeName(slice)->c_str());
raiseExcHelper(TypeError, "tuple indices must be integers, not %s", getTypeName(slice));
}
Box* tupleAdd(BoxedTuple* self, Box* rhs) {
......@@ -130,7 +130,7 @@ Box* tupleAdd(BoxedTuple* self, Box* rhs) {
Box* tupleMul(BoxedTuple* self, Box* rhs) {
if (rhs->cls != int_cls) {
raiseExcHelper(TypeError, "can't multiply sequence by non-int of type '%s'", getTypeName(rhs)->c_str());
raiseExcHelper(TypeError, "can't multiply sequence by non-int of type '%s'", getTypeName(rhs));
}
int n = static_cast<BoxedInt*>(rhs)->n;
......@@ -298,12 +298,12 @@ Box* tupleHash(BoxedTuple* self) {
extern "C" Box* tupleNew(Box* _cls, BoxedTuple* args, BoxedDict* kwargs) {
if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "tuple.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
raiseExcHelper(TypeError, "tuple.__new__(X): X is not a type object (%s)", getTypeName(_cls));
BoxedClass* cls = static_cast<BoxedClass*>(_cls);
if (!isSubclass(cls, tuple_cls))
raiseExcHelper(TypeError, "tuple.__new__(%s): %s is not a subtype of tuple", getNameOfClass(cls)->c_str(),
getNameOfClass(cls)->c_str());
raiseExcHelper(TypeError, "tuple.__new__(%s): %s is not a subtype of tuple", getNameOfClass(cls),
getNameOfClass(cls));
RELEASE_ASSERT(cls == tuple_cls, "");
......@@ -382,9 +382,7 @@ extern "C" void tupleIteratorGCHandler(GCVisitor* v, Box* b) {
void setupTuple() {
tuple_iterator_cls = new BoxedHeapClass(object_cls, &tupleIteratorGCHandler, 0, sizeof(BoxedTuple), false);
tuple_cls->giveAttr("__name__", boxStrConstant("tuple"));
tuple_iterator_cls = new BoxedHeapClass(object_cls, &tupleIteratorGCHandler, 0, sizeof(BoxedTuple), false, "tuple");
tuple_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)tupleNew, UNKNOWN, 1, 0, true, true)));
CLFunction* getitem = createRTFunction(2, 0, 0, 0);
......@@ -418,8 +416,6 @@ void setupTuple() {
tuple_cls->freeze();
tuple_iterator_cls->giveAttr("__name__", boxStrConstant("tupleiterator"));
CLFunction* hasnext = boxRTFunction((void*)tupleiterHasnextUnboxed, BOOL, 1);
addRTFunction(hasnext, (void*)tupleiterHasnext, BOXED_BOOL);
tuple_iterator_cls->giveAttr("__hasnext__", new BoxedFunction(hasnext));
......
......@@ -268,10 +268,6 @@ std::string builtinStr("__builtin__");
extern "C" BoxedFunction::BoxedFunction(CLFunction* f)
: f(f), closure(NULL), isGenerator(false), ndefaults(0), defaults(NULL) {
if (f->source) {
assert(f->source->ast);
// this->giveAttr("__name__", boxString(&f->source->ast->name));
this->giveAttr("__name__", boxString(f->source->getName()));
this->modname = f->source->parent_module->getattr("__name__", NULL);
} else {
this->modname = boxStringPtr(&builtinStr);
......@@ -294,10 +290,6 @@ extern "C" BoxedFunction::BoxedFunction(CLFunction* f, std::initializer_list<Box
}
if (f->source) {
assert(f->source->ast);
// this->giveAttr("__name__", boxString(&f->source->ast->name));
this->giveAttr("__name__", boxString(f->source->getName()));
this->modname = f->source->parent_module->getattr("__name__", NULL);
} else {
this->modname = boxStringPtr(&builtinStr);
......@@ -500,17 +492,17 @@ extern "C" void closureGCHandler(GCVisitor* v, Box* b) {
}
extern "C" {
BoxedClass* object_cls, *type_cls, *none_cls, *bool_cls, *int_cls, *float_cls, *str_cls, *function_cls,
*instancemethod_cls, *list_cls, *slice_cls, *module_cls, *dict_cls, *tuple_cls, *file_cls, *member_cls,
*closure_cls, *generator_cls, *complex_cls, *basestring_cls, *unicode_cls, *property_cls, *staticmethod_cls,
*classmethod_cls, *attrwrapper_cls;
BoxedClass* object_cls, *type_cls, *none_cls, *bool_cls, *int_cls, *float_cls,
* str_cls = NULL, *function_cls, *instancemethod_cls, *list_cls, *slice_cls, *module_cls, *dict_cls, *tuple_cls,
*file_cls, *member_cls, *closure_cls, *generator_cls, *complex_cls, *basestring_cls, *unicode_cls, *property_cls,
*staticmethod_cls, *classmethod_cls, *attrwrapper_cls, *getset_cls;
BoxedTuple* EmptyTuple;
}
extern "C" Box* createUserClass(const std::string* name, Box* _bases, Box* _attr_dict) {
ASSERT(_attr_dict->cls == dict_cls, "%s", getTypeName(_attr_dict)->c_str());
ASSERT(_attr_dict->cls == dict_cls, "%s", getTypeName(_attr_dict));
BoxedDict* attr_dict = static_cast<BoxedDict*>(_attr_dict);
assert(_bases->cls == tuple_cls);
......@@ -619,7 +611,7 @@ static Box* functionGet(BoxedFunction* self, Box* inst, Box* owner) {
}
static Box* functionCall(BoxedFunction* self, Box* args, Box* kwargs) {
RELEASE_ASSERT(self->cls == function_cls, "%s", getTypeName(self)->c_str());
RELEASE_ASSERT(self->cls == function_cls, "%s", getTypeName(self));
// This won't work if you subclass from function_cls, since runtimeCall will
// just call back into this function.
......@@ -631,6 +623,20 @@ static Box* functionCall(BoxedFunction* self, Box* args, Box* kwargs) {
return runtimeCall(self, ArgPassSpec(0, 0, true, true), args, kwargs, NULL, NULL, NULL);
}
static Box* func_name(Box* b, void*) {
assert(b->cls == function_cls);
BoxedFunction* func = static_cast<BoxedFunction*>(b);
// TODO this isn't right
// (For one thing, we need to able to *set* the __name__ of a function, but that probably
// should not involve setting the name in the source.)
return boxString(func->f->source->getName());
}
static int func_set_name(Box*, Box*, void*) {
RELEASE_ASSERT(0, "not implemented");
}
static Box* functionNonzero(BoxedFunction* self) {
return True;
}
......@@ -745,11 +751,7 @@ Box* typeRepr(BoxedClass* self) {
os << sm->s << '.';
}
Box* n = self->getattr("__name__");
RELEASE_ASSERT(n, "");
RELEASE_ASSERT(n->cls == str_cls, "should have prevented you from setting __name__ to non-string");
BoxedString* sn = static_cast<BoxedString*>(n);
os << sn->s;
os << self->tp_name;
os << "'>";
......@@ -941,9 +943,9 @@ Box* objectInit(Box* b, BoxedTuple* args) {
Box* objectRepr(Box* obj) {
char buf[80];
if (obj->cls == type_cls) {
snprintf(buf, 80, "<type '%s'>", getNameOfClass(static_cast<BoxedClass*>(obj))->c_str());
snprintf(buf, 80, "<type '%s'>", getNameOfClass(static_cast<BoxedClass*>(obj)));
} else {
snprintf(buf, 80, "<%s object at %p>", getTypeName(obj)->c_str(), obj);
snprintf(buf, 80, "<%s object at %p>", getTypeName(obj), obj);
}
return boxStrConstant(buf);
}
......@@ -952,6 +954,28 @@ Box* objectStr(Box* obj) {
return obj->reprIC();
}
static Box* type_name(Box* b, void*) {
assert(b->cls == type_cls);
BoxedClass* type = static_cast<BoxedClass*>(b);
// TODO is this predicate right?
if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
BoxedHeapClass* et = static_cast<BoxedHeapClass*>(type);
return et->ht_name;
} else {
const char* s = strrchr(type->tp_name, '.');
if (s == NULL)
s = type->tp_name;
else
s++;
return PyString_FromString(s);
}
}
static int type_set_name(Box* b, Box* v, void*) {
RELEASE_ASSERT(false, "not implemented");
}
// cls should be obj->cls.
// Added as parameter because it should typically be available
inline void initUserAttrs(Box* obj, BoxedClass* cls) {
......@@ -1007,7 +1031,23 @@ void setupRuntime() {
// TODO we leak all the string data!
str_cls = new BoxedHeapClass(basestring_cls, NULL, 0, sizeof(BoxedString), false);
unicode_cls = new BoxedHeapClass(basestring_cls, NULL, 0, sizeof(BoxedUnicode), false);
// Hold off on assigning names until str_cls is ready
object_cls->tp_name = "object";
BoxedString* boxed_type_name = new BoxedString("type");
BoxedString* boxed_basestring_name = new BoxedString("basestring");
BoxedString* boxed_str_name = new BoxedString("str");
BoxedString* boxed_none_name = new BoxedString("NoneType");
static_cast<BoxedHeapClass*>(type_cls)->ht_name = boxed_type_name;
static_cast<BoxedHeapClass*>(basestring_cls)->ht_name = boxed_basestring_name;
static_cast<BoxedHeapClass*>(str_cls)->ht_name = boxed_str_name;
static_cast<BoxedHeapClass*>(none_cls)->ht_name = boxed_none_name;
type_cls->tp_name = boxed_type_name->s.c_str();
basestring_cls->tp_name = boxed_basestring_name->s.c_str();
str_cls->tp_name = boxed_str_name->s.c_str();
none_cls->tp_name = boxed_none_name->s.c_str();
unicode_cls = new BoxedHeapClass(basestring_cls, NULL, 0, sizeof(BoxedUnicode), false, "unicode");
// It wasn't safe to add __base__ attributes until object+type+str are set up, so do that now:
type_cls->giveAttr("__base__", object_cls);
......@@ -1017,38 +1057,43 @@ void setupRuntime() {
object_cls->giveAttr("__base__", None);
tuple_cls = new BoxedHeapClass(object_cls, &tupleGCHandler, 0, sizeof(BoxedTuple), false);
tuple_cls = new BoxedHeapClass(object_cls, &tupleGCHandler, 0, sizeof(BoxedTuple), false, "tuple");
EmptyTuple = new BoxedTuple({});
gc::registerPermanentRoot(EmptyTuple);
module_cls = new BoxedHeapClass(object_cls, NULL, offsetof(BoxedModule, attrs), sizeof(BoxedModule), false);
module_cls
= new BoxedHeapClass(object_cls, NULL, offsetof(BoxedModule, attrs), sizeof(BoxedModule), false, "module");
// 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.
// We could have a multi-stage setup process, but that seems overkill for now.
int_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedInt), false);
bool_cls = new BoxedHeapClass(int_cls, NULL, 0, sizeof(BoxedBool), false);
complex_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedComplex), false);
long_cls = new BoxedHeapClass(object_cls, &BoxedLong::gchandler, 0, sizeof(BoxedLong), false);
float_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedFloat), false);
int_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedInt), false, "int");
bool_cls = new BoxedHeapClass(int_cls, NULL, 0, sizeof(BoxedBool), false, "bool");
complex_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedComplex), false, "complex");
long_cls = new BoxedHeapClass(object_cls, &BoxedLong::gchandler, 0, sizeof(BoxedLong), false, "long");
float_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedFloat), false, "float");
function_cls = new BoxedHeapClass(object_cls, &functionGCHandler, offsetof(BoxedFunction, attrs),
sizeof(BoxedFunction), false);
instancemethod_cls
= new BoxedHeapClass(object_cls, &instancemethodGCHandler, 0, sizeof(BoxedInstanceMethod), false);
list_cls = new BoxedHeapClass(object_cls, &listGCHandler, 0, sizeof(BoxedList), false);
slice_cls = new BoxedHeapClass(object_cls, &sliceGCHandler, 0, sizeof(BoxedSlice), false);
dict_cls = new BoxedHeapClass(object_cls, &dictGCHandler, 0, sizeof(BoxedDict), false);
file_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedFile), false);
set_cls = new BoxedHeapClass(object_cls, &setGCHandler, 0, sizeof(BoxedSet), false);
frozenset_cls = new BoxedHeapClass(object_cls, &setGCHandler, 0, sizeof(BoxedSet), false);
member_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedMemberDescriptor), false);
closure_cls
= new BoxedHeapClass(object_cls, &closureGCHandler, offsetof(BoxedClosure, attrs), sizeof(BoxedClosure), false);
property_cls = new BoxedHeapClass(object_cls, &propertyGCHandler, 0, sizeof(BoxedProperty), false);
staticmethod_cls = new BoxedHeapClass(object_cls, &staticmethodGCHandler, 0, sizeof(BoxedStaticmethod), false);
classmethod_cls = new BoxedHeapClass(object_cls, &classmethodGCHandler, 0, sizeof(BoxedClassmethod), false);
attrwrapper_cls = new BoxedHeapClass(object_cls, &AttrWrapper::gcHandler, 0, sizeof(AttrWrapper), false);
sizeof(BoxedFunction), false, "function");
instancemethod_cls = new BoxedHeapClass(object_cls, &instancemethodGCHandler, 0, sizeof(BoxedInstanceMethod), false,
"instancemethod");
list_cls = new BoxedHeapClass(object_cls, &listGCHandler, 0, sizeof(BoxedList), false, "list");
slice_cls = new BoxedHeapClass(object_cls, &sliceGCHandler, 0, sizeof(BoxedSlice), false, "slice");
dict_cls = new BoxedHeapClass(object_cls, &dictGCHandler, 0, sizeof(BoxedDict), false, "dict");
file_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedFile), false, "file");
set_cls = new BoxedHeapClass(object_cls, &setGCHandler, 0, sizeof(BoxedSet), false, "set");
frozenset_cls = new BoxedHeapClass(object_cls, &setGCHandler, 0, sizeof(BoxedSet), false, "frozenset");
member_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedMemberDescriptor), false, "member");
getset_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedGetsetDescriptor), false, "getset");
closure_cls = new BoxedHeapClass(object_cls, &closureGCHandler, offsetof(BoxedClosure, attrs), sizeof(BoxedClosure),
false, "closure");
property_cls = new BoxedHeapClass(object_cls, &propertyGCHandler, 0, sizeof(BoxedProperty), false, "property");
staticmethod_cls
= new BoxedHeapClass(object_cls, &staticmethodGCHandler, 0, sizeof(BoxedStaticmethod), false, "staticmethod");
classmethod_cls
= new BoxedHeapClass(object_cls, &classmethodGCHandler, 0, sizeof(BoxedClassmethod), false, "classmethod");
attrwrapper_cls
= new BoxedHeapClass(object_cls, &AttrWrapper::gcHandler, 0, sizeof(AttrWrapper), false, "attrwrapper");
STR = typeFromClass(str_cls);
BOXED_INT = typeFromClass(int_cls);
......@@ -1065,7 +1110,6 @@ void setupRuntime() {
LONG = typeFromClass(long_cls);
BOXED_COMPLEX = typeFromClass(complex_cls);
object_cls->giveAttr("__name__", boxStrConstant("object"));
object_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)objectNew, UNKNOWN, 1, 0, true, false)));
object_cls->giveAttr("__init__", new BoxedFunction(boxRTFunction((void*)objectInit, UNKNOWN, 1, 0, true, false)));
object_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)objectRepr, UNKNOWN, 1, 0, false, false)));
......@@ -1074,26 +1118,24 @@ void setupRuntime() {
auto typeCallObj = boxRTFunction((void*)typeCall, UNKNOWN, 1, 0, true, false);
typeCallObj->internal_callable = &typeCallInternal;
type_cls->giveAttr("__name__", new BoxedGetsetDescriptor(type_name, type_set_name, NULL));
type_cls->giveAttr("__call__", new BoxedFunction(typeCallObj));
type_cls->giveAttr("__name__", boxStrConstant("type"));
type_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)typeNew, UNKNOWN, 4, 2, false, false), { NULL, NULL }));
type_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)typeRepr, STR, 1)));
type_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)typeHash, BOXED_INT, 1)));
type_cls->freeze();
none_cls->giveAttr("__name__", boxStrConstant("NoneType"));
none_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)noneRepr, STR, 1)));
none_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)noneHash, UNKNOWN, 1)));
none_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)noneNonzero, BOXED_BOOL, 1)));
none_cls->freeze();
module_cls->giveAttr("__name__", boxStrConstant("module"));
module_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)moduleRepr, STR, 1)));
module_cls->freeze();
closure_cls->giveAttr("__name__", boxStrConstant("closure"));
closure_cls->freeze();
setupBool();
......@@ -1114,7 +1156,7 @@ void setupRuntime() {
setupUnicode();
setupDescr();
function_cls->giveAttr("__name__", boxStrConstant("function"));
function_cls->giveAttr("__name__", new BoxedGetsetDescriptor(func_name, func_set_name, NULL));
function_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)functionRepr, STR, 1)));
function_cls->giveAttr("__module__",
new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedFunction, modname)));
......@@ -1124,7 +1166,6 @@ void setupRuntime() {
function_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)functionNonzero, BOXED_BOOL, 1)));
function_cls->freeze();
instancemethod_cls->giveAttr("__name__", boxStrConstant("instancemethod"));
instancemethod_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)instancemethodRepr, STR, 1)));
instancemethod_cls->giveAttr("__eq__", new BoxedFunction(boxRTFunction((void*)instancemethodEq, UNKNOWN, 2)));
instancemethod_cls->giveAttr(
......@@ -1135,7 +1176,6 @@ void setupRuntime() {
"im_self", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedInstanceMethod, obj)));
instancemethod_cls->freeze();
slice_cls->giveAttr("__name__", boxStrConstant("slice"));
slice_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)sliceNew, UNKNOWN, 4, 2, false, false), { NULL, None }));
slice_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)sliceRepr, STR, 1)));
......@@ -1144,7 +1184,6 @@ void setupRuntime() {
slice_cls->giveAttr("step", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, SLICE_STEP_OFFSET));
slice_cls->freeze();
attrwrapper_cls->giveAttr("__name__", boxStrConstant("attrwrapper"));
attrwrapper_cls->giveAttr("__setitem__", new BoxedFunction(boxRTFunction((void*)AttrWrapper::setitem, UNKNOWN, 3)));
attrwrapper_cls->giveAttr("__getitem__", new BoxedFunction(boxRTFunction((void*)AttrWrapper::getitem, UNKNOWN, 2)));
attrwrapper_cls->giveAttr(
......
......@@ -79,7 +79,7 @@ extern "C" {
extern BoxedClass* object_cls, *type_cls, *bool_cls, *int_cls, *long_cls, *float_cls, *str_cls, *function_cls,
*none_cls, *instancemethod_cls, *list_cls, *slice_cls, *module_cls, *dict_cls, *tuple_cls, *file_cls,
*enumerate_cls, *xrange_cls, *member_cls, *method_cls, *closure_cls, *generator_cls, *complex_cls, *basestring_cls,
*unicode_cls, *property_cls, *staticmethod_cls, *classmethod_cls, *attrwrapper_cls;
*unicode_cls, *property_cls, *staticmethod_cls, *classmethod_cls, *attrwrapper_cls, *getset_cls;
}
extern "C" {
extern Box* None, *NotImplemented, *True, *False;
......@@ -232,8 +232,18 @@ public:
PyMappingMethods as_mapping;
PySequenceMethods as_sequence;
PyBufferProcs as_buffer;
PyObject* ht_name, *ht_slots;
BoxedString* ht_name;
PyObject** ht_slots;
BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size, bool is_user_defined,
const std::string& name);
BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size, bool is_user_defined,
BoxedString* name);
// This constructor is only used for bootstrapping purposes to be called for types that
// are initialized before str_cls.
BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size, bool is_user_defined);
};
......@@ -510,6 +520,18 @@ public:
DEFAULT_CLASS(member_cls);
};
class BoxedGetsetDescriptor : public Box {
public:
Box* (*get)(Box*, void*);
int (*set)(Box*, Box*, void*);
void* closure;
BoxedGetsetDescriptor(Box* (*get)(Box*, void*), int (*set)(Box*, Box*, void*), void* closure)
: get(get), set(set), closure(closure) {}
DEFAULT_CLASS(getset_cls);
};
class BoxedProperty : public Box {
public:
Box* prop_get;
......
......@@ -396,8 +396,6 @@ extern "C" const unsigned char _Py_ascii_whitespace[]
void setupUnicode() {
unicode_cls->giveAttr("__name__", boxStrConstant("unicode"));
unicode_cls->freeze();
}
......
# expected: fail
# - arbitrary stuff in classes
# I guess type.__name__ works specially:
class C(object):
__name__ = 1
print C.__name__
......
# expected: fail
# - type.__name__ is a descriptor
class C(object):
pass
......
# expected: fail
# This fails becasue we currently don't support setting for getset descriptors,
# and __name__ is a getset descriptor.
class C(object):
pass
......
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