Example #1
0
RewriterVar* JitFragmentWriter::imm(void* val) {
    return loadConst((uint64_t)val);
}
Example #2
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);
    });
}
Example #3
0
RewriterVar* JitFragmentWriter::imm(uint64_t val) {
    return loadConst(val);
}
Example #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;
}