Exemple #1
0
Fichier : code.c Projet : WeiY/ktap
int codegen_codeABx(FuncState *fs, OpCode o, int a, unsigned int bc)
{
	ktap_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
	ktap_assert(getCMode(o) == OpArgN);
	ktap_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
	return codegen_code(fs, CREATE_ABx(o, a, bc));
}
Exemple #2
0
static void DumpConstants(const ktap_proto *f, DumpState *D)
{
	int i, n = f->sizek;

	DumpInt(n, D);
	for (i = 0; i < n; i++) {
		const ktap_value* o=&f->k[i];
		DumpChar(ttypenv(o), D);
		switch (ttypenv(o)) {
		case KTAP_TNIL:
			break;
		case KTAP_TBOOLEAN:
			DumpChar(bvalue(o), D);
			break;
		case KTAP_TNUMBER:
			DumpNumber(nvalue(o), D);
			break;
		case KTAP_TSTRING:
			DumpString(rawtsvalue(o), D);
			break;
		default:
			printf("ktap: DumpConstants with unknown vaule type %d\n", ttypenv(o));
			ktap_assert(0);
		}
	}
	n = f->sizep;
	DumpInt(n, D);
	for (i = 0; i < n; i++)
		DumpFunction(f->p[i], D);
}
Exemple #3
0
static void leaveblock(ktap_funcstate *fs)
{
	ktap_blockcnt *bl = fs->bl;
	ktap_lexstate *ls = fs->ls;
	if (bl->previous && bl->upval) {
		/* create a 'jump to here' to close upvalues */
		int j = codegen_jump(fs);

		codegen_patchclose(fs, j, bl->nactvar);
		codegen_patchtohere(fs, j);
	}

	if (bl->isloop)
		breaklabel(ls);  /* close pending breaks */

	fs->bl = bl->previous;
	removevars(fs, bl->nactvar);
	ktap_assert(bl->nactvar == fs->nactvar);
	fs->freereg = fs->nactvar;  /* free registers */
	ls->dyd->label.n = bl->firstlabel;  /* remove local labels */
	if (bl->previous)  /* inner block? */
		movegotosout(fs, bl);  /* update pending gotos to outer block */
	else if (bl->firstgoto < ls->dyd->gt.n)  /* pending gotos in outer block? */
		undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]);  /* error */
}
Exemple #4
0
static ktap_locvar *getlocvar(ktap_funcstate *fs, int i)
{
	int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx;

	ktap_assert(idx < fs->nlocvars);
	return &fs->f->locvars[idx];
}
Exemple #5
0
Fichier : code.c Projet : WeiY/ktap
static void freereg(FuncState *fs, int reg)
{
	if (!ISK(reg) && reg >= fs->nactvar) {
		fs->freereg--;
		ktap_assert(reg == fs->freereg);
	}
}
Exemple #6
0
Fichier : code.c Projet : WeiY/ktap
int codegen_codeABC(FuncState *fs, OpCode o, int a, int b, int c)
{
	ktap_assert(getOpMode(o) == iABC);
	//ktap_assert(getBMode(o) != OpArgN || b == 0);
	//ktap_assert(getCMode(o) != OpArgN || c == 0);
	//ktap_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
	return codegen_code(fs, CREATE_ABC(o, a, b, c));
}
Exemple #7
0
static void anchor_token(ktap_lexstate *ls)
{
	/* last token from outer function must be EOS */
	ktap_assert((int)(ls->fs != NULL) || ls->t.token == TK_EOS);
	if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
		ktap_string *ts = ls->t.seminfo.ts;
		lex_newstring(ls, getstr(ts), ts->tsv.len);
	}
}
Exemple #8
0
Fichier : code.c Projet : WeiY/ktap
void codegen_patchlist(FuncState *fs, int list, int target)
{
	if (target == fs->pc)
		codegen_patchtohere(fs, list);
	else {
		ktap_assert(target < fs->pc);
		patchlistaux(fs, list, target, NO_REG, target);
	}
}
Exemple #9
0
Fichier : code.c Projet : WeiY/ktap
static void fixjump(FuncState *fs, int pc, int dest)
{
	Instruction *jmp = &fs->f->code[pc];
	int offset = dest-(pc+1);

	ktap_assert(dest != NO_JUMP);
	if (abs(offset) > MAXARG_sBx)
		lex_syntaxerror(fs->ls, "control structure too long");
	SETARG_sBx(*jmp, offset);
}
Exemple #10
0
static void enterblock(ktap_funcstate *fs, ktap_blockcnt *bl, u8 isloop)
{
	bl->isloop = isloop;
	bl->nactvar = fs->nactvar;
	bl->firstlabel = fs->ls->dyd->label.n;
	bl->firstgoto = fs->ls->dyd->gt.n;
	bl->upval = 0;
	bl->previous = fs->bl;
	fs->bl = bl;
	ktap_assert(fs->freereg == fs->nactvar);
}
Exemple #11
0
Fichier : code.c Projet : WeiY/ktap
void codegen_patchclose(FuncState *fs, int list, int level)
{
	level++;  /* argument is +1 to reserve 0 as non-op */
	while (list != NO_JUMP) {
		int next = getjump(fs, list);
		ktap_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
			   (GETARG_A(fs->f->code[list]) == 0 ||
			    GETARG_A(fs->f->code[list]) >= level));
		SETARG_A(fs->f->code[list], level);
		list = next;
	}
}
Exemple #12
0
static void singlevar(ktap_lexstate *ls, ktap_expdesc *var)
{
	ktap_string *varname = str_checkname(ls);
	ktap_funcstate *fs = ls->fs;

	if (singlevaraux(fs, varname, var, 1) == VVOID) {  /* global name? */
		ktap_expdesc key;
		singlevaraux(fs, ls->envn, var, 1);  /* get environment variable */
		ktap_assert(var->k == VLOCAL || var->k == VUPVAL);
		codestring(ls, &key, varname);  /* key is variable name */
		codegen_indexed(fs, var, &key);  /* env[varname] */
	}
}
Exemple #13
0
ktap_number ktapc_arith(int op, ktap_number v1, ktap_number v2)
{
	switch (op) {
	case KTAP_OPADD: return NUMADD(v1, v2);
	case KTAP_OPSUB: return NUMSUB(v1, v2);
	case KTAP_OPMUL: return NUMMUL(v1, v2);
	case KTAP_OPDIV: return NUMDIV(v1, v2);
	case KTAP_OPMOD: return NUMMOD(v1, v2);
	//case KTAP_OPPOW: return NUMPOW(v1, v2);
	case KTAP_OPUNM: return NUMUNM(v1);
	default: ktap_assert(0); return 0;
	}
}
Exemple #14
0
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;
}
Exemple #15
0
static void closegoto(ktap_lexstate *ls, int g, ktap_labeldesc *label)
{
	int i;
	ktap_funcstate *fs = ls->fs;
	ktap_labellist *gl = &ls->dyd->gt;
	ktap_labeldesc *gt = &gl->arr[g];

	ktap_assert(ktapc_ts_eqstr(gt->name, label->name));
	if (gt->nactvar < label->nactvar) {
		ktap_string *vname = getlocvar(fs, gt->nactvar)->varname;
		const char *msg = ktapc_sprintf(
			"<goto %s> at line %d jumps into the scope of local " KTAP_QS,
			getstr(gt->name), gt->line, getstr(vname));
		semerror(ls, msg);
	}

	codegen_patchlist(fs, gt->pc, label->pc);
	/* remove goto from pending list */
	for (i = g; i < gl->n - 1; i++)
		gl->arr[i] = gl->arr[i + 1];
	gl->n--;
}
Exemple #16
0
Fichier : code.c Projet : WeiY/ktap
static int codeextraarg(FuncState *fs, int a)
{
	ktap_assert(a <= MAXARG_Ax);
	return codegen_code(fs, CREATE_Ax(OP_EXTRAARG, a));
}