diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-08-20 17:03:05 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-08-20 17:03:05 -0300 |
commit | 6c283b2f4f8398322e7a9a62ec8e131852b4e015 (patch) | |
tree | 608d5b61b14dfdb91cc5cf72637e876337cffcb8 | |
parent | 576bded5137babb9c669ccff5aedf19ed65a7598 (diff) | |
download | lua-6c283b2f4f8398322e7a9a62ec8e131852b4e015.tar.gz lua-6c283b2f4f8398322e7a9a62ec8e131852b4e015.tar.bz2 lua-6c283b2f4f8398322e7a9a62ec8e131852b4e015.zip |
new simetric format for ABC instructions, to avoid exchanging operands
for `commutative' operators
-rw-r--r-- | lcode.c | 67 | ||||
-rw-r--r-- | ldebug.c | 19 | ||||
-rw-r--r-- | ldebug.h | 4 | ||||
-rw-r--r-- | lopcodes.c | 82 | ||||
-rw-r--r-- | lopcodes.h | 48 | ||||
-rw-r--r-- | lparser.c | 10 | ||||
-rw-r--r-- | lvm.c | 54 |
7 files changed, 131 insertions, 153 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 1.108 2002/06/13 13:39:55 roberto Exp $ | 2 | ** $Id: lcode.c,v 1.109 2002/08/05 14:07:34 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 | */ |
@@ -100,14 +100,14 @@ static Instruction *getjumpcontrol (FuncState *fs, int pc) { | |||
100 | static int need_value (FuncState *fs, int list, int cond) { | 100 | static int need_value (FuncState *fs, int list, int cond) { |
101 | for (; list != NO_JUMP; list = luaK_getjump(fs, list)) { | 101 | for (; list != NO_JUMP; list = luaK_getjump(fs, list)) { |
102 | Instruction i = *getjumpcontrol(fs, list); | 102 | Instruction i = *getjumpcontrol(fs, list); |
103 | if (GET_OPCODE(i) != OP_TEST || GETARG_B(i) != cond) return 1; | 103 | if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1; |
104 | } | 104 | } |
105 | return 0; /* not found */ | 105 | return 0; /* not found */ |
106 | } | 106 | } |
107 | 107 | ||
108 | 108 | ||
109 | static void patchtestreg (Instruction *i, int reg) { | 109 | static void patchtestreg (Instruction *i, int reg) { |
110 | if (reg == NO_REG) reg = GETARG_C(*i); | 110 | if (reg == NO_REG) reg = GETARG_B(*i); |
111 | SETARG_A(*i, reg); | 111 | SETARG_A(*i, reg); |
112 | } | 112 | } |
113 | 113 | ||
@@ -122,7 +122,7 @@ static void luaK_patchlistaux (FuncState *fs, int list, | |||
122 | luaK_fixjump(fs, list, dtarget); /* jump to default target */ | 122 | luaK_fixjump(fs, list, dtarget); /* jump to default target */ |
123 | } | 123 | } |
124 | else { | 124 | else { |
125 | if (GETARG_B(*i)) { | 125 | if (GETARG_C(*i)) { |
126 | lua_assert(ttarget != NO_JUMP); | 126 | lua_assert(ttarget != NO_JUMP); |
127 | patchtestreg(i, treg); | 127 | patchtestreg(i, treg); |
128 | luaK_fixjump(fs, list, ttarget); | 128 | luaK_fixjump(fs, list, ttarget); |
@@ -409,7 +409,7 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) { | |||
409 | } | 409 | } |
410 | default: break; | 410 | default: break; |
411 | } | 411 | } |
412 | /* not a constant in the right range: put in a register */ | 412 | /* not a constant in the right range: put it in a register */ |
413 | return luaK_exp2anyreg(fs, e); | 413 | return luaK_exp2anyreg(fs, e); |
414 | } | 414 | } |
415 | 415 | ||
@@ -432,8 +432,8 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *exp) { | |||
432 | break; | 432 | break; |
433 | } | 433 | } |
434 | case VINDEXED: { | 434 | case VINDEXED: { |
435 | int e = luaK_exp2anyreg(fs, exp); | 435 | int e = luaK_exp2RK(fs, exp); |
436 | luaK_codeABC(fs, OP_SETTABLE, e, var->info, var->aux); | 436 | luaK_codeABC(fs, OP_SETTABLE, var->info, var->aux, e); |
437 | break; | 437 | break; |
438 | } | 438 | } |
439 | default: { | 439 | default: { |
@@ -460,8 +460,9 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { | |||
460 | 460 | ||
461 | static void invertjump (FuncState *fs, expdesc *e) { | 461 | static void invertjump (FuncState *fs, expdesc *e) { |
462 | Instruction *pc = getjumpcontrol(fs, e->info); | 462 | Instruction *pc = getjumpcontrol(fs, e->info); |
463 | lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT)); | 463 | lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT) && |
464 | SETARG_B(*pc, !(GETARG_B(*pc))); | 464 | GET_OPCODE(*pc) != OP_TEST); |
465 | SETARG_A(*pc, !(GETARG_A(*pc))); | ||
465 | } | 466 | } |
466 | 467 | ||
467 | 468 | ||
@@ -470,13 +471,13 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) { | |||
470 | Instruction ie = getcode(fs, e); | 471 | Instruction ie = getcode(fs, e); |
471 | if (GET_OPCODE(ie) == OP_NOT) { | 472 | if (GET_OPCODE(ie) == OP_NOT) { |
472 | fs->pc--; /* remove previous OP_NOT */ | 473 | fs->pc--; /* remove previous OP_NOT */ |
473 | return luaK_condjump(fs, OP_TEST, NO_REG, !cond ,GETARG_B(ie)); | 474 | return luaK_condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond); |
474 | } | 475 | } |
475 | /* else go through */ | 476 | /* else go through */ |
476 | } | 477 | } |
477 | discharge2anyreg(fs, e); | 478 | discharge2anyreg(fs, e); |
478 | freeexp(fs, e); | 479 | freeexp(fs, e); |
479 | return luaK_condjump(fs, OP_TEST, NO_REG, cond, e->info); | 480 | return luaK_condjump(fs, OP_TEST, NO_REG, e->info, cond); |
480 | } | 481 | } |
481 | 482 | ||
482 | 483 | ||
@@ -605,11 +606,6 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { | |||
605 | luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ | 606 | luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ |
606 | break; | 607 | break; |
607 | } | 608 | } |
608 | case OPR_SUB: case OPR_DIV: case OPR_POW: { | ||
609 | /* non-comutative operators */ | ||
610 | luaK_exp2anyreg(fs, v); /* first operand must be a register */ | ||
611 | break; | ||
612 | } | ||
613 | default: { | 609 | default: { |
614 | luaK_exp2RK(fs, v); | 610 | luaK_exp2RK(fs, v); |
615 | break; | 611 | break; |
@@ -619,13 +615,11 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { | |||
619 | 615 | ||
620 | 616 | ||
621 | static void codebinop (FuncState *fs, expdesc *res, BinOpr op, | 617 | static void codebinop (FuncState *fs, expdesc *res, BinOpr op, |
622 | int o1, int o2, int ic) { | 618 | int o1, int o2) { |
623 | switch (op) { | 619 | switch (op) { |
624 | case OPR_SUB: | 620 | case OPR_SUB: |
625 | case OPR_DIV: | 621 | case OPR_DIV: |
626 | case OPR_POW: | 622 | case OPR_POW: |
627 | lua_assert(!ic); | ||
628 | /* go through */ | ||
629 | case OPR_ADD: | 623 | case OPR_ADD: |
630 | case OPR_MULT: { /* ORDER OPR */ | 624 | case OPR_MULT: { /* ORDER OPR */ |
631 | OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD); | 625 | OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD); |
@@ -635,20 +629,21 @@ static void codebinop (FuncState *fs, expdesc *res, BinOpr op, | |||
635 | } | 629 | } |
636 | case OPR_NE: | 630 | case OPR_NE: |
637 | case OPR_EQ: { | 631 | case OPR_EQ: { |
638 | res->info = luaK_condjump(fs, OP_EQ, o1, (op == OPR_EQ), o2); | 632 | res->info = luaK_condjump(fs, OP_EQ, (op == OPR_EQ), o1, o2); |
639 | res->k = VJMP; | 633 | res->k = VJMP; |
640 | break; | 634 | break; |
641 | } | 635 | } |
642 | case OPR_LT: | ||
643 | case OPR_LE: | ||
644 | case OPR_GT: | 636 | case OPR_GT: |
645 | case OPR_GE: { /* ORDER OPR */ | 637 | case OPR_GE: { /* ORDER OPR */ |
646 | OpCode opc; | 638 | int temp; |
647 | int i = op - OPR_LT; | 639 | temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ |
648 | if (ic) /* operands were interchanged? */ | 640 | op -= 2; /* GT -> LT, GE -> LE */ |
649 | i = (i+2)&3; /* correct operator */ | 641 | /* go through */ |
650 | opc = cast(OpCode, i + OP_LT); | 642 | } |
651 | res->info = luaK_condjump(fs, opc, o1, 1, o2); | 643 | case OPR_LT: |
644 | case OPR_LE: { | ||
645 | OpCode opc = cast(OpCode, (op - OPR_LT) + OP_LT); | ||
646 | res->info = luaK_condjump(fs, opc, 1, o1, o2); | ||
652 | res->k = VJMP; | 647 | res->k = VJMP; |
653 | break; | 648 | break; |
654 | } | 649 | } |
@@ -691,21 +686,11 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { | |||
691 | break; | 686 | break; |
692 | } | 687 | } |
693 | default: { | 688 | default: { |
694 | int o1, o2; | 689 | int o1 = luaK_exp2RK(fs, e1); |
695 | int ic; /* interchange flag */ | 690 | int o2 = luaK_exp2RK(fs, e2); |
696 | if (e1->k != VK) { /* not a constant operator? */ | ||
697 | o1 = e1->info; | ||
698 | o2 = luaK_exp2RK(fs, e2); /* maybe other operator is constant... */ | ||
699 | ic = 0; | ||
700 | } | ||
701 | else { /* interchange operands */ | ||
702 | o2 = luaK_exp2RK(fs, e1); /* constant must be 2nd operand */ | ||
703 | o1 = luaK_exp2anyreg(fs, e2); /* other operator must be in register */ | ||
704 | ic = 1; | ||
705 | } | ||
706 | freeexp(fs, e2); | 691 | freeexp(fs, e2); |
707 | freeexp(fs, e1); | 692 | freeexp(fs, e1); |
708 | codebinop(fs, e1, op, o1, o2, ic); | 693 | codebinop(fs, e1, op, o1, o2); |
709 | } | 694 | } |
710 | } | 695 | } |
711 | } | 696 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 1.131 2002/08/08 20:08:41 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.132 2002/08/12 17:23:12 roberto Exp roberto $ |
3 | ** Debug Interface | 3 | ** Debug Interface |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -269,6 +269,11 @@ static int checkopenop (const Proto *pt, int pc) { | |||
269 | } | 269 | } |
270 | 270 | ||
271 | 271 | ||
272 | static int checkRK (const Proto *pt, int r) { | ||
273 | return (r < pt->maxstacksize || (r >= MAXSTACK && r-MAXSTACK < pt->sizek)); | ||
274 | } | ||
275 | |||
276 | |||
272 | static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { | 277 | static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { |
273 | int pc; | 278 | int pc; |
274 | int last; /* stores position of last instruction that changed `reg' */ | 279 | int last; /* stores position of last instruction that changed `reg' */ |
@@ -285,11 +290,13 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { | |||
285 | case iABC: { | 290 | case iABC: { |
286 | b = GETARG_B(i); | 291 | b = GETARG_B(i); |
287 | c = GETARG_C(i); | 292 | c = GETARG_C(i); |
288 | if (testOpMode(op, OpModeBreg)) | 293 | if (testOpMode(op, OpModeBreg)) { |
289 | checkreg(pt, b); | 294 | checkreg(pt, b); |
290 | if (testOpMode(op, OpModeCreg)) | 295 | } |
291 | check(c < pt->maxstacksize || | 296 | else if (testOpMode(op, OpModeBrk)) |
292 | (c >= MAXSTACK && c-MAXSTACK < pt->sizek)); | 297 | check(checkRK(pt, b)); |
298 | if (testOpMode(op, OpModeCrk)) | ||
299 | check(checkRK(pt, c)); | ||
293 | break; | 300 | break; |
294 | } | 301 | } |
295 | case iABx: { | 302 | case iABx: { |
@@ -496,7 +503,7 @@ void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { | |||
496 | } | 503 | } |
497 | 504 | ||
498 | 505 | ||
499 | void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2) { | 506 | void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2) { |
500 | TObject temp; | 507 | TObject temp; |
501 | if (luaV_tonumber(p1, &temp) == NULL) | 508 | if (luaV_tonumber(p1, &temp) == NULL) |
502 | p2 = p1; /* first operand is wrong */ | 509 | p2 = p1; /* first operand is wrong */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.h,v 1.29 2002/08/08 20:08:41 roberto Exp roberto $ | 2 | ** $Id: ldebug.h,v 1.30 2002/08/12 17:23:12 roberto Exp roberto $ |
3 | ** Auxiliary functions from Debug Interface module | 3 | ** Auxiliary functions from Debug Interface module |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); | 24 | void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); |
25 | void luaG_concaterror (lua_State *L, StkId p1, StkId p2); | 25 | void luaG_concaterror (lua_State *L, StkId p1, StkId p2); |
26 | void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2); | 26 | void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2); |
27 | int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2); | 27 | int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2); |
28 | void luaG_runerror (lua_State *L, const char *fmt, ...); | 28 | void luaG_runerror (lua_State *L, const char *fmt, ...); |
29 | void luaG_errormsg (lua_State *L); | 29 | void luaG_errormsg (lua_State *L); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.c,v 1.19 2002/05/13 13:09:00 roberto Exp roberto $ | 2 | ** $Id: lopcodes.c,v 1.20 2002/06/12 14:51:31 roberto Exp roberto $ |
3 | ** extracted automatically from lopcodes.h by mkprint.lua | 3 | ** extracted automatically from lopcodes.h by mkprint.lua |
4 | ** DO NOT EDIT | 4 | ** DO NOT EDIT |
5 | ** See Copyright Notice in lua.h | 5 | ** See Copyright Notice in lua.h |
@@ -39,8 +39,6 @@ const char *const luaP_opnames[] = { | |||
39 | "EQ", | 39 | "EQ", |
40 | "LT", | 40 | "LT", |
41 | "LE", | 41 | "LE", |
42 | "GT", | ||
43 | "GE", | ||
44 | "TEST", | 42 | "TEST", |
45 | "CALL", | 43 | "CALL", |
46 | "TAILCALL", | 44 | "TAILCALL", |
@@ -56,49 +54,47 @@ const char *const luaP_opnames[] = { | |||
56 | 54 | ||
57 | #endif | 55 | #endif |
58 | 56 | ||
59 | #define opmode(t,x,b,c,sa,k,m) (((t)<<OpModeT) | \ | 57 | #define opmode(t,b,bk,ck,sa,k,m) (((t)<<OpModeT) | \ |
60 | ((b)<<OpModeBreg) | ((c)<<OpModeCreg) | \ | 58 | ((b)<<OpModeBreg) | ((bk)<<OpModeBrk) | ((ck)<<OpModeCrk) | \ |
61 | ((sa)<<OpModesetA) | ((k)<<OpModeK) | (m)) | 59 | ((sa)<<OpModesetA) | ((k)<<OpModeK) | (m)) |
62 | 60 | ||
63 | 61 | ||
64 | const lu_byte luaP_opmodes[NUM_OPCODES] = { | 62 | const lu_byte luaP_opmodes[NUM_OPCODES] = { |
65 | /* T _ B C sA K mode opcode */ | 63 | /* T B Bk Ck sA K mode opcode */ |
66 | opmode(0,0,1,0, 1,0,iABC) /* OP_MOVE */ | 64 | opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_MOVE */ |
67 | ,opmode(0,0,0,0, 1,1,iABx) /* OP_LOADK */ | 65 | ,opmode(0, 0, 0, 0, 1, 1, iABx) /* OP_LOADK */ |
68 | ,opmode(0,0,0,0, 1,0,iABC) /* OP_LOADBOOL */ | 66 | ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_LOADBOOL */ |
69 | ,opmode(0,0,1,0, 1,0,iABC) /* OP_LOADNIL */ | 67 | ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_LOADNIL */ |
70 | ,opmode(0,0,0,0, 1,0,iABC) /* OP_GETUPVAL */ | 68 | ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_GETUPVAL */ |
71 | ,opmode(0,0,0,0, 1,1,iABx) /* OP_GETGLOBAL */ | 69 | ,opmode(0, 0, 0, 0, 1, 1, iABx) /* OP_GETGLOBAL */ |
72 | ,opmode(0,0,1,1, 1,0,iABC) /* OP_GETTABLE */ | 70 | ,opmode(0, 1, 0, 1, 1, 0, iABC) /* OP_GETTABLE */ |
73 | ,opmode(0,0,0,0, 0,1,iABx) /* OP_SETGLOBAL */ | 71 | ,opmode(0, 0, 0, 0, 0, 1, iABx) /* OP_SETGLOBAL */ |
74 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_SETUPVAL */ | 72 | ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_SETUPVAL */ |
75 | ,opmode(0,0,1,1, 0,0,iABC) /* OP_SETTABLE */ | 73 | ,opmode(0, 0, 1, 1, 0, 0, iABC) /* OP_SETTABLE */ |
76 | ,opmode(0,0,0,0, 1,0,iABC) /* OP_NEWTABLE */ | 74 | ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_NEWTABLE */ |
77 | ,opmode(0,0,1,1, 1,0,iABC) /* OP_SELF */ | 75 | ,opmode(0, 1, 0, 1, 1, 0, iABC) /* OP_SELF */ |
78 | ,opmode(0,0,1,1, 1,0,iABC) /* OP_ADD */ | 76 | ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_ADD */ |
79 | ,opmode(0,0,1,1, 1,0,iABC) /* OP_SUB */ | 77 | ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_SUB */ |
80 | ,opmode(0,0,1,1, 1,0,iABC) /* OP_MUL */ | 78 | ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_MUL */ |
81 | ,opmode(0,0,1,1, 1,0,iABC) /* OP_DIV */ | 79 | ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_DIV */ |
82 | ,opmode(0,0,1,1, 1,0,iABC) /* OP_POW */ | 80 | ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_POW */ |
83 | ,opmode(0,0,1,0, 1,0,iABC) /* OP_UNM */ | 81 | ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_UNM */ |
84 | ,opmode(0,0,1,0, 1,0,iABC) /* OP_NOT */ | 82 | ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_NOT */ |
85 | ,opmode(0,0,1,1, 1,0,iABC) /* OP_CONCAT */ | 83 | ,opmode(0, 1, 0, 1, 1, 0, iABC) /* OP_CONCAT */ |
86 | ,opmode(0,0,0,0, 0,0,iAsBx) /* OP_JMP */ | 84 | ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_JMP */ |
87 | ,opmode(1,0,0,1, 0,0,iABC) /* OP_EQ */ | 85 | ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_EQ */ |
88 | ,opmode(1,0,0,1, 0,0,iABC) /* OP_LT */ | 86 | ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_LT */ |
89 | ,opmode(1,0,0,1, 0,0,iABC) /* OP_LE */ | 87 | ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_LE */ |
90 | ,opmode(1,0,0,1, 0,0,iABC) /* OP_GT */ | 88 | ,opmode(1, 1, 0, 0, 1, 0, iABC) /* OP_TEST */ |
91 | ,opmode(1,0,0,1, 0,0,iABC) /* OP_GE */ | 89 | ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_CALL */ |
92 | ,opmode(1,0,0,1, 1,0,iABC) /* OP_TEST */ | 90 | ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_TAILCALL */ |
93 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_CALL */ | 91 | ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_RETURN */ |
94 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_TAILCALL */ | 92 | ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_FORLOOP */ |
95 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_RETURN */ | 93 | ,opmode(1, 0, 0, 0, 0, 0, iABC) /* OP_TFORLOOP */ |
96 | ,opmode(0,0,0,0, 0,0,iAsBx) /* OP_FORLOOP */ | 94 | ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_TFORPREP */ |
97 | ,opmode(1,0,0,0, 0,0,iABC) /* OP_TFORLOOP */ | 95 | ,opmode(0, 0, 0, 0, 0, 0, iABx) /* OP_SETLIST */ |
98 | ,opmode(0,0,0,0, 0,0,iAsBx) /* OP_TFORPREP */ | 96 | ,opmode(0, 0, 0, 0, 0, 0, iABx) /* OP_SETLISTO */ |
99 | ,opmode(0,0,0,0, 0,0,iABx) /* OP_SETLIST */ | 97 | ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_CLOSE */ |
100 | ,opmode(0,0,0,0, 0,0,iABx) /* OP_SETLISTO */ | 98 | ,opmode(0, 0, 0, 0, 1, 0, iABx) /* OP_CLOSURE */ |
101 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_CLOSE */ | ||
102 | ,opmode(0,0,0,0, 1,0,iABx) /* OP_CLOSURE */ | ||
103 | }; | 99 | }; |
104 | 100 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.h,v 1.99 2002/06/12 14:51:31 roberto Exp $ | 2 | ** $Id: lopcodes.h,v 1.100 2002/08/05 14:46:43 roberto Exp roberto $ |
3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -14,9 +14,9 @@ | |||
14 | We assume that instructions are unsigned numbers. | 14 | We assume that instructions are unsigned numbers. |
15 | All instructions have an opcode in the first 6 bits. | 15 | All instructions have an opcode in the first 6 bits. |
16 | Instructions can have the following fields: | 16 | Instructions can have the following fields: |
17 | `A' : 8 bits (25-32) | 17 | `A' : 8 bits |
18 | `B' : 8 bits (17-24) | 18 | `B' : 9 bits |
19 | `C' : 10 bits (7-16) | 19 | `C' : 9 bits |
20 | `Bx' : 18 bits (`B' and `C' together) | 20 | `Bx' : 18 bits (`B' and `C' together) |
21 | `sBx' : signed Bx | 21 | `sBx' : signed Bx |
22 | 22 | ||
@@ -34,8 +34,8 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ | |||
34 | /* | 34 | /* |
35 | ** size and position of opcode arguments. | 35 | ** size and position of opcode arguments. |
36 | */ | 36 | */ |
37 | #define SIZE_C 10 | 37 | #define SIZE_C 9 |
38 | #define SIZE_B 8 | 38 | #define SIZE_B 9 |
39 | #define SIZE_Bx (SIZE_C + SIZE_B) | 39 | #define SIZE_Bx (SIZE_C + SIZE_B) |
40 | #define SIZE_A 8 | 40 | #define SIZE_A 8 |
41 | 41 | ||
@@ -112,16 +112,15 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ | |||
112 | 112 | ||
113 | 113 | ||
114 | /* | 114 | /* |
115 | ** invalid registers that fits in 8 bits | 115 | ** invalid register that fits in 8 bits |
116 | */ | 116 | */ |
117 | #define NO_REG MAXARG_A | 117 | #define NO_REG MAXARG_A |
118 | #define NO_REG1 (NO_REG+1) | ||
119 | 118 | ||
120 | 119 | ||
121 | /* | 120 | /* |
122 | ** R(x) - register | 121 | ** R(x) - register |
123 | ** Kst(x) - constant (in constant table) | 122 | ** Kst(x) - constant (in constant table) |
124 | ** R/K(x) == if x < MAXSTACK then R(x) else Kst(x-MAXSTACK) | 123 | ** RK(x) == if x < MAXSTACK then R(x) else Kst(x-MAXSTACK) |
125 | */ | 124 | */ |
126 | 125 | ||
127 | typedef enum { | 126 | typedef enum { |
@@ -135,21 +134,21 @@ OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */ | |||
135 | OP_GETUPVAL,/* A B R(A) := UpValue[B] */ | 134 | OP_GETUPVAL,/* A B R(A) := UpValue[B] */ |
136 | 135 | ||
137 | OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */ | 136 | OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */ |
138 | OP_GETTABLE,/* A B C R(A) := R(B)[R/K(C)] */ | 137 | OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */ |
139 | 138 | ||
140 | OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */ | 139 | OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */ |
141 | OP_SETUPVAL,/* A B UpValue[B] := R(A) */ | 140 | OP_SETUPVAL,/* A B UpValue[B] := R(A) */ |
142 | OP_SETTABLE,/* A B C R(B)[R/K(C)] := R(A) */ | 141 | OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */ |
143 | 142 | ||
144 | OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */ | 143 | OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */ |
145 | 144 | ||
146 | OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[R/K(C)] */ | 145 | OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */ |
147 | 146 | ||
148 | OP_ADD,/* A B C R(A) := R(B) + R/K(C) */ | 147 | OP_ADD,/* A B C R(A) := RK(B) + RK(C) */ |
149 | OP_SUB,/* A B C R(A) := R(B) - R/K(C) */ | 148 | OP_SUB,/* A B C R(A) := RK(B) - RK(C) */ |
150 | OP_MUL,/* A B C R(A) := R(B) * R/K(C) */ | 149 | OP_MUL,/* A B C R(A) := RK(B) * RK(C) */ |
151 | OP_DIV,/* A B C R(A) := R(B) / R/K(C) */ | 150 | OP_DIV,/* A B C R(A) := RK(B) / RK(C) */ |
152 | OP_POW,/* A B C R(A) := R(B) ^ R/K(C) */ | 151 | OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */ |
153 | OP_UNM,/* A B R(A) := -R(B) */ | 152 | OP_UNM,/* A B R(A) := -R(B) */ |
154 | OP_NOT,/* A B R(A) := not R(B) */ | 153 | OP_NOT,/* A B R(A) := not R(B) */ |
155 | 154 | ||
@@ -157,13 +156,11 @@ OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ | |||
157 | 156 | ||
158 | OP_JMP,/* sBx PC += sBx */ | 157 | OP_JMP,/* sBx PC += sBx */ |
159 | 158 | ||
160 | OP_EQ,/* A B C if ((R(A) == R/K(C)) ~= B) then pc++ */ | 159 | OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ |
161 | OP_LT,/* A B C if ((R(A) < R/K(C)) ~= B) then pc++ */ | 160 | OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ |
162 | OP_LE,/* A B C if ((R(A) <= R/K(C)) ~= B) then pc++ */ | 161 | OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ |
163 | OP_GT,/* A B C if ((R(A) > R/K(C)) ~= B) then pc++ */ | ||
164 | OP_GE,/* A B C if ((R(A) >= R/K(C)) ~= B) then pc++ */ | ||
165 | 162 | ||
166 | OP_TEST,/* A B C if (R(C) <=> B) then R(A) := R(C) else pc++ */ | 163 | OP_TEST,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ |
167 | 164 | ||
168 | OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ | 165 | OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ |
169 | OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ | 166 | OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ |
@@ -207,12 +204,15 @@ OP_CLOSURE/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ | |||
207 | */ | 204 | */ |
208 | enum OpModeMask { | 205 | enum OpModeMask { |
209 | OpModeBreg = 2, /* B is a register */ | 206 | OpModeBreg = 2, /* B is a register */ |
210 | OpModeCreg, /* C is a register/constant */ | 207 | OpModeBrk, /* B is a register/constant */ |
208 | OpModeCrk, /* C is a register/constant */ | ||
211 | OpModesetA, /* instruction set register A */ | 209 | OpModesetA, /* instruction set register A */ |
212 | OpModeK, /* Bx is a constant */ | 210 | OpModeK, /* Bx is a constant */ |
213 | OpModeT /* operator is a test */ | 211 | OpModeT /* operator is a test */ |
212 | |||
214 | }; | 213 | }; |
215 | 214 | ||
215 | |||
216 | extern const lu_byte luaP_opmodes[NUM_OPCODES]; | 216 | extern const lu_byte luaP_opmodes[NUM_OPCODES]; |
217 | 217 | ||
218 | #define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) | 218 | #define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.190 2002/07/04 18:23:42 roberto Exp $ | 2 | ** $Id: lparser.c,v 1.191 2002/08/05 17:35:45 roberto Exp roberto $ |
3 | ** Lua Parser | 3 | ** Lua Parser |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -324,7 +324,7 @@ static void open_func (LexState *ls, FuncState *fs) { | |||
324 | fs->bl = NULL; | 324 | fs->bl = NULL; |
325 | f->code = NULL; | 325 | f->code = NULL; |
326 | f->source = ls->source; | 326 | f->source = ls->source; |
327 | f->maxstacksize = 1; /* register 0 is always valid */ | 327 | f->maxstacksize = 2; /* registers 0/1 are always valid */ |
328 | f->numparams = 0; /* default for main chunk */ | 328 | f->numparams = 0; /* default for main chunk */ |
329 | f->is_vararg = 0; /* default for main chunk */ | 329 | f->is_vararg = 0; /* default for main chunk */ |
330 | } | 330 | } |
@@ -489,8 +489,8 @@ static void recfield (LexState *ls, struct ConsControl *cc) { | |||
489 | check(ls, '='); | 489 | check(ls, '='); |
490 | luaK_exp2RK(fs, &key); | 490 | luaK_exp2RK(fs, &key); |
491 | expr(ls, &val); | 491 | expr(ls, &val); |
492 | luaK_exp2anyreg(fs, &val); | 492 | luaK_codeABC(fs, OP_SETTABLE, cc->t->info, luaK_exp2RK(fs, &key), |
493 | luaK_codeABC(fs, OP_SETTABLE, val.info, cc->t->info, luaK_exp2RK(fs, &key)); | 493 | luaK_exp2RK(fs, &val)); |
494 | fs->freereg = reg; /* free registers */ | 494 | fs->freereg = reg; /* free registers */ |
495 | } | 495 | } |
496 | 496 | ||
@@ -735,7 +735,7 @@ static const struct { | |||
735 | lu_byte right; /* right priority */ | 735 | lu_byte right; /* right priority */ |
736 | } priority[] = { /* ORDER OPR */ | 736 | } priority[] = { /* ORDER OPR */ |
737 | {6, 6}, {6, 6}, {7, 7}, {7, 7}, /* arithmetic */ | 737 | {6, 6}, {6, 6}, {7, 7}, {7, 7}, /* arithmetic */ |
738 | {10, 9}, {5, 4}, /* power and concat (right associative) */ | 738 | {10, 9}, {5, 4}, /* power and concat (right associative) */ |
739 | {3, 3}, {3, 3}, /* equality */ | 739 | {3, 3}, {3, 3}, /* equality */ |
740 | {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ | 740 | {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ |
741 | {2, 2}, {1, 1} /* logical (and/or) */ | 741 | {2, 2}, {1, 1} /* logical (and/or) */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.251 2002/08/07 19:22:39 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.252 2002/08/12 17:23:12 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -318,7 +318,8 @@ void luaV_concat (lua_State *L, int total, int last) { | |||
318 | } | 318 | } |
319 | 319 | ||
320 | 320 | ||
321 | static void Arith (lua_State *L, StkId ra, StkId rb, StkId rc, TMS op) { | 321 | static void Arith (lua_State *L, StkId ra, |
322 | const TObject *rb, const TObject *rc, TMS op) { | ||
322 | TObject tempb, tempc; | 323 | TObject tempb, tempc; |
323 | const TObject *b, *c; | 324 | const TObject *b, *c; |
324 | if ((b = luaV_tonumber(rb, &tempb)) != NULL && | 325 | if ((b = luaV_tonumber(rb, &tempb)) != NULL && |
@@ -356,10 +357,9 @@ static void Arith (lua_State *L, StkId ra, StkId rb, StkId rc, TMS op) { | |||
356 | 357 | ||
357 | #define RA(i) (base+GETARG_A(i)) | 358 | #define RA(i) (base+GETARG_A(i)) |
358 | #define RB(i) (base+GETARG_B(i)) | 359 | #define RB(i) (base+GETARG_B(i)) |
360 | #define RKB(i) ((GETARG_B(i) < MAXSTACK) ? RB(i) : k+GETARG_B(i)-MAXSTACK) | ||
359 | #define RC(i) (base+GETARG_C(i)) | 361 | #define RC(i) (base+GETARG_C(i)) |
360 | #define RKC(i) ((GETARG_C(i) < MAXSTACK) ? \ | 362 | #define RKC(i) ((GETARG_C(i) < MAXSTACK) ? RC(i) : k+GETARG_C(i)-MAXSTACK) |
361 | base+GETARG_C(i) : \ | ||
362 | k+GETARG_C(i)-MAXSTACK) | ||
363 | #define KBx(i) (k+GETARG_Bx(i)) | 363 | #define KBx(i) (k+GETARG_Bx(i)) |
364 | 364 | ||
365 | 365 | ||
@@ -423,7 +423,7 @@ StkId luaV_execute (lua_State *L) { | |||
423 | break; | 423 | break; |
424 | } | 424 | } |
425 | case OP_GETGLOBAL: { | 425 | case OP_GETGLOBAL: { |
426 | StkId rb = KBx(i); | 426 | TObject *rb = KBx(i); |
427 | const TObject *v; | 427 | const TObject *v; |
428 | lua_assert(ttisstring(rb) && ttistable(&cl->g)); | 428 | lua_assert(ttisstring(rb) && ttistable(&cl->g)); |
429 | v = luaH_getstr(hvalue(&cl->g), tsvalue(rb)); | 429 | v = luaH_getstr(hvalue(&cl->g), tsvalue(rb)); |
@@ -456,7 +456,7 @@ StkId luaV_execute (lua_State *L) { | |||
456 | break; | 456 | break; |
457 | } | 457 | } |
458 | case OP_SETTABLE: { | 458 | case OP_SETTABLE: { |
459 | luaV_settable(L, RB(i), RKC(i), ra); | 459 | luaV_settable(L, ra, RKB(i), RKC(i)); |
460 | break; | 460 | break; |
461 | } | 461 | } |
462 | case OP_NEWTABLE: { | 462 | case OP_NEWTABLE: { |
@@ -482,8 +482,8 @@ StkId luaV_execute (lua_State *L) { | |||
482 | break; | 482 | break; |
483 | } | 483 | } |
484 | case OP_ADD: { | 484 | case OP_ADD: { |
485 | StkId rb = RB(i); | 485 | TObject *rb = RKB(i); |
486 | StkId rc = RKC(i); | 486 | TObject *rc = RKC(i); |
487 | if (ttisnumber(rb) && ttisnumber(rc)) { | 487 | if (ttisnumber(rb) && ttisnumber(rc)) { |
488 | setnvalue(ra, nvalue(rb) + nvalue(rc)); | 488 | setnvalue(ra, nvalue(rb) + nvalue(rc)); |
489 | } | 489 | } |
@@ -492,8 +492,8 @@ StkId luaV_execute (lua_State *L) { | |||
492 | break; | 492 | break; |
493 | } | 493 | } |
494 | case OP_SUB: { | 494 | case OP_SUB: { |
495 | StkId rb = RB(i); | 495 | TObject *rb = RKB(i); |
496 | StkId rc = RKC(i); | 496 | TObject *rc = RKC(i); |
497 | if (ttisnumber(rb) && ttisnumber(rc)) { | 497 | if (ttisnumber(rb) && ttisnumber(rc)) { |
498 | setnvalue(ra, nvalue(rb) - nvalue(rc)); | 498 | setnvalue(ra, nvalue(rb) - nvalue(rc)); |
499 | } | 499 | } |
@@ -502,8 +502,8 @@ StkId luaV_execute (lua_State *L) { | |||
502 | break; | 502 | break; |
503 | } | 503 | } |
504 | case OP_MUL: { | 504 | case OP_MUL: { |
505 | StkId rb = RB(i); | 505 | TObject *rb = RKB(i); |
506 | StkId rc = RKC(i); | 506 | TObject *rc = RKC(i); |
507 | if (ttisnumber(rb) && ttisnumber(rc)) { | 507 | if (ttisnumber(rb) && ttisnumber(rc)) { |
508 | setnvalue(ra, nvalue(rb) * nvalue(rc)); | 508 | setnvalue(ra, nvalue(rb) * nvalue(rc)); |
509 | } | 509 | } |
@@ -512,8 +512,8 @@ StkId luaV_execute (lua_State *L) { | |||
512 | break; | 512 | break; |
513 | } | 513 | } |
514 | case OP_DIV: { | 514 | case OP_DIV: { |
515 | StkId rb = RB(i); | 515 | TObject *rb = RKB(i); |
516 | StkId rc = RKC(i); | 516 | TObject *rc = RKC(i); |
517 | if (ttisnumber(rb) && ttisnumber(rc)) { | 517 | if (ttisnumber(rb) && ttisnumber(rc)) { |
518 | setnvalue(ra, nvalue(rb) / nvalue(rc)); | 518 | setnvalue(ra, nvalue(rb) / nvalue(rc)); |
519 | } | 519 | } |
@@ -522,7 +522,7 @@ StkId luaV_execute (lua_State *L) { | |||
522 | break; | 522 | break; |
523 | } | 523 | } |
524 | case OP_POW: { | 524 | case OP_POW: { |
525 | Arith(L, ra, RB(i), RKC(i), TM_POW); | 525 | Arith(L, ra, RKB(i), RKC(i), TM_POW); |
526 | break; | 526 | break; |
527 | } | 527 | } |
528 | case OP_UNM: { | 528 | case OP_UNM: { |
@@ -556,35 +556,25 @@ StkId luaV_execute (lua_State *L) { | |||
556 | break; | 556 | break; |
557 | } | 557 | } |
558 | case OP_EQ: { /* skip next instruction if test fails */ | 558 | case OP_EQ: { /* skip next instruction if test fails */ |
559 | if (equalobj(L, ra, RKC(i)) != GETARG_B(i)) pc++; | 559 | if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; |
560 | else dojump(pc, GETARG_sBx(*pc) + 1); | 560 | else dojump(pc, GETARG_sBx(*pc) + 1); |
561 | break; | 561 | break; |
562 | } | 562 | } |
563 | case OP_LT: { | 563 | case OP_LT: { |
564 | if (luaV_lessthan(L, ra, RKC(i)) != GETARG_B(i)) pc++; | 564 | if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; |
565 | else dojump(pc, GETARG_sBx(*pc) + 1); | 565 | else dojump(pc, GETARG_sBx(*pc) + 1); |
566 | break; | 566 | break; |
567 | } | 567 | } |
568 | case OP_LE: { | 568 | case OP_LE: { |
569 | if (luaV_lessequal(L, ra, RKC(i)) != GETARG_B(i)) pc++; | 569 | if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; |
570 | else dojump(pc, GETARG_sBx(*pc) + 1); | ||
571 | break; | ||
572 | } | ||
573 | case OP_GT: { | ||
574 | if (luaV_lessthan(L, RKC(i), ra) != GETARG_B(i)) pc++; | ||
575 | else dojump(pc, GETARG_sBx(*pc) + 1); | ||
576 | break; | ||
577 | } | ||
578 | case OP_GE: { | ||
579 | if (luaV_lessequal(L, RKC(i), ra) != GETARG_B(i)) pc++; | ||
580 | else dojump(pc, GETARG_sBx(*pc) + 1); | 570 | else dojump(pc, GETARG_sBx(*pc) + 1); |
581 | break; | 571 | break; |
582 | } | 572 | } |
583 | case OP_TEST: { | 573 | case OP_TEST: { |
584 | StkId rc = RKC(i); | 574 | TObject *rb = RB(i); |
585 | if (l_isfalse(rc) == GETARG_B(i)) pc++; | 575 | if (l_isfalse(rb) == GETARG_C(i)) pc++; |
586 | else { | 576 | else { |
587 | setobj(ra, rc); | 577 | setobj(ra, rb); |
588 | dojump(pc, GETARG_sBx(*pc) + 1); | 578 | dojump(pc, GETARG_sBx(*pc) + 1); |
589 | } | 579 | } |
590 | break; | 580 | break; |