Ejemplo n.º 1
0
Box* BoxedWrapperObject::__call__(BoxedWrapperObject* self, Box* args, Box* kwds) {
    STAT_TIMER(t0, "us_timer_boxedwrapperobject__call__", (self->cls->is_user_defined ? 1 : 2));

    assert(self->cls == wrapperobject_cls);
    assert(args->cls == tuple_cls);
    assert(kwds->cls == dict_cls);

    int flags = self->descr->wrapper->flags;
    wrapperfunc wrapper = self->descr->wrapper->wrapper;
    assert(self->descr->wrapper->offset > 0);

    Box* rtn;
    if (flags == PyWrapperFlag_KEYWORDS) {
        wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
        rtn = (*wk)(self->obj, args, self->descr->wrapped, kwds);
    } else if (flags == PyWrapperFlag_PYSTON || flags == 0) {
        rtn = (*wrapper)(self->obj, args, self->descr->wrapped);
    } else {
        RELEASE_ASSERT(0, "%d", flags);
    }

    checkAndThrowCAPIException();
    assert(rtn && "should have set + thrown an exception!");
    return rtn;
}
Ejemplo n.º 2
0
BoxedLong* _longNew(Box* val, Box* _base) {
    BoxedLong* rtn = new BoxedLong();
    if (_base) {
        if (!isSubclass(_base->cls, int_cls))
            raiseExcHelper(TypeError, "an integer is required");
        int base = static_cast<BoxedInt*>(_base)->n;

        if (!isSubclass(val->cls, str_cls))
            raiseExcHelper(TypeError, "long() can't convert non-string with explicit base");
        BoxedString* s = static_cast<BoxedString*>(val);

        rtn = (BoxedLong*)PyLong_FromString(s->data(), NULL, base);
        checkAndThrowCAPIException();
    } else {
        if (isSubclass(val->cls, long_cls)) {
            BoxedLong* l = static_cast<BoxedLong*>(val);
            if (val->cls == long_cls)
                return l;
            BoxedLong* rtn = new BoxedLong();
            mpz_init_set(rtn->n, l->n);
            return rtn;
        } else if (isSubclass(val->cls, int_cls)) {
            mpz_init_set_si(rtn->n, static_cast<BoxedInt*>(val)->n);
        } else if (val->cls == str_cls) {
            llvm::StringRef s = static_cast<BoxedString*>(val)->s();
            assert(s.data()[s.size()] == '\0');
            int r = mpz_init_set_str(rtn->n, s.data(), 10);
            RELEASE_ASSERT(r == 0, "");
        } else if (val->cls == float_cls) {
            mpz_init_set_si(rtn->n, static_cast<BoxedFloat*>(val)->d);
        } else {
            static BoxedString* long_str = static_cast<BoxedString*>(PyString_InternFromString("__long__"));
            Box* r = callattr(val, long_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }),
                              ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);

            if (!r) {
                fprintf(stderr, "TypeError: long() argument must be a string or a number, not '%s'\n",
                        getTypeName(val));
                raiseExcHelper(TypeError, "");
            }

            if (isSubclass(r->cls, int_cls)) {
                mpz_init_set_si(rtn->n, static_cast<BoxedInt*>(r)->n);
            } else if (!isSubclass(r->cls, long_cls)) {
                raiseExcHelper(TypeError, "__long__ returned non-long (type %s)", r->cls->tp_name);
            } else {
                return static_cast<BoxedLong*>(r);
            }
        }
    }
