History

Lua 5.2.0-work1

Lua Team committed 16 years ago

Commit 4ea600a1 parent d44fc9186 files · +6353 −5138Browse files

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

Unified · Split

src/lcode.c+141−112
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $2** $Id: lcode.c,v 2.42 2009/09/23 20:33:05 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*/
@@ -21,6 +21,7 @@ · 15 unmodified lines
21#include "lobject.h"21#include "lobject.h"
22#include "lopcodes.h"22#include "lopcodes.h"
23#include "lparser.h"23#include "lparser.h"
24#include "lstring.h"
24#include "ltable.h"25#include "ltable.h"
25 26
26 27
@@ -35,20 +36,14 @@ static int isnumeral(expdesc *e) { · 8 unmodified lines
35void luaK_nil (FuncState *fs, int from, int n) {36void luaK_nil (FuncState *fs, int from, int n) {
36 Instruction *previous;37 Instruction *previous;
37 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */38 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
38 if (fs->pc == 0) { /* function start? */39 previous = &fs->f->code[fs->pc-1];
39 if (from >= fs->nactvar)40 if (GET_OPCODE(*previous) == OP_LOADNIL) {
40 return; /* positions are already clean */41 int pfrom = GETARG_A(*previous);
41 }42 int pto = GETARG_B(*previous);
42 else {43 if (pfrom <= from && from <= pto+1) { /* can connect both? */
43 previous = &fs->f->code[fs->pc-1];44 if (from+n-1 > pto)
44 if (GET_OPCODE(*previous) == OP_LOADNIL) {45 SETARG_B(*previous, from+n-1);
45 int pfrom = GETARG_A(*previous);46 return;
46 int pto = GETARG_B(*previous);
47 if (pfrom <= from && from <= pto+1) { /* can connect both? */
48 if (from+n-1 > pto)
49 SETARG_B(*previous, from+n-1);
50 return;
51 }
52 }47 }
53 }48 }
54 }49 }
@@ -196,6 +191,55 @@ void luaK_concat (FuncState *fs, int *l1, int l2) { · 141 unmodified lines
196}191}
197 192
198 193
194static int luaK_code (FuncState *fs, Instruction i) {
195 Proto *f = fs->f;
196 dischargejpc(fs); /* `pc' will change */
197 /* put new instruction in code array */
198 luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
199 MAX_INT, "opcodes");
200 f->code[fs->pc] = i;
201 /* save corresponding line information */
202 luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
203 MAX_INT, "opcodes");
204 f->lineinfo[fs->pc] = fs->ls->lastline;
205 return fs->pc++;
206}
207
208
209int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
210 lua_assert(getOpMode(o) == iABC);
211 lua_assert(getBMode(o) != OpArgN || b == 0);
212 lua_assert(getCMode(o) != OpArgN || c == 0);
213 lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
214 return luaK_code(fs, CREATE_ABC(o, a, b, c));
215}
216
217
218int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
219 lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
220 lua_assert(getCMode(o) == OpArgN);
221 lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
222 return luaK_code(fs, CREATE_ABx(o, a, bc));
223}
224
225
226static int codeextraarg (FuncState *fs, int a) {
227 lua_assert(a <= MAXARG_Ax);
228 return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
229}
230
231
232int luaK_codeABxX (FuncState *fs, OpCode o, int reg, int k) {
233 if (k < MAXARG_Bx)
234 return luaK_codeABx(fs, o, reg, k + 1);
235 else {
236 int p = luaK_codeABx(fs, o, reg, 0);
237 codeextraarg(fs, k);
238 return p;
239 }
240}
241
242
199void luaK_checkstack (FuncState *fs, int n) {243void luaK_checkstack (FuncState *fs, int n) {
200 int newstack = fs->freereg + n;244 int newstack = fs->freereg + n;
201 if (newstack > fs->f->maxstacksize) {245 if (newstack > fs->f->maxstacksize) {
@@ -226,24 +270,29 @@ static void freeexp (FuncState *fs, expdesc *e) { · 24 unmodified lines
226}270}
227 271
228 272
229static int addk (FuncState *fs, TValue *k, TValue *v) {273static int addk (FuncState *fs, TValue *key, TValue *v) {
230 lua_State *L = fs->L;274 lua_State *L = fs->L;
231 TValue *idx = luaH_set(L, fs->h, k);275 TValue *idx = luaH_set(L, fs->h, key);
232 Proto *f = fs->f;276 Proto *f = fs->f;
233 int oldsize = f->sizek;277 int k, oldsize;
234 if (ttisnumber(idx)) {278 if (ttisnumber(idx)) {
235 lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v));279 lua_Number n = nvalue(idx);
236 return cast_int(nvalue(idx));280 lua_number2int(k, n);
237 }281 if (luaO_rawequalObj(&f->k[k], v))
238 else { /* constant not found; create a new entry */282 return k;
239 setnvalue(idx, cast_num(fs->nk));283 /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");
240 luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,284 go through and create a new entry for this value */
241 MAXARG_Bx, "constant table overflow");
242 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
243 setobj(L, &f->k[fs->nk], v);
244 luaC_barrier(L, f, v);
245 return fs->nk++;
246 }285 }
286 /* constant not found; create a new entry */
287 oldsize = f->sizek;
288 k = fs->nk;
289 setnvalue(idx, cast_num(k));
290 luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
291 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
292 setobj(L, &f->k[k], v);
293 fs->nk++;
294 luaC_barrier(L, f, v);
295 return k;
247}296}
248 297
249 298
@@ -255,9 +304,20 @@ int luaK_stringK (FuncState *fs, TString *s) { · 5 unmodified lines
255 304
256 305
257int luaK_numberK (FuncState *fs, lua_Number r) {306int luaK_numberK (FuncState *fs, lua_Number r) {
307 int n;
308 lua_State *L = fs->L;
258 TValue o;309 TValue o;
259 setnvalue(&o, r);310 setnvalue(&o, r);
260 return addk(fs, &o, &o);311 if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */
312 /* use raw representation as key to avoid numeric problems */
313 setsvalue(L, L->top, luaS_newlstr(L, (char *)&r, sizeof(r)));
314 incr_top(L);
315 n = addk(fs, L->top - 1, &o);
316 L->top--;
317 }
318 else
319 n = addk(fs, &o, &o); /* regular case */
320 return n;
261}321}
262 322
263 323
@@ -313,7 +373,7 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { · 49 unmodified lines
313 break;373 break;
314 }374 }
315 case VGLOBAL: {375 case VGLOBAL: {
316 e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);376 e->u.s.info = luaK_codeABxX(fs, OP_GETGLOBAL, 0, e->u.s.info);
317 e->k = VRELOCABLE;377 e->k = VRELOCABLE;
318 break;378 break;
319 }379 }
@@ -352,11 +412,11 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { · 32 unmodified lines
352 break;412 break;
353 }413 }
354 case VK: {414 case VK: {
355 luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info);415 luaK_codek(fs, reg, e->u.s.info);
356 break;416 break;
357 }417 }
358 case VKNUM: {418 case VKNUM: {
359 luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));419 luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
360 break;420 break;
361 }421 }
362 case VRELOCABLE: {422 case VRELOCABLE: {
@@ -444,19 +504,21 @@ void luaK_exp2val (FuncState *fs, expdesc *e) { · 81 unmodified lines
444int luaK_exp2RK (FuncState *fs, expdesc *e) {504int luaK_exp2RK (FuncState *fs, expdesc *e) {
445 luaK_exp2val(fs, e);505 luaK_exp2val(fs, e);
446 switch (e->k) {506 switch (e->k) {
447 case VKNUM:
448 case VTRUE:507 case VTRUE:
449 case VFALSE:508 case VFALSE:
450 case VNIL: {509 case VNIL: {
451 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */510 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
452 e->u.s.info = (e->k == VNIL) ? nilK(fs) :511 e->u.s.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
453 (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
454 boolK(fs, (e->k == VTRUE));
455 e->k = VK;512 e->k = VK;
456 return RKASK(e->u.s.info);513 return RKASK(e->u.s.info);
457 }514 }
458 else break;515 else break;
459 }516 }
517 case VKNUM: {
518 e->u.s.info = luaK_numberK(fs, e->u.nval);
519 e->k = VK;
520 /* go through */
521 }
460 case VK: {522 case VK: {
461 if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */523 if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */
462 return RKASK(e->u.s.info);524 return RKASK(e->u.s.info);
@@ -483,7 +545,7 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { · 20 unmodified lines
483 }545 }
484 case VGLOBAL: {546 case VGLOBAL: {
485 int e = luaK_exp2anyreg(fs, ex);547 int e = luaK_exp2anyreg(fs, ex);
486 luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);548 luaK_codeABxX(fs, OP_SETGLOBAL, e, var->u.s.info);
487 break;549 break;
488 }550 }
489 case VINDEXED: {551 case VINDEXED: {
@@ -544,15 +606,18 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { · 54 unmodified lines
544 pc = NO_JUMP; /* always true; do nothing */606 pc = NO_JUMP; /* always true; do nothing */
545 break;607 break;
546 }608 }
547 case VFALSE: {
548 pc = luaK_jump(fs); /* always jump */
549 break;
550 }
551 case VJMP: {609 case VJMP: {
552 invertjump(fs, e);610 invertjump(fs, e);
553 pc = e->u.s.info;611 pc = e->u.s.info;
554 break;612 break;
555 }613 }
614 case VFALSE: {
615 if (!hasjumps(e)) {
616 pc = luaK_jump(fs); /* always jump */
617 break;
618 }
619 /* else go through */
620 }
556 default: {621 default: {
557 pc = jumponcond(fs, e, 0);622 pc = jumponcond(fs, e, 0);
558 break;623 break;
@@ -572,14 +637,17 @@ static void luaK_goiffalse (FuncState *fs, expdesc *e) { · 13 unmodified lines
572 pc = NO_JUMP; /* always false; do nothing */637 pc = NO_JUMP; /* always false; do nothing */
573 break;638 break;
574 }639 }
575 case VTRUE: {
576 pc = luaK_jump(fs); /* always jump */
577 break;
578 }
579 case VJMP: {640 case VJMP: {
580 pc = e->u.s.info;641 pc = e->u.s.info;
581 break;642 break;
582 }643 }
644 case VTRUE: {
645 if (!hasjumps(e)) {
646 pc = luaK_jump(fs); /* always jump */
647 break;
648 }
649 /* else go through */
650 }
583 default: {651 default: {
584 pc = jumponcond(fs, e, 1);652 pc = jumponcond(fs, e, 1);
585 break;653 break;
@@ -633,26 +701,11 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { · 47 unmodified lines
633 701
634 702
635static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {703static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
636 lua_Number v1, v2, r;704 lua_Number r;
637 if (!isnumeral(e1) || !isnumeral(e2)) return 0;705 if (!isnumeral(e1) || !isnumeral(e2)) return 0;
638 v1 = e1->u.nval;706 if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0)
639 v2 = e2->u.nval;707 return 0; /* do not attempt to divide by 0 */
640 switch (op) {708 r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval);
641 case OP_ADD: r = luai_numadd(v1, v2); break;
642 case OP_SUB: r = luai_numsub(v1, v2); break;
643 case OP_MUL: r = luai_nummul(v1, v2); break;
644 case OP_DIV:
645 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
646 r = luai_numdiv(v1, v2); break;
647 case OP_MOD:
648 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
649 r = luai_nummod(v1, v2); break;
650 case OP_POW: r = luai_numpow(v1, v2); break;
651 case OP_UNM: r = luai_numunm(v1); break;
652 case OP_LEN: return 0; /* no constant folding for 'len' */
653 default: lua_assert(0); r = 0; break;
654 }
655 if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
656 e1->u.nval = r;709 e1->u.nval = r;
657 return 1;710 return 1;
658}711}
@@ -699,9 +752,12 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { · 40 unmodified lines
699 e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;752 e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
700 switch (op) {753 switch (op) {
701 case OPR_MINUS: {754 case OPR_MINUS: {
702 if (!isnumeral(e))755 if (isnumeral(e)) /* minus constant? */
703 luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */756 e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */
704 codearith(fs, OP_UNM, e, &e2);757 else {
758 luaK_exp2anyreg(fs, e);
759 codearith(fs, OP_UNM, e, &e2);
760 }
705 break;761 break;
706 }762 }
707 case OPR_NOT: codenot(fs, e); break;763 case OPR_NOT: codenot(fs, e); break;
@@ -772,18 +828,19 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { · 64 unmodified lines
772 }828 }
773 break;829 break;
774 }830 }
775 case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;831 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
776 case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;832 case OPR_MOD: case OPR_POW: {
777 case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;833 codearith(fs, op - OPR_ADD + OP_ADD, e1, e2);
778 case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;834 break;
779 case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;835 }
780 case OPR_POW: codearith(fs, OP_POW, e1, e2); break;836 case OPR_EQ: case OPR_LT: case OPR_LE: {
781 case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;837 codecomp(fs, op - OPR_EQ + OP_EQ, 1, e1, e2);
782 case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;838 break;
783 case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;839 }
784 case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;840 case OPR_NE: case OPR_GT: case OPR_GE: {
785 case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;841 codecomp(fs, op - OPR_NE + OP_EQ, 0, e1, e2);
786 case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;842 break;
843 }
787 default: lua_assert(0);844 default: lua_assert(0);
788 }845 }
789}846}
@@ -794,46 +851,18 @@ void luaK_fixline (FuncState *fs, int line) { · 4 unmodified lines
794}851}
795 852
796 853
797static int luaK_code (FuncState *fs, Instruction i, int line) {
798 Proto *f = fs->f;
799 dischargejpc(fs); /* `pc' will change */
800 /* put new instruction in code array */
801 luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
802 MAX_INT, "code size overflow");
803 f->code[fs->pc] = i;
804 /* save corresponding line information */
805 luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
806 MAX_INT, "code size overflow");
807 f->lineinfo[fs->pc] = line;
808 return fs->pc++;
809}
810
811
812int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
813 lua_assert(getOpMode(o) == iABC);
814 lua_assert(getBMode(o) != OpArgN || b == 0);
815 lua_assert(getCMode(o) != OpArgN || c == 0);
816 return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
817}
818
819
820int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
821 lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
822 lua_assert(getCMode(o) == OpArgN);
823 return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
824}
825
826
827void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {854void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
828 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;855 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
829 int b = (tostore == LUA_MULTRET) ? 0 : tostore;856 int b = (tostore == LUA_MULTRET) ? 0 : tostore;
830 lua_assert(tostore != 0);857 lua_assert(tostore != 0);
831 if (c <= MAXARG_C)858 if (c <= MAXARG_C)
832 luaK_codeABC(fs, OP_SETLIST, base, b, c);859 luaK_codeABC(fs, OP_SETLIST, base, b, c);
833 else {860 else if (c <= MAXARG_Ax) {
834 luaK_codeABC(fs, OP_SETLIST, base, b, 0);861 luaK_codeABC(fs, OP_SETLIST, base, b, 0);
835 luaK_code(fs, cast(Instruction, c), fs->ls->lastline);862 codeextraarg(fs, c);
836 }863 }
864 else
865 luaX_syntaxerror(fs->ls, "constructor too long");
837 fs->freereg = base + 1; /* free registers with list values */866 fs->freereg = base + 1; /* free registers with list values */
838}867}
839 868