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; }
static void freereg(FuncState *fs, int reg) { if (!ISK(reg) && reg >= fs->nactvar) { fs->freereg--; ktap_assert(reg == fs->freereg); } }
/* * 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]); }
static const char* kname(Proto* p, int c) { if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) return svalue(&p->k[INDEXK(c)]); else return "?"; }
/** * 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; }
/* ** finish execution of an opcode interrupted by an yield */ void luaV_finishOp (lua_State *L) { CallInfo *ci = L->ci; StkId base = ci->u.l.base; Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ OpCode op = GET_OPCODE(inst); switch (op) { /* finish its execution */ case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { setobjs2s(L, base + GETARG_A(inst), --L->top); break; } case OP_LE: case OP_LT: case OP_EQ: { int res = !l_isfalse(L->top - 1); L->top--; /* metamethod should not be called when operand is K */ lua_assert(!ISK(GETARG_B(inst))); if (op == OP_LE && /* "<=" using "<" instead? */ ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE))) res = !res; /* invert result */ lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); if (res != GETARG_A(inst)) /* condition failed? */ ci->u.l.savedpc++; /* skip jump instruction */ break; } case OP_CONCAT: { StkId top = L->top - 1; /* top when 'call_binTM' was called */ int b = GETARG_B(inst); /* first element to concatenate */ int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */ setobj2s(L, top - 2, top); /* put TM result in proper position */ if (total > 1) { /* are there elements to concat? */ L->top = top - 1; /* top is one after last element (at top-2) */ luaV_concat(L, total); /* concat them (may yield again) */ } /* move final result to final position */ setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1); L->top = ci->top; /* restore top */ break; } case OP_TFORCALL: { lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); L->top = ci->top; /* correct top */ break; } case OP_CALL: { if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ L->top = ci->top; /* adjust results */ break; } case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE: break; default: lua_assert(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 ICACHE_FLASH_ATTR freereg (FuncState *fs, int reg) { if (!ISK(reg) && reg >= fs->nactvar) { fs->freereg--; lua_assert(reg == fs->freereg); } }
/*static*/ void FuncState::freereg (/*FuncState *fs,*/ int reg) { if (!ISK(reg) && reg >= nactvar) { free_reg--; lua_assert(reg == free_reg); } }
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 freereg (FuncState *fs, int reg) { if (!ISK(reg)) { fs->freereg--; lua_assert(reg == fs->freereg); } }
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"); } }
int luaU_guess_locals(Proto* f, int main) { intArray blocklist; LocVarArray locallist; int regassign[MAXARG_A+1]; int regusage[MAXARG_A+1]; int regblock[MAXARG_A+1]; int lastfree; int i,i2,x,pc; int func_endpc = FUNC_BLOCK_END(f); if (f->lineinfo != NULL) { return 0; } if (f->sizelocvars > 0) { return 0; } intArray_Init(&blocklist, MAXARG_A+1); addi(blocklist, func_endpc); LocVarArray_Init(&locallist, MAXARG_A+1); lastfree = 0; for (i=0; i<f->maxstacksize; i++) { regassign[i] = 0; regusage[i] = 0; regblock[i] = 0; } // parameters for (i = 0; i < f->numparams; i++) { add(locallist,0,func_endpc); regassign[lastfree] = 0; regusage[lastfree] = 1; regblock[lastfree] = func_endpc; lastfree++; } // vararg if (NEED_ARG(f)) { add(locallist,0,func_endpc); lastfree++; regassign[lastfree] = 0; regusage[lastfree] = 1; regblock[lastfree] = func_endpc; lastfree++; } #if LUA_VERSION_NUM == 501 // nil optimizations { Instruction i = f->code[0]; OpCode o = GET_OPCODE(i); int a = GETARG_A(i); int b = GETARG_B(i); int c = GETARG_C(i); int ixx,num_nil = -1; switch (o) { // read Ra only case OP_SETGLOBAL: case OP_SETUPVAL: case OP_TESTSET: num_nil = a; break; // read Rb only case OP_MOVE: case OP_UNM: case OP_NOT: case OP_LEN: if (!ISK(b)) { num_nil = b; } break; // read Rb and Rc case OP_GETTABLE: case OP_SETTABLE: case OP_SELF: case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_MOD: case OP_POW: case OP_EQ: case OP_LT: case OP_LE: if (!ISK(b)) { num_nil = b; } if (!ISK(c)) { num_nil = MAX(num_nil, c); } break; case OP_RETURN: // read Ra to a+b-2 // only return 1 value // move before return multiple values num_nil = MAX(num_nil, a+b-2); break; } for (ixx = lastfree; ixx <= num_nil; ixx++) { if (ixx!=num_nil) { add(locallist,0,last(blocklist)); lastfree++; } regassign[lastfree] = 0; regusage[lastfree] = 1; regblock[lastfree] = last(blocklist); lastfree++; } } #endif // start code checking for (pc = 0; pc < f->sizecode; pc++) { Instruction instr = f->code[pc]; OpCode o = GET_OPCODE(instr); int a = GETARG_A(instr); int b = GETARG_B(instr); int c = GETARG_C(instr); int bc = GETARG_Bx(instr); int sbc = GETARG_sBx(instr); int dest = 0; int setreg = -1; int setregto = -1; int setreg2 = -1; int loadreg = -1; int loadreg2 = -1; int loadreg3 = -1; int loadregto = -1; int intlocfrom = -1; int intlocto = -1; if ((o==OP_JMP) || (o==OP_FORPREP)) { dest = pc + sbc + 2; } else if ((pc+1!=f->sizecode) && (GET_OPCODE(f->code[pc+1])==OP_JMP)) { dest = pc + 1 + GETARG_sBx(f->code[pc+1]) + 2; } // check which registers were read or written to. switch (o) { case OP_MOVE: setreg = a; if (b<=a) { intlocfrom = b; intlocto = b; } loadreg = b; break; case OP_UNM: case OP_NOT: case OP_LEN: setreg = a; loadreg = b; break; case OP_LOADNIL: setreg = a; setregto = b; break; case OP_LOADK: #if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 case OP_LOADKX: #endif case OP_GETUPVAL: #if LUA_VERSION_NUM == 501 case OP_GETGLOBAL: #endif #if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 case OP_GETTABUP: #endif case OP_LOADBOOL: case OP_NEWTABLE: case OP_CLOSURE: setreg = a; break; case OP_GETTABLE: setreg = a; loadreg = b; if (!ISK(c)) { loadreg2 = c; } break; #if LUA_VERSION_NUM == 501 case OP_SETGLOBAL: #endif case OP_SETUPVAL: loadreg = a; break; #if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 case OP_SETTABUP: if (!ISK(b)) { loadreg2 = b; } if (!ISK(c)) { if (loadreg2==-1) { loadreg2 = c; } else { loadreg3 = c; } } break; #endif case OP_SETTABLE: loadreg = a; if (!ISK(b)) { loadreg2 = b; } if (!ISK(c)) { if (loadreg2==-1) { loadreg2 = c; } else { loadreg3 = c; } if ((a+1!=c) && (c>a)) { intlocto = c-1; } } intlocfrom = 0; if (a-1>=intlocto) { intlocto = a-1; } break; case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_POW: case OP_MOD: setreg = a; if (!ISK(b)) { loadreg = b; } if (!ISK(c)) { if (loadreg==-1) { loadreg = c; } else { loadreg2 = c; } } break; case OP_CONCAT: setreg = a; loadreg = b; loadregto = c; break; case OP_CALL: if (c==0) { setreg = a; setregto = f->maxstacksize; } else if (c>=2) { setreg = a; setregto = a+c-2; } else if (c==1) { intlocfrom = 0; intlocto = a-1; } if (b==0) { loadreg = a; loadregto = f->maxstacksize; } else { loadreg = a; loadregto = a+b-1; } break; case OP_RETURN: if (b==0) { loadreg = a; loadregto = f->maxstacksize; } else if (b>=2) { loadreg = a; loadregto = a+b-2; } break; case OP_TAILCALL: if (b==0) { loadreg = a; loadregto = f->maxstacksize; } else { loadreg = a; loadregto = a+b-1; } break; case OP_VARARG: if (b==0) { setreg = a; setregto = f->maxstacksize; } else { setreg = a; setregto = a+b-1; } break; case OP_SELF: setreg = a; setregto = a+1; loadreg = b; if (a>b) { intlocfrom = 0; intlocto = b; } if (!ISK(c)) { loadreg2 = c; } break; case OP_EQ: case OP_LT: case OP_LE: if (!ISK(b)) { loadreg = b; } if (!ISK(c)) { if (loadreg==-1) { loadreg = c; } else { loadreg2 = c; } } break; case OP_TEST: loadreg = a; break; case OP_TESTSET: setreg = a; loadreg = b; break; case OP_SETLIST: loadreg = a; if (b==0) { loadregto = f->maxstacksize; } else { loadregto = a+b; } break; case OP_FORLOOP: #if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 case OP_TFORCALL: #endif case OP_TFORLOOP: break; case OP_FORPREP: loadreg = a; loadregto = a+2; setreg = a; setregto = a+3; intlocfrom = a; intlocto = a+3; regassign[a] = pc; regassign[a+1] = pc; regassign[a+2] = pc; regassign[a+3] = pc+1; regblock[a] = dest; regblock[a+1] = dest; regblock[a+2] = dest; regblock[a+3] = dest-1; addi(blocklist, dest-1); if (GET_OPCODE(f->code[dest-2])==OP_JMP) { last(blocklist)--; } break; case OP_JMP: if (GET_OPCODE(f->code[dest-1]) == LUADEC_TFORLOOP) { int a = GETARG_A(f->code[dest-1]); int c = GETARG_C(f->code[dest-1]); setreg = a; setregto = a+c+2; loadreg = a; loadregto = a+2; intlocfrom = a; intlocto = a+c+2; regassign[a] = pc; regassign[a+1] = pc; regassign[a+2] = pc; regblock[a] = dest+1; regblock[a+1] = dest+1; regblock[a+2] = dest+1; for (x=a+3;x<=a+c+2;x++) { regassign[x] = pc+1; regblock[x] = dest-1; } } if (dest>pc) { addi(blocklist, dest-1); if (GET_OPCODE(f->code[dest-2])==OP_JMP) { last(blocklist)--; } } break; #if LUA_VERSION_NUM == 501 case OP_CLOSE: #endif #if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 case OP_EXTRAARG: #endif default: break; } for (i=1; i<blocklist.size; i++) { x = blocklist.values[i]; i2 = i-1; while ((i2>=0) && (blocklist.values[i2]<x)) { blocklist.values[i2+1] = blocklist.values[i2]; i2 = i2-1; } blocklist.values[i2+1] = x; } if (loadreg!=-1) { if (loadregto==-1) loadregto = loadreg; for (i=loadreg;i<=loadregto;i++) { regusage[i]--; } if (loadreg2!=-1) regusage[loadreg2]--; if (loadreg3!=-1) regusage[loadreg3]--; } if (setreg!=-1) { if (setregto==-1) setregto = setreg; for (i=setreg;i<=setregto;i++) { regusage[i]++; } if (setreg2!=-1) regusage[setreg2]++; } i2 = lastfree-1; for (i=lastfree; i<f->maxstacksize; i++) { if ((regusage[i]<0) || (regusage[i]>1)) { i2 = i; } if ((intlocfrom!=-1) && ((intlocfrom<=i) && (i<=intlocto))) { i2 = i; } } for (i=setreg; i<=setregto; i++) { if (i>i2) { regassign[i] = pc+1; regblock[i] = last(blocklist); } } for (i=lastfree; i<=i2; i++) { //fprintf(stderr,"%d %d %d %d\n",i,regassign[i],regblock[i],block); add(locallist,regassign[i],regblock[i]); lastfree++; } while (blocklist.size > 0 && last(blocklist) <= pc+1) { intArray_Pop(&blocklist); } if (blocklist.size == 0) { fprintf(stderr, "cannot find blockend > %d , pc = %d, f->sizecode = %d\n", pc+1, pc, f->sizecode); } while ((lastfree!=0) && (regblock[lastfree-1] <= pc+1)) { lastfree--; regusage[lastfree]=0; } } intArray_Clear(&blocklist); // print out information { int length = locallist.size; f->sizelocvars = length; if (f->sizelocvars>0) { f->locvars = luaM_newvector(glstate,f->sizelocvars,LocVar); for (i = 0; i < length; i++) { char names[10]; sprintf(names,"l_%d_%d",main,i); f->locvars[i].varname = luaS_new(glstate, names); f->locvars[i].startpc = locallist.values[i].startpc; f->locvars[i].endpc = locallist.values[i].endpc; } } } LocVarArray_Clear(&locallist); // run with all functions for (i=0; i<f->sizep; i++) { luaU_guess_locals(f->p[i],main+i+1); } return 1; }
void BijouBlock_dump2(VM, BijouBlock* b, int level) { char * str; size_t x; INDENT; printf("; block at: %p, %s (level %d)\n", (void *)b, b->funcname != NULL ? b->funcname : "", level); INDENT; printf("; %zu registers\n", b->regc); INDENT; printf("; constants (%zu)\n", kv_size(b->k)); for (x = 0; x < kv_size(b->k); ++x) { str = TValue_to_string(kv_A(b->k, x)); int s = ttisstring(&kv_A(b->k, x)); INDENT; printf("\t%zu: (%s) %s%s%s\n", x, TValue_type_to_string(kv_A(b->k, x)), s ? "\"" : "", str, s ? "\"" : ""); if (ttisnumber(&kv_A(b->k, x))) B_FREE(str); } INDENT; printf("; locals (%zu)\n", kv_size(b->locals)); for (x = 0; x < kv_size(b->locals); ++x) { str = TValue_to_string(kv_A(b->locals, x)); INDENT; printf("\t%zu: (%s) %s\n", x, TValue_type_to_string(kv_A(b->locals, x)), str); if (ttisnumber(&kv_A(b->locals, x))) B_FREE(str); } INDENT; printf("; upvals (%zu)\n", kv_size(b->upvals)); for (x = 0; x < kv_size(b->upvals); ++x) { str = TValue_to_string(kv_A(b->upvals, x)); INDENT; printf("\t%zu: (%s) %s\n", x, TValue_type_to_string(kv_A(b->upvals, x)), str); if (ttisnumber(&kv_A(b->upvals, x))) B_FREE(str); } INDENT; printf("; code section (%zu instructions)\n", kv_size(b->code)); for (x = 0; x < kv_size(b->code); ++x) { bInst i = kv_A(b->code, x); INDENT; print_op(i); printf("\t"); switch (GET_OPCODE(i)) { case OP_MOVE: printf("; R[%d] = R[%d]", GETARG_A(i), GETARG_B(i)); break; case OP_LOADK: printf("; R[%d] = K[%d]", GETARG_A(i), GETARG_Bx(i)); break; case OP_LOADBOOL: printf("; R[%d] = %s", GETARG_A(i), GETARG_B(i) == 0 ? "false" : "true" ); break; case OP_LOADNULL: printf("; R[%d] = null", GETARG_A(i)); break; case OP_GETGLOBAL: printf("; R[%d] = globals[K[%d]]", GETARG_A(i), GETARG_Bx(i)); break; case OP_SETGLOBAL: printf("; globals[K[%d]] = R[%d]", GETARG_Bx(i), GETARG_A(i)); break; case OP_GETLOCAL: printf("; R[%d] = locals[K[%d]]", GETARG_A(i), GETARG_Bx(i)); break; case OP_SETLOCAL: printf("; locals[K[%d]] = R[%d]", GETARG_Bx(i), GETARG_A(i)); break; case OP_ADD: printf("; R[%d] = RK[%d] + RK[%d]", GETARG_A(i), GETARG_B(i), GETARG_C(i)); break; case OP_SUB: printf("; R[%d] = RK[%d] - RK[%d]", GETARG_A(i), GETARG_B(i), GETARG_C(i)); break; case OP_MUL: printf("; R[%d] = RK[%d] * RK[%d]", GETARG_A(i), GETARG_B(i), GETARG_C(i)); break; case OP_DIV: printf("; R[%d] = RK[%d] / RK[%d]", GETARG_A(i), GETARG_B(i), GETARG_C(i)); break; case OP_POW: printf("; R[%d] = RK[%d] ** RK[%d]", GETARG_A(i), GETARG_B(i), GETARG_C(i)); break; case OP_REM: printf("; R[%d] = RK[%d] %% RK[%d]", GETARG_A(i), GETARG_B(i), GETARG_C(i)); break; case OP_UNM: printf("; R[%d] = -RK[%d]", GETARG_A(i), GETARG_B(i)); break; case OP_NOT: printf("; R[%d] = !RK[%d]", GETARG_A(i), GETARG_B(i)); break; case OP_CLOSURE: printf("; R[%d] = ", GETARG_A(i)); if (ISK(GETARG_Bx(i))) { BijouFunction *func = kv_A(vm->functions, GETARG_Bx(i) & ~0x100); printf("%s\n", func->name); } else printf("closure[%d] (%s)\n", GETARG_Bx(i), b->children[GETARG_Bx(i)]->funcname); break; case OP_CALL: printf("; R[%d] = R[%d](", GETARG_A(i), GETARG_B(i)); size_t x; for (x = 0; x < GETARG_C(i); ++x) { printf("R[%zu], ", x); } if (x > 0) { printf("\b\b"); } printf(")"); break; case OP_GETEXTERNAL: printf("; R[%d] = closure(K[%d])", GETARG_A(i), GETARG_B(i)); break; } printf("\n"); } INDENT; printf("; functions (%zu definitions)\n", b->numchildren); for (x = 0; x < b->numchildren; ++x) { BijouBlock_dump2(vm, b->children[x], level + 1); } }
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; }