Exemple #1
0
static Box* _intNew(Box* val, Box* base) {
    if (isSubclass(val->cls, int_cls)) {
        RELEASE_ASSERT(!base, "");
        BoxedInt* n = static_cast<BoxedInt*>(val);
        if (val->cls == int_cls)
            return n;
        return new BoxedInt(n->n);
    } else if (isSubclass(val->cls, str_cls)) {
        int base_n;
        if (!base)
            base_n = 10;
        else {
            RELEASE_ASSERT(base->cls == int_cls, "");
            base_n = static_cast<BoxedInt*>(base)->n;
        }

        BoxedString* s = static_cast<BoxedString*>(val);

        RELEASE_ASSERT(s->size() == strlen(s->data()), "");
        Box* r = PyInt_FromString(s->data(), NULL, base_n);
        if (!r)
            throwCAPIException();
        return r;
    } else if (isSubclass(val->cls, unicode_cls)) {
        int base_n;
        if (!base)
            base_n = 10;
        else {
            RELEASE_ASSERT(base->cls == int_cls, "");
            base_n = static_cast<BoxedInt*>(base)->n;
        }

        Box* r = PyInt_FromUnicode(PyUnicode_AS_UNICODE(val), PyUnicode_GET_SIZE(val), base_n);
        if (!r)
            throwCAPIException();
        return r;
    } else if (val->cls == float_cls) {
        RELEASE_ASSERT(!base, "");
        double d = static_cast<BoxedFloat*>(val)->d;
        return new BoxedInt(d);
    } else {
        RELEASE_ASSERT(!base, "");
        static const std::string int_str("__int__");
        Box* r = callattr(val, &int_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }),
                          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));
            raiseExcHelper(TypeError, "");
        }

        if (!isSubclass(r->cls, int_cls) && !isSubclass(r->cls, long_cls)) {
            raiseExcHelper(TypeError, "__int__ returned non-int (type %s)", r->cls->tp_name);
        }
        return r;
    }
