Example #1
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;
}
Example #2
0
static void adjust_assign(ktap_lexstate *ls, int nvars, int nexps, ktap_expdesc *e)
{
	ktap_funcstate *fs = ls->fs;
	int extra = nvars - nexps;

	if (hasmultret(e->k)) {
		extra++;  /* includes call itself */
		if (extra < 0)
			extra = 0;
		codegen_setreturns(fs, e, extra);  /* last exp. provides the difference */
		if (extra > 1)
			codegen_reserveregs(fs, extra-1);
	} else {
		if (e->k != VVOID)
			codegen_exp2nextreg(fs, e);  /* close last expression */
		if (extra > 0) {
			int reg = fs->freereg;

			codegen_reserveregs(fs, extra);
			codegen_nil(fs, reg, extra);
		}
	}
}