Commit dff7b960 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Refactor: abstract this functionality more

parent 2538f588
...@@ -52,54 +52,62 @@ bool IN_SHUTDOWN = false; ...@@ -52,54 +52,62 @@ 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)
CallattrIC* BoxedClass::getHasnextIC() { Box* BoxedClass::callHasnext(Box* obj, bool null_on_nonexistent) {
assert(obj->cls == this);
auto ic = hasnext_ic.get(); auto ic = hasnext_ic.get();
if (!ic) { if (!ic) {
ic = new CallattrIC(); ic = new CallattrIC();
hasnext_ic.reset(ic); hasnext_ic.reset(ic);
} }
return ic;
static std::string hasnext_str("__hasnext__");
return ic->call(obj, &hasnext_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = null_on_nonexistent }),
ArgPassSpec(0), nullptr, nullptr, nullptr, nullptr, nullptr);
} }
CallattrIC* BoxedClass::getNextIC() {
Box* BoxedClass::callNext(Box* obj) {
assert(obj->cls == this);
auto ic = next_ic.get(); auto ic = next_ic.get();
if (!ic) { if (!ic) {
ic = new CallattrIC(); ic = new CallattrIC();
next_ic.reset(ic); next_ic.reset(ic);
} }
return ic;
static std::string next_str("next");
return ic->call(obj, &next_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = false }), ArgPassSpec(0),
nullptr, nullptr, nullptr, nullptr, nullptr);
} }
NonzeroIC* BoxedClass::getNonzeroIC() {
bool BoxedClass::callNonzero(Box* obj) {
assert(obj->cls == this);
auto ic = nonzero_ic.get(); auto ic = nonzero_ic.get();
if (!ic) { if (!ic) {
ic = new NonzeroIC(); ic = new NonzeroIC();
nonzero_ic.reset(ic); nonzero_ic.reset(ic);
} }
return ic;
return ic->call(obj);
} }
BoxIterator& BoxIterator::operator++() { BoxIterator& BoxIterator::operator++() {
static std::string hasnext_str("__hasnext__");
static std::string next_str("next"); static std::string next_str("next");
assert(iter); assert(iter);
Box* hasnext = iter->cls->getHasnextIC()->call(iter, &hasnext_str, Box* hasnext = iter->cls->callHasnext(iter, true);
CallattrFlags({.cls_only = true, .null_on_nonexistent = true }),
ArgPassSpec(0), nullptr, nullptr, nullptr, nullptr, nullptr);
if (hasnext) { if (hasnext) {
if (hasnext->cls->getNonzeroIC()->call(hasnext)) { if (hasnext->cls->callNonzero(hasnext)) {
value = iter->cls->getNextIC()->call(iter, &next_str, value = iter->cls->callNext(iter);
CallattrFlags({.cls_only = true, .null_on_nonexistent = true }),
ArgPassSpec(0), nullptr, nullptr, nullptr, nullptr, nullptr);
} else { } else {
iter = nullptr; iter = nullptr;
value = nullptr; value = nullptr;
} }
} else { } else {
try { try {
value = iter->cls->getNextIC()->call(iter, &next_str, value = iter->cls->callNext(iter);
CallattrFlags({.cls_only = true, .null_on_nonexistent = true }),
ArgPassSpec(0), nullptr, nullptr, nullptr, nullptr, nullptr);
} catch (Box* e) { } catch (Box* e) {
if ((e == StopIteration) || isSubclass(e->cls, StopIteration)) { if ((e == StopIteration) || isSubclass(e->cls, StopIteration)) {
iter = nullptr; iter = nullptr;
......
...@@ -182,9 +182,9 @@ public: ...@@ -182,9 +182,9 @@ public:
// 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;
std::unique_ptr<NonzeroIC> nonzero_ic; std::unique_ptr<NonzeroIC> nonzero_ic;
CallattrIC* getHasnextIC(); Box* callHasnext(Box* obj, bool null_on_nonexistent);
CallattrIC* getNextIC(); Box* callNext(Box* obj);
NonzeroIC* getNonzeroIC(); bool callNonzero(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