summaryrefslogtreecommitdiff
path: root/src/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lcode.c')
-rw-r--r--src/lcode.c77
1 files changed, 50 insertions, 27 deletions
diff --git a/src/lcode.c b/src/lcode.c
index 54ef0581..f7f1182d 100644
--- a/src/lcode.c
+++ b/src/lcode.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.c,v 2.6 2004/08/24 20:09:11 roberto Exp $
+** $Id: lcode.c,v 2.8 2004/12/03 20:35:33 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -53,13 +53,13 @@ int luaK_jump (FuncState *fs) {
}
-static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) {
+static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
luaK_codeABC(fs, op, A, B, C);
return luaK_jump(fs);
}
-static void luaK_fixjump (FuncState *fs, int pc, int dest) {
+static void fixjump (FuncState *fs, int pc, int dest) {
Instruction *jmp = &fs->f->code[pc];
int offset = dest-(pc+1);
lua_assert(dest != NO_JUMP);
@@ -79,7 +79,7 @@ int luaK_getlabel (FuncState *fs) {
}
-static int luaK_getjump (FuncState *fs, int pc) {
+static int getjump (FuncState *fs, int pc) {
int offset = GETARG_sBx(fs->f->code[pc]);
if (offset == NO_JUMP) /* point to itself represents end of list */
return NO_JUMP; /* end of list */
@@ -102,7 +102,7 @@ static Instruction *getjumpcontrol (FuncState *fs, int pc) {
** (or produce an inverted value)
*/
static int need_value (FuncState *fs, int list, int cond) {
- for (; list != NO_JUMP; list = luaK_getjump(fs, list)) {
+ for (; list != NO_JUMP; list = getjump(fs, list)) {
Instruction i = *getjumpcontrol(fs, list);
if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1;
}
@@ -116,25 +116,25 @@ static void patchtestreg (Instruction *i, int reg) {
}
-static void luaK_patchlistaux (FuncState *fs, int list,
+static void patchlistaux (FuncState *fs, int list,
int ttarget, int treg, int ftarget, int freg, int dtarget) {
while (list != NO_JUMP) {
- int next = luaK_getjump(fs, list);
+ int next = getjump(fs, list);
Instruction *i = getjumpcontrol(fs, list);
if (GET_OPCODE(*i) != OP_TEST) {
lua_assert(dtarget != NO_JUMP);
- luaK_fixjump(fs, list, dtarget); /* jump to default target */
+ fixjump(fs, list, dtarget); /* jump to default target */
}
else {
if (GETARG_C(*i)) {
lua_assert(ttarget != NO_JUMP);
patchtestreg(i, treg);
- luaK_fixjump(fs, list, ttarget);
+ fixjump(fs, list, ttarget);
}
else {
lua_assert(ftarget != NO_JUMP);
patchtestreg(i, freg);
- luaK_fixjump(fs, list, ftarget);
+ fixjump(fs, list, ftarget);
}
}
list = next;
@@ -142,8 +142,8 @@ static void luaK_patchlistaux (FuncState *fs, int list,
}
-static void luaK_dischargejpc (FuncState *fs) {
- luaK_patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc, NO_REG, fs->pc);
+static void dischargejpc (FuncState *fs) {
+ patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc, NO_REG, fs->pc);
fs->jpc = NO_JUMP;
}
@@ -153,7 +153,7 @@ void luaK_patchlist (FuncState *fs, int list, int target) {
luaK_patchtohere(fs, list);
else {
lua_assert(target < fs->pc);
- luaK_patchlistaux(fs, list, target, NO_REG, target, NO_REG, target);
+ patchlistaux(fs, list, target, NO_REG, target, NO_REG, target);
}
}
@@ -171,9 +171,9 @@ void luaK_concat (FuncState *fs, int *l1, int l2) {
else {
int list = *l1;
int next;
- while ((next = luaK_getjump(fs, list)) != NO_JUMP) /* find last element */
+ while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
list = next;
- luaK_fixjump(fs, list, l2);
+ fixjump(fs, list, l2);
}
}
@@ -243,7 +243,14 @@ int luaK_numberK (FuncState *fs, lua_Number r) {
}
-static int nil_constant (FuncState *fs) {
+static int boolK (FuncState *fs, int b) {
+ TValue o;
+ setbvalue(&o, b);
+ return addk(fs, &o, &o);
+}
+
+
+static int nilK (FuncState *fs) {
TValue k, v;
setnilvalue(&v);
/* cannot use nil as key; instead use table itself to represent nil */
@@ -358,7 +365,7 @@ static void discharge2anyreg (FuncState *fs, expdesc *e) {
}
-static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) {
+static void exp2reg (FuncState *fs, expdesc *e, int reg) {
discharge2reg(fs, e, reg);
if (e->k == VJMP)
luaK_concat(fs, &e->t, e->info); /* put this jump in `t' list */
@@ -375,8 +382,8 @@ static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) {
luaK_patchtohere(fs, fj);
}
final = luaK_getlabel(fs);
- luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f);
- luaK_patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t);
+ patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f);
+ patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t);
}
e->f = e->t = NO_JUMP;
e->info = reg;
@@ -388,7 +395,7 @@ void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
luaK_dischargevars(fs, e);
freeexp(fs, e);
luaK_reserveregs(fs, 1);
- luaK_exp2reg(fs, e, fs->freereg - 1);
+ exp2reg(fs, e, fs->freereg - 1);
}
@@ -397,7 +404,7 @@ int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
if (e->k == VNONRELOC) {
if (!hasjumps(e)) return e->info; /* exp is already in a register */
if (e->info >= fs->nactvar) { /* reg. is not a local? */
- luaK_exp2reg(fs, e, e->info); /* put value on it */
+ exp2reg(fs, e, e->info); /* put value on it */
return e->info;
}
}
@@ -417,9 +424,11 @@ void luaK_exp2val (FuncState *fs, expdesc *e) {
int luaK_exp2RK (FuncState *fs, expdesc *e) {
luaK_exp2val(fs, e);
switch (e->k) {
+ case VTRUE:
+ case VFALSE:
case VNIL: {
if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
- e->info = nil_constant(fs);
+ e->info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
e->k = VK;
return RKASK(e->info);
}
@@ -441,7 +450,7 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
switch (var->k) {
case VLOCAL: {
freeexp(fs, ex);
- luaK_exp2reg(fs, ex, var->info);
+ exp2reg(fs, ex, var->info);
return;
}
case VUPVAL: {
@@ -493,13 +502,13 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) {
Instruction ie = getcode(fs, e);
if (GET_OPCODE(ie) == OP_NOT) {
fs->pc--; /* remove previous OP_NOT */
- return luaK_condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond);
+ return condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond);
}
/* else go through */
}
discharge2anyreg(fs, e);
freeexp(fs, e);
- return luaK_condjump(fs, OP_TEST, NO_REG, e->info, cond);
+ return condjump(fs, OP_TEST, NO_REG, e->info, cond);
}
@@ -651,7 +660,7 @@ static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
}
else if (op == OPR_NE) cond = 0;
- res->info = luaK_condjump(fs, ops[op - OPR_NE], cond, o1, o2);
+ res->info = condjump(fs, ops[op - OPR_NE], cond, o1, o2);
res->k = VJMP;
}
}
@@ -708,7 +717,7 @@ void luaK_fixline (FuncState *fs, int line) {
int luaK_code (FuncState *fs, Instruction i, int line) {
Proto *f = fs->f;
- luaK_dischargejpc(fs); /* `pc' will change */
+ dischargejpc(fs); /* `pc' will change */
/* put new instruction in code array */
luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
MAX_INT, "code size overflow");
@@ -735,3 +744,17 @@ int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
}
+
+void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
+ int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
+ int b = (tostore == LUA_MULTRET) ? 0 : tostore;
+ lua_assert(tostore != 0);
+ if (c <= MAXARG_C)
+ luaK_codeABC(fs, OP_SETLIST, base, b, c);
+ else {
+ luaK_codeABC(fs, OP_SETLIST, base, b, 0);
+ luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
+ }
+ fs->freereg = base + 1; /* free registers with list values */
+}
+