Exemple #2
0
Box* tupleMul(BoxedTuple* self, Box* rhs) {
    Py_ssize_t n;
    if (PyIndex_Check(rhs)) {
        n = PyNumber_AsSsize_t(rhs, PyExc_OverflowError);
        if (n == -1 && PyErr_Occurred())
            throwCAPIException();
    } else {
        raiseExcHelper(TypeError, "can't multiply sequence by non-int of type '%s'", getTypeName(rhs));
    }

    int s = self->size();

    if (n < 0)
        n = 0;

    if ((s == 0 || n == 1) && PyTuple_CheckExact(self)) {
        return self;
    } else {
        BoxedTuple* rtn = BoxedTuple::create(n * s);
        int rtn_i = 0;
        for (int i = 0; i < n; ++i) {
            memmove(&rtn->elts[rtn_i], &self->elts[0], sizeof(Box*) * s);
            rtn_i += s;
        }
        return rtn;
    }
}
Exemple #3
0
Box* setInit(Box* _self, Box* container, BoxedDict* kwargs) {
    RELEASE_ASSERT(PySet_Check(_self), "");

    if (PySet_Check(_self) && !_PyArg_NoKeywords("set()", kwargs)) {
        throwCAPIException();
    }

    if (!container)
        return incref(None);

    BoxedSet* self = static_cast<BoxedSet*>(_self);

    setClearInternal(self);

    if (PyAnySet_Check(container)) {
        for (auto&& elt : ((BoxedSet*)container)->s) {
            self->s.insert(incref(elt));
        }
    } else if (PyDict_CheckExact(container)) {
        for (auto&& elt : ((BoxedDict*)container)->d) {
            self->s.insert(incref(elt.first));
        }

    } else {
        for (auto elt : container->pyElements()) {
            _setAddStolen(self, elt);
        }
    }

    return incref(None);
}
Exemple #4
0
Box* frozensetNew(Box* _cls, Box* container, BoxedDict* kwargs) {
    RELEASE_ASSERT(_cls->cls == type_cls, "");
    BoxedClass* cls = static_cast<BoxedClass*>(_cls);
    RELEASE_ASSERT(isSubclass(cls, frozenset_cls), "");
    if (_cls == frozenset_cls && !_PyArg_NoKeywords("frozenset()", kwargs)) {
        throwCAPIException();
    }

    if (_cls != frozenset_cls) {
        return makeNewSet(cls, container);
    }

    if (container != NULL) {
        if (container->cls == frozenset_cls)
            return incref(container);

        BoxedSet* result = makeNewSet(cls, container);
        if (result->s.size() != 0) {
            return result;
        }
        Py_DECREF(result);
    }

    static Box* emptyfrozenset = NULL;
    if (!emptyfrozenset) {
        emptyfrozenset = new (frozenset_cls) BoxedSet();
        PyGC_RegisterStaticConstant(emptyfrozenset);
    }

    Py_INCREF(emptyfrozenset);
    return emptyfrozenset;
}
Exemple #5
0
llvm_compat_bool calliterHasnextUnboxed(Box* b) {
    calliterobject* it = (calliterobject*)b;
    if (!it->it_nextvalue) {
        it->it_nextvalue = calliter_next(it);
        if (PyErr_Occurred()) {
            throwCAPIException();
        }
    }
    return it->it_nextvalue != NULL;
}
Exemple #6
0
Box* setNew(Box* _cls, Box* container, BoxedDict* kwargs) {
    RELEASE_ASSERT(_cls->cls == type_cls, "");
    BoxedClass* cls = static_cast<BoxedClass*>(_cls);
    RELEASE_ASSERT(isSubclass(cls, set_cls), "");

    if (_cls == set_cls && !_PyArg_NoKeywords("set()", kwargs)) {
        throwCAPIException();
    }

    // Note: set.__new__ explicitly ignores the container argument.
    return makeNewSet(cls, NULL);
}
Exemple #7
0
Box* tupleContains(BoxedTuple* self, Box* elt) {
    int size = self->size();
    for (Box* e : *self) {
        int r = PyObject_RichCompareBool(elt, e, Py_EQ);
        if (r == -1)
            throwCAPIException();

        if (r)
            return True;
    }
    return False;
}
Exemple #8
0
Box* tupleGetitem(BoxedTuple* self, Box* slice) {
    assert(self->cls == tuple_cls);

    if (PyIndex_Check(slice)) {
        Py_ssize_t i = PyNumber_AsSsize_t(slice, PyExc_IndexError);
        if (i == -1 && PyErr_Occurred())
            throwCAPIException();
        return tupleGetitemUnboxed(self, i);
    } 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));
}
Exemple #9
0
Box* tupleCount(BoxedTuple* self, Box* elt) {
    int size = self->size();
    int count = 0;
    for (int i = 0; i < size; i++) {
        Box* e = self->elts[i];
        int r = PyObject_RichCompareBool(e, elt, Py_EQ);
        if (r == -1)
            throwCAPIException();
        if (r)
            count++;
    }
    return boxInt(count);
}
Exemple #10
0
extern "C" Box* tupleNew(Box* _cls, BoxedTuple* args, BoxedDict* kwargs) {
    if (!PyType_Check(_cls))
        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),
                       getNameOfClass(cls));

    int args_sz = args->size();
    int kwargs_sz = kwargs ? kwargs->d.size() : 0;

    if (args_sz + kwargs_sz > 1)
        raiseExcHelper(TypeError, "tuple() takes at most 1 argument (%d given)", args_sz + kwargs_sz);

    if (args_sz || kwargs_sz) {
        Box* elements;
        // if initializing from iterable argument, check common case positional args first
        if (args_sz) {
            elements = args->elts[0];
        } else {
            assert(kwargs_sz);
            auto const seq = *(kwargs->d.begin());
            auto const kw = static_cast<BoxedString*>(seq.first.value);

            if (kw->s() == "sequence")
                elements = seq.second;
            else
                raiseExcHelper(TypeError, "'%s' is an invalid keyword argument for this function", kw->data());
        }

        if (cls == tuple_cls) {
            // Call PySequence_Tuple since it has some perf special-cases
            // that can make it quite a bit faster than the generic pyElements iteration:
            Box* r = PySequence_Tuple(elements);
            if (!r)
                throwCAPIException();
            return r;
        }

        std::vector<Box*, StlCompatAllocator<Box*>> elts;
        for (auto e : elements->pyElements())
            elts.push_back(e);

        return BoxedTuple::create(elts.size(), &elts[0], cls);
    } else {
        if (cls == tuple_cls)
            return EmptyTuple;
        return BoxedTuple::create(0, cls);
    }
}
Exemple #11
0
llvm_compat_bool iterwrapperHasnextUnboxed(Box* s) {
    RELEASE_ASSERT(s->cls == iterwrapper_cls, "");
    BoxedIterWrapper* self = static_cast<BoxedIterWrapper*>(s);

    Box* next = PyIter_Next(self->iter);
    RELEASE_ASSERT(!self->next, "");
    self->next = next;
    if (!next) {
        if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_StopIteration))
            throwCAPIException();
        PyErr_Clear();
    }
    return next != NULL;
}
Exemple #12
0
static Box* setRepr(BoxedSet* self) {
    RELEASE_ASSERT(PyAnySet_Check(self), "");

    std::vector<char> chars;
    int status = Py_ReprEnter((PyObject*)self);

    if (status != 0) {
        if (status < 0)
            throwCAPIException();

        std::string ty = std::string(self->cls->tp_name);
        chars.insert(chars.end(), ty.begin(), ty.end());
        chars.push_back('(');
        chars.push_back('.');
        chars.push_back('.');
        chars.push_back('.');
        chars.push_back(')');

        return boxString(llvm::StringRef(&chars[0], chars.size()));
    }

    try {
        std::string ty = std::string(self->cls->tp_name);
        chars.insert(chars.end(), ty.begin(), ty.end());

        chars.push_back('(');
        chars.push_back('[');

        bool first = true;
        for (auto&& elt : self->s) {

            if (!first) {
                chars.push_back(',');
                chars.push_back(' ');
            }
            BoxedString* str = static_cast<BoxedString*>(repr(elt.value));
            AUTO_DECREF(str);
            chars.insert(chars.end(), str->s().begin(), str->s().end());

            first = false;
        }
        chars.push_back(']');
        chars.push_back(')');
    } catch (ExcInfo e) {
        Py_ReprLeave((PyObject*)self);
        throw e;
    }
    Py_ReprLeave((PyObject*)self);
    return boxString(llvm::StringRef(&chars[0], chars.size()));
}
Exemple #13
0
Box* tupleIndex(BoxedTuple* self, Box* elt) {
    int size = self->size();
    for (int i = 0; i < size; i++) {
        Box* e = self->elts[i];

        int r = PyObject_RichCompareBool(e, elt, Py_EQ);
        if (r == -1)
            throwCAPIException();

        if (r)
            return boxInt(i);
    }

    raiseExcHelper(ValueError, "tuple.index(x): x not in tuple");
}
Exemple #14
0
Box* tupleRepr(BoxedTuple* t) {

    assert(isSubclass(t->cls, tuple_cls));
    int n;
    std::vector<char> chars;
    int status = Py_ReprEnter((PyObject*)t);
    n = t->size();
    if (n == 0) {
        chars.push_back('(');
        chars.push_back(')');
        return boxString(llvm::StringRef(&chars[0], chars.size()));
    }

    if (status != 0) {
        if (status < 0)
            throwCAPIException();
        chars.push_back('(');
        chars.push_back('.');
        chars.push_back('.');
        chars.push_back('.');
        chars.push_back(')');

        return boxString(llvm::StringRef(&chars[0], chars.size()));
    }

    try {
        chars.push_back('(');
        for (int i = 0; i < n; i++) {
            if (i) {
                chars.push_back(',');
                chars.push_back(' ');
            }
            BoxedString* elt_repr = static_cast<BoxedString*>(repr(t->elts[i]));
            chars.insert(chars.end(), elt_repr->s().begin(), elt_repr->s().end());
        }

        if (n == 1)
            chars.push_back(',');

        chars.push_back(')');
    } catch (ExcInfo e) {
        Py_ReprLeave((PyObject*)t);
        throw e;
    }
    Py_ReprLeave((PyObject*)t);

    return boxString(llvm::StringRef(&chars[0], chars.size()));
}
Exemple #15
0
template <ExceptionStyle S> Box* tupleGetitem(BoxedTuple* self, Box* slice) {
    if (S == CAPI) {
        try {
            return tupleGetitem<CXX>(self, slice);
        } catch (ExcInfo e) {
            setCAPIException(e);
            return NULL;
        }
    }

    assert(isSubclass(self->cls, tuple_cls));

    if (PyIndex_Check(slice)) {
        Py_ssize_t i = PyNumber_AsSsize_t(slice, PyExc_IndexError);
        if (i == -1 && PyErr_Occurred())
            throwCAPIException();
        return tupleGetitemUnboxed(self, i);
    } 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));
}
Exemple #16
0
Box* tupleIndex(BoxedTuple* self, Box* elt, Box* startBox, Box** args) {
    Box* endBox = args[0];

    Py_ssize_t start, end;
    _PyEval_SliceIndex(startBox, &start);
    _PyEval_SliceIndex(endBox, &end);

    Py_ssize_t size = self->size();

    if (start < 0) {
        start += size;
        if (start < 0) {
            start = 0;
        }
    }
    if (end < 0) {
        end += size;
        if (end < 0) {
            end = 0;
        }
    } else if (end > size) {
        end = size;
    }

    for (Py_ssize_t i = start; i < end; i++) {
        Box* e = self->elts[i];

        int r = PyObject_RichCompareBool(e, elt, Py_EQ);
        if (r == -1)
            throwCAPIException();

        if (r)
            return boxInt(i);
    }

    raiseExcHelper(ValueError, "tuple.index(x): x not in tuple");
}
Exemple #17
0
extern "C" Box* dir(Box* obj) {
    Box* r = PyObject_Dir(obj);
    if (!r)
        throwCAPIException();
    return r;
}
Exemple #18
0
Box* sysCurrentFrames() {
    Box* rtn = _PyThread_CurrentFrames();
    if (!rtn)
        throwCAPIException();
    return rtn;
}
Exemple #19
0
Box* seqreviterHasnext(Box* s) {
    Box* rtn = seqreviterHasnext_capi(s);
    if (!rtn)
        throwCAPIException();
    return rtn;
}
Exemple #20
0
SearchResult findModule(const std::string& name, BoxedString* full_name, BoxedList* path_list) {
    static BoxedString* meta_path_str = internStringImmortal("meta_path");
    BoxedList* meta_path = static_cast<BoxedList*>(sys_module->getattr(meta_path_str));
    if (!meta_path || meta_path->cls != list_cls)
        raiseExcHelper(RuntimeError, "sys.meta_path must be a list of import hooks");

    static BoxedString* findmodule_str = internStringImmortal("find_module");
    for (int i = 0; i < meta_path->size; i++) {
        Box* finder = meta_path->elts->elts[i];

        auto path_pass = path_list ? path_list : None;
        CallattrFlags callattr_flags{.cls_only = false, .null_on_nonexistent = false, .argspec = ArgPassSpec(2) };
        Box* loader = callattr(finder, findmodule_str, callattr_flags, full_name, path_pass, NULL, NULL, NULL);

        if (loader != None)
            return SearchResult(loader);
    }

    if (!path_list)
        path_list = getSysPath();

    if (path_list == NULL || path_list->cls != list_cls) {
        raiseExcHelper(RuntimeError, "sys.path must be a list of directory names");
    }

    static BoxedString* path_hooks_str = internStringImmortal("path_hooks");
    BoxedList* path_hooks = static_cast<BoxedList*>(sys_module->getattr(path_hooks_str));
    if (!path_hooks || path_hooks->cls != list_cls)
        raiseExcHelper(RuntimeError, "sys.path_hooks must be a list of import hooks");

    static BoxedString* path_importer_cache_str = internStringImmortal("path_importer_cache");
    BoxedDict* path_importer_cache = static_cast<BoxedDict*>(sys_module->getattr(path_importer_cache_str));
    if (!path_importer_cache || path_importer_cache->cls != dict_cls)
        raiseExcHelper(RuntimeError, "sys.path_importer_cache must be a dict");

    llvm::SmallString<128> joined_path;
    for (int i = 0; i < path_list->size; i++) {
        Box* _p = path_list->elts->elts[i];
        if (_p->cls != str_cls)
            continue;
        BoxedString* p = static_cast<BoxedString*>(_p);

        joined_path.clear();
        llvm::sys::path::append(joined_path, p->s(), name);
        std::string dn(joined_path.str());

        llvm::sys::path::append(joined_path, "__init__.py");
        std::string fn(joined_path.str());

        PyObject* importer = get_path_importer(path_importer_cache, path_hooks, _p);
        if (importer == NULL)
            throwCAPIException();

        if (importer != None) {
            CallattrFlags callattr_flags{.cls_only = false, .null_on_nonexistent = false, .argspec = ArgPassSpec(1) };
            Box* loader = callattr(importer, findmodule_str, callattr_flags, full_name, NULL, NULL, NULL, NULL);
            if (loader != None)
                return SearchResult(loader);
        }

        if (pathExists(fn))
            return SearchResult(std::move(dn), SearchResult::PKG_DIRECTORY);

        joined_path.clear();
        llvm::sys::path::append(joined_path, std::string(p->s()), name + ".py");
        fn = joined_path.str();

        if (pathExists(fn))
            return SearchResult(std::move(fn), SearchResult::PY_SOURCE);

        joined_path.clear();
        llvm::sys::path::append(joined_path, p->s(), name + ".pyston.so");
        fn = joined_path.str();

        if (pathExists(fn))
            return SearchResult(std::move(fn), SearchResult::C_EXTENSION);
    }

    return SearchResult("", SearchResult::SEARCH_ERROR);
}

