Skip to content

Commit

Permalink
new opcodes for table access with constant keys (strings and integers)
Browse files Browse the repository at this point in the history
  • Loading branch information
roberto-ieru committed Apr 28, 2017
1 parent 173e41b commit 502a1d1
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 99 deletions.
74 changes: 56 additions & 18 deletions lcode.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lcode.c,v 2.116 2017/04/25 20:01:14 roberto Exp roberto $
** $Id: lcode.c,v 2.117 2017/04/26 17:46:52 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -580,18 +580,26 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
e->k = VRELOCABLE;
break;
}
case VINDEXUP: {
e->u.info = luaK_codeABC(fs, OP_GETTABUP, 0, e->u.ind.t, e->u.ind.idx);
e->k = VRELOCABLE;
break;
}
case VINDEXI: {
freereg(fs, e->u.ind.t);
e->u.info = luaK_codeABC(fs, OP_GETI, 0, e->u.ind.t, e->u.ind.idx);
e->k = VRELOCABLE;
break;
}
case VINDEXSTR: {
freereg(fs, e->u.ind.t);
e->u.info = luaK_codeABC(fs, OP_GETFIELD, 0, e->u.ind.t, e->u.ind.idx);
e->k = VRELOCABLE;
break;
}
case VINDEXED: {
OpCode op;
if (e->u.ind.vt == VLOCAL) { /* is 't' in a register? */
freeregs(fs, e->u.ind.t, e->u.ind.idx);
op = OP_GETTABLE;
}
else {
lua_assert(e->u.ind.vt == VUPVAL);
freereg(fs, e->u.ind.idx);
op = OP_GETTABUP; /* 't' is in an upvalue */
}
e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
freeregs(fs, e->u.ind.t, e->u.ind.idx);
e->u.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.ind.t, e->u.ind.idx);
e->k = VRELOCABLE;
break;
}
Expand Down Expand Up @@ -807,10 +815,24 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
break;
}
case VINDEXUP: {
int e = luaK_exp2RK(fs, ex);
luaK_codeABC(fs, OP_SETTABUP, var->u.ind.t, var->u.ind.idx, e);
break;
}
case VINDEXI: {
int e = luaK_exp2RK(fs, ex);
luaK_codeABC(fs, OP_SETI, var->u.ind.t, var->u.ind.idx, e);
break;
}
case VINDEXSTR: {
int e = luaK_exp2RK(fs, ex);
luaK_codeABC(fs, OP_SETFIELD, var->u.ind.t, var->u.ind.idx, e);
break;
}
case VINDEXED: {
OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
int e = luaK_exp2RK(fs, ex);
luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
luaK_codeABC(fs, OP_SETTABLE, var->u.ind.t, var->u.ind.idx, e);
break;
}
default: lua_assert(0); /* invalid var kind to store */
Expand Down Expand Up @@ -959,7 +981,8 @@ static void codenot (FuncState *fs, expdesc *e) {
** Check whether expression 'e' is a literal string
*/
static int isKstr (FuncState *fs, expdesc *e) {
return (e->k == VK && ttisstring(&fs->f->k[e->u.info]));
return (e->k == VK && !hasjumps(e) && e->u.info <= MAXARG_C &&
ttisstring(&fs->f->k[e->u.info]));
}


Expand All @@ -976,15 +999,30 @@ static int isKint (expdesc *e) {
/*
** Create expression 't[k]'. 't' must have its final result already in a
** register or upvalue. Upvalues can only be indexed by literal strings.
** Keys can be literal strings in the constant table or arbitrary
** values in registers.
*/
void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
lua_assert(!hasjumps(t) && (vkisinreg(t->k) || t->k == VUPVAL));
if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non string? */
luaK_exp2anyreg(fs, t); /* put it in a register */
t->u.ind.t = t->u.info; /* register or upvalue index */
t->u.ind.idx = luaK_exp2RK(fs, k); /* R/K index for key */
t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL : VLOCAL;
t->k = VINDEXED;
if (t->k == VUPVAL) {
t->u.ind.idx = k->u.info; /* literal string */
t->k = VINDEXUP;
}
else if (isKstr(fs, k)) {
t->u.ind.idx = k->u.info; /* literal string */
t->k = VINDEXSTR;
}
else if (isKint(k)) {
t->u.ind.idx = k->u.ival; /* integer constant */
t->k = VINDEXI;
}
else {
t->u.ind.idx = luaK_exp2anyreg(fs, k); /* register */
t->k = VINDEXED;
}
}


Expand Down
92 changes: 62 additions & 30 deletions ldebug.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: ldebug.c,v 2.121 2016/10/19 12:32:10 roberto Exp roberto $
** $Id: ldebug.c,v 2.122 2017/04/26 17:46:52 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -350,28 +350,36 @@ static const char *getobjname (Proto *p, int lastpc, int reg,


/*
** find a "name" for the RK value 'c'
** Find a "name" for the constant 'c'.
*/
static void kname (Proto *p, int pc, int c, const char **name) {
if (ISK(c)) { /* is 'c' a constant? */
TValue *kvalue = &p->k[INDEXK(c)];
if (ttisstring(kvalue)) { /* literal constant? */
*name = svalue(kvalue); /* it is its own name */
return;
}
/* else no reasonable name found */
}
else { /* 'c' is a register */
const char *what = getobjname(p, pc, c, name); /* search for 'c' */
if (what && *what == 'c') { /* found a constant name? */
return; /* 'name' already filled */
}
/* else no reasonable name found */
}
*name = "?"; /* no reasonable name found */
static void kname (Proto *p, int c, const char **name) {
TValue *kvalue = &p->k[INDEXK(c)];
*name = (ttisstring(kvalue)) ? svalue(kvalue) : "?";
}


/*
** Find a "name" for the register 'c'.
*/
static void rname (Proto *p, int pc, int c, const char **name) {
const char *what = getobjname(p, pc, c, name); /* search for 'c' */
if (!(what && *what == 'c')) /* did not find a constant name? */
*name = "?";
}


/*
** Find a "name" for the R/K index 'c'.
*/
static void rkname (Proto *p, int pc, int c, const char **name) {
if (ISK(c)) /* is 'c' a constant? */
kname(p, INDEXK(c), name);
else /* 'c' is a register */
rname(p, pc, c, name);
}



static int filterpc (int pc, int jmptarget) {
if (pc < jmptarget) /* is code conditional (inside a jump)? */
return -1; /* cannot know who sets that register */
Expand Down Expand Up @@ -428,8 +436,22 @@ static int findsetreg (Proto *p, int lastpc, int reg) {
}


static const char *getobjname (Proto *p, int lastpc, int reg,
const char **name) {
/*
** Check whether table being indexed by instruction 'i' is the
** environment '_ENV'
*/
static const char *gxf (Proto *p, int pc, Instruction i, int isup) {
int t = GETARG_B(i); /* table index */
const char *name; /* name of indexed variable */
if (isup) /* is an upvalue? */
name = upvalname(p, t);
else
getobjname(p, pc, t, &name);
return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field";
}


const char *getobjname (Proto *p, int lastpc, int reg, const char **name) {
int pc;
*name = luaF_getlocalname(p, reg + 1, lastpc);
if (*name) /* is a local? */
Expand All @@ -446,15 +468,24 @@ static const char *getobjname (Proto *p, int lastpc, int reg,
return getobjname(p, pc, b, name); /* get name for 'b' */
break;
}
case OP_GETTABUP:
case OP_GETTABUP: {
int k = GETARG_C(i); /* key index */
kname(p, k, name);
return gxf(p, pc, i, 1);
}
case OP_GETTABLE: {
int k = GETARG_C(i); /* key index */
int t = GETARG_B(i); /* table index */
const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
? luaF_getlocalname(p, t + 1, pc)
: upvalname(p, t);
kname(p, pc, k, name);
return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
rname(p, pc, k, name);
return gxf(p, pc, i, 0);
}
case OP_GETI: {
*name = "integer index";
return "field";
}
case OP_GETFIELD: {
int k = GETARG_C(i); /* key index */
kname(p, k, name);
return gxf(p, pc, i, 0);
}
case OP_GETUPVAL: {
*name = upvalname(p, GETARG_B(i));
Expand All @@ -472,7 +503,7 @@ static const char *getobjname (Proto *p, int lastpc, int reg,
}
case OP_SELF: {
int k = GETARG_C(i); /* key index */
kname(p, pc, k, name);
rkname(p, pc, k, name);
return "method";
}
default: break; /* go through to return NULL */
Expand Down Expand Up @@ -508,9 +539,10 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
}
/* other instructions can do calls through metamethods */
case OP_SELF: case OP_GETTABUP: case OP_GETTABLE:
case OP_GETI: case OP_GETFIELD:
tm = TM_INDEX;
break;
case OP_SETTABUP: case OP_SETTABLE:
case OP_SETTABUP: case OP_SETTABLE: case OP_SETI: case OP_SETFIELD:
tm = TM_NEWINDEX;
break;
case OP_ADDI:
Expand Down
18 changes: 13 additions & 5 deletions lopcodes.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lopcodes.c,v 1.56 2017/04/20 19:53:55 roberto Exp roberto $
** $Id: lopcodes.c,v 1.57 2017/04/26 17:46:52 roberto Exp roberto $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
Expand All @@ -25,11 +25,15 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
"LOADBOOL",
"LOADNIL",
"GETUPVAL",
"SETUPVAL",
"GETTABUP",
"GETTABLE",
"GETI",
"GETFIELD",
"SETTABUP",
"SETUPVAL",
"SETTABLE",
"SETI",
"SETFIELD",
"NEWTABLE",
"SELF",
"ADDI",
Expand Down Expand Up @@ -82,11 +86,15 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */
,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */
,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_GETTABLE */
,opmode(0, 1, OpArgR, OpArgU, iABC) /* OP_GETI */
,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETFIELD */
,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */
,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
,opmode(0, 0, OpArgR, OpArgK, iABC) /* OP_SETTABLE */
,opmode(0, 0, OpArgU, OpArgK, iABC) /* OP_SETI */
,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETFIELD */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
,opmode(0, 1, OpArgR, OpArgU, iABC) /* OP_ADDI */
Expand Down
20 changes: 11 additions & 9 deletions lopcodes.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lopcodes.h,v 1.151 2017/04/24 20:26:39 roberto Exp roberto $
** $Id: lopcodes.h,v 1.152 2017/04/26 17:46:52 roberto Exp roberto $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -178,17 +178,21 @@ OP_LOADKX,/* A R(A) := Kst(extra arg) */
OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
OP_LOADNIL,/* A B R(A), R(A+1), ..., R(A+B) := nil */
OP_GETUPVAL,/* A B R(A) := UpValue[B] */
OP_SETUPVAL,/* A B UpValue[B] := R(A) */

OP_GETTABUP,/* A B C R(A) := UpValue[B][RK(C)] */
OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
OP_GETTABUP,/* A B C R(A) := UpValue[B][K(C):string] */
OP_GETTABLE,/* A B C R(A) := R(B)[R(C)] */
OP_GETI,/* A B C R(A) := R(B)[C] */
OP_GETFIELD,/* A B C R(A) := R(B)[Kst(C):string] */

OP_SETTABUP,/* A B C UpValue[A][RK(B)] := RK(C) */
OP_SETUPVAL,/* A B UpValue[B] := R(A) */
OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
OP_SETTABUP,/* A B C UpValue[A][K(B):string] := RK(C) */
OP_SETTABLE,/* A B C R(A)[R(B)] := RK(C) */
OP_SETI,/* A B C R(A)[B] := RK(C) */
OP_SETFIELD,/* A B C R(A)[K(B):string] := RK(C) */

OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */

OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C):string] */

OP_ADDI,/* A B C R(A) := R(B) + C */
OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
Expand Down Expand Up @@ -259,8 +263,6 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
(*) In OP_LOADKX, the next 'instruction' is always EXTRAARG.
(*) In OP_GETTABUP, OP_SETTABUP, and OP_SELF, the index must be a string.
(*) For comparisons, A specifies what condition the test should accept
(true or false).
Expand Down
Loading

0 comments on commit 502a1d1

Please sign in to comment.