History

Lua 5.2.0-beta-rc1

Lua Team committed 15 years ago

Commit 30837cc1 parent 9bce00553 files · +2418 −1456Browse files

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

Unified · Split

src/lcode.c+42−38
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lcode.c,v 2.49 2010/07/07 16:27:29 roberto Exp $2** $Id: lcode.c,v 2.56 2011/05/31 18:27:56 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*/
@@ -23,6 +23,7 @@ · 17 unmodified lines
23#include "lparser.h"23#include "lparser.h"
24#include "lstring.h"24#include "lstring.h"
25#include "ltable.h"25#include "ltable.h"
26#include "lvm.h"
26 27
27 28
28#define hasjumps(e) ((e)->t != (e)->f)29#define hasjumps(e) ((e)->t != (e)->f)
@@ -35,19 +36,23 @@ static int isnumeral(expdesc *e) { · 6 unmodified lines
35 36
36void luaK_nil (FuncState *fs, int from, int n) {37void luaK_nil (FuncState *fs, int from, int n) {
37 Instruction *previous;38 Instruction *previous;
39 int l = from + n - 1; /* last register to set nil */
38 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */40 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
39 previous = &fs->f->code[fs->pc-1];41 previous = &fs->f->code[fs->pc-1];
40 if (GET_OPCODE(*previous) == OP_LOADNIL) {42 if (GET_OPCODE(*previous) == OP_LOADNIL) {
41 int pfrom = GETARG_A(*previous);43 int pfrom = GETARG_A(*previous);
42 int pto = GETARG_B(*previous);44 int pl = pfrom + GETARG_B(*previous);
43 if (pfrom <= from && from <= pto+1) { /* can connect both? */45 if ((pfrom <= from && from <= pl + 1) ||
44 if (from+n-1 > pto)46 (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */
45 SETARG_B(*previous, from+n-1);47 if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */
48 if (pl > l) l = pl; /* l = max(l, pl) */
49 SETARG_A(*previous, from);
50 SETARG_B(*previous, l - from);
46 return;51 return;
47 }52 }
48 }53 } /* else go through */
49 }54 }
50 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 */
51}56}
52 57
53 58
@@ -171,6 +176,19 @@ void luaK_patchlist (FuncState *fs, int list, int target) { · 117 unmodified lines
171}176}
172 177
173 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
174void luaK_patchtohere (FuncState *fs, int list) {192void luaK_patchtohere (FuncState *fs, int list) {
175 luaK_getlabel(fs);193 luaK_getlabel(fs);
176 luaK_concat(fs, &fs->jpc, list);194 luaK_concat(fs, &fs->jpc, list);
@@ -229,11 +247,11 @@ static int codeextraarg (FuncState *fs, int a) { · 52 unmodified lines
229}247}
230 248
231 249
232int luaK_codeABxX (FuncState *fs, OpCode o, int reg, int k) {250int luaK_codek (FuncState *fs, int reg, int k) {
233 if (k < MAXARG_Bx)251 if (k <= MAXARG_Bx)
234 return luaK_codeABx(fs, o, reg, k + 1);252 return luaK_codeABx(fs, OP_LOADK, reg, k);
235 else {253 else {
236 int p = luaK_codeABx(fs, o, reg, 0);254 int p = luaK_codeABx(fs, OP_LOADKX, reg, 0);
237 codeextraarg(fs, k);255 codeextraarg(fs, k);
238 return p;256 return p;
239 }257 }
@@ -278,7 +296,7 @@ static int addk (FuncState *fs, TValue *key, TValue *v) { · 38 unmodified lines
278 if (ttisnumber(idx)) {296 if (ttisnumber(idx)) {
279 lua_Number n = nvalue(idx);297 lua_Number n = nvalue(idx);
280 lua_number2int(k, n);298 lua_number2int(k, n);
281 if (luaO_rawequalObj(&f->k[k], v))299 if (luaV_rawequalobj(&f->k[k], v))
282 return k;300 return k;
283 /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");301 /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");
284 go through and create a new entry for this value */302 go through and create a new entry for this value */
@@ -564,15 +582,15 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { · 279 unmodified lines
564 582
565 583
566void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {584void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
567 int func;585 int ereg;
568 luaK_exp2anyreg(fs, e);586 luaK_exp2anyreg(fs, e);
587 ereg = e->u.info; /* register where 'e' was placed */
569 freeexp(fs, e);588 freeexp(fs, e);
570 func = fs->freereg;589 e->u.info = fs->freereg; /* base register for op_self */
571 luaK_codeABC(fs, OP_SELF, func, e->u.info, luaK_exp2RK(fs, key));
572 freeexp(fs, key);
573 luaK_reserveregs(fs, 2);
574 e->u.info = func;
575 e->k = VNONRELOC;590 e->k = VNONRELOC;
591 luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */
592 luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key));
593 freeexp(fs, key);
576}594}
577 595
578 596
@@ -603,21 +621,14 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { · 24 unmodified lines
603 int pc; /* pc of last jump */621 int pc; /* pc of last jump */
604 luaK_dischargevars(fs, e);622 luaK_dischargevars(fs, e);
605 switch (e->k) {623 switch (e->k) {
606 case VK: case VKNUM: case VTRUE: {
607 pc = NO_JUMP; /* always true; do nothing */
608 break;
609 }
610 case VJMP: {624 case VJMP: {
611 invertjump(fs, e);625 invertjump(fs, e);
612 pc = e->u.info;626 pc = e->u.info;
613 break;627 break;
614 }628 }
615 case VFALSE: {629 case VK: case VKNUM: case VTRUE: {
616 if (!hasjumps(e)) {630 pc = NO_JUMP; /* always true; do nothing */
617 pc = luaK_jump(fs); /* always jump */631 break;
618 break;
619 }
620 /* else go through */
621 }632 }
622 default: {633 default: {
623 pc = jumponcond(fs, e, 0);634 pc = jumponcond(fs, e, 0);
@@ -634,20 +645,13 @@ static void luaK_goiffalse (FuncState *fs, expdesc *e) { · 10 unmodified lines
634 int pc; /* pc of last jump */645 int pc; /* pc of last jump */
635 luaK_dischargevars(fs, e);646 luaK_dischargevars(fs, e);
636 switch (e->k) {647 switch (e->k) {
637 case VNIL: case VFALSE: {
638 pc = NO_JUMP; /* always false; do nothing */
639 break;
640 }
641 case VJMP: {648 case VJMP: {
642 pc = e->u.info;649 pc = e->u.info;
643 break;650 break;
644 }651 }
645 case VTRUE: {652 case VNIL: case VFALSE: {
646 if (!hasjumps(e)) {653 pc = NO_JUMP; /* always false; do nothing */
647 pc = luaK_jump(fs); /* always jump */654 break;
648 break;
649 }
650 /* else go through */
651 }655 }
652 default: {656 default: {
653 pc = jumponcond(fs, e, 1);657 pc = jumponcond(fs, e, 1);