static const char* kname(Proto* p, int c) { if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) return svalue(&p->k[INDEXK(c)]); else return "?"; }
static int do_getinstruction(lua_State *L) /** getinstruction(f,i) */ { const Proto* f=Pget(L,1); int pc=luaL_checkinteger(L,2); if (pc<=0 || pc>f->sizecode || f->code==NULL) return 0; pc--; { const Instruction* code=f->code; Instruction i=code[pc]; OpCode o=GET_OPCODE(i); int a=GETARG_A(i); int b=GETARG_B(i); int c=GETARG_C(i); int ax=GETARG_Ax(i); int bx=GETARG_Bx(i); int sbx=GETARG_sBx(i); int line=getfuncline(f,pc); if (line>0) lua_pushinteger(L,line); else lua_pushnil(L); lua_pushstring(L,luaP_opnames[o]); switch (getOpMode(o)) { case iABC: lua_pushinteger(L,a); if (getBMode(o)!=OpArgN) lua_pushinteger(L,ISK(b) ? (MYK(INDEXK(b))) : b); else lua_pushnil(L); if (getCMode(o)!=OpArgN) lua_pushinteger(L,ISK(c) ? (MYK(INDEXK(c))) : c); else lua_pushnil(L); break; case iABx: lua_pushinteger(L,a); if (getBMode(o)==OpArgK) lua_pushinteger(L,MYK(bx)); else lua_pushinteger(L,bx); lua_pushnil(L); break; case iAsBx: lua_pushinteger(L,a); lua_pushinteger(L,sbx); lua_pushnil(L); break; case iAx: lua_pushinteger(L,MYK(ax)); lua_pushnil(L); lua_pushnil(L); break; } switch (o) { case OP_JMP: case OP_FORLOOP: case OP_FORPREP: case OP_TFORLOOP: lua_pop(L,1); lua_pushinteger(L,sbx+pc+2); break; default: break; } } return 5; }
/* local op, a, b, c, test = jit.util.bytecode(func, pc) */ static int ju_bytecode(lua_State *L) { Proto *pt = check_LCL(L)->l.p; int pc = luaL_checkint(L, 2); if (pc >= 1 && pc <= pt->sizecode) { Instruction ins = pt->code[pc-1]; OpCode op = GET_OPCODE(ins); if (pc > 1 && (((int)OP_SETLIST) << POS_OP) == (pt->code[pc-2] & (MASK1(SIZE_OP,POS_OP) | MASK1(SIZE_C,POS_C)))) { lua_pushstring(L, luaP_opnames[OP_SETLIST]); lua_pushnumber(L, (lua_Number)ins); /* Fake extended op. */ return 1; } if (op >= NUM_OPCODES) return 0; /* Just in case. */ lua_pushstring(L, luaP_opnames[op]); lua_pushinteger(L, GETARG_A(ins)); switch (getOpMode(op)) { case iABC: { int b = GETARG_B(ins), c = GETARG_C(ins); switch (getBMode(op)) { case OpArgN: lua_pushnil(L); break; case OpArgK: if (ISK(b)) b = -1-INDEXK(b); case OpArgR: case OpArgU: lua_pushinteger(L, b); break; } switch (getCMode(op)) { case OpArgN: lua_pushnil(L); break; case OpArgK: if (ISK(c)) c = -1-INDEXK(c); case OpArgR: case OpArgU: lua_pushinteger(L, c); break; } lua_pushboolean(L, testTMode(op)); return 5; } case iABx: { int bx = GETARG_Bx(ins); lua_pushinteger(L, getBMode(op) == OpArgK ? -1-bx : bx); return 3; } case iAsBx: lua_pushinteger(L, GETARG_sBx(ins)); return 3; } } return 0; }
/* * This function must be called before all code loaded. */ void kp_optimize_code(ktap_state *ks, int level, ktap_proto *f) { int i; for (i = 0; i < f->sizecode; i++) { int instr = f->code[i]; ktap_value *k = f->k; if (GET_OPCODE(instr) == OP_GETTABUP) { if ((GETARG_B(instr) == 0) && ISK(GETARG_C(instr))) { ktap_value *field = k + INDEXK(GETARG_C(instr)); if (ttype(field) == KTAP_TSTRING) { int index = cfunction_cache_getindex(ks, field); if (index == -1) break; SET_OPCODE(instr, OP_LOAD_GLOBAL); SETARG_C(instr, index); f->code[i] = instr; break; } } } } /* continue optimize sub functions */ for (i = 0; i < f->sizep; i++) kp_optimize_code(ks, level + 1, f->p[i]); }
/** * Is the operand a reference to a short string constant? */ static int isshortstr(FuncState *fs, int kk) { if (ISK(kk)) { Proto *f = fs->f; kk = INDEXK(kk); lua_assert(kk >= 0 && kk < f->sizek); return ttisshrstring(&f->k[kk]); } return 0; }
static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { switch (mode) { case OpArgN: check(r == 0); break; case OpArgU: break; case OpArgR: checkreg(pt, r); break; case OpArgK: check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize); break; } return 1; }
void RaviCodeGenerator::emit_BITWISE_SHIFT_OP(RaviFunctionDef *def, OpCode op, int A, int B, int C, int pc) { bool traced = emit_debug_trace(def, op, pc); emit_load_base(def); llvm::Value *ra = emit_gep_register(def, A); // If the RHS is a constant and we know that LHS is // and integer then we can optimize the code generation if (op == OP_RAVI_SHL_II && ISK(C)) { lua_Integer y = def->p->k[INDEXK(C)].value_.i; emit_bitwise_shiftl(def, ra, B, y); } else if (op == OP_RAVI_SHR_II && ISK(C)) { lua_Integer y = def->p->k[INDEXK(C)].value_.i; emit_bitwise_shiftl(def, ra, B, -y); } else { // RHS is not a constant llvm::Value *rc = emit_gep_register_or_constant(def, C); llvm::Value *rb = emit_gep_register_or_constant(def, B); // Since the Lua OP_SHL and OP_SHR bytecodes // could invoke metamethods we need to set // 'savedpc' switch (op) { case OP_SHL: if (!traced) emit_update_savedpc(def, pc); case OP_RAVI_SHL_II: CreateCall4(def->builder, def->raviV_op_shlF, def->L, ra, rb, rc); break; case OP_SHR: if (!traced) emit_update_savedpc(def, pc); case OP_RAVI_SHR_II: CreateCall4(def->builder, def->raviV_op_shrF, def->L, ra, rb, rc); break; default: fprintf(stderr, "unexpected value of opcode %d\n", (int)op); abort(); } } }
/* ** find a "name" for the RK value 'c' */ static void kname (Proto *p, int pc, int c, const char **name) { if (ISK(c)) { /* is 'c' a constant? */ TValue *kvalue = &p->k[INDEXK(c)]; if (ttisstring(kvalue)) { /* literal constant? */ *name = svalue(kvalue); /* it is its own name */ return; } /* else no reasonable name found */ } else { /* 'c' is a register */ const char *what = getobjname(p, pc, c, name); /* search for 'c' */ if (what && *what == 'c') { /* found a constant name? */ return; /* 'name' already filled */ } /* else no reasonable name found */ } *name = "?"; /* no reasonable name found */ }
/* ** find a "name" for the RK value 'c' */ void kname2 (LuaProto *p, int pc, int c, std::string& name) { if (ISK(c)) { /* is 'c' a constant? */ LuaValue *kvalue = &p->constants[INDEXK(c)]; if (kvalue->isString()) { /* literal constant? */ name = kvalue->getString()->c_str(); /* it is its own name */ return; } /* else no reasonable name found */ } else { /* 'c' is a register */ const char *what = getobjname2(p, pc, c, name); /* search for 'c' */ if (what && *what == 'c') { /* found a constant name? */ return; /* 'name' already filled */ } /* else no reasonable name found */ } name = "?"; /* no reasonable name found */ }
static void PrintCode(const Proto* f) { const Instruction* code=f->code; int pc,n=f->sizecode; for (pc=0; pc<n; pc++) { Instruction i=code[pc]; OpCode o=GET_OPCODE(i); int a=GETARG_A(i); int b=GETARG_B(i); int c=GETARG_C(i); int ax=GETARG_Ax(i); int bx=GETARG_Bx(i); int sbx=GETARG_sBx(i); int line=getfuncline(f,pc); printf("\t%d\t",pc+1); if (line>0) printf("[%d]\t",line); else printf("[-]\t"); printf("%-9s\t",luaP_opnames[o]); switch (getOpMode(o)) { case iABC: printf("%d",a); if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (MYK(INDEXK(b))) : b); if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (MYK(INDEXK(c))) : c); break; case iABx: printf("%d",a); if (getBMode(o)==OpArgK) printf(" %d",MYK(bx)); if (getBMode(o)==OpArgU) printf(" %d",bx); break; case iAsBx: printf("%d %d",a,sbx); break; case iAx: printf("%d",MYK(ax)); break; } switch (o) { case OP_LOADK: printf("\t; "); PrintConstant(f,bx); break; case OP_GETUPVAL: case OP_SETUPVAL: printf("\t; %s",UPVALNAME(b)); break; case OP_GETTABUP: printf("\t; %s",UPVALNAME(b)); if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); } break; case OP_SETTABUP: printf("\t; %s",UPVALNAME(a)); if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); } if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); } break; case OP_GETTABLE: case OP_SELF: if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); } break; case OP_SETTABLE: case OP_ADD: case OP_SUB: case OP_MUL: case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND: case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: case OP_EQ: case OP_LT: case OP_LE: if (ISK(b) || ISK(c)) { printf("\t; "); if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); printf(" "); if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); } break; case OP_JMP: case OP_FORLOOP: case OP_FORPREP: case OP_TFORLOOP: printf("\t; to %d",sbx+pc+2); break; case OP_CLOSURE: printf("\t; %p",VOID(f->p[bx])); break; case OP_SETLIST: if (c==0) printf("\t; %d",(int)code[++pc]); else printf("\t; %d",c); break; case OP_EXTRAARG: printf("\t; "); PrintConstant(f,ax); break; default: break; } printf("\n"); } }
static void PrintCode(const Proto* f) { const Instruction* code=f->code; int pc,n=f->sizecode; for (pc=0; pc<n; pc++) { Instruction i=code[pc]; OpCode o=GET_OPCODE(i); int a=GETARG_A(i); int b=GETARG_B(i); int c=GETARG_C(i); int bx=GETARG_Bx(i); int sbx=GETARG_sBx(i); int line=getline(f,pc); printf("\t%d\t",pc+1); if (line>0) printf("[%d]\t",line); else printf("[-]\t"); printf("%-9s\t",luaP_opnames[o]); switch (getOpMode(o)) { case iABC: printf("%d",a); if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b); if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); break; case iABx: if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx); break; case iAsBx: if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); break; } switch (o) { case OP_LOADK: printf("\t; "); PrintConstant(f,bx); break; case OP_GETUPVAL: case OP_SETUPVAL: printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-"); break; case OP_GETGLOBAL: case OP_SETGLOBAL: printf("\t; %s",svalue(&f->k[bx])); break; case OP_GETTABLE: case OP_SELF: if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); } break; case OP_SETTABLE: case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_POW: case OP_EQ: case OP_LT: case OP_LE: if (ISK(b) || ISK(c)) { printf("\t; "); if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); printf(" "); if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); } break; case OP_JMP: case OP_FORLOOP: case OP_FORPREP: printf("\t; to %d",sbx+pc+2); break; case OP_CLOSURE: printf("\t; %p",VOID(f->p[bx])); break; case OP_SETLIST: if (c==0) printf("\t; %d",(int)code[++pc]); else printf("\t; %d",c); break; default: break; } printf("\n"); } }
const char* raviP_instruction_to_str(char *buf, size_t n, Instruction i) { OpCode o = GET_OPCODE(i); int a = GETARG_A(i); int b = GETARG_B(i); int c = GETARG_C(i); int ax = GETARG_Ax(i); int bx = GETARG_Bx(i); int sbx = GETARG_sBx(i); snprintf(buf, n, "%s ", luaP_opnames[o]); switch (getOpMode(o)) { case iABC: snprintf(buf+strlen(buf), n-strlen(buf), "A=%d", a); if (getBMode(o) != OpArgN) snprintf(buf + strlen(buf), n - strlen(buf), " B=%d", (getBMode(o) == OpArgK && ISK(b)) ? (MYK(INDEXK(b))) : b); if (getCMode(o) != OpArgN) snprintf(buf + strlen(buf), n - strlen(buf), " C=%d", (getCMode(o) == OpArgK && ISK(c)) ? (MYK(INDEXK(c))) : c); break; case iABx: snprintf(buf + strlen(buf), n - strlen(buf), "A=%d", a); if (getBMode(o) == OpArgK) snprintf(buf + strlen(buf), n - strlen(buf), " Bx=%d", MYK(bx)); if (getBMode(o) == OpArgU) snprintf(buf + strlen(buf), n - strlen(buf), " Bx=%d", bx); break; case iAsBx: snprintf(buf + strlen(buf), n - strlen(buf), "As=%d Bx=%d", a, sbx); break; case iAx: snprintf(buf + strlen(buf), n - strlen(buf), "Ax=%d", MYK(ax)); break; } return buf; }