History

Lua 5.1-beta

Lua Team committed 20 years ago

Commit 27f2ec71 parent 573ffb039 files · +1862 −1502Browse files

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

Unified · Split

src/lcode.c+161−118
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lcode.c,v 2.16 2005/08/29 20:49:21 roberto Exp $2** $Id: lcode.c,v 2.22 2005/11/16 11:55:27 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*/
@@ -27,16 +27,24 @@ · 21 unmodified lines
27#define hasjumps(e) ((e)->t != (e)->f)27#define hasjumps(e) ((e)->t != (e)->f)
28 28
29 29
30static int isnumeral(expdesc *e) {
31 return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
32}
33
34
30void luaK_nil (FuncState *fs, int from, int n) {35void luaK_nil (FuncState *fs, int from, int n) {
31 Instruction *previous;36 Instruction *previous;
32 if (fs->pc > fs->lasttarget && /* no jumps to current position? */37 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
33 GET_OPCODE(*(previous = &fs->f->code[fs->pc-1])) == OP_LOADNIL) {38 if (fs->pc == 0) /* function start? */
34 int pfrom = GETARG_A(*previous);39 return; /* positions are already clean */
35 int pto = GETARG_B(*previous);40 if (GET_OPCODE(*(previous = &fs->f->code[fs->pc-1])) == OP_LOADNIL) {
36 if (pfrom <= from && from <= pto+1) { /* can connect both? */41 int pfrom = GETARG_A(*previous);
37 if (from+n-1 > pto)42 int pto = GETARG_B(*previous);
38 SETARG_B(*previous, from+n-1);43 if (pfrom <= from && from <= pto+1) { /* can connect both? */
39 return;44 if (from+n-1 > pto)
45 SETARG_B(*previous, from+n-1);
46 return;
47 }
40 }48 }
41 }49 }
42 luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */50 luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */
@@ -115,20 +123,22 @@ static int need_value (FuncState *fs, int list) { · 72 unmodified lines
115}123}
116 124
117 125
118static void patchtestreg (Instruction *i, int reg) {126static int patchtestreg (FuncState *fs, int node, int reg) {
119 if (reg != NO_REG)127 Instruction *i = getjumpcontrol(fs, node);
128 if (GET_OPCODE(*i) != OP_TESTSET)
129 return 0; /* cannot patch other instructions */
130 if (reg != NO_REG && reg != GETARG_B(*i))
120 SETARG_A(*i, reg);131 SETARG_A(*i, reg);
121 else /* no register to put value; change TESTSET to TEST */132 else /* no register to put value or register already has the value */
122 *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));133 *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
134
135 return 1;
123}136}
124 137
125 138
126static void removevalues (FuncState *fs, int list) {139static void removevalues (FuncState *fs, int list) {
127 for (; list != NO_JUMP; list = getjump(fs, list)) {140 for (; list != NO_JUMP; list = getjump(fs, list))
128 Instruction *i = getjumpcontrol(fs, list);141 patchtestreg(fs, list, NO_REG);
129 if (GET_OPCODE(*i) == OP_TESTSET)
130 patchtestreg(i, NO_REG);
131 }
132}142}
133 143
134 144
@@ -136,11 +146,8 @@ static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, · 1 unmodified line
136 int dtarget) {146 int dtarget) {
137 while (list != NO_JUMP) {147 while (list != NO_JUMP) {
138 int next = getjump(fs, list);148 int next = getjump(fs, list);
139 Instruction *i = getjumpcontrol(fs, list);149 if (patchtestreg(fs, list, reg))
140 if (GET_OPCODE(*i) == OP_TESTSET) {
141 patchtestreg(i, reg);
142 fixjump(fs, list, vtarget);150 fixjump(fs, list, vtarget);
143 }
144 else151 else
145 fixjump(fs, list, dtarget); /* jump to default target */152 fixjump(fs, list, dtarget); /* jump to default target */
146 list = next;153 list = next;
@@ -210,7 +217,7 @@ static void freereg (FuncState *fs, int reg) { · 63 unmodified lines
210 217
211static void freeexp (FuncState *fs, expdesc *e) {218static void freeexp (FuncState *fs, expdesc *e) {
212 if (e->k == VNONRELOC)219 if (e->k == VNONRELOC)
213 freereg(fs, e->info);220 freereg(fs, e->u.s.info);
214}221}
215 222
216 223
@@ -280,7 +287,7 @@ void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { · 63 unmodified lines
280void luaK_setoneret (FuncState *fs, expdesc *e) {287void luaK_setoneret (FuncState *fs, expdesc *e) {
281 if (e->k == VCALL) { /* expression is an open function call? */288 if (e->k == VCALL) { /* expression is an open function call? */
282 e->k = VNONRELOC;289 e->k = VNONRELOC;
283 e->info = GETARG_A(getcode(fs, e));290 e->u.s.info = GETARG_A(getcode(fs, e));
284 }291 }
285 else if (e->k == VVARARG) {292 else if (e->k == VVARARG) {
286 SETARG_B(getcode(fs, e), 2);293 SETARG_B(getcode(fs, e), 2);
@@ -296,19 +303,19 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { · 9 unmodified lines
296 break;303 break;
297 }304 }
298 case VUPVAL: {305 case VUPVAL: {
299 e->info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->info, 0);306 e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0);
300 e->k = VRELOCABLE;307 e->k = VRELOCABLE;
301 break;308 break;
302 }309 }
303 case VGLOBAL: {310 case VGLOBAL: {
304 e->info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->info);311 e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);
305 e->k = VRELOCABLE;312 e->k = VRELOCABLE;
306 break;313 break;
307 }314 }
308 case VINDEXED: {315 case VINDEXED: {
309 freereg(fs, e->aux);316 freereg(fs, e->u.s.aux);
310 freereg(fs, e->info);317 freereg(fs, e->u.s.info);
311 e->info = luaK_codeABC(fs, OP_GETTABLE, 0, e->info, e->aux);318 e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux);
312 e->k = VRELOCABLE;319 e->k = VRELOCABLE;
313 break;320 break;
314 }321 }
@@ -340,7 +347,11 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { · 25 unmodified lines
340 break;347 break;
341 }348 }
342 case VK: {349 case VK: {
343 luaK_codeABx(fs, OP_LOADK, reg, e->info);350 luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info);
351 break;
352 }
353 case VKNUM: {
354 luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));
344 break;355 break;
345 }356 }
346 case VRELOCABLE: {357 case VRELOCABLE: {
@@ -349,8 +360,8 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { · 2 unmodified lines
349 break;360 break;
350 }361 }
351 case VNONRELOC: {362 case VNONRELOC: {
352 if (reg != e->info)363 if (reg != e->u.s.info)
353 luaK_codeABC(fs, OP_MOVE, reg, e->info, 0);364 luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0);
354 break;365 break;
355 }366 }
356 default: {367 default: {
@@ -358,7 +369,7 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { · 1 unmodified line
358 return; /* nothing to do... */369 return; /* nothing to do... */
359 }370 }
360 }371 }
361 e->info = reg;372 e->u.s.info = reg;
362 e->k = VNONRELOC;373 e->k = VNONRELOC;
363}374}
364 375
@@ -374,15 +385,13 @@ static void discharge2anyreg (FuncState *fs, expdesc *e) { · 9 unmodified lines
374static void exp2reg (FuncState *fs, expdesc *e, int reg) {385static void exp2reg (FuncState *fs, expdesc *e, int reg) {
375 discharge2reg(fs, e, reg);386 discharge2reg(fs, e, reg);
376 if (e->k == VJMP)387 if (e->k == VJMP)
377 luaK_concat(fs, &e->t, e->info); /* put this jump in `t' list */388 luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */
378 if (hasjumps(e)) {389 if (hasjumps(e)) {
379 int final; /* position after whole expression */390 int final; /* position after whole expression */
380 int p_f = NO_JUMP; /* position of an eventual LOAD false */391 int p_f = NO_JUMP; /* position of an eventual LOAD false */
381 int p_t = NO_JUMP; /* position of an eventual LOAD true */392 int p_t = NO_JUMP; /* position of an eventual LOAD true */
382 if (need_value(fs, e->t) || need_value(fs, e->f)) {393 if (need_value(fs, e->t) || need_value(fs, e->f)) {
383 int fj = NO_JUMP; /* first jump (over LOAD ops.) */394 int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
384 if (e->k != VJMP)
385 fj = luaK_jump(fs);
386 p_f = code_label(fs, reg, 0, 1);395 p_f = code_label(fs, reg, 0, 1);
387 p_t = code_label(fs, reg, 1, 0);396 p_t = code_label(fs, reg, 1, 0);
388 luaK_patchtohere(fs, fj);397 luaK_patchtohere(fs, fj);
@@ -392,7 +401,7 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) { · 3 unmodified lines
392 patchlistaux(fs, e->t, final, reg, p_t);401 patchlistaux(fs, e->t, final, reg, p_t);
393 }402 }
394 e->f = e->t = NO_JUMP;403 e->f = e->t = NO_JUMP;
395 e->info = reg;404 e->u.s.info = reg;
396 e->k = VNONRELOC;405 e->k = VNONRELOC;
397}406}
398 407
@@ -408,14 +417,14 @@ void luaK_exp2nextreg (FuncState *fs, expdesc *e) { · 9 unmodified lines
408int luaK_exp2anyreg (FuncState *fs, expdesc *e) {417int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
409 luaK_dischargevars(fs, e);418 luaK_dischargevars(fs, e);
410 if (e->k == VNONRELOC) {419 if (e->k == VNONRELOC) {
411 if (!hasjumps(e)) return e->info; /* exp is already in a register */ 420 if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */
412 if (e->info >= fs->nactvar) { /* reg. is not a local? */421 if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */
413 exp2reg(fs, e, e->info); /* put value on it */422 exp2reg(fs, e, e->u.s.info); /* put value on it */
414 return e->info;423 return e->u.s.info;
415 }424 }
416 }425 }
417 luaK_exp2nextreg(fs, e); /* default */426 luaK_exp2nextreg(fs, e); /* default */
418 return e->info;427 return e->u.s.info;
419}428}
420 429
421 430
@@ -430,19 +439,22 @@ void luaK_exp2val (FuncState *fs, expdesc *e) { · 8 unmodified lines
430int luaK_exp2RK (FuncState *fs, expdesc *e) {439int luaK_exp2RK (FuncState *fs, expdesc *e) {
431 luaK_exp2val(fs, e);440 luaK_exp2val(fs, e);
432 switch (e->k) {441 switch (e->k) {
442 case VKNUM:
433 case VTRUE:443 case VTRUE:
434 case VFALSE:444 case VFALSE:
435 case VNIL: {445 case VNIL: {
436 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */446 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
437 e->info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));447 e->u.s.info = (e->k == VNIL) ? nilK(fs) :
448 (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
449 boolK(fs, (e->k == VTRUE));
438 e->k = VK;450 e->k = VK;
439 return RKASK(e->info);451 return RKASK(e->u.s.info);
440 }452 }
441 else break;453 else break;
442 }454 }
443 case VK: {455 case VK: {
444 if (e->info <= MAXINDEXRK) /* constant fit in argC? */456 if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */
445 return RKASK(e->info);457 return RKASK(e->u.s.info);
446 else break;458 else break;
447 }459 }
448 default: break;460 default: break;
@@ -456,22 +468,22 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { · 7 unmodified lines
456 switch (var->k) {468 switch (var->k) {
457 case VLOCAL: {469 case VLOCAL: {
458 freeexp(fs, ex);470 freeexp(fs, ex);
459 exp2reg(fs, ex, var->info);471 exp2reg(fs, ex, var->u.s.info);
460 return;472 return;
461 }473 }
462 case VUPVAL: {474 case VUPVAL: {
463 int e = luaK_exp2anyreg(fs, ex);475 int e = luaK_exp2anyreg(fs, ex);
464 luaK_codeABC(fs, OP_SETUPVAL, e, var->info, 0);476 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0);
465 break;477 break;
466 }478 }
467 case VGLOBAL: {479 case VGLOBAL: {
468 int e = luaK_exp2anyreg(fs, ex);480 int e = luaK_exp2anyreg(fs, ex);
469 luaK_codeABx(fs, OP_SETGLOBAL, e, var->info);481 luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);
470 break;482 break;
471 }483 }
472 case VINDEXED: {484 case VINDEXED: {
473 int e = luaK_exp2RK(fs, ex);485 int e = luaK_exp2RK(fs, ex);
474 luaK_codeABC(fs, OP_SETTABLE, var->info, var->aux, e);486 luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e);
475 break;487 break;
476 }488 }
477 default: {489 default: {
@@ -489,15 +501,15 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { · 11 unmodified lines
489 freeexp(fs, e);501 freeexp(fs, e);
490 func = fs->freereg;502 func = fs->freereg;
491 luaK_reserveregs(fs, 2);503 luaK_reserveregs(fs, 2);
492 luaK_codeABC(fs, OP_SELF, func, e->info, luaK_exp2RK(fs, key));504 luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
493 freeexp(fs, key);505 freeexp(fs, key);
494 e->info = func;506 e->u.s.info = func;
495 e->k = VNONRELOC;507 e->k = VNONRELOC;
496}508}
497 509
498 510
499static void invertjump (FuncState *fs, expdesc *e) {511static void invertjump (FuncState *fs, expdesc *e) {
500 Instruction *pc = getjumpcontrol(fs, e->info);512 Instruction *pc = getjumpcontrol(fs, e->u.s.info);
501 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&513 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
502 GET_OPCODE(*pc) != OP_TEST);514 GET_OPCODE(*pc) != OP_TEST);
503 SETARG_A(*pc, !(GETARG_A(*pc)));515 SETARG_A(*pc, !(GETARG_A(*pc)));
@@ -515,7 +527,7 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) { · 11 unmodified lines
515 }527 }
516 discharge2anyreg(fs, e);528 discharge2anyreg(fs, e);
517 freeexp(fs, e);529 freeexp(fs, e);
518 return condjump(fs, OP_TESTSET, NO_REG, e->info, cond);530 return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond);
519}531}
520 532
521 533
@@ -523,7 +535,7 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { · 1 unmodified line
523 int pc; /* pc of last jump */535 int pc; /* pc of last jump */
524 luaK_dischargevars(fs, e);536 luaK_dischargevars(fs, e);
525 switch (e->k) {537 switch (e->k) {
526 case VK: case VTRUE: {538 case VK: case VKNUM: case VTRUE: {
527 pc = NO_JUMP; /* always true; do nothing */539 pc = NO_JUMP; /* always true; do nothing */
528 break;540 break;
529 }541 }
@@ -533,7 +545,7 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { · 3 unmodified lines
533 }545 }
534 case VJMP: {546 case VJMP: {
535 invertjump(fs, e);547 invertjump(fs, e);
536 pc = e->info;548 pc = e->u.s.info;
537 break;549 break;
538 }550 }
539 default: {551 default: {
@@ -547,7 +559,7 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { · 7 unmodified lines
547}559}
548 560
549 561
550void luaK_goiffalse (FuncState *fs, expdesc *e) {562static void luaK_goiffalse (FuncState *fs, expdesc *e) {
551 int pc; /* pc of last jump */563 int pc; /* pc of last jump */
552 luaK_dischargevars(fs, e);564 luaK_dischargevars(fs, e);
553 switch (e->k) {565 switch (e->k) {
@@ -560,7 +572,7 @@ void luaK_goiffalse (FuncState *fs, expdesc *e) { · 6 unmodified lines
560 break;572 break;
561 }573 }
562 case VJMP: {574 case VJMP: {
563 pc = e->info;575 pc = e->u.s.info;
564 break;576 break;
565 }577 }
566 default: {578 default: {
@@ -581,7 +593,7 @@ static void codenot (FuncState *fs, expdesc *e) { · 14 unmodified lines
581 e->k = VTRUE;593 e->k = VTRUE;
582 break;594 break;
583 }595 }
584 case VK: case VTRUE: {596 case VK: case VKNUM: case VTRUE: {
585 e->k = VFALSE;597 e->k = VFALSE;
586 break;598 break;
587 }599 }
@@ -593,7 +605,7 @@ static void codenot (FuncState *fs, expdesc *e) { · 5 unmodified lines
593 case VNONRELOC: {605 case VNONRELOC: {
594 discharge2anyreg(fs, e);606 discharge2anyreg(fs, e);
595 freeexp(fs, e);607 freeexp(fs, e);
596 e->info = luaK_codeABC(fs, OP_NOT, 0, e->info, 0);608 e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0);
597 e->k = VRELOCABLE;609 e->k = VRELOCABLE;
598 break;610 break;
599 }611 }
@@ -610,34 +622,81 @@ static void codenot (FuncState *fs, expdesc *e) { · 10 unmodified lines
610 622
611 623
612void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {624void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
613 t->aux = luaK_exp2RK(fs, k);625 t->u.s.aux = luaK_exp2RK(fs, k);
614 t->k = VINDEXED;626 t->k = VINDEXED;
615}627}
616 628
617 629
630static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
631 lua_Number v1, v2, r;
632 if (!isnumeral(e1) || !isnumeral(e2)) return 0;
633 v1 = e1->u.nval;
634 v2 = e2->u.nval;
635 switch (op) {
636 case OP_ADD: r = luai_numadd(v1, v2); break;
637 case OP_SUB: r = luai_numsub(v1, v2); break;
638 case OP_MUL: r = luai_nummul(v1, v2); break;
639 case OP_DIV:
640 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
641 r = luai_numdiv(v1, v2); break;
642 case OP_MOD:
643 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
644 r = luai_nummod(v1, v2); break;
645 case OP_POW: r = luai_numpow(v1, v2); break;
646 case OP_UNM: r = luai_numunm(v1); break;
647 case OP_LEN: return 0; /* no constant folding for 'len' */
648 default: lua_assert(0); r = 0; break;
649 }
650 if (r != r) return 0; /* do not attempt to produce NaN */
651 e1->u.nval = r;
652 return 1;
653}
654
655
656static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
657 if (constfolding(op, e1, e2))
658 return;
659 else {
660 int o1 = luaK_exp2RK(fs, e1);
661 int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
662 freeexp(fs, e2);
663 freeexp(fs, e1);
664 e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
665 e1->k = VRELOCABLE;
666 }
667}
668
669
670static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
671 expdesc *e2) {
672 int o1 = luaK_exp2RK(fs, e1);
673 int o2 = luaK_exp2RK(fs, e2);
674 freeexp(fs, e2);
675 freeexp(fs, e1);
676 if (cond == 0 && op != OP_EQ) {
677 int temp; /* exchange args to replace by `<' or `<=' */
678 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
679 cond = 1;
680 }
681 e1->u.s.info = condjump(fs, op, cond, o1, o2);
682 e1->k = VJMP;
683}
684
685
618void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {686void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
687 expdesc e2;
688 e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
619 switch (op) {689 switch (op) {
620 case OPR_MINUS: {690 case OPR_MINUS: {
621 luaK_exp2val(fs, e);691 if (e->k == VK)
622 if (e->k == VK && ttisnumber(&fs->f->k[e->info]))692 luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
623 e->info = luaK_numberK(fs, luai_numunm(L, nvalue(&fs->f->k[e->info])));693 codearith(fs, OP_UNM, e, &e2);
624 else {
625 luaK_exp2anyreg(fs, e);
626 freeexp(fs, e);
627 e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0);
628 e->k = VRELOCABLE;
629 }
630 break;
631 }
632 case OPR_NOT: {
633 codenot(fs, e);
634 break;694 break;
635 }695 }
696 case OPR_NOT: codenot(fs, e); break;
636 case OPR_LEN: {697 case OPR_LEN: {
637 luaK_exp2anyreg(fs, e);698 luaK_exp2anyreg(fs, e); /* cannot operate on constants */
638 freeexp(fs, e);699 codearith(fs, OP_LEN, e, &e2);
639 e->info = luaK_codeABC(fs, OP_LEN, 0, e->info, 0);
640 e->k = VRELOCABLE;
641 break;700 break;
642 }701 }
643 default: lua_assert(0);702 default: lua_assert(0);
@@ -660,74 +719,58 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { · 16 unmodified lines
660 break;719 break;
661 }720 }
662 default: {721 default: {
663 luaK_exp2RK(fs, v);722 if (!isnumeral(v)) luaK_exp2RK(fs, v);
664 break;723 break;
665 }724 }
666 }725 }
667}726}
668 727
669 728
670static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
671 int o1, int o2) {
672 if (op <= OPR_POW) { /* arithmetic operator? */
673 OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD); /* ORDER OP */
674 res->info = luaK_codeABC(fs, opc, 0, o1, o2);
675 res->k = VRELOCABLE;
676 }
677 else { /* test operator */
678 static const OpCode ops[] = {OP_EQ, OP_EQ, OP_LT, OP_LE, OP_LT, OP_LE};
679 int cond = 1;
680 if (op >= OPR_GT) { /* `>' or `>='? */
681 int temp; /* exchange args and replace by `<' or `<=' */
682 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
683 }
684 else if (op == OPR_NE) cond = 0;
685 res->info = condjump(fs, ops[op - OPR_NE], cond, o1, o2);
686 res->k = VJMP;
687 }
688}
689
690
691void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {729void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
692 switch (op) {730 switch (op) {
693 case OPR_AND: {731 case OPR_AND: {
694 lua_assert(e1->t == NO_JUMP); /* list must be closed */732 lua_assert(e1->t == NO_JUMP); /* list must be closed */
695 luaK_dischargevars(fs, e2);733 luaK_dischargevars(fs, e2);
696 luaK_concat(fs, &e1->f, e2->f);734 luaK_concat(fs, &e1->f, e2->f);
697 e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->t = e2->t;735 e1->k = e2->k; e1->u.s.info = e2->u.s.info;
736 e1->u.s.aux = e2->u.s.aux; e1->t = e2->t;
698 break;737 break;
699 }738 }
700 case OPR_OR: {739 case OPR_OR: {
701 lua_assert(e1->f == NO_JUMP); /* list must be closed */740 lua_assert(e1->f == NO_JUMP); /* list must be closed */
702 luaK_dischargevars(fs, e2);741 luaK_dischargevars(fs, e2);
703 luaK_concat(fs, &e1->t, e2->t);742 luaK_concat(fs, &e1->t, e2->t);
704 e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->f = e2->f;743 e1->k = e2->k; e1->u.s.info = e2->u.s.info;
744 e1->u.s.aux = e2->u.s.aux; e1->f = e2->f;
705 break;745 break;
706 }746 }
707 case OPR_CONCAT: {747 case OPR_CONCAT: {
708 luaK_exp2val(fs, e2);748 luaK_exp2val(fs, e2);
709 if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {749 if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
710 lua_assert(e1->info == GETARG_B(getcode(fs, e2))-1);750 lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1);
711 freeexp(fs, e1);751 freeexp(fs, e1);
712 SETARG_B(getcode(fs, e2), e1->info);752 SETARG_B(getcode(fs, e2), e1->u.s.info);
713 e1->k = e2->k; e1->info = e2->info;753 e1->k = e2->k; e1->u.s.info = e2->u.s.info;
714 }754 }
715 else {755 else {
716 luaK_exp2nextreg(fs, e2);756 luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
717 freeexp(fs, e2);757 codearith(fs, OP_CONCAT, e1, e2);
718 freeexp(fs, e1);
719 e1->info = luaK_codeABC(fs, OP_CONCAT, 0, e1->info, e2->info);
720 e1->k = VRELOCABLE;
721 }758 }
722 break;759 break;
723 }760 }
724 default: {761 case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;
725 int o1 = luaK_exp2RK(fs, e1);762 case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
726 int o2 = luaK_exp2RK(fs, e2);763 case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
727 freeexp(fs, e2);764 case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
728 freeexp(fs, e1);765 case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
729 codebinop(fs, e1, op, o1, o2);766 case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
730 }767 case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
768 case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
769 case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
770 case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
771 case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
772 case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
773 default: lua_assert(0);
731 }774 }
732}775}
733 776
@@ -737,7 +780,7 @@ void luaK_fixline (FuncState *fs, int line) { · 3 unmodified lines
737}780}
738 781
739 782
740int luaK_code (FuncState *fs, Instruction i, int line) {783static int luaK_code (FuncState *fs, Instruction i, int line) {
741 Proto *f = fs->f;784 Proto *f = fs->f;
742 dischargejpc(fs); /* `pc' will change */785 dischargejpc(fs); /* `pc' will change */
743 /* put new instruction in code array */786 /* put new instruction in code array */