aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c43
-rw-r--r--ldebug.c15
-rw-r--r--lopcodes.h2
-rw-r--r--lvm.c6
-rw-r--r--testes/errors.lua3
5 files changed, 35 insertions, 34 deletions
diff --git a/lcode.c b/lcode.c
index 42670794..6c124ff6 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1086,22 +1086,6 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
1086 1086
1087 1087
1088/* 1088/*
1089** Emit SELF instruction (convert expression 'e' into 'e:key(e,').
1090*/
1091void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
1092 int ereg;
1093 luaK_exp2anyreg(fs, e);
1094 ereg = e->u.info; /* register where 'e' was placed */
1095 freeexp(fs, e);
1096 e->u.info = fs->freereg; /* base register for op_self */
1097 e->k = VNONRELOC; /* self expression has a fixed register */
1098 luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */
1099 codeABRK(fs, OP_SELF, e->u.info, ereg, key);
1100 freeexp(fs, key);
1101}
1102
1103
1104/*
1105** Negate condition 'e' (where 'e' is a comparison). 1089** Negate condition 'e' (where 'e' is a comparison).
1106*/ 1090*/
1107static void negatecondition (FuncState *fs, expdesc *e) { 1091static void negatecondition (FuncState *fs, expdesc *e) {
@@ -1276,6 +1260,33 @@ static int isSCnumber (expdesc *e, int *pi, int *isfloat) {
1276 1260
1277 1261
1278/* 1262/*
1263** Emit SELF instruction or equivalent: the code will convert
1264** expression 'e' into 'e.key(e,'.
1265*/
1266void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
1267 int ereg, base;
1268 luaK_exp2anyreg(fs, e);
1269 ereg = e->u.info; /* register where 'e' (the receiver) was placed */
1270 freeexp(fs, e);
1271 base = e->u.info = fs->freereg; /* base register for op_self */
1272 e->k = VNONRELOC; /* self expression has a fixed register */
1273 luaK_reserveregs(fs, 2); /* method and 'self' produced by op_self */
1274 lua_assert(key->k == VKSTR);
1275 /* is method name a short string in a valid K index? */
1276 if (strisshr(key->u.strval) && luaK_exp2K(fs, key)) {
1277 /* can use 'self' opcode */
1278 luaK_codeABCk(fs, OP_SELF, base, ereg, key->u.info, 0);
1279 }
1280 else { /* cannot use 'self' opcode; use move+gettable */
1281 luaK_exp2anyreg(fs, key); /* put method name in a register */
1282 luaK_codeABC(fs, OP_MOVE, base + 1, ereg, 0); /* copy self to base+1 */
1283 luaK_codeABC(fs, OP_GETTABLE, base, ereg, key->u.info); /* get method */
1284 }
1285 freeexp(fs, key);
1286}
1287
1288
1289/*
1279** Create expression 't[k]'. 't' must have its final result already in a 1290** Create expression 't[k]'. 't' must have its final result already in a
1280** register or upvalue. Upvalues can only be indexed by literal strings. 1291** register or upvalue. Upvalues can only be indexed by literal strings.
1281** Keys can be literal strings in the constant table or arbitrary 1292** Keys can be literal strings in the constant table or arbitrary
diff --git a/ldebug.c b/ldebug.c
index ee3ac17f..09ec197c 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -542,18 +542,6 @@ static void rname (const Proto *p, int pc, int c, const char **name) {
542 542
543 543
544/* 544/*
545** Find a "name" for a 'C' value in an RK instruction.
546*/
547static void rkname (const Proto *p, int pc, Instruction i, const char **name) {
548 int c = GETARG_C(i); /* key index */
549 if (GETARG_k(i)) /* is 'c' a constant? */
550 kname(p, c, name);
551 else /* 'c' is a register */
552 rname(p, pc, c, name);
553}
554
555
556/*
557** Check whether table being indexed by instruction 'i' is the 545** Check whether table being indexed by instruction 'i' is the
558** environment '_ENV' 546** environment '_ENV'
559*/ 547*/
@@ -600,7 +588,8 @@ static const char *getobjname (const Proto *p, int lastpc, int reg,
600 return isEnv(p, lastpc, i, 0); 588 return isEnv(p, lastpc, i, 0);
601 } 589 }
602 case OP_SELF: { 590 case OP_SELF: {
603 rkname(p, lastpc, i, name); 591 int k = GETARG_C(i); /* key index */
592 kname(p, k, name);
604 return "method"; 593 return "method";
605 } 594 }
606 default: break; /* go through to return NULL */ 595 default: break; /* go through to return NULL */
diff --git a/lopcodes.h b/lopcodes.h
index 31f6fac0..7511eb22 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -256,7 +256,7 @@ OP_SETFIELD,/* A B C R[A][K[B]:shortstring] := RK(C) */
256 256
257OP_NEWTABLE,/* A B C k R[A] := {} */ 257OP_NEWTABLE,/* A B C k R[A] := {} */
258 258
259OP_SELF,/* A B C R[A+1] := R[B]; R[A] := R[B][RK(C):string] */ 259OP_SELF,/* A B C R[A+1] := R[B]; R[A] := R[B][K[C]:shortstring] */
260 260
261OP_ADDI,/* A B sC R[A] := R[B] + sC */ 261OP_ADDI,/* A B sC R[A] := R[B] + sC */
262 262
diff --git a/lvm.c b/lvm.c
index 1c564a71..b6b18a69 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1382,10 +1382,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1382 StkId ra = RA(i); 1382 StkId ra = RA(i);
1383 lu_byte tag; 1383 lu_byte tag;
1384 TValue *rb = vRB(i); 1384 TValue *rb = vRB(i);
1385 TValue *rc = RKC(i); 1385 TValue *rc = KC(i);
1386 TString *key = tsvalue(rc); /* key must be a string */ 1386 TString *key = tsvalue(rc); /* key must be a short string */
1387 setobj2s(L, ra + 1, rb); 1387 setobj2s(L, ra + 1, rb);
1388 luaV_fastget(rb, key, s2v(ra), luaH_getstr, tag); 1388 luaV_fastget(rb, key, s2v(ra), luaH_getshortstr, tag);
1389 if (tagisempty(tag)) 1389 if (tagisempty(tag))
1390 Protect(luaV_finishget(L, rb, rc, ra, tag)); 1390 Protect(luaV_finishget(L, rb, rc, ra, tag));
1391 vmbreak; 1391 vmbreak;
diff --git a/testes/errors.lua b/testes/errors.lua
index 0925fe58..027e1b03 100644
--- a/testes/errors.lua
+++ b/testes/errors.lua
@@ -321,7 +321,8 @@ t = nil
321checkmessage(s.."; aaa = bbb + 1", "global 'bbb'") 321checkmessage(s.."; aaa = bbb + 1", "global 'bbb'")
322checkmessage("local _ENV=_ENV;"..s.."; aaa = bbb + 1", "global 'bbb'") 322checkmessage("local _ENV=_ENV;"..s.."; aaa = bbb + 1", "global 'bbb'")
323checkmessage(s.."; local t = {}; aaa = t.bbb + 1", "field 'bbb'") 323checkmessage(s.."; local t = {}; aaa = t.bbb + 1", "field 'bbb'")
324checkmessage(s.."; local t = {}; t:bbb()", "method 'bbb'") 324-- cannot use 'self' opcode
325checkmessage(s.."; local t = {}; t:bbb()", "field 'bbb'")
325 326
326checkmessage([[aaa=9 327checkmessage([[aaa=9
327repeat until 3==3 328repeat until 3==3