Ejemplo n.º 3
0
Box* BoxedMethodDescriptor::__call__(BoxedMethodDescriptor* self, Box* obj, BoxedTuple* varargs, Box** _args) {
    STAT_TIMER(t0, "us_timer_boxedmethoddescriptor__call__", 10);
    BoxedDict* kwargs = static_cast<BoxedDict*>(_args[0]);

    assert(self->cls == method_cls);
    assert(varargs->cls == tuple_cls);
    assert(kwargs->cls == dict_cls);

    int ml_flags = self->method->ml_flags;

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

    threading::GLPromoteRegion _gil_lock;

    Box* rtn;
    if (call_flags == METH_NOARGS) {
        RELEASE_ASSERT(varargs->size() == 0, "");
        RELEASE_ASSERT(kwargs->d.size() == 0, "");
        rtn = (Box*)self->method->ml_meth(obj, NULL);
    } else if (call_flags == METH_VARARGS) {
        RELEASE_ASSERT(kwargs->d.size() == 0, "");
        rtn = (Box*)self->method->ml_meth(obj, varargs);
    } else if (call_flags == (METH_VARARGS | METH_KEYWORDS)) {
        rtn = (Box*)((PyCFunctionWithKeywords)self->method->ml_meth)(obj, varargs, kwargs);
    } else if (call_flags == METH_O) {
        RELEASE_ASSERT(kwargs->d.size() == 0, "");
        RELEASE_ASSERT(varargs->size() == 1, "");
        rtn = (Box*)self->method->ml_meth(obj, varargs->elts[0]);
    } else {
        RELEASE_ASSERT(0, "0x%x", call_flags);
    }

    checkAndThrowCAPIException();
    assert(rtn && "should have set + thrown an exception!");
    return rtn;
}
Ejemplo n.º 4
0
Box* BoxedWrapperObject::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2,
                                 Box* arg3, Box** args, const std::vector<BoxedString*>* keyword_names) {
    assert(_self->cls == wrapperobject_cls);
    BoxedWrapperObject* self = static_cast<BoxedWrapperObject*>(_self);

    int flags = self->descr->wrapper->flags;
    wrapperfunc wrapper = self->descr->wrapper->wrapper;
    assert(self->descr->wrapper->offset > 0);

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

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

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

    bool rewrite_success = false;
    rearrangeArguments(paramspec, NULL, self->descr->wrapper->name.data(), NULL, rewrite_args, rewrite_success, argspec,
                       arg1, arg2, arg3, args, keyword_names, oarg1, oarg2, oarg3, args);

    assert(oarg1 && oarg1->cls == tuple_cls);
    if (!paramspec.takes_kwargs)
        assert(oarg2 == NULL);
    assert(oarg3 == NULL);
    assert(oargs == NULL);

    if (!rewrite_success)
        rewrite_args = NULL;

    Box* rtn;
    if (flags == PyWrapperFlag_KEYWORDS) {
        wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
        rtn = (*wk)(self->obj, oarg1, self->descr->wrapped, oarg2);

        if (rewrite_args) {
            auto rewriter = rewrite_args->rewriter;
            auto r_obj = rewrite_args->obj->getAttr(offsetof(BoxedWrapperObject, obj), Location::forArg(0));
            rewrite_args->out_rtn = rewriter->call(
                true, (void*)wk, r_obj, rewrite_args->arg1,
                rewriter->loadConst((intptr_t)self->descr->wrapped, Location::forArg(2)), rewrite_args->arg2);
            rewriter->call(false, (void*)checkAndThrowCAPIException);
            rewrite_args->out_success = true;
        }
    } else if (flags == PyWrapperFlag_PYSTON || flags == 0) {
        rtn = (*wrapper)(self->obj, oarg1, self->descr->wrapped);

        if (rewrite_args) {
            auto rewriter = rewrite_args->rewriter;
            auto r_obj = rewrite_args->obj->getAttr(offsetof(BoxedWrapperObject, obj), Location::forArg(0));
            rewrite_args->out_rtn
                = rewriter->call(true, (void*)wrapper, r_obj, rewrite_args->arg1,
                                 rewriter->loadConst((intptr_t)self->descr->wrapped, Location::forArg(2)));
            rewriter->call(false, (void*)checkAndThrowCAPIException);
            rewrite_args->out_success = true;
        }
    } else {
        RELEASE_ASSERT(0, "%d", flags);
    }

    checkAndThrowCAPIException();
    assert(rtn && "should have set + thrown an exception!");
    return rtn;
}