PyObject* PyImport_GetImporter(PyObject* path) noexcept {
    PyObject* importer = NULL, * path_importer_cache = NULL, * path_hooks = NULL;

    if ((path_importer_cache = PySys_GetObject("path_importer_cache"))) {
        if ((path_hooks = PySys_GetObject("path_hooks"))) {
            importer = get_path_importer(path_importer_cache, path_hooks, path);
        }
    }
    Py_XINCREF(importer); /* get_path_importer returns a borrowed reference */
    return importer;
}
Exemple #21
0
Box* methodDescrTppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3,
                        Box** args, const std::vector<BoxedString*>* keyword_names) noexcept(S == CAPI) {
    if (S == CAPI) {
        try {
            return methodDescrTppCall<CXX>(_self, NULL, argspec, arg1, arg2, arg3, args, keyword_names);
        } catch (ExcInfo e) {
            setCAPIException(e);
            return NULL;
        }
    }

    STAT_TIMER(t0, "us_timer_boxedmethoddescriptor__call__", 10);

    assert(_self->cls == &PyMethodDescr_Type || _self->cls == &PyClassMethodDescr_Type);
    PyMethodDescrObject* self = reinterpret_cast<PyMethodDescrObject*>(_self);

    bool is_classmethod = (_self->cls == &PyClassMethodDescr_Type);

    int ml_flags = self->d_method->ml_flags;
    int call_flags = ml_flags & ~(METH_CLASS | METH_COEXIST | METH_STATIC);

    if (rewrite_args && !rewrite_args->func_guarded) {
        rewrite_args->obj->addAttrGuard(offsetof(PyMethodDescrObject, d_method), (intptr_t)self->d_method);
    }

    ParamReceiveSpec paramspec(0, 0, false, false);
    Box** defaults = NULL;
    if (call_flags == METH_NOARGS) {
        paramspec = ParamReceiveSpec(1, 0, false, false);
    } else if (call_flags == METH_VARARGS) {
        paramspec = ParamReceiveSpec(1, 0, true, false);
    } else if (call_flags == (METH_VARARGS | METH_KEYWORDS)) {
        paramspec = ParamReceiveSpec(1, 0, true, true);
    } else if (call_flags == METH_O) {
        paramspec = ParamReceiveSpec(2, 0, false, false);
    } else if ((call_flags & ~(METH_O3 | METH_D3)) == 0) {
        int num_args = 0;
        if (call_flags & METH_O)
            num_args++;
        if (call_flags & METH_O2)
            num_args += 2;

        int num_defaults = 0;
        if (call_flags & METH_D1)
            num_defaults++;
        if (call_flags & METH_D2)
            num_defaults += 2;

        paramspec = ParamReceiveSpec(1 + num_args, num_defaults, false, false);
        if (num_defaults) {
            static Box* _defaults[] = { NULL, NULL, NULL };
            assert(num_defaults <= 3);
            defaults = _defaults;
        }
    } else {
        RELEASE_ASSERT(0, "0x%x", call_flags);
    }

    bool arg1_class_guarded = false;
    if (rewrite_args && argspec.num_args >= 1) {
        // Try to do the guard before rearrangeArguments if possible:
        rewrite_args->arg1->addAttrGuard(offsetof(Box, cls), (intptr_t)arg1->cls);
        arg1_class_guarded = true;
    }

    auto continuation = [=](CallRewriteArgs* rewrite_args, Box* arg1, Box* arg2, Box* arg3, Box** args) {
        if (is_classmethod) {
            rewrite_args = NULL;
            if (!PyType_Check(arg1))
                raiseExcHelper(TypeError, "descriptor '%s' requires a type but received a '%s'",
                               self->d_method->ml_name, getFullTypeName(arg1).c_str());
        } else {
            if (!isSubclass(arg1->cls, self->d_type))
                raiseExcHelper(TypeError, "descriptor '%s' requires a '%s' arg1 but received a '%s'",
                               self->d_method->ml_name, self->d_type->tp_name, getFullTypeName(arg1).c_str());
        }

        if (rewrite_args && !arg1_class_guarded) {
            rewrite_args->arg1->addAttrGuard(offsetof(Box, cls), (intptr_t)arg1->cls);
        }

        Box* rtn;
        if (call_flags == METH_NOARGS) {
            {
                UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_builtins");
                rtn = (Box*)self->d_method->ml_meth(arg1, NULL);
            }
            if (rewrite_args)
                rewrite_args->out_rtn
                    = rewrite_args->rewriter->call(true, (void*)self->d_method->ml_meth, rewrite_args->arg1,
                                                   rewrite_args->rewriter->loadConst(0, Location::forArg(1)))
                          ->setType(RefType::OWNED);
        } else if (call_flags == METH_VARARGS) {
            {
                UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_builtins");
                rtn = (Box*)self->d_method->ml_meth(arg1, arg2);
            }
            if (rewrite_args)
                rewrite_args->out_rtn
                    = rewrite_args->rewriter->call(true, (void*)self->d_method->ml_meth, rewrite_args->arg1,
                                                   rewrite_args->arg2)->setType(RefType::OWNED);
        } else if (call_flags == (METH_VARARGS | METH_KEYWORDS)) {
            {
                UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_builtins");
                rtn = (Box*)((PyCFunctionWithKeywords)self->d_method->ml_meth)(arg1, arg2, arg3);
            }
            if (rewrite_args)
                rewrite_args->out_rtn
                    = rewrite_args->rewriter->call(true, (void*)self->d_method->ml_meth, rewrite_args->arg1,
                                                   rewrite_args->arg2, rewrite_args->arg3)->setType(RefType::OWNED);
        } else if (call_flags == METH_O) {
            {
                UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_builtins");
                rtn = (Box*)self->d_method->ml_meth(arg1, arg2);
            }
            if (rewrite_args)
                rewrite_args->out_rtn
                    = rewrite_args->rewriter->call(true, (void*)self->d_method->ml_meth, rewrite_args->arg1,
                                                   rewrite_args->arg2)->setType(RefType::OWNED);
        } else if ((call_flags & ~(METH_O3 | METH_D3)) == 0) {
            {
                UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_builtins");
                rtn = ((Box * (*)(Box*, Box*, Box*, Box**))self->d_method->ml_meth)(arg1, arg2, arg3, args);
            }
            if (rewrite_args) {
                if (paramspec.totalReceived() == 2)
                    rewrite_args->out_rtn
                        = rewrite_args->rewriter->call(true, (void*)self->d_method->ml_meth, rewrite_args->arg1,
                                                       rewrite_args->arg2)->setType(RefType::OWNED);
                else if (paramspec.totalReceived() == 3)
                    rewrite_args->out_rtn
                        = rewrite_args->rewriter->call(true, (void*)self->d_method->ml_meth, rewrite_args->arg1,
                                                       rewrite_args->arg2, rewrite_args->arg3)->setType(RefType::OWNED);
                else if (paramspec.totalReceived() > 3)
                    rewrite_args->out_rtn
                        = rewrite_args->rewriter->call(true, (void*)self->d_method->ml_meth, rewrite_args->arg1,
                                                       rewrite_args->arg2, rewrite_args->arg3,
                                                       rewrite_args->args)->setType(RefType::OWNED);
                else
                    abort();
            }
        } else {
            RELEASE_ASSERT(0, "0x%x", call_flags);
        }

        if (!rtn)
            throwCAPIException();

        if (rewrite_args) {
            rewrite_args->rewriter->checkAndThrowCAPIException(rewrite_args->out_rtn);
            rewrite_args->out_success = true;
        }

        return rtn;
    };

    return rearrangeArgumentsAndCall(paramspec, NULL, self->d_method->ml_name, defaults, rewrite_args, argspec, arg1,
                                     arg2, arg3, args, keyword_names, continuation);
}
Exemple #22
0
Box* wrapperDescrTppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2,
                         Box* arg3, Box** args, const std::vector<BoxedString*>* keyword_names) noexcept(S == CAPI) {
    if (S == CAPI) {
        try {
            return wrapperDescrTppCall<CXX>(_self, NULL, argspec, arg1, arg2, arg3, args, keyword_names);
        } catch (ExcInfo e) {
            setCAPIException(e);
            return NULL;
        }
    }

    if (rewrite_args) {
        // We are going to embed references to _self->d_base->wrapper and _self->d_wrapped
        rewrite_args->obj->addGuard((intptr_t)_self);
        rewrite_args->rewriter->addGCReference(_self);
    }

    STAT_TIMER(t0, "us_timer_boxedwrapperdecsriptor_call", (_self->cls->is_user_defined ? 10 : 20));

    assert(_self->cls == &PyWrapperDescr_Type);
    PyWrapperDescrObject* self = reinterpret_cast<PyWrapperDescrObject*>(_self);

    int flags = self->d_base->flags;
    wrapperfunc wrapper = self->d_base->wrapper;

    ParamReceiveSpec paramspec(1, 0, true, false);
    if (flags == PyWrapperFlag_KEYWORDS) {
        paramspec = ParamReceiveSpec(1, 0, true, true);
    } else if (flags == PyWrapperFlag_PYSTON || flags == 0) {
        paramspec = ParamReceiveSpec(1, 0, true, false);
    } else if (flags == PyWrapperFlag_1ARG) {
        paramspec = ParamReceiveSpec(1, 0, false, false);
    } else if (flags == PyWrapperFlag_2ARG) {
        paramspec = ParamReceiveSpec(2, 0, false, false);
    } else {
        RELEASE_ASSERT(0, "%d", flags);
    }

    auto continuation = [=](CallRewriteArgs* rewrite_args, Box* arg1, Box* arg2, Box* arg3, Box** args) {
#ifndef NDEBUG
        if (paramspec.takes_varargs)
            assert(arg2 && arg2->cls == tuple_cls);
#endif

        Box* rtn;
        if (flags == PyWrapperFlag_KEYWORDS) {
            wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
            rtn = (*wk)(arg1, arg2, self->d_wrapped, arg3);

            if (rewrite_args) {
                auto rewriter = rewrite_args->rewriter;
                rewrite_args->out_rtn
                    = rewriter->call(true, (void*)wk, rewrite_args->arg1, rewrite_args->arg2,
                                     rewriter->loadConst((intptr_t)self->d_wrapped, Location::forArg(2)),
                                     rewrite_args->arg3)->setType(RefType::OWNED);
                rewrite_args->rewriter->checkAndThrowCAPIException(rewrite_args->out_rtn);
                rewrite_args->out_success = true;
            }
        } else if (flags == PyWrapperFlag_PYSTON || flags == 0) {
            rtn = (*wrapper)(arg1, arg2, self->d_wrapped);

            if (rewrite_args) {
                auto rewriter = rewrite_args->rewriter;
                rewrite_args->out_rtn
                    = rewriter->call(true, (void*)wrapper, rewrite_args->arg1, rewrite_args->arg2,
                                     rewriter->loadConst((intptr_t)self->d_wrapped, Location::forArg(2)))
                          ->setType(RefType::OWNED);
                rewrite_args->rewriter->checkAndThrowCAPIException(rewrite_args->out_rtn);
                rewrite_args->out_success = true;
            }
        } else if (flags == PyWrapperFlag_1ARG) {
            wrapperfunc_1arg wrapper_1arg = (wrapperfunc_1arg)wrapper;
            rtn = (*wrapper_1arg)(arg1, self->d_wrapped);

            if (rewrite_args) {
                auto rewriter = rewrite_args->rewriter;
                rewrite_args->out_rtn
                    = rewriter->call(true, (void*)wrapper, rewrite_args->arg1,
                                     rewriter->loadConst((intptr_t)self->d_wrapped, Location::forArg(1)))
                          ->setType(RefType::OWNED);
                rewrite_args->rewriter->checkAndThrowCAPIException(rewrite_args->out_rtn);
                rewrite_args->out_success = true;
            }
        } else if (flags == PyWrapperFlag_2ARG) {
            rtn = (*wrapper)(arg1, arg2, self->d_wrapped);

            if (rewrite_args) {
                auto rewriter = rewrite_args->rewriter;
                rewrite_args->out_rtn
                    = rewriter->call(true, (void*)wrapper, rewrite_args->arg1, rewrite_args->arg2,
                                     rewriter->loadConst((intptr_t)self->d_wrapped, Location::forArg(2)))
                          ->setType(RefType::OWNED);
                rewrite_args->rewriter->checkAndThrowCAPIException(rewrite_args->out_rtn);
                rewrite_args->out_success = true;
            }
        } else {
            RELEASE_ASSERT(0, "%d", flags);
        }

        if (S == CXX && !rtn)
            throwCAPIException();
        return rtn;
    };

    return callCXXFromStyle<S>([&]() {
        return rearrangeArgumentsAndCall(paramspec, NULL, self->d_base->name, NULL, rewrite_args, argspec, arg1, arg2,
                                         arg3, args, keyword_names, continuation);
    });
}
Exemple #23
0
Box* superGetattribute(Box* _s, Box* _attr) {
    RELEASE_ASSERT(_s->cls == super_cls, "");
    BoxedSuper* s = static_cast<BoxedSuper*>(_s);

    RELEASE_ASSERT(_attr->cls == str_cls, "");
    BoxedString* attr = static_cast<BoxedString*>(_attr);

    bool skip = s->obj_type == NULL;

    if (!skip) {
        // Looks like __class__ is supposed to be "super", not the class of the the proxied object.
        skip = (attr->s() == class_str);
    }

    if (!skip) {
        PyObject* mro, *res, *tmp, *dict;
        PyTypeObject* starttype;
        descrgetfunc f;
        Py_ssize_t i, n;

        starttype = s->obj_type;
        mro = starttype->tp_mro;

        if (mro == NULL)
            n = 0;
        else {
            assert(PyTuple_Check(mro));
            n = PyTuple_GET_SIZE(mro);
        }
        for (i = 0; i < n; i++) {
            if ((PyObject*)(s->type) == PyTuple_GET_ITEM(mro, i))
                break;
        }
        i++;
        res = NULL;
        for (; i < n; i++) {
            tmp = PyTuple_GET_ITEM(mro, i);

// Pyston change:
#if 0
            if (PyType_Check(tmp))
                dict = ((PyTypeObject *)tmp)->tp_dict;
            else if (PyClass_Check(tmp))
                dict = ((PyClassObject *)tmp)->cl_dict;
            else
                continue;
            res = PyDict_GetItem(dict, name);
#endif
            res = tmp->getattr(attr);

            if (res != NULL) {
// Pyston change:
#if 0
                Py_INCREF(res);
                f = Py_TYPE(res)->tp_descr_get;
                if (f != NULL) {
                    tmp = f(res,
                        /* Only pass 'obj' param if
                           this is instance-mode sper
                           (See SF ID #743627)
                        */
                        (s->obj == (PyObject *)
                                    s->obj_type
                            ? (PyObject *)NULL
                            : s->obj),
                        (PyObject *)starttype);
                    Py_DECREF(res);
                    res = tmp;
                }
#endif
                return processDescriptor(res, (s->obj == s->obj_type ? None : s->obj), s->obj_type);
            }
        }
    }

    Box* rtn = PyObject_GenericGetAttr(s, attr);
    if (!rtn)
        throwCAPIException();
    return rtn;
}
Exemple #24
0
Box* BoxedMethodDescriptor::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1,
                                    Box* arg2, Box* arg3, Box** args, const std::vector<BoxedString*>* keyword_names) {
    STAT_TIMER(t0, "us_timer_boxedmethoddescriptor__call__", 10);

    assert(_self->cls == method_cls);
    BoxedMethodDescriptor* self = static_cast<BoxedMethodDescriptor*>(_self);

    int ml_flags = self->method->ml_flags;
    int call_flags = ml_flags & (~METH_CLASS);

    if (rewrite_args && !rewrite_args->func_guarded) {
        rewrite_args->obj->addAttrGuard(offsetof(BoxedMethodDescriptor, method), (intptr_t)self->method);
    }

    ParamReceiveSpec paramspec(0, 0, false, false);
    if (call_flags == METH_NOARGS) {
        paramspec = ParamReceiveSpec(1, 0, false, false);
    } else if (call_flags == METH_VARARGS) {
        paramspec = ParamReceiveSpec(1, 0, true, false);
    } else if (call_flags == (METH_VARARGS | METH_KEYWORDS)) {
        paramspec = ParamReceiveSpec(1, 0, true, true);
    } else if (call_flags == METH_O) {
        paramspec = ParamReceiveSpec(2, 0, false, false);
    } else {
        RELEASE_ASSERT(0, "0x%x", call_flags);
    }

    Box* oarg1 = NULL;
    Box* oarg2 = NULL;
    Box* oarg3 = NULL;
    Box** oargs = NULL;

    bool rewrite_success = false;
    rearrangeArguments(paramspec, NULL, self->method->ml_name, NULL, rewrite_args, rewrite_success, argspec, arg1, arg2,
                       arg3, args, keyword_names, oarg1, oarg2, oarg3, args);

    if (!rewrite_success)
        rewrite_args = NULL;

    if (ml_flags & METH_CLASS) {
        rewrite_args = NULL;
        if (!isSubclass(oarg1->cls, type_cls))
            raiseExcHelper(TypeError, "descriptor '%s' requires a type but received a '%s'", self->method->ml_name,
                           getFullTypeName(oarg1).c_str());
    } else {
        if (!isSubclass(oarg1->cls, self->type))
            raiseExcHelper(TypeError, "descriptor '%s' requires a '%s' oarg1 but received a '%s'",
                           self->method->ml_name, getFullNameOfClass(self->type).c_str(),
                           getFullTypeName(oarg1).c_str());
    }

    if (rewrite_args) {
        rewrite_args->arg1->addAttrGuard(offsetof(Box, cls), (intptr_t)oarg1->cls);
    }

    Box* rtn;
    if (call_flags == METH_NOARGS) {
        {
            UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_builtins");
            rtn = (Box*)self->method->ml_meth(oarg1, NULL);
        }
        if (rewrite_args)
            rewrite_args->out_rtn
                = rewrite_args->rewriter->call(true, (void*)self->method->ml_meth, rewrite_args->arg1,
                                               rewrite_args->rewriter->loadConst(0, Location::forArg(1)));
    } else if (call_flags == METH_VARARGS) {
        {
            UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_builtins");
            rtn = (Box*)self->method->ml_meth(oarg1, oarg2);
        }
        if (rewrite_args)
            rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)self->method->ml_meth, rewrite_args->arg1,
                                                                 rewrite_args->arg2);
    } else if (call_flags == (METH_VARARGS | METH_KEYWORDS)) {
        {
            UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_builtins");
            rtn = (Box*)((PyCFunctionWithKeywords)self->method->ml_meth)(oarg1, oarg2, oarg3);
        }
        if (rewrite_args)
            rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)self->method->ml_meth, rewrite_args->arg1,
                                                                 rewrite_args->arg2, rewrite_args->arg3);
    } else if (call_flags == METH_O) {
        {
            UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_builtins");
            rtn = (Box*)self->method->ml_meth(oarg1, oarg2);
        }
        if (rewrite_args)
            rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)self->method->ml_meth, rewrite_args->arg1,
                                                                 rewrite_args->arg2);
    } else {
        RELEASE_ASSERT(0, "0x%x", call_flags);
    }

    if (!rtn)
        throwCAPIException();

    if (rewrite_args) {
        rewrite_args->rewriter->call(false, (void*)checkAndThrowCAPIException);
        rewrite_args->out_success = true;
    }

    return rtn;
}