예제 #1
0
파일: code.c 프로젝트: WeiY/ktap
void codegen_dischargevars(FuncState *fs, expdesc *e)
{
	switch (e->k) {
	case VLOCAL: {
		e->k = VNONRELOC;
		break;
	}
	case VUPVAL: {
		e->u.info = codegen_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
		e->k = VRELOCABLE;
		break;
	}
	case VINDEXED: {
		OpCode op = OP_GETTABUP;  /* assume 't' is in an upvalue */
		freereg(fs, e->u.ind.idx);
		if (e->u.ind.vt == VLOCAL) {  /* 't' is in a register? */
			freereg(fs, e->u.ind.t);
			op = OP_GETTABLE;
		}
		e->u.info = codegen_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
		e->k = VRELOCABLE;
		break;
	}
	case VVARARG:
	case VCALL: {
		codegen_setoneret(fs, e);
		break;
	}
	default:
		break;  /* there is one value available (somewhere) */
	}
}
예제 #2
0
파일: code.c 프로젝트: WeiY/ktap
void codegen_nil(FuncState *fs, int from, int n)
{
	Instruction *previous;
	int l = from + n - 1;  /* last register to set nil */

	if (fs->pc > fs->lasttarget) {  /* no jumps to current position? */
		previous = &fs->f->code[fs->pc-1];
		if (GET_OPCODE(*previous) == OP_LOADNIL) {
			int pfrom = GETARG_A(*previous);
			int pl = pfrom + GETARG_B(*previous);

			if ((pfrom <= from && from <= pl + 1) ||
				(from <= pfrom && pfrom <= l + 1)) {  /* can connect both? */
				if (pfrom < from)
					from = pfrom;  /* from = min(from, pfrom) */
				if (pl > l)
					l = pl;  /* l = max(l, pl) */
				SETARG_A(*previous, from);
				SETARG_B(*previous, l - from);
				return;
			}
		}  /* else go through */
	}
	codegen_codeABC(fs, OP_LOADNIL, from, n - 1, 0);  /* else no optimization */
}
예제 #3
0
파일: code.c 프로젝트: unixbhaskar/ktap
static void discharge2reg(ktap_funcstate *fs, ktap_expdesc *e, int reg)
{
	codegen_dischargevars(fs, e);
	switch (e->k) {
	case VNIL: {
		codegen_nil(fs, reg, 1);
		break;
	}
	case VFALSE:  case VTRUE: {
		codegen_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
 		break;
	}
	case VEVENT:
		codegen_codeABC(fs, OP_EVENT, reg, 0, 0);
		break;
	case VEVENTNAME:
		codegen_codeABC(fs, OP_EVENTNAME, reg, 0, 0);
		break;
	case VEVENTARG:
		codegen_codeABC(fs, OP_EVENTARG, reg, e->u.info, 0);
		break;
	case VK: {
		codegen_codek(fs, reg, e->u.info);
		break;
	}
	case VKNUM: {
		codegen_codek(fs, reg, codegen_numberK(fs, e->u.nval));
		break;
	}
	case VRELOCABLE: {
		ktap_instruction *pc = &getcode(fs, e);
		SETARG_A(*pc, reg);
		break;
	}
	case VNONRELOC: {
		if (reg != e->u.info)
			codegen_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
		break;
	}
	default:
		ktap_assert(e->k == VVOID || e->k == VJMP);
		return;  /* nothing to do... */
	}

	e->u.info = reg;
	e->k = VNONRELOC;
}
예제 #4
0
파일: code.c 프로젝트: WeiY/ktap
static int condjump(FuncState *fs, OpCode op, int A, int B, int C)
{
	codegen_codeABC(fs, op, A, B, C);
	return codegen_jump(fs);
}
예제 #5
0
파일: code.c 프로젝트: WeiY/ktap
void codegen_ret(FuncState *fs, int first, int nret)
{
	codegen_codeABC(fs, OP_RETURN, first, nret+1, 0);
}
예제 #6
0
파일: code.c 프로젝트: WeiY/ktap
static int code_label(FuncState *fs, int A, int b, int jump)
{
	codegen_getlabel(fs);  /* those instructions may be jump targets */
	return codegen_codeABC(fs, OP_LOADBOOL, A, b, jump);
}
예제 #7
0
파일: code.c 프로젝트: unixbhaskar/ktap
void codegen_ret(ktap_funcstate *fs, int first, int nret)
{
	codegen_codeABC(fs, OP_RETURN, first, nret+1, 0);
}