Commit 5945006b authored by Kevin Modzelewski's avatar Kevin Modzelewski

Add repr ics and refactor things slightly

parent dff7b960
...@@ -455,7 +455,7 @@ struct _typeobject { ...@@ -455,7 +455,7 @@ struct _typeobject {
void* _hcls; void* _hcls;
void* _hcattrs; void* _hcattrs;
char _dep_getattrs[56]; // FIXME: this is hardcoding the size of this particular implementation of std::unordered_map char _dep_getattrs[56]; // FIXME: this is hardcoding the size of this particular implementation of std::unordered_map
char _ics[24]; char _ics[32];
void* _base; void* _base;
void* _gcvisit_func; void* _gcvisit_func;
int _attrs_offset; int _attrs_offset;
......
...@@ -404,6 +404,8 @@ public: ...@@ -404,6 +404,8 @@ public:
HCAttrs() : hcls(root_hcls), attr_list(nullptr) {} HCAttrs() : hcls(root_hcls), attr_list(nullptr) {}
}; };
class BoxedString;
class Box : public PythonGCObject { class Box : public PythonGCObject {
public: public:
BoxedClass* cls; BoxedClass* cls;
...@@ -435,6 +437,12 @@ public: ...@@ -435,6 +437,12 @@ public:
Box* getattr(const std::string& attr, GetattrRewriteArgs* rewrite_args); Box* getattr(const std::string& attr, GetattrRewriteArgs* rewrite_args);
Box* getattr(const std::string& attr) { return getattr(attr, NULL); } Box* getattr(const std::string& attr) { return getattr(attr, NULL); }
void delattr(const std::string& attr, DelattrRewriteArgs* rewrite_args); void delattr(const std::string& attr, DelattrRewriteArgs* rewrite_args);
Box* reprIC();
BoxedString* reprICAsString();
bool nonzeroIC();
Box* hasnextOrNullIC();
Box* nextIC();
}; };
static_assert(offsetof(Box, cls) == offsetof(struct _object, ob_type), ""); static_assert(offsetof(Box, cls) == offsetof(struct _object, ob_type), "");
......
...@@ -48,7 +48,7 @@ extern "C" Box* listRepr(BoxedList* self) { ...@@ -48,7 +48,7 @@ extern "C" Box* listRepr(BoxedList* self) {
if (i > 0) if (i > 0)
os << ", "; os << ", ";
BoxedString* s = static_cast<BoxedString*>(repr(self->elts->elts[i])); BoxedString* s = static_cast<BoxedString*>(self->elts->elts[i]->reprIC());
os << s->s; os << s->s;
} }
os << ']'; os << ']';
......
...@@ -52,7 +52,7 @@ bool IN_SHUTDOWN = false; ...@@ -52,7 +52,7 @@ bool IN_SHUTDOWN = false;
#define SLICE_STOP_OFFSET ((char*)&(((BoxedSlice*)0x01)->stop) - (char*)0x1) #define SLICE_STOP_OFFSET ((char*)&(((BoxedSlice*)0x01)->stop) - (char*)0x1)
#define SLICE_STEP_OFFSET ((char*)&(((BoxedSlice*)0x01)->step) - (char*)0x1) #define SLICE_STEP_OFFSET ((char*)&(((BoxedSlice*)0x01)->step) - (char*)0x1)
Box* BoxedClass::callHasnext(Box* obj, bool null_on_nonexistent) { Box* BoxedClass::callHasnextIC(Box* obj, bool null_on_nonexistent) {
assert(obj->cls == this); assert(obj->cls == this);
auto ic = hasnext_ic.get(); auto ic = hasnext_ic.get();
...@@ -66,7 +66,7 @@ Box* BoxedClass::callHasnext(Box* obj, bool null_on_nonexistent) { ...@@ -66,7 +66,7 @@ Box* BoxedClass::callHasnext(Box* obj, bool null_on_nonexistent) {
ArgPassSpec(0), nullptr, nullptr, nullptr, nullptr, nullptr); ArgPassSpec(0), nullptr, nullptr, nullptr, nullptr, nullptr);
} }
Box* BoxedClass::callNext(Box* obj) { Box* BoxedClass::callNextIC(Box* obj) {
assert(obj->cls == this); assert(obj->cls == this);
auto ic = next_ic.get(); auto ic = next_ic.get();
...@@ -80,7 +80,21 @@ Box* BoxedClass::callNext(Box* obj) { ...@@ -80,7 +80,21 @@ Box* BoxedClass::callNext(Box* obj) {
nullptr, nullptr, nullptr, nullptr, nullptr); nullptr, nullptr, nullptr, nullptr, nullptr);
} }
bool BoxedClass::callNonzero(Box* obj) { Box* BoxedClass::callReprIC(Box* obj) {
assert(obj->cls == this);
auto ic = repr_ic.get();
if (!ic) {
ic = new CallattrIC();
repr_ic.reset(ic);
}
static std::string repr_str("__repr__");
return ic->call(obj, &repr_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = false }), ArgPassSpec(0),
nullptr, nullptr, nullptr, nullptr, nullptr);
}
bool BoxedClass::callNonzeroIC(Box* obj) {
assert(obj->cls == this); assert(obj->cls == this);
auto ic = nonzero_ic.get(); auto ic = nonzero_ic.get();
...@@ -92,22 +106,46 @@ bool BoxedClass::callNonzero(Box* obj) { ...@@ -92,22 +106,46 @@ bool BoxedClass::callNonzero(Box* obj) {
return ic->call(obj); return ic->call(obj);
} }
Box* Box::reprIC() {
return this->cls->callReprIC(this);
}
BoxedString* Box::reprICAsString() {
Box* r = this->reprIC();
if (r->cls != str_cls) {
raiseExcHelper(TypeError, "__repr__ did not return a string!");
}
return static_cast<BoxedString*>(r);
}
bool Box::nonzeroIC() {
return this->cls->callNonzeroIC(this);
}
Box* Box::hasnextOrNullIC() {
return this->cls->callHasnextIC(this, true);
}
Box* Box::nextIC() {
return this->cls->callNextIC(this);
}
BoxIterator& BoxIterator::operator++() { BoxIterator& BoxIterator::operator++() {
static std::string next_str("next"); static std::string next_str("next");
assert(iter); assert(iter);
Box* hasnext = iter->cls->callHasnext(iter, true); Box* hasnext = iter->hasnextOrNullIC();
if (hasnext) { if (hasnext) {
if (hasnext->cls->callNonzero(hasnext)) { if (hasnext->nonzeroIC()) {
value = iter->cls->callNext(iter); value = iter->nextIC();
} else { } else {
iter = nullptr; iter = nullptr;
value = nullptr; value = nullptr;
} }
} else { } else {
try { try {
value = iter->cls->callNext(iter); value = iter->nextIC();
} catch (Box* e) { } catch (Box* e) {
if ((e == StopIteration) || isSubclass(e->cls, StopIteration)) { if ((e == StopIteration) || isSubclass(e->cls, StopIteration)) {
iter = nullptr; iter = nullptr;
...@@ -661,7 +699,7 @@ public: ...@@ -661,7 +699,7 @@ public:
os << ", "; os << ", ";
first = false; first = false;
BoxedString* v = repr(attrs->attr_list->attrs[p.second]); BoxedString* v = attrs->attr_list->attrs[p.second]->reprICAsString();
os << p.first << ": " << v->s; os << p.first << ": " << v->s;
} }
os << "})"; os << "})";
...@@ -717,8 +755,7 @@ Box* objectRepr(Box* obj) { ...@@ -717,8 +755,7 @@ Box* objectRepr(Box* obj) {
} }
Box* objectStr(Box* obj) { Box* objectStr(Box* obj) {
static const std::string repr_str("__repr__"); return obj->reprIC();
return callattrInternal(obj, &repr_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
} }
bool TRACK_ALLOCATIONS = false; bool TRACK_ALLOCATIONS = false;
......
...@@ -180,11 +180,12 @@ public: ...@@ -180,11 +180,12 @@ public:
ICInvalidator dependent_icgetattrs; ICInvalidator dependent_icgetattrs;
// TODO: these don't actually get deallocated right now // TODO: these don't actually get deallocated right now
std::unique_ptr<CallattrIC> hasnext_ic, next_ic; std::unique_ptr<CallattrIC> hasnext_ic, next_ic, repr_ic;
std::unique_ptr<NonzeroIC> nonzero_ic; std::unique_ptr<NonzeroIC> nonzero_ic;
Box* callHasnext(Box* obj, bool null_on_nonexistent); Box* callHasnextIC(Box* obj, bool null_on_nonexistent);
Box* callNext(Box* obj); Box* callNextIC(Box* obj);
bool callNonzero(Box* obj); Box* callReprIC(Box* obj);
bool callNonzeroIC(Box* obj);
// Only a single base supported for now. // Only a single base supported for now.
// Is NULL iff this is object_cls // Is NULL iff this is object_cls
......
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