コード例 #1
0
ファイル: PromiseMap.cpp プロジェクト: jafyvilla/Livre
 void flush( const std::string& name ) const
 {
     getPromise( name ).flush();
 }
コード例 #2
0
ファイル: PromiseMap.cpp プロジェクト: jafyvilla/Livre
 void reset( const std::string& name ) const
 {
     getPromise( name ).reset();
 }
コード例 #3
0
ファイル: CodeVerifier.cpp プロジェクト: reactorlabs/rir
void CodeVerifier::verifyFunctionLayout(SEXP sexp, InterpreterInstance* ctx) {
    if (TYPEOF(sexp) != EXTERNALSXP)
        Rf_error("RIR Verifier: Invalid SEXPTYPE");
    Function* f = Function::unpack(sexp);

    // get the code objects
    std::vector<Code*> objs;
    objs.push_back(f->body());
    for (size_t i = 0; i < f->numArgs; ++i)
        if (f->defaultArg(i))
            objs.push_back(f->defaultArg(i));

    if (f->size > XLENGTH(sexp))
        Rf_error("RIR Verifier: Reported size must be smaller than the size of "
                 "the vector");

    // check that the call instruction has proper arguments and number of
    // instructions is valid
    while (!objs.empty()) {
        auto c = objs.back();
        objs.pop_back();

        if (c->info.magic != CODE_MAGIC)
            Rf_error("RIR Verifier: Invalid code magic number");
        if (c->src == 0)
            Rf_error("RIR Verifier: Code must have AST");
        unsigned oldo = c->stackLength;
        calculateAndVerifyStack(c);
        if (oldo != c->stackLength)
            Rf_error("RIR Verifier: Invalid stack layout reported");

        if (((uintptr_t)(c + 1) + pad4(c->codeSize) +
             c->srcLength * sizeof(Code::SrclistEntry)) == 0)
            Rf_error("RIR Verifier: Invalid code length reported");

        Opcode* cptr = c->code();
        Opcode* start = cptr;
        Opcode* end = start + c->codeSize;
        while (true) {
            if (cptr > end)
                Rf_error("RIR Verifier: Bytecode overflow");
            BC cur = BC::decode(cptr, c);
            switch (hasSources(cur.bc)) {
            case Sources::Required:
                if (c->getSrcIdxAt(cptr, true) == 0)
                    Rf_error("RIR Verifier: Source required but not found");
                break;
            case Sources::NotNeeded:
                if (c->getSrcIdxAt(cptr, true) != 0)
                    Rf_error("RIR Verifier: Sources not needed but stored");
                break;
            case Sources::May: {
            }
            }
            if (*cptr == Opcode::br_ || *cptr == Opcode::brobj_ ||
                *cptr == Opcode::brtrue_ || *cptr == Opcode::brfalse_) {
                int off = *reinterpret_cast<int*>(cptr + 1);
                if (cptr + cur.size() + off < start ||
                    cptr + cur.size() + off > end)
                    Rf_error("RIR Verifier: Branch outside closure");
            }
            if (*cptr == Opcode::ldvar_) {
                unsigned* argsIndex = reinterpret_cast<Immediate*>(cptr + 1);
                if (*argsIndex >= cp_pool_length(ctx))
                    Rf_error("RIR Verifier: Invalid arglist index");
                SEXP sym = cp_pool_at(ctx, *argsIndex);
                if (TYPEOF(sym) != SYMSXP)
                    Rf_error("RIR Verifier: LdVar binding not a symbol");
                if (!(strlen(CHAR(PRINTNAME(sym)))))
                    Rf_error("RIR Verifier: LdVar empty binding name");
            }
            if (*cptr == Opcode::promise_) {
                unsigned* promidx = reinterpret_cast<Immediate*>(cptr + 1);
                objs.push_back(c->getPromise(*promidx));
            }
            if (*cptr == Opcode::ldarg_) {
                unsigned idx = *reinterpret_cast<Immediate*>(cptr + 1);
                if (idx >= MAX_ARG_IDX)
                    Rf_error("RIR Verifier: Loading out of index argument");
            }
            if (*cptr == Opcode::call_implicit_ ||
                *cptr == Opcode::named_call_implicit_) {
                uint32_t nargs = *reinterpret_cast<Immediate*>(cptr + 1);

                for (size_t i = 0, e = nargs; i != e; ++i) {
                    uint32_t offset = cur.callExtra().immediateCallArguments[i];
                    if (offset == MISSING_ARG_IDX || offset == DOTS_ARG_IDX)
                        continue;
                    objs.push_back(c->getPromise(offset));
                }
                if (*cptr == Opcode::named_call_implicit_) {
                    for (size_t i = 0, e = nargs; i != e; ++i) {
                        uint32_t offset = cur.callExtra().callArgumentNames[i];
                        if (offset) {
                            SEXP name = cp_pool_at(ctx, offset);
                            if (TYPEOF(name) != SYMSXP && name != R_NilValue)
                                Rf_error("RIR Verifier: Calling target not a "
                                         "symbol");
                        }
                    }
                }
            }
            if (*cptr == Opcode::named_call_) {
                uint32_t nargs = *reinterpret_cast<Immediate*>(cptr + 1);
                for (size_t i = 0, e = nargs; i != e; ++i) {
                    uint32_t offset = cur.callExtra().callArgumentNames[i];
                    if (offset) {
                        SEXP name = cp_pool_at(ctx, offset);
                        if (TYPEOF(name) != SYMSXP && name != R_NilValue)
                            Rf_error(
                                "RIR Verifier: Calling target not a symbol");
                    }
                }
            }
            if (*cptr == Opcode::mk_env_ || *cptr == Opcode::mk_stub_env_) {
                uint32_t nargs = *reinterpret_cast<Immediate*>(cptr + 1);
                for (size_t i = 0, e = nargs; i != e; ++i) {
                    uint32_t offset = cur.mkEnvExtra().names[i];
                    SEXP name = cp_pool_at(ctx, offset);
                    if (TYPEOF(name) != SYMSXP)
                        Rf_error(
                            "RIR Verifier: environment argument not a symbol");
                }
            }

            cptr += cur.size();
            if (cptr == start + c->codeSize) {
                if (!(cur.isJmp() && cur.immediate.offset < 0) &&
                    !(cur.isExit()))
                    Rf_error("RIR Verifier: Last opcode should jump backwards "
                             "or exit");
                break;
            }
        }
    }
}