History

Lua 5.1-work3

Lua Team committed 21 years ago

Commit ec3e02b1 parent cdf85b646 files · +1107 −738Browse files

Showing the changes to src/lcode.c (1 of 46 files). Show all

Unified · Split

src/lcode.c+50−27
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lcode.c,v 2.6 2004/08/24 20:09:11 roberto Exp $2** $Id: lcode.c,v 2.8 2004/12/03 20:35:33 roberto Exp $
3** Code generator for Lua3** Code generator for Lua
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -53,13 +53,13 @@ int luaK_jump (FuncState *fs) { · 47 unmodified lines
53}53}
54 54
55 55
56static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) {56static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
57 luaK_codeABC(fs, op, A, B, C);57 luaK_codeABC(fs, op, A, B, C);
58 return luaK_jump(fs);58 return luaK_jump(fs);
59}59}
60 60
61 61
62static void luaK_fixjump (FuncState *fs, int pc, int dest) {62static void fixjump (FuncState *fs, int pc, int dest) {
63 Instruction *jmp = &fs->f->code[pc];63 Instruction *jmp = &fs->f->code[pc];
64 int offset = dest-(pc+1);64 int offset = dest-(pc+1);
65 lua_assert(dest != NO_JUMP);65 lua_assert(dest != NO_JUMP);
@@ -79,7 +79,7 @@ int luaK_getlabel (FuncState *fs) { · 13 unmodified lines
79}79}
80 80
81 81
82static int luaK_getjump (FuncState *fs, int pc) {82static int getjump (FuncState *fs, int pc) {
83 int offset = GETARG_sBx(fs->f->code[pc]);83 int offset = GETARG_sBx(fs->f->code[pc]);
84 if (offset == NO_JUMP) /* point to itself represents end of list */84 if (offset == NO_JUMP) /* point to itself represents end of list */
85 return NO_JUMP; /* end of list */85 return NO_JUMP; /* end of list */
@@ -102,7 +102,7 @@ static Instruction *getjumpcontrol (FuncState *fs, int pc) { · 16 unmodified lines
102** (or produce an inverted value)102** (or produce an inverted value)
103*/103*/
104static int need_value (FuncState *fs, int list, int cond) {104static int need_value (FuncState *fs, int list, int cond) {
105 for (; list != NO_JUMP; list = luaK_getjump(fs, list)) {105 for (; list != NO_JUMP; list = getjump(fs, list)) {
106 Instruction i = *getjumpcontrol(fs, list);106 Instruction i = *getjumpcontrol(fs, list);
107 if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1;107 if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1;
108 }108 }
@@ -116,25 +116,25 @@ static void patchtestreg (Instruction *i, int reg) { · 7 unmodified lines
116}116}
117 117
118 118
119static void luaK_patchlistaux (FuncState *fs, int list,119static void patchlistaux (FuncState *fs, int list,
120 int ttarget, int treg, int ftarget, int freg, int dtarget) {120 int ttarget, int treg, int ftarget, int freg, int dtarget) {
121 while (list != NO_JUMP) {121 while (list != NO_JUMP) {
122 int next = luaK_getjump(fs, list);122 int next = getjump(fs, list);
123 Instruction *i = getjumpcontrol(fs, list);123 Instruction *i = getjumpcontrol(fs, list);
124 if (GET_OPCODE(*i) != OP_TEST) {124 if (GET_OPCODE(*i) != OP_TEST) {
125 lua_assert(dtarget != NO_JUMP);125 lua_assert(dtarget != NO_JUMP);
126 luaK_fixjump(fs, list, dtarget); /* jump to default target */126 fixjump(fs, list, dtarget); /* jump to default target */
127 }127 }
128 else {128 else {
129 if (GETARG_C(*i)) {129 if (GETARG_C(*i)) {
130 lua_assert(ttarget != NO_JUMP);130 lua_assert(ttarget != NO_JUMP);
131 patchtestreg(i, treg);131 patchtestreg(i, treg);
132 luaK_fixjump(fs, list, ttarget);132 fixjump(fs, list, ttarget);
133 }133 }
134 else {134 else {
135 lua_assert(ftarget != NO_JUMP);135 lua_assert(ftarget != NO_JUMP);
136 patchtestreg(i, freg);136 patchtestreg(i, freg);
137 luaK_fixjump(fs, list, ftarget);137 fixjump(fs, list, ftarget);
138 }138 }
139 }139 }
140 list = next;140 list = next;
@@ -142,8 +142,8 @@ static void luaK_patchlistaux (FuncState *fs, int list, · 1 unmodified line
142}142}
143 143
144 144
145static void luaK_dischargejpc (FuncState *fs) {145static void dischargejpc (FuncState *fs) {
146 luaK_patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc, NO_REG, fs->pc);146 patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc, NO_REG, fs->pc);
147 fs->jpc = NO_JUMP;147 fs->jpc = NO_JUMP;
148}148}
149 149
@@ -153,7 +153,7 @@ void luaK_patchlist (FuncState *fs, int list, int target) { · 3 unmodified lines
153 luaK_patchtohere(fs, list);153 luaK_patchtohere(fs, list);
154 else {154 else {
155 lua_assert(target < fs->pc);155 lua_assert(target < fs->pc);
156 luaK_patchlistaux(fs, list, target, NO_REG, target, NO_REG, target);156 patchlistaux(fs, list, target, NO_REG, target, NO_REG, target);
157 }157 }
158}158}
159 159
@@ -171,9 +171,9 @@ void luaK_concat (FuncState *fs, int *l1, int l2) { · 11 unmodified lines
171 else {171 else {
172 int list = *l1;172 int list = *l1;
173 int next;173 int next;
174 while ((next = luaK_getjump(fs, list)) != NO_JUMP) /* find last element */174 while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
175 list = next;175 list = next;
176 luaK_fixjump(fs, list, l2);176 fixjump(fs, list, l2);
177 }177 }
178}178}
179 179
@@ -243,7 +243,14 @@ int luaK_numberK (FuncState *fs, lua_Number r) { · 63 unmodified lines
243}243}
244 244
245 245
246static int nil_constant (FuncState *fs) {246static int boolK (FuncState *fs, int b) {
247 TValue o;
248 setbvalue(&o, b);
249 return addk(fs, &o, &o);
250}
251
252
253static int nilK (FuncState *fs) {
247 TValue k, v;254 TValue k, v;
248 setnilvalue(&v);255 setnilvalue(&v);
249 /* cannot use nil as key; instead use table itself to represent nil */256 /* cannot use nil as key; instead use table itself to represent nil */
@@ -358,7 +365,7 @@ static void discharge2anyreg (FuncState *fs, expdesc *e) { · 108 unmodified lines
358}365}
359 366
360 367
361static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) {368static void exp2reg (FuncState *fs, expdesc *e, int reg) {
362 discharge2reg(fs, e, reg);369 discharge2reg(fs, e, reg);
363 if (e->k == VJMP)370 if (e->k == VJMP)
364 luaK_concat(fs, &e->t, e->info); /* put this jump in `t' list */371 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) { · 10 unmodified lines
375 luaK_patchtohere(fs, fj);382 luaK_patchtohere(fs, fj);
376 }383 }
377 final = luaK_getlabel(fs);384 final = luaK_getlabel(fs);
378 luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f);385 patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f);
379 luaK_patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t);386 patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t);
380 }387 }
381 e->f = e->t = NO_JUMP;388 e->f = e->t = NO_JUMP;
382 e->info = reg;389 e->info = reg;
@@ -388,7 +395,7 @@ void luaK_exp2nextreg (FuncState *fs, expdesc *e) { · 5 unmodified lines
388 luaK_dischargevars(fs, e);395 luaK_dischargevars(fs, e);
389 freeexp(fs, e);396 freeexp(fs, e);
390 luaK_reserveregs(fs, 1);397 luaK_reserveregs(fs, 1);
391 luaK_exp2reg(fs, e, fs->freereg - 1);398 exp2reg(fs, e, fs->freereg - 1);
392}399}
393 400
394 401
@@ -397,7 +404,7 @@ int luaK_exp2anyreg (FuncState *fs, expdesc *e) { · 2 unmodified lines
397 if (e->k == VNONRELOC) {404 if (e->k == VNONRELOC) {
398 if (!hasjumps(e)) return e->info; /* exp is already in a register */ 405 if (!hasjumps(e)) return e->info; /* exp is already in a register */
399 if (e->info >= fs->nactvar) { /* reg. is not a local? */406 if (e->info >= fs->nactvar) { /* reg. is not a local? */
400 luaK_exp2reg(fs, e, e->info); /* put value on it */407 exp2reg(fs, e, e->info); /* put value on it */
401 return e->info;408 return e->info;
402 }409 }
403 }410 }
@@ -417,9 +424,11 @@ void luaK_exp2val (FuncState *fs, expdesc *e) { · 13 unmodified lines
417int luaK_exp2RK (FuncState *fs, expdesc *e) {424int luaK_exp2RK (FuncState *fs, expdesc *e) {
418 luaK_exp2val(fs, e);425 luaK_exp2val(fs, e);
419 switch (e->k) {426 switch (e->k) {
427 case VTRUE:
428 case VFALSE:
420 case VNIL: {429 case VNIL: {
421 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */430 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
422 e->info = nil_constant(fs);431 e->info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
423 e->k = VK;432 e->k = VK;
424 return RKASK(e->info);433 return RKASK(e->info);
425 }434 }
@@ -441,7 +450,7 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { · 15 unmodified lines
441 switch (var->k) {450 switch (var->k) {
442 case VLOCAL: {451 case VLOCAL: {
443 freeexp(fs, ex);452 freeexp(fs, ex);
444 luaK_exp2reg(fs, ex, var->info);453 exp2reg(fs, ex, var->info);
445 return;454 return;
446 }455 }
447 case VUPVAL: {456 case VUPVAL: {
@@ -493,13 +502,13 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) { · 45 unmodified lines
493 Instruction ie = getcode(fs, e);502 Instruction ie = getcode(fs, e);
494 if (GET_OPCODE(ie) == OP_NOT) {503 if (GET_OPCODE(ie) == OP_NOT) {
495 fs->pc--; /* remove previous OP_NOT */504 fs->pc--; /* remove previous OP_NOT */
496 return luaK_condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond);505 return condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond);
497 }506 }
498 /* else go through */507 /* else go through */
499 }508 }
500 discharge2anyreg(fs, e);509 discharge2anyreg(fs, e);
501 freeexp(fs, e);510 freeexp(fs, e);
502 return luaK_condjump(fs, OP_TEST, NO_REG, e->info, cond);511 return condjump(fs, OP_TEST, NO_REG, e->info, cond);
503}512}
504 513
505 514
@@ -651,7 +660,7 @@ static void codebinop (FuncState *fs, expdesc *res, BinOpr op, · 145 unmodified lines
651 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */660 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
652 }661 }
653 else if (op == OPR_NE) cond = 0;662 else if (op == OPR_NE) cond = 0;
654 res->info = luaK_condjump(fs, ops[op - OPR_NE], cond, o1, o2);663 res->info = condjump(fs, ops[op - OPR_NE], cond, o1, o2);
655 res->k = VJMP;664 res->k = VJMP;
656 }665 }
657}666}
@@ -708,7 +717,7 @@ void luaK_fixline (FuncState *fs, int line) { · 50 unmodified lines
708 717
709int luaK_code (FuncState *fs, Instruction i, int line) {718int luaK_code (FuncState *fs, Instruction i, int line) {
710 Proto *f = fs->f;719 Proto *f = fs->f;
711 luaK_dischargejpc(fs); /* `pc' will change */720 dischargejpc(fs); /* `pc' will change */
712 /* put new instruction in code array */721 /* put new instruction in code array */
713 luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,722 luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
714 MAX_INT, "code size overflow");723 MAX_INT, "code size overflow");
@@ -735,3 +744,17 @@ int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { · 20 unmodified lines
735 return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);744 return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
736}745}
737 746
747
748void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
749 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
750 int b = (tostore == LUA_MULTRET) ? 0 : tostore;
751 lua_assert(tostore != 0);
752 if (c <= MAXARG_C)
753 luaK_codeABC(fs, OP_SETLIST, base, b, c);
754 else {
755 luaK_codeABC(fs, OP_SETLIST, base, b, 0);
756 luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
757 }
758 fs->freereg = base + 1; /* free registers with list values */
759}
760