summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c22
-rw-r--r--lcode.h3
-rw-r--r--ldebug.c35
-rw-r--r--lopcodes.c6
-rw-r--r--lopcodes.h4
-rw-r--r--lparser.c23
-rw-r--r--lparser.h11
-rw-r--r--lvm.c16
8 files changed, 89 insertions, 31 deletions
diff --git a/lcode.c b/lcode.c
index 0d570c65..a61ef112 100644
--- a/lcode.c
+++ b/lcode.c
@@ -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
502void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
503 if (e->k != VUPVAL || hasjumps(e))
504 luaK_exp2anyreg(fs, e);
505}
506
507
496void luaK_exp2val (FuncState *fs, expdesc *e) { 508void 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
697void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { 714void 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
diff --git a/lcode.h b/lcode.h
index 63371ad4..44996a43 100644
--- a/lcode.h
+++ b/lcode.h
@@ -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);
57LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); 57LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
58LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); 58LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
59LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); 59LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
60LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
60LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); 61LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
61LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); 62LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
62LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); 63LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
diff --git a/ldebug.c b/ldebug.c
index 6b15634e..2c62383e 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -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
271static const char *getobjname (lua_State *L, CallInfo *ci, int reg, 271static 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
416static 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
416void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { 430void 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);
diff --git a/lopcodes.c b/lopcodes.c
index 4bcd2b6e..7a355752 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -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 */
diff --git a/lopcodes.h b/lopcodes.h
index bd8cc082..b7ba60b7 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -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 */
172OP_GETUPVAL,/* A B R(A) := UpValue[B] */ 172OP_GETUPVAL,/* A B R(A) := UpValue[B] */
173 173
174OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx - 1)] */ 174OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx - 1)] */
175OP_GETTABUP,/* A B C R(A) := UpValue[B][RK(C)] */
175OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */ 176OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
176 177
177OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx - 1)] := R(A) */ 178OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx - 1)] := R(A) */
179OP_SETTABUP,/* A B C UpValue[A][RK(B)] := RK(C) */
178OP_SETUPVAL,/* A B UpValue[B] := R(A) */ 180OP_SETUPVAL,/* A B UpValue[B] := R(A) */
179OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */ 181OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
180 182
diff --git a/lparser.c b/lparser.c
index a42c6401..8984bc79 100644
--- a/lparser.c
+++ b/lparser.c
@@ -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*/
954static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { 954static 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
977static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { 980static 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);
diff --git a/lparser.h b/lparser.h
index 4fcdc621..d46265dc 100644
--- a/lparser.h
+++ b/lparser.h
@@ -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 */
diff --git a/lvm.c b/lvm.c
index 7ee9388f..ae4f6293 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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);