diff options
-rw-r--r-- | lcode.c | 22 | ||||
-rw-r--r-- | lcode.h | 3 | ||||
-rw-r--r-- | ldebug.c | 35 | ||||
-rw-r--r-- | lopcodes.c | 6 | ||||
-rw-r--r-- | lopcodes.h | 4 | ||||
-rw-r--r-- | lparser.c | 23 | ||||
-rw-r--r-- | lparser.h | 11 | ||||
-rw-r--r-- | lvm.c | 16 |
8 files changed, 89 insertions, 31 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 2.42 2009/09/23 20:33:05 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.43 2010/01/11 17:38:30 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 | */ |
@@ -384,6 +384,12 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { | |||
384 | e->k = VRELOCABLE; | 384 | e->k = VRELOCABLE; |
385 | break; | 385 | break; |
386 | } | 386 | } |
387 | case VINDEXEDUP: { | ||
388 | freereg(fs, e->u.s.aux); | ||
389 | e->u.s.info = luaK_codeABC(fs, OP_GETTABUP, 0, e->u.s.info, e->u.s.aux); | ||
390 | e->k = VRELOCABLE; | ||
391 | break; | ||
392 | } | ||
387 | case VVARARG: | 393 | case VVARARG: |
388 | case VCALL: { | 394 | case VCALL: { |
389 | luaK_setoneret(fs, e); | 395 | luaK_setoneret(fs, e); |
@@ -493,6 +499,12 @@ int luaK_exp2anyreg (FuncState *fs, expdesc *e) { | |||
493 | } | 499 | } |
494 | 500 | ||
495 | 501 | ||
502 | void luaK_exp2anyregup (FuncState *fs, expdesc *e) { | ||
503 | if (e->k != VUPVAL || hasjumps(e)) | ||
504 | luaK_exp2anyreg(fs, e); | ||
505 | } | ||
506 | |||
507 | |||
496 | void luaK_exp2val (FuncState *fs, expdesc *e) { | 508 | void luaK_exp2val (FuncState *fs, expdesc *e) { |
497 | if (hasjumps(e)) | 509 | if (hasjumps(e)) |
498 | luaK_exp2anyreg(fs, e); | 510 | luaK_exp2anyreg(fs, e); |
@@ -553,6 +565,11 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { | |||
553 | luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); | 565 | luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); |
554 | break; | 566 | break; |
555 | } | 567 | } |
568 | case VINDEXEDUP: { | ||
569 | int e = luaK_exp2RK(fs, ex); | ||
570 | luaK_codeABC(fs, OP_SETTABUP, var->u.s.info, var->u.s.aux, e); | ||
571 | break; | ||
572 | } | ||
556 | default: { | 573 | default: { |
557 | lua_assert(0); /* invalid var kind to store */ | 574 | lua_assert(0); /* invalid var kind to store */ |
558 | break; | 575 | break; |
@@ -695,8 +712,9 @@ static void codenot (FuncState *fs, expdesc *e) { | |||
695 | 712 | ||
696 | 713 | ||
697 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | 714 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { |
715 | lua_assert(!hasjumps(t)); | ||
698 | t->u.s.aux = luaK_exp2RK(fs, k); | 716 | t->u.s.aux = luaK_exp2RK(fs, k); |
699 | t->k = VINDEXED; | 717 | t->k = (t->k == VUPVAL) ? VINDEXEDUP : VINDEXED; |
700 | } | 718 | } |
701 | 719 | ||
702 | 720 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.h,v 1.51 2009/06/18 16:35:05 roberto Exp roberto $ | 2 | ** $Id: lcode.h,v 1.52 2009/09/23 20:33:05 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 | */ |
@@ -57,6 +57,7 @@ LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); | |||
57 | LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); | 57 | LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); |
58 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); | 58 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); |
59 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); | 59 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); |
60 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); | ||
60 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); | 61 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); |
61 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); | 62 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); |
62 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); | 63 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 2.62 2010/01/11 17:37:59 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 2.63 2010/01/13 16:18:25 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 | */ |
@@ -270,12 +270,10 @@ static const char *kname (Proto *p, int c) { | |||
270 | 270 | ||
271 | static const char *getobjname (lua_State *L, CallInfo *ci, int reg, | 271 | static const char *getobjname (lua_State *L, CallInfo *ci, int reg, |
272 | const char **name) { | 272 | const char **name) { |
273 | Proto *p; | 273 | Proto *p = ci_func(ci)->l.p; |
274 | int lastpc, pc; | ||
275 | const char *what = NULL; | 274 | const char *what = NULL; |
276 | lua_assert(isLua(ci)); | 275 | int lastpc = currentpc(ci); |
277 | p = ci_func(ci)->l.p; | 276 | int pc; |
278 | lastpc = currentpc(ci); | ||
279 | *name = luaF_getlocalname(p, reg + 1, lastpc); | 277 | *name = luaF_getlocalname(p, reg + 1, lastpc); |
280 | if (*name) /* is a local? */ | 278 | if (*name) /* is a local? */ |
281 | return "local"; | 279 | return "local"; |
@@ -305,6 +303,7 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, | |||
305 | } | 303 | } |
306 | break; | 304 | break; |
307 | } | 305 | } |
306 | case OP_GETTABUP: | ||
308 | case OP_GETTABLE: { | 307 | case OP_GETTABLE: { |
309 | if (reg == a) { | 308 | if (reg == a) { |
310 | int k = GETARG_C(i); /* key index */ | 309 | int k = GETARG_C(i); /* key index */ |
@@ -378,6 +377,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { | |||
378 | return getobjname(L, ci, GETARG_A(i), name); | 377 | return getobjname(L, ci, GETARG_A(i), name); |
379 | case OP_GETGLOBAL: | 378 | case OP_GETGLOBAL: |
380 | case OP_SELF: | 379 | case OP_SELF: |
380 | case OP_GETTABUP: | ||
381 | case OP_GETTABLE: tm = TM_INDEX; break; | 381 | case OP_GETTABLE: tm = TM_INDEX; break; |
382 | case OP_SETGLOBAL: | 382 | case OP_SETGLOBAL: |
383 | case OP_SETTABLE: tm = TM_NEWINDEX; break; | 383 | case OP_SETTABLE: tm = TM_NEWINDEX; break; |
@@ -413,13 +413,30 @@ static int isinstack (CallInfo *ci, const TValue *o) { | |||
413 | } | 413 | } |
414 | 414 | ||
415 | 415 | ||
416 | static const char *getupvalname (CallInfo *ci, const TValue *o, | ||
417 | const char **name) { | ||
418 | LClosure *c = &ci_func(ci)->l; | ||
419 | int i; | ||
420 | for (i = 0; i < c->nupvalues; i++) { | ||
421 | if (c->upvals[i]->v == o) { | ||
422 | *name = getstr(c->p->upvalues[i].name); | ||
423 | return "upvalue"; | ||
424 | } | ||
425 | } | ||
426 | return NULL; | ||
427 | } | ||
428 | |||
429 | |||
416 | void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { | 430 | void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { |
417 | CallInfo *ci = L->ci; | 431 | CallInfo *ci = L->ci; |
418 | const char *name = NULL; | 432 | const char *name = NULL; |
419 | const char *t = typename(ttype(o)); | 433 | const char *t = typename(ttype(o)); |
420 | const char *kind = (isLua(ci) && isinstack(ci, o)) ? | 434 | const char *kind = NULL; |
421 | getobjname(L, ci, cast_int(o - ci->u.l.base), &name) : | 435 | if (isLua(ci)) { |
422 | NULL; | 436 | kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ |
437 | if (!kind && isinstack(ci, o)) /* no? try a register */ | ||
438 | kind = getobjname(L, ci, cast_int(o - ci->u.l.base), &name); | ||
439 | } | ||
423 | if (kind) | 440 | if (kind) |
424 | luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", | 441 | luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", |
425 | op, kind, name, t); | 442 | op, kind, name, t); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.c,v 1.40 2008/10/30 15:39:30 roberto Exp roberto $ | 2 | ** $Id: lopcodes.c,v 1.41 2009/11/19 19:06:52 roberto Exp roberto $ |
3 | ** See Copyright Notice in lua.h | 3 | ** See Copyright Notice in lua.h |
4 | */ | 4 | */ |
5 | 5 | ||
@@ -20,8 +20,10 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { | |||
20 | "LOADNIL", | 20 | "LOADNIL", |
21 | "GETUPVAL", | 21 | "GETUPVAL", |
22 | "GETGLOBAL", | 22 | "GETGLOBAL", |
23 | "GETTABUP", | ||
23 | "GETTABLE", | 24 | "GETTABLE", |
24 | "SETGLOBAL", | 25 | "SETGLOBAL", |
26 | "SETTABUP", | ||
25 | "SETUPVAL", | 27 | "SETUPVAL", |
26 | "SETTABLE", | 28 | "SETTABLE", |
27 | "NEWTABLE", | 29 | "NEWTABLE", |
@@ -68,8 +70,10 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { | |||
68 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ | 70 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ |
69 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ | 71 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ |
70 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ | 72 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ |
73 | ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ | ||
71 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ | 74 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ |
72 | ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ | 75 | ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ |
76 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */ | ||
73 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ | 77 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ |
74 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ | 78 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ |
75 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ | 79 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.h,v 1.132 2009/10/28 12:20:07 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.133 2009/11/19 19:06:52 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 | */ |
@@ -172,9 +172,11 @@ OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */ | |||
172 | OP_GETUPVAL,/* A B R(A) := UpValue[B] */ | 172 | OP_GETUPVAL,/* A B R(A) := UpValue[B] */ |
173 | 173 | ||
174 | OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx - 1)] */ | 174 | OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx - 1)] */ |
175 | OP_GETTABUP,/* A B C R(A) := UpValue[B][RK(C)] */ | ||
175 | OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */ | 176 | OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */ |
176 | 177 | ||
177 | OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx - 1)] := R(A) */ | 178 | OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx - 1)] := R(A) */ |
179 | OP_SETTABUP,/* A B C UpValue[A][RK(B)] := RK(C) */ | ||
178 | OP_SETUPVAL,/* A B UpValue[B] := R(A) */ | 180 | OP_SETUPVAL,/* A B UpValue[B] := R(A) */ |
179 | OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */ | 181 | OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */ |
180 | 182 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 2.74 2010/01/05 18:46:58 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 2.75 2010/01/06 11:48:02 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 | */ |
@@ -452,7 +452,7 @@ static void fieldsel (LexState *ls, expdesc *v) { | |||
452 | /* fieldsel -> ['.' | ':'] NAME */ | 452 | /* fieldsel -> ['.' | ':'] NAME */ |
453 | FuncState *fs = ls->fs; | 453 | FuncState *fs = ls->fs; |
454 | expdesc key; | 454 | expdesc key; |
455 | luaK_exp2anyreg(fs, v); | 455 | luaK_exp2anyregup(fs, v); |
456 | luaX_next(ls); /* skip the dot or colon */ | 456 | luaX_next(ls); /* skip the dot or colon */ |
457 | checkname(ls, &key); | 457 | checkname(ls, &key); |
458 | luaK_indexed(fs, v, &key); | 458 | luaK_indexed(fs, v, &key); |
@@ -747,7 +747,7 @@ static void primaryexp (LexState *ls, expdesc *v) { | |||
747 | } | 747 | } |
748 | case '[': { /* `[' exp1 `]' */ | 748 | case '[': { /* `[' exp1 `]' */ |
749 | expdesc key; | 749 | expdesc key; |
750 | luaK_exp2anyreg(fs, v); | 750 | luaK_exp2anyregup(fs, v); |
751 | yindex(ls, &key); | 751 | yindex(ls, &key); |
752 | luaK_indexed(fs, v, &key); | 752 | luaK_indexed(fs, v, &key); |
753 | break; | 753 | break; |
@@ -951,24 +951,27 @@ struct LHS_assign { | |||
951 | ** local value in a safe place and use this safe copy in the previous | 951 | ** local value in a safe place and use this safe copy in the previous |
952 | ** assignment. | 952 | ** assignment. |
953 | */ | 953 | */ |
954 | static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { | 954 | static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v, |
955 | expkind ix, OpCode op) { | ||
955 | FuncState *fs = ls->fs; | 956 | FuncState *fs = ls->fs; |
956 | int extra = fs->freereg; /* eventual position to save local variable */ | 957 | int extra = fs->freereg; /* eventual position to save local variable */ |
957 | int conflict = 0; | 958 | int conflict = 0; |
958 | for (; lh; lh = lh->prev) { | 959 | for (; lh; lh = lh->prev) { |
959 | if (lh->v.k == VINDEXED) { | 960 | if (lh->v.k == ix) { |
960 | if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ | 961 | if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ |
961 | conflict = 1; | 962 | conflict = 1; |
963 | lh->v.k = VINDEXED; | ||
962 | lh->v.u.s.info = extra; /* previous assignment will use safe copy */ | 964 | lh->v.u.s.info = extra; /* previous assignment will use safe copy */ |
963 | } | 965 | } |
964 | if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ | 966 | if (v->k == VLOCAL && lh->v.u.s.aux == v->u.s.info) { /* conflict? */ |
965 | conflict = 1; | 967 | conflict = 1; |
968 | lua_assert(lh->v.k == VINDEXED); | ||
966 | lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ | 969 | lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ |
967 | } | 970 | } |
968 | } | 971 | } |
969 | } | 972 | } |
970 | if (conflict) { | 973 | if (conflict) { |
971 | luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */ | 974 | luaK_codeABC(fs, op, fs->freereg, v->u.s.info, 0); /* make copy */ |
972 | luaK_reserveregs(fs, 1); | 975 | luaK_reserveregs(fs, 1); |
973 | } | 976 | } |
974 | } | 977 | } |
@@ -976,14 +979,16 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { | |||
976 | 979 | ||
977 | static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { | 980 | static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { |
978 | expdesc e; | 981 | expdesc e; |
979 | check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, | 982 | check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXEDUP, |
980 | "syntax error"); | 983 | "syntax error"); |
981 | if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ | 984 | if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ |
982 | struct LHS_assign nv; | 985 | struct LHS_assign nv; |
983 | nv.prev = lh; | 986 | nv.prev = lh; |
984 | primaryexp(ls, &nv.v); | 987 | primaryexp(ls, &nv.v); |
985 | if (nv.v.k == VLOCAL) | 988 | if (nv.v.k == VLOCAL) |
986 | check_conflict(ls, lh, &nv.v); | 989 | check_conflict(ls, lh, &nv.v, VINDEXED, OP_MOVE); |
990 | else if (nv.v.k == VUPVAL) | ||
991 | check_conflict(ls, lh, &nv.v, VINDEXEDUP, OP_GETUPVAL); | ||
987 | checklimit(ls->fs, nvars, LUAI_MAXCCALLS - G(ls->L)->nCcalls, | 992 | checklimit(ls->fs, nvars, LUAI_MAXCCALLS - G(ls->L)->nCcalls, |
988 | "variable names"); | 993 | "variable names"); |
989 | assignment(ls, &nv, nvars+1); | 994 | assignment(ls, &nv, nvars+1); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.h,v 1.60 2009/09/30 15:38:37 roberto Exp roberto $ | 2 | ** $Id: lparser.h,v 1.61 2009/10/11 20:02:19 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 | */ |
@@ -23,10 +23,11 @@ typedef enum { | |||
23 | VFALSE, | 23 | VFALSE, |
24 | VK, /* info = index of constant in `k' */ | 24 | VK, /* info = index of constant in `k' */ |
25 | VKNUM, /* nval = numerical value */ | 25 | VKNUM, /* nval = numerical value */ |
26 | VLOCAL, /* info = local register; aux = read only */ | 26 | VLOCAL, /* info = local register */ |
27 | VUPVAL, /* info = index of upvalue in 'upvalues'; aux = read only */ | 27 | VUPVAL, /* info = index of upvalue in 'upvalues' */ |
28 | VGLOBAL, /* info = index of table; aux = index of global name in `k' */ | 28 | VGLOBAL, /* info = index of global name in 'k' */ |
29 | VINDEXED, /* info = table register; aux = index register (or `k') */ | 29 | VINDEXED, /* info = table R/K; aux = index R/K */ |
30 | VINDEXEDUP, /* info = table upvalue; aux = R/K */ | ||
30 | VJMP, /* info = instruction pc */ | 31 | VJMP, /* info = instruction pc */ |
31 | VRELOCABLE, /* info = instruction pc */ | 32 | VRELOCABLE, /* info = instruction pc */ |
32 | VNONRELOC, /* info = result register */ | 33 | VNONRELOC, /* info = result register */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.102 2009/12/17 16:20:01 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.103 2010/01/15 16:23:58 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 | */ |
@@ -362,7 +362,7 @@ void luaV_finishOp (lua_State *L) { | |||
362 | switch (op) { /* finish its execution */ | 362 | switch (op) { /* finish its execution */ |
363 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: | 363 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: |
364 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: | 364 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: |
365 | case OP_GETGLOBAL: case OP_GETTABLE: case OP_SELF: { | 365 | case OP_GETGLOBAL: case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { |
366 | setobjs2s(L, base + GETARG_A(inst), --L->top); | 366 | setobjs2s(L, base + GETARG_A(inst), --L->top); |
367 | break; | 367 | break; |
368 | } | 368 | } |
@@ -403,7 +403,7 @@ void luaV_finishOp (lua_State *L) { | |||
403 | L->top = ci->top; /* adjust results */ | 403 | L->top = ci->top; /* adjust results */ |
404 | break; | 404 | break; |
405 | } | 405 | } |
406 | case OP_TAILCALL: case OP_SETGLOBAL: case OP_SETTABLE: | 406 | case OP_TAILCALL: case OP_SETGLOBAL: case OP_SETTABUP: case OP_SETTABLE: |
407 | break; | 407 | break; |
408 | default: lua_assert(0); | 408 | default: lua_assert(0); |
409 | } | 409 | } |
@@ -504,6 +504,11 @@ void luaV_execute (lua_State *L) { | |||
504 | Protect(luaV_gettable(L, &g, rb, ra)); | 504 | Protect(luaV_gettable(L, &g, rb, ra)); |
505 | continue; | 505 | continue; |
506 | } | 506 | } |
507 | case OP_GETTABUP: { | ||
508 | int b = GETARG_B(i); | ||
509 | Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra)); | ||
510 | continue; | ||
511 | } | ||
507 | case OP_GETTABLE: { | 512 | case OP_GETTABLE: { |
508 | Protect(luaV_gettable(L, RB(i), RKC(i), ra)); | 513 | Protect(luaV_gettable(L, RB(i), RKC(i), ra)); |
509 | continue; | 514 | continue; |
@@ -516,6 +521,11 @@ void luaV_execute (lua_State *L) { | |||
516 | Protect(luaV_settable(L, &g, rb, ra)); | 521 | Protect(luaV_settable(L, &g, rb, ra)); |
517 | continue; | 522 | continue; |
518 | } | 523 | } |
524 | case OP_SETTABUP: { | ||
525 | int a = GETARG_A(i); | ||
526 | Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i))); | ||
527 | continue; | ||
528 | } | ||
519 | case OP_SETUPVAL: { | 529 | case OP_SETUPVAL: { |
520 | UpVal *uv = cl->upvals[GETARG_B(i)]; | 530 | UpVal *uv = cl->upvals[GETARG_B(i)]; |
521 | setobj(L, uv->v, ra); | 531 | setobj(L, uv->v, ra); |