Example #1
0
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;
}
Example #2
0
/* 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;
}
Example #3
0
File: code.c Project: WeiY/ktap
static void freereg(FuncState *fs, int reg)
{
	if (!ISK(reg) && reg >= fs->nactvar) {
		fs->freereg--;
		ktap_assert(reg == fs->freereg);
	}
}
Example #4
0
File: vm.c Project: joelagnel/ktap
/*
 * 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]);
}
Example #5
0
static const char* kname(Proto* p, int c)
{
	if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
		return svalue(&p->k[INDEXK(c)]);
	else
		return "?";
}
Example #6
0
/**
 * 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;
}
Example #7
0
File: lvm.c Project: lriki/Volkoff
/*
** 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);
  }
}
Example #8
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;
}
Example #9
0
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();
    }
  }
}
Example #10
0
/*
** 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 */
}
Example #11
0
/*
** 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 */
}
Example #12
0
static void ICACHE_FLASH_ATTR freereg (FuncState *fs, int reg) {
  if (!ISK(reg) && reg >= fs->nactvar) {
    fs->freereg--;
    lua_assert(reg == fs->freereg);
  }
}
Example #13
0
File: lcode.cpp Project: swizl/lua
/*static*/ void FuncState::freereg (/*FuncState *fs,*/ int reg) {
	if (!ISK(reg) && reg >= nactvar) {
		free_reg--;
		lua_assert(reg == free_reg);
	}
}
Example #14
0
File: luac.c Project: bysdxt/xLua
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");
 }
}
Example #15
0
static void freereg (FuncState *fs, int reg) {
  if (!ISK(reg)) {
    fs->freereg--;
    lua_assert(reg == fs->freereg);
  }
}
Example #16
0
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");
 }
}
Example #17
0
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;
}
Example #18
0
File: block.c Project: erik/bijou
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);
    }
}
Example #19
0
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;
}