Commit b2f7eddc authored by Kevin Modzelewski's avatar Kevin Modzelewski

Make int more subclass-friendly

parent fd8ea7ce
...@@ -323,7 +323,7 @@ public: ...@@ -323,7 +323,7 @@ public:
Box(const ObjectFlavor* flavor, BoxedClass* cls); Box(const ObjectFlavor* flavor, BoxedClass* cls);
HCAttrs* getAttrs(); HCAttrs* getAttrsPtr();
void setattr(const std::string& attr, Box* val, SetattrRewriteArgs2* rewrite_args2); void setattr(const std::string& attr, Box* val, SetattrRewriteArgs2* rewrite_args2);
void giveAttr(const std::string& attr, Box* val) { void giveAttr(const std::string& attr, Box* val) {
......
...@@ -56,7 +56,7 @@ Box* boxInt(int64_t n) { ...@@ -56,7 +56,7 @@ Box* boxInt(int64_t n) {
if (0 <= n && n < NUM_INTERNED_INTS) { if (0 <= n && n < NUM_INTERNED_INTS) {
return interned_ints[n]; return interned_ints[n];
} }
return new BoxedInt(n); return new BoxedInt(int_cls, n);
} }
// BoxedInt::BoxedInt(int64_t n) : Box(int_cls), n(n) {} // BoxedInt::BoxedInt(int64_t n) : Box(int_cls), n(n) {}
......
...@@ -120,8 +120,10 @@ extern "C" Box* intAddFloat(BoxedInt* lhs, BoxedFloat* rhs) { ...@@ -120,8 +120,10 @@ extern "C" Box* intAddFloat(BoxedInt* lhs, BoxedFloat* rhs) {
} }
extern "C" Box* intAdd(BoxedInt* lhs, Box* rhs) { extern "C" Box* intAdd(BoxedInt* lhs, Box* rhs) {
assert(lhs->cls == int_cls); if (!isSubclass(lhs->cls, int_cls))
if (rhs->cls == int_cls) { raiseExcHelper(TypeError, "descriptor '__add__' requires a 'int' object but received a '%s'", getTypeName(rhs)->c_str());
if (isSubclass(rhs->cls, int_cls)) {
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
return boxInt(lhs->n + rhs_int->n); return boxInt(lhs->n + rhs_int->n);
} else if (rhs->cls == float_cls) { } else if (rhs->cls == float_cls) {
...@@ -410,8 +412,12 @@ extern "C" Box* intInvert(BoxedInt* v) { ...@@ -410,8 +412,12 @@ extern "C" Box* intInvert(BoxedInt* v) {
} }
extern "C" Box* intPos(BoxedInt* v) { extern "C" Box* intPos(BoxedInt* v) {
assert(v->cls == int_cls); if (!isSubclass(v->cls, int_cls))
return v; raiseExcHelper(TypeError, "descriptor '__pos__' requires a 'int' object but received a '%s'", getTypeName(rhs)->c_str());
if (v->cls == int_cls)
return v;
return boxInt(v->n);
} }
extern "C" Box* intNeg(BoxedInt* v) { extern "C" Box* intNeg(BoxedInt* v) {
...@@ -425,7 +431,9 @@ extern "C" Box* intNonzero(BoxedInt* v) { ...@@ -425,7 +431,9 @@ extern "C" Box* intNonzero(BoxedInt* v) {
} }
extern "C" BoxedString* intRepr(BoxedInt* v) { extern "C" BoxedString* intRepr(BoxedInt* v) {
assert(v->cls == int_cls); if (!isSubclass(v->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__repr__' requires a 'int' object but received a '%s'", getTypeName(rhs)->c_str());
char buf[80]; char buf[80];
int len = snprintf(buf, 80, "%ld", v->n); int len = snprintf(buf, 80, "%ld", v->n);
return new BoxedString(std::string(buf, len)); return new BoxedString(std::string(buf, len));
...@@ -437,42 +445,53 @@ extern "C" Box* intHash(BoxedInt* self) { ...@@ -437,42 +445,53 @@ extern "C" Box* intHash(BoxedInt* self) {
} }
extern "C" Box* intNew1(Box* cls) { extern "C" Box* intNew1(Box* cls) {
assert(cls == int_cls); if (!is_subclass(_cls->cls, type_cls))
return new BoxedInt(0); raiseExcHelper(TypeError, "int.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
return boxInt(0);
} }
extern "C" Box* intNew2(Box* cls, Box* val) { extern "C" Box* intNew2(Box* _cls, Box* val) {
assert(cls == int_cls); if (!is_subclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "int.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
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());
assert(cls->instance_size >= sizeof(BoxedInt));
void* mem = rt_alloc(cls->instance_size);
BoxedInt* rtn = ::new (mem) BoxedInt(cls, 0);
initUserAttrs(rtn, cls);
if (val->cls == int_cls) { if (val->cls == int_cls) {
return val; rtn->n = static_cast<BoxedInt*>(val)->n;
} else if (val->cls == str_cls) { } else if (val->cls == str_cls) {
BoxedString* s = static_cast<BoxedString*>(val); BoxedString* s = static_cast<BoxedString*>(val);
std::istringstream ss(s->s); std::istringstream ss(s->s);
int64_t n; int64_t n;
ss >> n; ss >> n;
return boxInt(n); rtn->n = n;
} else if (val->cls == float_cls) { } else if (val->cls == float_cls) {
double d = static_cast<BoxedFloat*>(val)->d; double d = static_cast<BoxedFloat*>(val)->d;
return boxInt(d); rtn->n = d;
} else { } else {
fprintf(stderr, "TypeError: int() argument must be a string or a number, not '%s'\n", fprintf(stderr, "TypeError: int() argument must be a string or a number, not '%s'\n",
getTypeName(val)->c_str()); getTypeName(val)->c_str());
raiseExcHelper(TypeError, ""); raiseExcHelper(TypeError, "");
} }
return rtn;
} }
extern "C" Box* intInit1(BoxedInt* self) { extern "C" Box* intInit1(Box* self) {
assert(self->cls == int_cls); // int.__init__ will actually let you call it with anything
return None; return None;
} }
extern "C" Box* intInit2(BoxedInt* self, Box* val) { extern "C" Box* intInit2(BoxedInt* self, Box* val) {
assert(self->cls == int_cls); // int.__init__ will actually let you call it with anything
return None; return None;
} }
...@@ -483,8 +502,9 @@ static void _addFuncIntFloatUnknown(const char* name, void* int_func, void* floa ...@@ -483,8 +502,9 @@ static void _addFuncIntFloatUnknown(const char* name, void* int_func, void* floa
v_ii.push_back(BOXED_INT); v_ii.push_back(BOXED_INT);
v_if.push_back(BOXED_INT); v_if.push_back(BOXED_INT);
v_if.push_back(BOXED_FLOAT); v_if.push_back(BOXED_FLOAT);
v_iu.push_back(BOXED_INT); // Only the unknown version can accept non-ints (ex if you access the function directly ex via int.__add__)
v_iu.push_back(NULL); v_iu.push_back(UNKNOWN);
v_iu.push_back(UNKNOWN);
CLFunction* cl = createRTFunction(); CLFunction* cl = createRTFunction();
addRTFunction(cl, int_func, BOXED_INT, v_ii, false); addRTFunction(cl, int_func, BOXED_INT, v_ii, false);
...@@ -548,7 +568,7 @@ void setupInt() { ...@@ -548,7 +568,7 @@ void setupInt() {
int_cls->freeze(); int_cls->freeze();
for (int i = 0; i < NUM_INTERNED_INTS; i++) { for (int i = 0; i < NUM_INTERNED_INTS; i++) {
interned_ints[i] = new BoxedInt(i); interned_ints[i] = new BoxedInt(int_cls, i);
gc::registerStaticRootObj(interned_ints[i]); gc::registerStaticRootObj(interned_ints[i]);
} }
} }
......
...@@ -85,7 +85,7 @@ extern "C" Box* listPop2(BoxedList* self, Box* idx) { ...@@ -85,7 +85,7 @@ extern "C" Box* listPop2(BoxedList* self, Box* idx) {
} }
extern "C" Box* listLen(BoxedList* self) { extern "C" Box* listLen(BoxedList* self) {
return new BoxedInt(self->size); return boxInt(self->size);
} }
Box* _listSlice(BoxedList* self, i64 start, i64 stop, i64 step) { Box* _listSlice(BoxedList* self, i64 start, i64 stop, i64 step) {
...@@ -361,7 +361,7 @@ Box* listCount(BoxedList* self, Box* elt) { ...@@ -361,7 +361,7 @@ Box* listCount(BoxedList* self, Box* elt) {
if (b) if (b)
count++; count++;
} }
return new BoxedInt(count); return boxInt(count);
} }
Box* listIndex(BoxedList* self, Box* elt) { Box* listIndex(BoxedList* self, Box* elt) {
...@@ -372,7 +372,7 @@ Box* listIndex(BoxedList* self, Box* elt) { ...@@ -372,7 +372,7 @@ Box* listIndex(BoxedList* self, Box* elt) {
Box* cmp = compareInternal(e, elt, AST_TYPE::Eq, NULL); Box* cmp = compareInternal(e, elt, AST_TYPE::Eq, NULL);
bool b = nonzero(cmp); bool b = nonzero(cmp);
if (b) if (b)
return new BoxedInt(i); return boxInt(i);
} }
BoxedString* tostr = static_cast<BoxedString*>(repr(elt)); BoxedString* tostr = static_cast<BoxedString*>(repr(elt));
......
...@@ -346,7 +346,7 @@ Box::Box(const ObjectFlavor* flavor, BoxedClass* cls) : GCObject(flavor), cls(cl ...@@ -346,7 +346,7 @@ Box::Box(const ObjectFlavor* flavor, BoxedClass* cls) : GCObject(flavor), cls(cl
} }
HCAttrs* Box::getAttrs() { HCAttrs* Box::getAttrsPtr() {
assert(cls->instancesHaveAttrs()); assert(cls->instancesHaveAttrs());
char* p = reinterpret_cast<char*>(this); char* p = reinterpret_cast<char*>(this);
...@@ -376,7 +376,7 @@ Box* Box::getattr(const std::string& attr, GetattrRewriteArgs* rewrite_args, Get ...@@ -376,7 +376,7 @@ Box* Box::getattr(const std::string& attr, GetattrRewriteArgs* rewrite_args, Get
if (!cls->instancesHaveAttrs()) if (!cls->instancesHaveAttrs())
return NULL; return NULL;
HCAttrs* attrs = getAttrs(); HCAttrs* attrs = getAttrsPtr();
HiddenClass* hcls = attrs->hcls; HiddenClass* hcls = attrs->hcls;
if (rewrite_args) { if (rewrite_args) {
...@@ -464,7 +464,7 @@ void Box::setattr(const std::string& attr, Box* val, SetattrRewriteArgs2* rewrit ...@@ -464,7 +464,7 @@ void Box::setattr(const std::string& attr, Box* val, SetattrRewriteArgs2* rewrit
} }
} }
HCAttrs* attrs = getAttrs(); HCAttrs* attrs = getAttrsPtr();
HiddenClass* hcls = attrs->hcls; HiddenClass* hcls = attrs->hcls;
int numattrs = hcls->attr_offsets.size(); int numattrs = hcls->attr_offsets.size();
......
...@@ -105,7 +105,7 @@ extern "C" void boxGCHandler(GCVisitor* v, void* p) { ...@@ -105,7 +105,7 @@ extern "C" void boxGCHandler(GCVisitor* v, void* p) {
v->visit(b->cls); v->visit(b->cls);
if (b->cls->instancesHaveAttrs()) { if (b->cls->instancesHaveAttrs()) {
HCAttrs* attrs = b->getAttrs(); HCAttrs* attrs = b->getAttrsPtr();
v->visit(attrs->hcls); v->visit(attrs->hcls);
int nattrs = attrs->hcls->attr_offsets.size(); int nattrs = attrs->hcls->attr_offsets.size();
...@@ -388,10 +388,7 @@ Box* objectNew1(BoxedClass* cls) { ...@@ -388,10 +388,7 @@ Box* objectNew1(BoxedClass* cls) {
void* mem = rt_alloc(cls->instance_size); void* mem = rt_alloc(cls->instance_size);
Box* rtn = ::new (mem) Box(&object_flavor, cls); Box* rtn = ::new (mem) Box(&object_flavor, cls);
if (cls->attrs_offset) { initUserAttrs(rtn, cls);
HCAttrs* attrs = rtn->getAttrs();
attrs = new ((void*)attrs) HCAttrs();
}
return rtn; return rtn;
} }
......
...@@ -163,7 +163,7 @@ class BoxedInt : public Box { ...@@ -163,7 +163,7 @@ class BoxedInt : public Box {
public: public:
int64_t n; int64_t n;
BoxedInt(int64_t n) __attribute__((visibility("default"))) : Box(&int_flavor, int_cls), n(n) {} BoxedInt(BoxedClass* cls, int64_t n) __attribute__((visibility("default"))) : Box(&int_flavor, cls), n(n) {}
}; };
class BoxedFloat : public Box { class BoxedFloat : public Box {
...@@ -300,5 +300,16 @@ Box* exceptionNew2(BoxedClass* cls, Box* message); ...@@ -300,5 +300,16 @@ Box* exceptionNew2(BoxedClass* cls, Box* message);
extern BoxedClass* Exception, *AssertionError, *AttributeError, *TypeError, *NameError, *KeyError, *IndexError, extern BoxedClass* Exception, *AssertionError, *AttributeError, *TypeError, *NameError, *KeyError, *IndexError,
*IOError, *OSError, *ZeroDivisionError, *ValueError, *UnboundLocalError, *RuntimeError, *ImportError; *IOError, *OSError, *ZeroDivisionError, *ValueError, *UnboundLocalError, *RuntimeError, *ImportError;
// cls should be obj->cls.
// Added as parameter because it should typically be available
inline void initUserAttrs(Box* obj, BoxedClass* cls) {
assert(obj->cls == cls);
if (cls->attrs_offset) {
HCAttrs* attrs = obj->getAttrsPtr();
attrs = new ((void*)attrs) HCAttrs();
}
}
} }
#endif #endif
...@@ -42,7 +42,7 @@ def f2(): ...@@ -42,7 +42,7 @@ def f2():
f2() f2()
def f3(): def f3():
class I(object): class I(int):
def foo(self): def foo(self):
print self + 1 print self + 1
...@@ -56,6 +56,8 @@ def f3(): ...@@ -56,6 +56,8 @@ def f3():
e = a + c e = a + c
print d, type(d) print d, type(d)
print e, type(e) print e, type(e)
f = +a
print f, type(f)
print a.foo() print a.foo()
f3() f3()
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