summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/lua/lcode.c')
-rw-r--r--apps/plugins/lua/lcode.c400
1 files changed, 221 insertions, 179 deletions
diff --git a/apps/plugins/lua/lcode.c b/apps/plugins/lua/lcode.c
index cff626b7fa..820b95c0e1 100644
--- a/apps/plugins/lua/lcode.c
+++ b/apps/plugins/lua/lcode.c
@@ -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.62.1.1 2013/04/12 18:48:47 roberto Exp $
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*/
@@ -21,7 +21,9 @@
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"
26#include "lvm.h"
25 27
26 28
27#define hasjumps(e) ((e)->t != (e)->f) 29#define hasjumps(e) ((e)->t != (e)->f)
@@ -34,25 +36,23 @@ static int isnumeral(expdesc *e) {
34 36
35void luaK_nil (FuncState *fs, int from, int n) { 37void luaK_nil (FuncState *fs, int from, int n) {
36 Instruction *previous; 38 Instruction *previous;
39 int l = from + n - 1; /* last register to set nil */
37 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ 40 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
38 if (fs->pc == 0) { /* function start? */ 41 previous = &fs->f->code[fs->pc-1];
39 if (from >= fs->nactvar) 42 if (GET_OPCODE(*previous) == OP_LOADNIL) {
40 return; /* positions are already clean */ 43 int pfrom = GETARG_A(*previous);
41 } 44 int pl = pfrom + GETARG_B(*previous);
42 else { 45 if ((pfrom <= from && from <= pl + 1) ||
43 previous = &fs->f->code[fs->pc-1]; 46 (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */
44 if (GET_OPCODE(*previous) == OP_LOADNIL) { 47 if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */
45 int pfrom = GETARG_A(*previous); 48 if (pl > l) l = pl; /* l = max(l, pl) */
46 int pto = GETARG_B(*previous); 49 SETARG_A(*previous, from);
47 if (pfrom <= from && from <= pto+1) { /* can connect both? */ 50 SETARG_B(*previous, l - from);
48 if (from+n-1 > pto) 51 return;
49 SETARG_B(*previous, from+n-1);
50 return;
51 }
52 } 52 }
53 } 53 } /* else go through */
54 } 54 }
55 luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */ 55 luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */
56} 56}
57 57
58 58
@@ -176,6 +176,19 @@ void luaK_patchlist (FuncState *fs, int list, int target) {
176} 176}
177 177
178 178
179LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) {
180 level++; /* argument is +1 to reserve 0 as non-op */
181 while (list != NO_JUMP) {
182 int next = getjump(fs, list);
183 lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
184 (GETARG_A(fs->f->code[list]) == 0 ||
185 GETARG_A(fs->f->code[list]) >= level));
186 SETARG_A(fs->f->code[list], level);
187 list = next;
188 }
189}
190
191
179void luaK_patchtohere (FuncState *fs, int list) { 192void luaK_patchtohere (FuncState *fs, int list) {
180 luaK_getlabel(fs); 193 luaK_getlabel(fs);
181 luaK_concat(fs, &fs->jpc, list); 194 luaK_concat(fs, &fs->jpc, list);
@@ -196,6 +209,55 @@ void luaK_concat (FuncState *fs, int *l1, int l2) {
196} 209}
197 210
198 211
212static int luaK_code (FuncState *fs, Instruction i) {
213 Proto *f = fs->f;
214 dischargejpc(fs); /* `pc' will change */
215 /* put new instruction in code array */
216 luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
217 MAX_INT, "opcodes");
218 f->code[fs->pc] = i;
219 /* save corresponding line information */
220 luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
221 MAX_INT, "opcodes");
222 f->lineinfo[fs->pc] = fs->ls->lastline;
223 return fs->pc++;
224}
225
226
227int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
228 lua_assert(getOpMode(o) == iABC);
229 lua_assert(getBMode(o) != OpArgN || b == 0);
230 lua_assert(getCMode(o) != OpArgN || c == 0);
231 lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
232 return luaK_code(fs, CREATE_ABC(o, a, b, c));
233}
234
235
236int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
237 lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
238 lua_assert(getCMode(o) == OpArgN);
239 lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
240 return luaK_code(fs, CREATE_ABx(o, a, bc));
241}
242
243
244static int codeextraarg (FuncState *fs, int a) {
245 lua_assert(a <= MAXARG_Ax);
246 return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
247}
248
249
250int luaK_codek (FuncState *fs, int reg, int k) {
251 if (k <= MAXARG_Bx)
252 return luaK_codeABx(fs, OP_LOADK, reg, k);
253 else {
254 int p = luaK_codeABx(fs, OP_LOADKX, reg, 0);
255 codeextraarg(fs, k);
256 return p;
257 }
258}
259
260
199void luaK_checkstack (FuncState *fs, int n) { 261void luaK_checkstack (FuncState *fs, int n) {
200 int newstack = fs->freereg + n; 262 int newstack = fs->freereg + n;
201 if (newstack > fs->f->maxstacksize) { 263 if (newstack > fs->f->maxstacksize) {
@@ -222,42 +284,59 @@ static void freereg (FuncState *fs, int reg) {
222 284
223static void freeexp (FuncState *fs, expdesc *e) { 285static void freeexp (FuncState *fs, expdesc *e) {
224 if (e->k == VNONRELOC) 286 if (e->k == VNONRELOC)
225 freereg(fs, e->u.s.info); 287 freereg(fs, e->u.info);
226} 288}
227 289
228 290
229static int addk (FuncState *fs, TValue *k, TValue *v) { 291static int addk (FuncState *fs, TValue *key, TValue *v) {
230 lua_State *L = fs->L; 292 lua_State *L = fs->ls->L;
231 TValue *idx = luaH_set(L, fs->h, k); 293 TValue *idx = luaH_set(L, fs->h, key);
232 Proto *f = fs->f; 294 Proto *f = fs->f;
233 int oldsize = f->sizek; 295 int k, oldsize;
234 if (ttisnumber(idx)) { 296 if (ttisnumber(idx)) {
235 lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); 297 lua_Number n = nvalue(idx);
236 return cast_int(nvalue(idx)); 298 lua_number2int(k, n);
237 } 299 if (luaV_rawequalobj(&f->k[k], v))
238 else { /* constant not found; create a new entry */ 300 return k;
239 setnvalue(idx, cast_num(fs->nk)); 301 /* 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, 302 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 } 303 }
304 /* constant not found; create a new entry */
305 oldsize = f->sizek;
306 k = fs->nk;
307 /* numerical value does not need GC barrier;
308 table has no metatable, so it does not need to invalidate cache */
309 setnvalue(idx, cast_num(k));
310 luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
311 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
312 setobj(L, &f->k[k], v);
313 fs->nk++;
314 luaC_barrier(L, f, v);
315 return k;
247} 316}
248 317
249 318
250int luaK_stringK (FuncState *fs, TString *s) { 319int luaK_stringK (FuncState *fs, TString *s) {
251 TValue o; 320 TValue o;
252 setsvalue(fs->L, &o, s); 321 setsvalue(fs->ls->L, &o, s);
253 return addk(fs, &o, &o); 322 return addk(fs, &o, &o);
254} 323}
255 324
256 325
257int luaK_numberK (FuncState *fs, lua_Number r) { 326int luaK_numberK (FuncState *fs, lua_Number r) {
327 int n;
328 lua_State *L = fs->ls->L;
258 TValue o; 329 TValue o;
259 setnvalue(&o, r); 330 setnvalue(&o, r);
260 return addk(fs, &o, &o); 331 if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */
332 /* use raw representation as key to avoid numeric problems */
333 setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r)));
334 n = addk(fs, L->top - 1, &o);
335 L->top--;
336 }
337 else
338 n = addk(fs, &o, &o); /* regular case */
339 return n;
261} 340}
262 341
263 342
@@ -272,7 +351,7 @@ static int nilK (FuncState *fs) {
272 TValue k, v; 351 TValue k, v;
273 setnilvalue(&v); 352 setnilvalue(&v);
274 /* cannot use nil as key; instead use table itself to represent nil */ 353 /* cannot use nil as key; instead use table itself to represent nil */
275 sethvalue(fs->L, &k, fs->h); 354 sethvalue(fs->ls->L, &k, fs->h);
276 return addk(fs, &k, &v); 355 return addk(fs, &k, &v);
277} 356}
278 357
@@ -292,7 +371,7 @@ void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
292void luaK_setoneret (FuncState *fs, expdesc *e) { 371void luaK_setoneret (FuncState *fs, expdesc *e) {
293 if (e->k == VCALL) { /* expression is an open function call? */ 372 if (e->k == VCALL) { /* expression is an open function call? */
294 e->k = VNONRELOC; 373 e->k = VNONRELOC;
295 e->u.s.info = GETARG_A(getcode(fs, e)); 374 e->u.info = GETARG_A(getcode(fs, e));
296 } 375 }
297 else if (e->k == VVARARG) { 376 else if (e->k == VVARARG) {
298 SETARG_B(getcode(fs, e), 2); 377 SETARG_B(getcode(fs, e), 2);
@@ -308,19 +387,18 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
308 break; 387 break;
309 } 388 }
310 case VUPVAL: { 389 case VUPVAL: {
311 e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0); 390 e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
312 e->k = VRELOCABLE;
313 break;
314 }
315 case VGLOBAL: {
316 e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);
317 e->k = VRELOCABLE; 391 e->k = VRELOCABLE;
318 break; 392 break;
319 } 393 }
320 case VINDEXED: { 394 case VINDEXED: {
321 freereg(fs, e->u.s.aux); 395 OpCode op = OP_GETTABUP; /* assume 't' is in an upvalue */
322 freereg(fs, e->u.s.info); 396 freereg(fs, e->u.ind.idx);
323 e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux); 397 if (e->u.ind.vt == VLOCAL) { /* 't' is in a register? */
398 freereg(fs, e->u.ind.t);
399 op = OP_GETTABLE;
400 }
401 e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
324 e->k = VRELOCABLE; 402 e->k = VRELOCABLE;
325 break; 403 break;
326 } 404 }
@@ -347,16 +425,16 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
347 luaK_nil(fs, reg, 1); 425 luaK_nil(fs, reg, 1);
348 break; 426 break;
349 } 427 }
350 case VFALSE: case VTRUE: { 428 case VFALSE: case VTRUE: {
351 luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); 429 luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
352 break; 430 break;
353 } 431 }
354 case VK: { 432 case VK: {
355 luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info); 433 luaK_codek(fs, reg, e->u.info);
356 break; 434 break;
357 } 435 }
358 case VKNUM: { 436 case VKNUM: {
359 luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval)); 437 luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
360 break; 438 break;
361 } 439 }
362 case VRELOCABLE: { 440 case VRELOCABLE: {
@@ -365,8 +443,8 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
365 break; 443 break;
366 } 444 }
367 case VNONRELOC: { 445 case VNONRELOC: {
368 if (reg != e->u.s.info) 446 if (reg != e->u.info)
369 luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0); 447 luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
370 break; 448 break;
371 } 449 }
372 default: { 450 default: {
@@ -374,7 +452,7 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
374 return; /* nothing to do... */ 452 return; /* nothing to do... */
375 } 453 }
376 } 454 }
377 e->u.s.info = reg; 455 e->u.info = reg;
378 e->k = VNONRELOC; 456 e->k = VNONRELOC;
379} 457}
380 458
@@ -390,7 +468,7 @@ static void discharge2anyreg (FuncState *fs, expdesc *e) {
390static void exp2reg (FuncState *fs, expdesc *e, int reg) { 468static void exp2reg (FuncState *fs, expdesc *e, int reg) {
391 discharge2reg(fs, e, reg); 469 discharge2reg(fs, e, reg);
392 if (e->k == VJMP) 470 if (e->k == VJMP)
393 luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */ 471 luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */
394 if (hasjumps(e)) { 472 if (hasjumps(e)) {
395 int final; /* position after whole expression */ 473 int final; /* position after whole expression */
396 int p_f = NO_JUMP; /* position of an eventual LOAD false */ 474 int p_f = NO_JUMP; /* position of an eventual LOAD false */
@@ -406,7 +484,7 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) {
406 patchlistaux(fs, e->t, final, reg, p_t); 484 patchlistaux(fs, e->t, final, reg, p_t);
407 } 485 }
408 e->f = e->t = NO_JUMP; 486 e->f = e->t = NO_JUMP;
409 e->u.s.info = reg; 487 e->u.info = reg;
410 e->k = VNONRELOC; 488 e->k = VNONRELOC;
411} 489}
412 490
@@ -422,14 +500,20 @@ void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
422int luaK_exp2anyreg (FuncState *fs, expdesc *e) { 500int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
423 luaK_dischargevars(fs, e); 501 luaK_dischargevars(fs, e);
424 if (e->k == VNONRELOC) { 502 if (e->k == VNONRELOC) {
425 if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */ 503 if (!hasjumps(e)) return e->u.info; /* exp is already in a register */
426 if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */ 504 if (e->u.info >= fs->nactvar) { /* reg. is not a local? */
427 exp2reg(fs, e, e->u.s.info); /* put value on it */ 505 exp2reg(fs, e, e->u.info); /* put value on it */
428 return e->u.s.info; 506 return e->u.info;
429 } 507 }
430 } 508 }
431 luaK_exp2nextreg(fs, e); /* default */ 509 luaK_exp2nextreg(fs, e); /* default */
432 return e->u.s.info; 510 return e->u.info;
511}
512
513
514void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
515 if (e->k != VUPVAL || hasjumps(e))
516 luaK_exp2anyreg(fs, e);
433} 517}
434 518
435 519
@@ -444,22 +528,24 @@ void luaK_exp2val (FuncState *fs, expdesc *e) {
444int luaK_exp2RK (FuncState *fs, expdesc *e) { 528int luaK_exp2RK (FuncState *fs, expdesc *e) {
445 luaK_exp2val(fs, e); 529 luaK_exp2val(fs, e);
446 switch (e->k) { 530 switch (e->k) {
447 case VKNUM:
448 case VTRUE: 531 case VTRUE:
449 case VFALSE: 532 case VFALSE:
450 case VNIL: { 533 case VNIL: {
451 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */ 534 if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */
452 e->u.s.info = (e->k == VNIL) ? nilK(fs) : 535 e->u.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; 536 e->k = VK;
456 return RKASK(e->u.s.info); 537 return RKASK(e->u.info);
457 } 538 }
458 else break; 539 else break;
459 } 540 }
541 case VKNUM: {
542 e->u.info = luaK_numberK(fs, e->u.nval);
543 e->k = VK;
544 /* go through */
545 }
460 case VK: { 546 case VK: {
461 if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */ 547 if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */
462 return RKASK(e->u.s.info); 548 return RKASK(e->u.info);
463 else break; 549 else break;
464 } 550 }
465 default: break; 551 default: break;
@@ -473,22 +559,18 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
473 switch (var->k) { 559 switch (var->k) {
474 case VLOCAL: { 560 case VLOCAL: {
475 freeexp(fs, ex); 561 freeexp(fs, ex);
476 exp2reg(fs, ex, var->u.s.info); 562 exp2reg(fs, ex, var->u.info);
477 return; 563 return;
478 } 564 }
479 case VUPVAL: { 565 case VUPVAL: {
480 int e = luaK_exp2anyreg(fs, ex); 566 int e = luaK_exp2anyreg(fs, ex);
481 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0); 567 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
482 break;
483 }
484 case VGLOBAL: {
485 int e = luaK_exp2anyreg(fs, ex);
486 luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);
487 break; 568 break;
488 } 569 }
489 case VINDEXED: { 570 case VINDEXED: {
571 OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
490 int e = luaK_exp2RK(fs, ex); 572 int e = luaK_exp2RK(fs, ex);
491 luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); 573 luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
492 break; 574 break;
493 } 575 }
494 default: { 576 default: {
@@ -501,20 +583,20 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
501 583
502 584
503void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { 585void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
504 int func; 586 int ereg;
505 luaK_exp2anyreg(fs, e); 587 luaK_exp2anyreg(fs, e);
588 ereg = e->u.info; /* register where 'e' was placed */
506 freeexp(fs, e); 589 freeexp(fs, e);
507 func = fs->freereg; 590 e->u.info = fs->freereg; /* base register for op_self */
508 luaK_reserveregs(fs, 2);
509 luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
510 freeexp(fs, key);
511 e->u.s.info = func;
512 e->k = VNONRELOC; 591 e->k = VNONRELOC;
592 luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */
593 luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key));
594 freeexp(fs, key);
513} 595}
514 596
515 597
516static void invertjump (FuncState *fs, expdesc *e) { 598static void invertjump (FuncState *fs, expdesc *e) {
517 Instruction *pc = getjumpcontrol(fs, e->u.s.info); 599 Instruction *pc = getjumpcontrol(fs, e->u.info);
518 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && 600 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
519 GET_OPCODE(*pc) != OP_TEST); 601 GET_OPCODE(*pc) != OP_TEST);
520 SETARG_A(*pc, !(GETARG_A(*pc))); 602 SETARG_A(*pc, !(GETARG_A(*pc)));
@@ -532,7 +614,7 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) {
532 } 614 }
533 discharge2anyreg(fs, e); 615 discharge2anyreg(fs, e);
534 freeexp(fs, e); 616 freeexp(fs, e);
535 return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond); 617 return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
536} 618}
537 619
538 620
@@ -540,17 +622,13 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
540 int pc; /* pc of last jump */ 622 int pc; /* pc of last jump */
541 luaK_dischargevars(fs, e); 623 luaK_dischargevars(fs, e);
542 switch (e->k) { 624 switch (e->k) {
543 case VK: case VKNUM: case VTRUE: {
544 pc = NO_JUMP; /* always true; do nothing */
545 break;
546 }
547 case VFALSE: {
548 pc = luaK_jump(fs); /* always jump */
549 break;
550 }
551 case VJMP: { 625 case VJMP: {
552 invertjump(fs, e); 626 invertjump(fs, e);
553 pc = e->u.s.info; 627 pc = e->u.info;
628 break;
629 }
630 case VK: case VKNUM: case VTRUE: {
631 pc = NO_JUMP; /* always true; do nothing */
554 break; 632 break;
555 } 633 }
556 default: { 634 default: {
@@ -564,20 +642,16 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
564} 642}
565 643
566 644
567static void luaK_goiffalse (FuncState *fs, expdesc *e) { 645void luaK_goiffalse (FuncState *fs, expdesc *e) {
568 int pc; /* pc of last jump */ 646 int pc; /* pc of last jump */
569 luaK_dischargevars(fs, e); 647 luaK_dischargevars(fs, e);
570 switch (e->k) { 648 switch (e->k) {
571 case VNIL: case VFALSE: { 649 case VJMP: {
572 pc = NO_JUMP; /* always false; do nothing */ 650 pc = e->u.info;
573 break;
574 }
575 case VTRUE: {
576 pc = luaK_jump(fs); /* always jump */
577 break; 651 break;
578 } 652 }
579 case VJMP: { 653 case VNIL: case VFALSE: {
580 pc = e->u.s.info; 654 pc = NO_JUMP; /* always false; do nothing */
581 break; 655 break;
582 } 656 }
583 default: { 657 default: {
@@ -610,7 +684,7 @@ static void codenot (FuncState *fs, expdesc *e) {
610 case VNONRELOC: { 684 case VNONRELOC: {
611 discharge2anyreg(fs, e); 685 discharge2anyreg(fs, e);
612 freeexp(fs, e); 686 freeexp(fs, e);
613 e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0); 687 e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
614 e->k = VRELOCABLE; 688 e->k = VRELOCABLE;
615 break; 689 break;
616 } 690 }
@@ -627,38 +701,28 @@ static void codenot (FuncState *fs, expdesc *e) {
627 701
628 702
629void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { 703void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
630 t->u.s.aux = luaK_exp2RK(fs, k); 704 lua_assert(!hasjumps(t));
705 t->u.ind.t = t->u.info;
706 t->u.ind.idx = luaK_exp2RK(fs, k);
707 t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL
708 : check_exp(vkisinreg(t->k), VLOCAL);
631 t->k = VINDEXED; 709 t->k = VINDEXED;
632} 710}
633 711
634 712
635static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { 713static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
636 lua_Number v1, v2, r; 714 lua_Number r;
637 if (!isnumeral(e1) || !isnumeral(e2)) return 0; 715 if (!isnumeral(e1) || !isnumeral(e2)) return 0;
638 v1 = e1->u.nval; 716 if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0)
639 v2 = e2->u.nval; 717 return 0; /* do not attempt to divide by 0 */
640 switch (op) { 718 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; 719 e1->u.nval = r;
657 return 1; 720 return 1;
658} 721}
659 722
660 723
661static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { 724static void codearith (FuncState *fs, OpCode op,
725 expdesc *e1, expdesc *e2, int line) {
662 if (constfolding(op, e1, e2)) 726 if (constfolding(op, e1, e2))
663 return; 727 return;
664 else { 728 else {
@@ -672,8 +736,9 @@ static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
672 freeexp(fs, e2); 736 freeexp(fs, e2);
673 freeexp(fs, e1); 737 freeexp(fs, e1);
674 } 738 }
675 e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2); 739 e1->u.info = luaK_codeABC(fs, op, 0, o1, o2);
676 e1->k = VRELOCABLE; 740 e1->k = VRELOCABLE;
741 luaK_fixline(fs, line);
677 } 742 }
678} 743}
679 744
@@ -689,25 +754,28 @@ static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
689 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ 754 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
690 cond = 1; 755 cond = 1;
691 } 756 }
692 e1->u.s.info = condjump(fs, op, cond, o1, o2); 757 e1->u.info = condjump(fs, op, cond, o1, o2);
693 e1->k = VJMP; 758 e1->k = VJMP;
694} 759}
695 760
696 761
697void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { 762void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
698 expdesc e2; 763 expdesc e2;
699 e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; 764 e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
700 switch (op) { 765 switch (op) {
701 case OPR_MINUS: { 766 case OPR_MINUS: {
702 if (!isnumeral(e)) 767 if (isnumeral(e)) /* minus constant? */
703 luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ 768 e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */
704 codearith(fs, OP_UNM, e, &e2); 769 else {
770 luaK_exp2anyreg(fs, e);
771 codearith(fs, OP_UNM, e, &e2, line);
772 }
705 break; 773 break;
706 } 774 }
707 case OPR_NOT: codenot(fs, e); break; 775 case OPR_NOT: codenot(fs, e); break;
708 case OPR_LEN: { 776 case OPR_LEN: {
709 luaK_exp2anyreg(fs, e); /* cannot operate on constants */ 777 luaK_exp2anyreg(fs, e); /* cannot operate on constants */
710 codearith(fs, OP_LEN, e, &e2); 778 codearith(fs, OP_LEN, e, &e2, line);
711 break; 779 break;
712 } 780 }
713 default: lua_assert(0); 781 default: lua_assert(0);
@@ -742,7 +810,8 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
742} 810}
743 811
744 812
745void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { 813void luaK_posfix (FuncState *fs, BinOpr op,
814 expdesc *e1, expdesc *e2, int line) {
746 switch (op) { 815 switch (op) {
747 case OPR_AND: { 816 case OPR_AND: {
748 lua_assert(e1->t == NO_JUMP); /* list must be closed */ 817 lua_assert(e1->t == NO_JUMP); /* list must be closed */
@@ -761,29 +830,30 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
761 case OPR_CONCAT: { 830 case OPR_CONCAT: {
762 luaK_exp2val(fs, e2); 831 luaK_exp2val(fs, e2);
763 if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { 832 if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
764 lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1); 833 lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1);
765 freeexp(fs, e1); 834 freeexp(fs, e1);
766 SETARG_B(getcode(fs, e2), e1->u.s.info); 835 SETARG_B(getcode(fs, e2), e1->u.info);
767 e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info; 836 e1->k = VRELOCABLE; e1->u.info = e2->u.info;
768 } 837 }
769 else { 838 else {
770 luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ 839 luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
771 codearith(fs, OP_CONCAT, e1, e2); 840 codearith(fs, OP_CONCAT, e1, e2, line);
772 } 841 }
773 break; 842 break;
774 } 843 }
775 case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break; 844 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
776 case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break; 845 case OPR_MOD: case OPR_POW: {
777 case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break; 846 codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line);
778 case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break; 847 break;
779 case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break; 848 }
780 case OPR_POW: codearith(fs, OP_POW, e1, e2); break; 849 case OPR_EQ: case OPR_LT: case OPR_LE: {
781 case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break; 850 codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2);
782 case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break; 851 break;
783 case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break; 852 }
784 case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break; 853 case OPR_NE: case OPR_GT: case OPR_GE: {
785 case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break; 854 codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2);
786 case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break; 855 break;
856 }
787 default: lua_assert(0); 857 default: lua_assert(0);
788 } 858 }
789} 859}
@@ -794,46 +864,18 @@ void luaK_fixline (FuncState *fs, int line) {
794} 864}
795 865
796 866
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) { 867void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
828 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; 868 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
829 int b = (tostore == LUA_MULTRET) ? 0 : tostore; 869 int b = (tostore == LUA_MULTRET) ? 0 : tostore;
830 lua_assert(tostore != 0); 870 lua_assert(tostore != 0);
831 if (c <= MAXARG_C) 871 if (c <= MAXARG_C)
832 luaK_codeABC(fs, OP_SETLIST, base, b, c); 872 luaK_codeABC(fs, OP_SETLIST, base, b, c);
833 else { 873 else if (c <= MAXARG_Ax) {
834 luaK_codeABC(fs, OP_SETLIST, base, b, 0); 874 luaK_codeABC(fs, OP_SETLIST, base, b, 0);
835 luaK_code(fs, cast(Instruction, c), fs->ls->lastline); 875 codeextraarg(fs, c);
836 } 876 }
877 else
878 luaX_syntaxerror(fs->ls, "constructor too long");
837 fs->freereg = base + 1; /* free registers with list values */ 879 fs->freereg = base + 1; /* free registers with list values */
838} 880}
839 881