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