Example #1
0
void raise3(Box* arg0, Box* arg1, Box* arg2) {
    // TODO switch this to PyErr_Normalize

    if (arg2 == None)
        arg2 = getTraceback();

    if (isSubclass(arg0->cls, type_cls)) {
        BoxedClass* c = static_cast<BoxedClass*>(arg0);
        if (isSubclass(c, BaseException)) {
            Box* exc_obj;

            if (isSubclass(arg1->cls, BaseException)) {
                exc_obj = arg1;
                c = exc_obj->cls;
            } else if (arg1 != None) {
                exc_obj = runtimeCall(c, ArgPassSpec(1), arg1, NULL, NULL, NULL, NULL);
            } else {
                exc_obj = runtimeCall(c, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
            }

            raiseRaw(ExcInfo(c, exc_obj, arg2));
        }
    }

    if (isSubclass(arg0->cls, BaseException)) {
        if (arg1 != None)
            raiseExcHelper(TypeError, "instance exception may not have a separate value");
        raiseRaw(ExcInfo(arg0->cls, arg0, arg2));
    }

    raiseExcHelper(TypeError, "exceptions must be old-style classes or derived from BaseException, not %s",
                   getTypeName(arg0));
}
Example #2
0
BoxIterator& BoxIterator::operator++() {
    static std::string hasnext_str("__hasnext__");
    static std::string next_str("next");

    Box* hasnext = callattrInternal(iter, &hasnext_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
    if (nonzero(hasnext)) {
        value = callattrInternal(iter, &next_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
    } else {
        iter = nullptr;
        value = nullptr;
    }
    return *this;
}
Example #3
0
static Box* property_copy(BoxedProperty* old, Box* get, Box* set, Box* del) {
    RELEASE_ASSERT(isSubclass(old->cls, property_cls), "");

    if (!get || get == Py_None)
        get = old->prop_get;
    if (!set || set == Py_None)
        set = old->prop_set;
    if (!del || del == Py_None)
        del = old->prop_del;

    // Optimization for the case when the old propery is not subclassed
    if (old->cls == property_cls) {
        BoxedProperty* prop = new BoxedProperty(get, set, del, old->prop_doc);

        prop->getter_doc = false;
        if ((old->getter_doc && get != Py_None) || !old->prop_doc)
            propertyDocCopy(prop, get);

        return prop;
    } else {
        if (!get)
            get = Py_None;
        if (!set)
            set = Py_None;
        if (!del)
            del = Py_None;
        Box* doc;
        if ((old->getter_doc && get != Py_None) || !old->prop_doc)
            doc = Py_None;
        else
            doc = old->prop_doc;

        return runtimeCall(old->cls, ArgPassSpec(4), get, set, del, &doc, NULL);
    }
}
// Have a special helper function for syntax errors, since we want to include the location
// of the syntax error in the traceback, even though it is not part of the execution:
void raiseSyntaxError(const char* msg, int lineno, int col_offset, llvm::StringRef file, llvm::StringRef func) {
    Box* exc = runtimeCall(SyntaxError, ArgPassSpec(1), boxString(msg), NULL, NULL, NULL, NULL);

    auto tb = new BoxedTraceback(LineInfo(lineno, col_offset, boxString(file), boxString(func)), None);
    assert(!PyErr_Occurred());
    throw ExcInfo(exc->cls, exc, tb);
}
Example #5
0
extern "C" PyObject* PyObject_Call(PyObject* callable_object, PyObject* args, PyObject* kw) {
    try {
        return runtimeCall(callable_object, ArgPassSpec(0, 0, true, true), args, kw, NULL, NULL, NULL);
    } catch (Box* b) {
        Py_FatalError("unimplemented");
    }
}
Example #6
0
// Have a special helper function for syntax errors, since we want to include the location
// of the syntax error in the traceback, even though it is not part of the execution:
void raiseSyntaxError(const char* msg, int lineno, int col_offset, const std::string& file, const std::string& func) {
    Box* exc = runtimeCall(SyntaxError, ArgPassSpec(1), boxStrConstant(msg), NULL, NULL, NULL, NULL);

    auto tb = getTraceback();
    std::vector<const LineInfo*> entries = tb->lines;
    entries.push_back(new LineInfo(lineno, col_offset, file, func));
    raiseRaw(ExcInfo(exc->cls, exc, new BoxedTraceback(std::move(entries))));
}
Example #7
0
static Box* sysExit(Box* arg) {
    assert(arg);
    Box* exc = runtimeCall(SystemExit, ArgPassSpec(1), arg, NULL, NULL, NULL, NULL);
    // TODO this should be handled by the SystemExit constructor
    exc->giveAttr("code", arg);

    raiseExc(exc);
}
Example #8
0
extern "C" PyObject* PyFrozenSet_New(PyObject* iterable) noexcept {
    try {
        return runtimeCall(frozenset_cls, ArgPassSpec(iterable ? 1 : 0), iterable, NULL, NULL, NULL, NULL);
    } catch (ExcInfo e) {
        setCAPIException(e);
        return NULL;
    }
}
Example #9
0
llvm::iterator_range<BoxIterator> Box::pyElements() {
    static std::string iter_str("__iter__");

    Box* iter = callattr(const_cast<Box*>(this), &iter_str, true, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
    if (iter) {
        return llvm::iterator_range<BoxIterator>(++BoxIterator(iter), BoxIterator(nullptr));
    }

    raiseExcHelper(TypeError, "'%s' object is not iterable", getTypeName(this)->c_str());
}
Example #10
0
extern "C" PyObject* PySet_New(PyObject* iterable) noexcept {
    if (!iterable)
        return new BoxedSet(); // Fast path for empty set.

    try {
        return runtimeCall(set_cls, ArgPassSpec(iterable ? 1 : 0), iterable, NULL, NULL, NULL, NULL);
    } catch (ExcInfo e) {
        setCAPIException(e);
        return NULL;
    }
}
Example #11
0
static Box* propertySet(Box* self, Box* obj, Box* val) {
    RELEASE_ASSERT(isSubclass(self->cls, property_cls), "");

    BoxedProperty* prop = static_cast<BoxedProperty*>(self);
    Box* func;
    if (val == NULL) {
        func = prop->prop_del;
    } else {
        func = prop->prop_set;
    }

    if (func == NULL) {
        raiseExcHelper(AttributeError, val == NULL ? "can't delete attribute" : "can't set attribute");
    }

    if (val == NULL) {
        autoDecref(runtimeCall(func, ArgPassSpec(1), obj, NULL, NULL, NULL, NULL));
    } else {
        autoDecref(runtimeCall(func, ArgPassSpec(2), obj, val, NULL, NULL, NULL));
    }
    return incref(Py_None);
}
Example #12
0
static void* thread_start(Box* target, Box* varargs, Box* kwargs) {
    assert(target);
    assert(varargs);

    try {
        runtimeCall(target, ArgPassSpec(0, 0, true, kwargs != NULL), varargs, kwargs, NULL, NULL, NULL);
    } catch (Box* b) {
        std::string msg = formatException(b);
        printLastTraceback();
        fprintf(stderr, "%s\n", msg.c_str());
    }
    return NULL;
}
Example #13
0
void raiseExcHelper(BoxedClass* cls, const char* msg, ...) {
    if (msg != NULL) {
        va_list ap;
        va_start(ap, msg);

        // printf("Raising: ");
        // vprintf(msg, ap);
        // printf("\n");
        // va_start(ap, msg);

        char buf[1024];
        vsnprintf(buf, sizeof(buf), msg, ap);

        va_end(ap);

        BoxedString* message = boxStrConstant(buf);
        Box* exc_obj = runtimeCall(cls, ArgPassSpec(1), message, NULL, NULL, NULL, NULL);
        raiseExc(exc_obj);
    } else {
        Box* exc_obj = runtimeCall(cls, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
        raiseExc(exc_obj);
    }
}
Example #14
0
static Box* propertyGet(Box* self, Box* obj, Box* type) {
    RELEASE_ASSERT(isSubclass(self->cls, property_cls), "");

    BoxedProperty* prop = static_cast<BoxedProperty*>(self);
    if (obj == NULL || obj == Py_None) {
        return incref(self);
    }

    if (prop->prop_get == NULL) {
        raiseExcHelper(AttributeError, "unreadable attribute");
    }

    return runtimeCall(prop->prop_get, ArgPassSpec(1), obj, NULL, NULL, NULL, NULL);
}
Example #15
0
extern "C" PyObject* PyObject_CallObject(PyObject* obj, PyObject* args) {
    RELEASE_ASSERT(args, ""); // actually it looks like this is allowed to be NULL
    RELEASE_ASSERT(args->cls == tuple_cls, "");

    // TODO do something like this?  not sure if this is safe; will people expect that calling into a known function
    // won't end up doing a GIL check?
    // threading::GLDemoteRegion _gil_demote;

    try {
        Box* r = runtimeCall(obj, ArgPassSpec(0, 0, true, false), args, NULL, NULL, NULL, NULL);
        return r;
    } catch (Box* b) {
        Py_FatalError("unimplemented");
    }
}
Example #16
0
extern "C" int PyDict_SetItem(PyObject* mp, PyObject* _key, PyObject* _item) {
    Box* b = static_cast<Box*>(mp);
    Box* key = static_cast<Box*>(_key);
    Box* item = static_cast<Box*>(_item);

    static std::string setitem_str("__setitem__");
    Box* r;
    try {
        // TODO should demote GIL?
        r = callattrInternal(b, &setitem_str, CLASS_ONLY, NULL, ArgPassSpec(2), key, item, NULL, NULL, NULL);
    } catch (Box* b) {
        fprintf(stderr, "Error: uncaught error would be propagated to C code!\n");
        Py_FatalError("unimplemented");
    }

    RELEASE_ASSERT(r, "");
    return 0;
}
Example #17
0
static PyObject* superGet(PyObject* _self, PyObject* obj, PyObject* type) noexcept(S == CAPI) {
    BoxedSuper* self = static_cast<BoxedSuper*>(_self);

    if (obj == NULL || obj == None || self->obj != NULL) {
        /* Not binding to an object, or already bound */
        return self;
    }
    if (self->cls != super_cls) {
        /* If self is an instance of a (strict) subclass of super,
           call its type */
        return runtimeCallInternal<S, NOT_REWRITABLE>(self->cls, NULL, ArgPassSpec(2), self->type, obj, NULL, NULL,
                                                      NULL);
    } else {
        /* Inline the common case */
        BoxedClass* obj_type = superCheck<S>(self->type, obj);
        if (obj_type == NULL)
            return NULL;
        return new BoxedSuper(self->type, obj, obj_type);
    }
}
Example #18
0
void runCollection() {
    static StatCounter sc("gc_collections");
    sc.log();

    ncollections++;

    if (VERBOSITY("gc") >= 2)
        printf("Collection #%d\n", ncollections);

    Timer _t("collecting", /*min_usec=*/10000);

    markPhase();
    std::list<Box*, StlCompatAllocator<Box*>> weakly_referenced;
    sweepPhase(weakly_referenced);

    for (auto o : weakly_referenced) {
        PyWeakReference** list = (PyWeakReference**)PyObject_GET_WEAKREFS_LISTPTR(o);
        while (PyWeakReference* head = *list) {
            assert(isValidGCObject(head));
            if (head->wr_object != Py_None) {
                _PyWeakref_ClearRef(head);
                if (head->wr_callback) {

                    runtimeCall(head->wr_callback, ArgPassSpec(1), reinterpret_cast<Box*>(head), NULL, NULL, NULL,
                                NULL);
                    head->wr_callback = NULL;
                }
            }
        }
    }

    if (VERBOSITY("gc") >= 2)
        printf("Collection #%d done\n\n", ncollections);

    long us = _t.end();
    static StatCounter sc_us("gc_collections_us");
    sc_us.log(us);

    // dumpHeapStatistics();
}
Example #19
0
static void* thread_start(Box* target, Box* varargs, Box* kwargs) {
    assert(target);
    assert(varargs);

#if STAT_TIMERS
    // TODO: maybe we should just not log anything for threads...
    static uint64_t* timer_counter = Stats::getStatCounter("us_timer_thread_start");
    StatTimer timer(timer_counter, 0, true);
    timer.pushTopLevel(getCPUTicks());
#endif

    try {
        runtimeCall(target, ArgPassSpec(0, 0, true, kwargs != NULL), varargs, kwargs, NULL, NULL, NULL);
    } catch (ExcInfo e) {
        e.printExcAndTraceback();
    }

#if STAT_TIMERS
    timer.popTopLevel(getCPUTicks());
#endif

    return NULL;
}
Example #20
0
static Box* sysExit(Box* arg) {
    assert(arg);
    Box* exc = runtimeCall(SystemExit, ArgPassSpec(1), arg, NULL, NULL, NULL, NULL);
    raiseExc(exc);
}
Example #21
0
// TODO this should be auto-generated as a slot wrapper:
Box* BoxedMethodDescriptor::__call__(BoxedMethodDescriptor* self, Box* obj, BoxedTuple* varargs, Box** _args) {
    BoxedDict* kwargs = static_cast<BoxedDict*>(_args[0]);
    return BoxedMethodDescriptor::tppCall(self, NULL, ArgPassSpec(1, 0, true, true), obj, varargs, kwargs, NULL, NULL);
}
Example #22
0
void raiseExcHelper(BoxedClass* cls, Box* arg) {
    Box* exc_obj = runtimeCall(cls, ArgPassSpec(1), arg, NULL, NULL, NULL, NULL);
    raiseExc(exc_obj);
}
Example #23
0
void prependToSysPath(const std::string& path) {
    BoxedList* sys_path = getSysPath();
    static std::string attr = "insert";
    callattr(sys_path, &attr, false, ArgPassSpec(2), boxInt(0), new BoxedString(path), NULL, NULL, NULL);
}