aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/lcode.c b/lcode.c
index e471ffd1..844ceea0 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.32 2000/05/24 13:54:49 roberto Exp roberto $ 2** $Id: lcode.c,v 1.33 2000/05/24 18:04:17 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -69,16 +69,16 @@ static int luaK_getjump (FuncState *fs, int pc) {
69 69
70 70
71/* 71/*
72** discharge list of jumps to last target.
73** returns current `pc' and marks it as a jump target (to avoid wrong 72** returns current `pc' and marks it as a jump target (to avoid wrong
74** optimizations with consecutive instructions not in the same basic block). 73** optimizations with consecutive instructions not in the same basic block).
74** discharge list of jumps to last target.
75*/ 75*/
76int luaK_getlabel (FuncState *fs) { 76int luaK_getlabel (FuncState *fs) {
77 if (fs->pc != fs->lasttarget) { 77 if (fs->pc != fs->lasttarget) {
78 int lasttarget = fs->lasttarget; 78 int lasttarget = fs->lasttarget;
79 fs->lasttarget = fs->pc; 79 fs->lasttarget = fs->pc;
80 luaK_patchlist(fs, fs->jlt, lasttarget); /* discharge old list `jlt' */ 80 luaK_patchlist(fs, fs->jlt, lasttarget); /* discharge old list `jlt' */
81 fs->jlt = NO_JUMP; /* nobody jumps to this new label (till now) */ 81 fs->jlt = NO_JUMP; /* nobody jumps to this new label (yet) */
82 } 82 }
83 return fs->pc; 83 return fs->pc;
84} 84}
@@ -86,7 +86,7 @@ int luaK_getlabel (FuncState *fs) {
86 86
87void luaK_deltastack (FuncState *fs, int delta) { 87void luaK_deltastack (FuncState *fs, int delta) {
88 fs->stacklevel += delta; 88 fs->stacklevel += delta;
89 if (delta > 0 && fs->stacklevel > fs->f->maxstacksize) { 89 if (fs->stacklevel > fs->f->maxstacksize) {
90 if (fs->stacklevel > MAXSTACK) 90 if (fs->stacklevel > MAXSTACK)
91 luaK_error(fs->ls, "function or expression too complex"); 91 luaK_error(fs->ls, "function or expression too complex");
92 fs->f->maxstacksize = fs->stacklevel; 92 fs->f->maxstacksize = fs->stacklevel;
@@ -99,7 +99,7 @@ void luaK_kstr (LexState *ls, int c) {
99} 99}
100 100
101 101
102static int real_constant (FuncState *fs, Number r) { 102static int number_constant (FuncState *fs, Number r) {
103 /* check whether `r' has appeared within the last LOOKBACKNUMS entries */ 103 /* check whether `r' has appeared within the last LOOKBACKNUMS entries */
104 Proto *f = fs->f; 104 Proto *f = fs->f;
105 int c = f->nknum; 105 int c = f->nknum;
@@ -116,17 +116,17 @@ static int real_constant (FuncState *fs, Number r) {
116 116
117 117
118void luaK_number (FuncState *fs, Number f) { 118void luaK_number (FuncState *fs, Number f) {
119 if (f <= (Number)MAXARG_S && (int)f == f) 119 if (f <= (Number)MAXARG_S && (Number)(int)f == f)
120 luaK_code1(fs, OP_PUSHINT, (int)f); /* f has a short integer value */ 120 luaK_code1(fs, OP_PUSHINT, (int)f); /* f has a short integer value */
121 else 121 else
122 luaK_code1(fs, OP_PUSHNUM, real_constant(fs, f)); 122 luaK_code1(fs, OP_PUSHNUM, number_constant(fs, f));
123} 123}
124 124
125 125
126void luaK_adjuststack (FuncState *fs, int n) { 126void luaK_adjuststack (FuncState *fs, int n) {
127 if (n > 0) 127 if (n > 0)
128 luaK_code1(fs, OP_POP, n); 128 luaK_code1(fs, OP_POP, n);
129 else if (n < 0) 129 else
130 luaK_code1(fs, OP_PUSHNIL, -n); 130 luaK_code1(fs, OP_PUSHNIL, -n);
131} 131}
132 132
@@ -170,7 +170,7 @@ static int discharge (FuncState *fs, expdesc *var) {
170 170
171static void discharge1 (FuncState *fs, expdesc *var) { 171static void discharge1 (FuncState *fs, expdesc *var) {
172 discharge(fs, var); 172 discharge(fs, var);
173 /* if it has jumps it is already discharged */ 173 /* if it has jumps then it is already discharged */
174 if (var->u.l.t == NO_JUMP && var->u.l.f == NO_JUMP) 174 if (var->u.l.t == NO_JUMP && var->u.l.f == NO_JUMP)
175 luaK_setcallreturns(fs, 1); /* call must return 1 value */ 175 luaK_setcallreturns(fs, 1); /* call must return 1 value */
176} 176}
@@ -275,12 +275,10 @@ static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) {
275 discharge1(fs, v); 275 discharge1(fs, v);
276 previous = &fs->f->code[fs->pc-1]; 276 previous = &fs->f->code[fs->pc-1];
277 LUA_ASSERT(L, GET_OPCODE(*previous) != OP_SETLINE, "bad place to set line"); 277 LUA_ASSERT(L, GET_OPCODE(*previous) != OP_SETLINE, "bad place to set line");
278 if (ISJUMP(GET_OPCODE(*previous))) { 278 if (!ISJUMP(GET_OPCODE(*previous)))
279 if (invert)
280 SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));
281 }
282 else
283 luaK_code1(fs, jump, NO_JUMP); 279 luaK_code1(fs, jump, NO_JUMP);
280 else if (invert)
281 SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));
284 luaK_concat(fs, exitlist, fs->pc-1); /* insert last jump in `exitlist' */ 282 luaK_concat(fs, exitlist, fs->pc-1); /* insert last jump in `exitlist' */
285 luaK_patchlist(fs, *golist, luaK_getlabel(fs)); 283 luaK_patchlist(fs, *golist, luaK_getlabel(fs));
286 *golist = NO_JUMP; 284 *golist = NO_JUMP;
@@ -431,12 +429,17 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
431 break; 429 break;
432 430
433 case OP_SETTABLE: 431 case OP_SETTABLE:
432 delta = -arg2;
433 break;
434
434 case OP_SETLIST: 435 case OP_SETLIST:
436 if (arg2 == 0) return NO_JUMP; /* nothing to do */
435 delta = -arg2; 437 delta = -arg2;
436 break; 438 break;
437 439
438 case OP_SETMAP: 440 case OP_SETMAP:
439 delta = -2*(arg1+1); 441 if (arg1 == 0) return NO_JUMP; /* nothing to do */
442 delta = -2*arg1;
440 break; 443 break;
441 444
442 case OP_RETURN: 445 case OP_RETURN:
@@ -448,6 +451,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
448 break; 451 break;
449 452
450 case OP_PUSHNIL: 453 case OP_PUSHNIL:
454 if (arg1 == 0) return NO_JUMP; /* nothing to do */
451 delta = arg1; 455 delta = arg1;
452 switch(GET_OPCODE(i)) { 456 switch(GET_OPCODE(i)) {
453 case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break; 457 case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break;
@@ -456,6 +460,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
456 break; 460 break;
457 461
458 case OP_POP: 462 case OP_POP:
463 if (arg1 == 0) return NO_JUMP; /* nothing to do */
459 delta = -arg1; 464 delta = -arg1;
460 switch(GET_OPCODE(i)) { 465 switch(GET_OPCODE(i)) {
461 case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break; 466 case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break;
@@ -561,13 +566,14 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
561 fs->f->code[fs->pc-1] = i; /* change previous instruction */ 566 fs->f->code[fs->pc-1] = i; /* change previous instruction */
562 return fs->pc-1; /* do not generate new instruction */ 567 return fs->pc-1; /* do not generate new instruction */
563 } 568 }
569 /* build new instruction */
564 switch ((enum Mode)luaK_opproperties[o].mode) { 570 switch ((enum Mode)luaK_opproperties[o].mode) {
565 case iO: i = CREATE_0(o); break; 571 case iO: i = CREATE_0(o); break;
566 case iU: i = CREATE_U(o, arg1); break; 572 case iU: i = CREATE_U(o, arg1); break;
567 case iS: i = CREATE_S(o, arg1); break; 573 case iS: i = CREATE_S(o, arg1); break;
568 case iAB: i = CREATE_AB(o, arg1, arg2); break; 574 case iAB: i = CREATE_AB(o, arg1, arg2); break;
569 } 575 }
570 /* actually create the new instruction */ 576 /* put new instruction in code array */
571 luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, 577 luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction,
572 "code size overflow", MAX_INT); 578 "code size overflow", MAX_INT);
573 fs->f->code[fs->pc] = i; 579 fs->f->code[fs->pc] = i;