lua

A copy of the Lua development repository
Log | Files | Refs | README

commit a1ef58b3a5986293ed0b7acef50073d94c7f932f
parent 283e7455ffe32235eaf790ebd3c40c7970b7a833
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Wed,  4 Oct 2017 18:56:05 -0300

eplicit 1-bit opcode operand 'k'

Diffstat:
Mlcode.c | 74+++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Mlcode.h | 8++++++--
Mldebug.c | 17++++++++---------
Mlopcodes.h | 71+++++++++++++++++++++++++++++------------------------------------------
Mltests.c | 7++++---
Mlvm.c | 22+++++++++++-----------
6 files changed, 103 insertions(+), 96 deletions(-)

diff --git a/lcode.c b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 2.128 2017/10/02 22:50:57 roberto Exp roberto $ +** $Id: lcode.c,v 2.129 2017/10/04 15:49:24 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -202,7 +202,7 @@ static int patchtestreg (FuncState *fs, int node, int reg) { else { /* no register to put value or register already has the value; change instruction to simple test */ - *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); + *i = CREATE_ABCk(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i), 0); } return 1; } @@ -365,13 +365,18 @@ static int luaK_code (FuncState *fs, Instruction i) { ** Format and emit an 'iABC' instruction. (Assertions check consistency ** of parameters versus opcode.) */ -int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { +int luaK_codeABCk (FuncState *fs, OpCode o, int a, int b, int c, int k) { lua_assert(getOpMode(o) == iABC); - lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C); - return luaK_code(fs, CREATE_ABC(o, a, b, c)); + lua_assert(a <= MAXARG_A && b <= MAXARG_B && + c <= MAXARG_C && (k & ~1) == 0); + return luaK_code(fs, CREATE_ABCk(o, a, b, c, k)); } +#define codeABsC(fs,o,a,b,c,k) luaK_codeABCk(fs,o,a,b,((c) + MAXARG_sC),k) + + + /* ** Format and emit an 'iABx' instruction. */ @@ -448,7 +453,7 @@ void luaK_reserveregs (FuncState *fs, int n) { ) */ static void freereg (FuncState *fs, int reg) { - if (!ISK(reg) && reg >= fs->nactvar) { + if (reg >= fs->nactvar) { fs->freereg--; lua_assert(reg == fs->freereg); } @@ -853,7 +858,7 @@ void luaK_exp2val (FuncState *fs, expdesc *e) { ** Ensures final expression result is in a valid R/K index ** (that is, it is either in a register or in 'k' with an index ** in the range of R/K indices). -** Returns R/K index. +** Returns 1 if expression is K, 0 otherwise. */ int luaK_exp2RK (FuncState *fs, expdesc *e) { luaK_exp2val(fs, e); @@ -867,12 +872,20 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) { vk: e->k = VK; if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */ - return RKASK(e->u.info); + return 1; else break; default: break; } /* not a constant in the right range: put it in a register */ - return luaK_exp2anyreg(fs, e); + luaK_exp2anyreg(fs, e); + return 0; +} + + +static void codeABRK (FuncState *fs, OpCode o, int a, int b, + expdesc *ec) { + int k = luaK_exp2RK(fs, ec); + luaK_codeABCk(fs, o, a, b, ec->u.info, k); } @@ -892,23 +905,19 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { break; } case VINDEXUP: { - int e = luaK_exp2RK(fs, ex); - luaK_codeABC(fs, OP_SETTABUP, var->u.ind.t, var->u.ind.idx, e); + codeABRK(fs, OP_SETTABUP, var->u.ind.t, var->u.ind.idx, ex); break; } case VINDEXI: { - int e = luaK_exp2RK(fs, ex); - luaK_codeABC(fs, OP_SETI, var->u.ind.t, var->u.ind.idx, e); + codeABRK(fs, OP_SETI, var->u.ind.t, var->u.ind.idx, ex); break; } case VINDEXSTR: { - int e = luaK_exp2RK(fs, ex); - luaK_codeABC(fs, OP_SETFIELD, var->u.ind.t, var->u.ind.idx, e); + codeABRK(fs, OP_SETFIELD, var->u.ind.t, var->u.ind.idx, ex); break; } case VINDEXED: { - int e = luaK_exp2RK(fs, ex); - luaK_codeABC(fs, OP_SETTABLE, var->u.ind.t, var->u.ind.idx, e); + codeABRK(fs, OP_SETTABLE, var->u.ind.t, var->u.ind.idx, ex); break; } default: lua_assert(0); /* invalid var kind to store */ @@ -928,7 +937,7 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { e->u.info = fs->freereg; /* base register for op_self */ e->k = VNONRELOC; /* self expression has a fixed register */ luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ - luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key)); + codeABRK(fs, OP_SELF, e->u.info, ereg, key); freeexp(fs, key); } @@ -1064,11 +1073,21 @@ static int isKstr (FuncState *fs, expdesc *e) { /* ** Check whether expression 'e' is a literal integer in -** proper range +** proper range to fit in register C +*/ +static int isCint (expdesc *e) { + return (e->k == VKINT && !hasjumps(e) && + l_castS2U(e->u.ival) <= l_castS2U(MAXARG_C)); +} + + +/* +** Check whether expression 'e' is a literal integer in +** proper range to fit in register sC */ -static int isKint (expdesc *e) { +static int isSCint (expdesc *e) { return (e->k == VKINT && !hasjumps(e) && - l_castS2U(e->u.ival) <= l_castS2U(MAXARG_Cr)); + l_castS2U(e->u.ival + MAXARG_sC) <= l_castS2U(MAXARG_C)); } @@ -1091,7 +1110,7 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { t->u.ind.idx = k->u.info; /* literal string */ t->k = VINDEXSTR; } - else if (isKint(k)) { + else if (isCint(k)) { t->u.ind.idx = k->u.ival; /* integer constant */ t->k = VINDEXI; } @@ -1187,16 +1206,14 @@ static void codebinexpval (FuncState *fs, OpCode op, */ static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2, int flip, int line) { - if (!isKint(e2)) + if (!isSCint(e2)) codebinexpval(fs, op, e1, e2, line); /* use standard operators */ else { /* use immediate operators */ int v2 = cast_int(e2->u.ival); /* immediate operand */ int v1 = luaK_exp2anyreg(fs, e1); - if (flip) - v2 |= BITRK; /* signal that operands were flipped */ op = cast(OpCode, op - OP_ADD + OP_ADDI); freeexp(fs, e1); - e1->u.info = luaK_codeABC(fs, op, 0, v1, v2); /* generate opcode */ + e1->u.info = codeABsC(fs, op, 0, v1, v2, flip); /* generate opcode */ e1->k = VRELOCABLE; /* all those operations are relocatable */ luaK_fixline(fs, line); } @@ -1210,7 +1227,7 @@ static void codearith (FuncState *fs, OpCode op, static void codecommutative (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2, int line) { int flip = 0; - if (isKint(e1)) { + if (isSCint(e1)) { expdesc temp = *e1; *e1 = *e2; *e2 = temp; /* swap 'e1' and 'e2' */ flip = 1; } @@ -1223,8 +1240,7 @@ static void codecommutative (FuncState *fs, OpCode op, ** 'e1' was already put in register by 'luaK_infix'. */ static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { - int rk1 = (e1->k == VK) ? RKASK(e1->u.info) - : check_exp(e1->k == VNONRELOC, e1->u.info); + int rk1 = check_exp(e1->k == VNONRELOC, e1->u.info); int rk2 = luaK_exp2anyreg(fs, e2); freeexps(fs, e1, e2); switch (opr) { diff --git a/lcode.h b/lcode.h @@ -1,5 +1,5 @@ /* -** $Id: lcode.h,v 1.66 2017/09/13 19:50:08 roberto Exp roberto $ +** $Id: lcode.h,v 1.67 2017/09/28 16:53:29 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -37,6 +37,9 @@ typedef enum BinOpr { } BinOpr; +#define luaK_codeABC(fs,o,a,b,c) luaK_codeABCk(fs,o,a,b,c,0) + + typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; @@ -50,7 +53,8 @@ typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); LUAI_FUNC int luaK_codeAsBx (FuncState *fs, OpCode o, int A, int Bx); -LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); +LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, + int B, int C, int k); LUAI_FUNC void luaK_fixline (FuncState *fs, int line); LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); diff --git a/ldebug.c b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.130 2017/07/10 17:35:12 roberto Exp roberto $ +** $Id: ldebug.c,v 2.131 2017/10/04 15:49:24 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -402,7 +402,7 @@ static const char *getobjname (Proto *p, int lastpc, int reg, ** Find a "name" for the constant 'c'. */ static void kname (Proto *p, int c, const char **name) { - TValue *kvalue = &p->k[INDEXK(c)]; + TValue *kvalue = &p->k[c]; *name = (ttisstring(kvalue)) ? svalue(kvalue) : "?"; } @@ -418,17 +418,17 @@ static void rname (Proto *p, int pc, int c, const char **name) { /* -** Find a "name" for the R/K index 'c'. +** Find a "name" for a 'C' value in an RK instruction. */ -static void rkname (Proto *p, int pc, int c, const char **name) { - if (ISK(c)) /* is 'c' a constant? */ - kname(p, INDEXK(c), name); +static void rkname (Proto *p, int pc, Instruction i, const char **name) { + int c = GETARG_C(i); /* key index */ + if (GETARG_k(i)) /* is 'c' a constant? */ + kname(p, 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 */ @@ -549,8 +549,7 @@ static const char *gxf (Proto *p, int pc, Instruction i, int isup) { break; } case OP_SELF: { - int k = GETARG_C(i); /* key index */ - rkname(p, pc, k, name); + rkname(p, pc, i, name); return "method"; } default: break; /* go through to return NULL */ diff --git a/lopcodes.h b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.164 2017/10/02 22:51:32 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.165 2017/10/04 15:49:24 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -17,7 +17,7 @@ 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 -iABC | C(9) | | B(8) | | A(8) | | Op(7) | +iABC |k| C(8) | | B(8) | | A(8) | | Op(7) | iABx | Bx(17) | | A(8) | | Op(7) | iAsBx | sBx (signed)(17) | | A(8) | | Op(7) | iAx | Ax(25) | | Op(7) | @@ -34,19 +34,21 @@ enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ /* ** size and position of opcode arguments. */ -#define SIZE_C 9 +#define SIZE_C 8 +#define SIZE_Cx (SIZE_C + 1) #define SIZE_B 8 -#define SIZE_Bx (SIZE_C + SIZE_B) +#define SIZE_Bx (SIZE_Cx + SIZE_B) #define SIZE_A 8 -#define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A) +#define SIZE_Ax (SIZE_Cx + SIZE_B + SIZE_A) #define SIZE_OP 7 #define POS_OP 0 #define POS_A (POS_OP + SIZE_OP) -#define POS_C (POS_A + SIZE_A) -#define POS_B (POS_C + SIZE_C) -#define POS_Bx POS_C +#define POS_B (POS_A + SIZE_A) +#define POS_C (POS_B + SIZE_B) +#define POS_k (POS_C + SIZE_C) +#define POS_Bx POS_B #define POS_Ax POS_A @@ -70,10 +72,11 @@ enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ #endif -#define MAXARG_A ((1<<SIZE_A)-1) -#define MAXARG_B ((1<<SIZE_B)-1) -#define MAXARG_C ((1<<SIZE_C)-1) -#define MAXARG_Cr ((1<<(SIZE_C - 1))-1) +#define MAXARG_A ((1<<SIZE_A)-1) +#define MAXARG_B ((1<<SIZE_B)-1) +#define MAXARG_C ((1<<SIZE_C)-1) +#define MAXARG_sC (MAXARG_C >> 1) +#define MAXARG_Cx ((1<<(SIZE_C + 1))-1) /* creates a mask with 'n' 1 bits at position 'p' */ @@ -104,11 +107,10 @@ enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ #define SETARG_B(i,v) setarg(i, v, POS_B, SIZE_B) #define GETARG_C(i) check_exp(checkopm(i, iABC), getarg(i, POS_C, SIZE_C)) +#define GETARG_sC(i) (GETARG_C(i) - MAXARG_sC) #define SETARG_C(i,v) setarg(i, v, POS_C, SIZE_C) -#define GETARG_Cr(i) \ - check_exp(checkopm(i, iABC), getarg(i, POS_C, SIZE_C - 1)) -#define GETARG_Ck(i) getarg(i, (POS_C + SIZE_C - 1), 1) +#define GETARG_k(i) (cast(int, ((i) & (1 << POS_k)))) #define GETARG_Bx(i) check_exp(checkopm(i, iABx), getarg(i, POS_Bx, SIZE_Bx)) #define SETARG_Bx(i,v) setarg(i, v, POS_Bx, SIZE_Bx) @@ -121,10 +123,11 @@ enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ #define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx)) -#define CREATE_ABC(o,a,b,c) ((cast(Instruction, o)<<POS_OP) \ +#define CREATE_ABCk(o,a,b,c,k) ((cast(Instruction, o)<<POS_OP) \ | (cast(Instruction, a)<<POS_A) \ | (cast(Instruction, b)<<POS_B) \ - | (cast(Instruction, c)<<POS_C)) + | (cast(Instruction, c)<<POS_C)) \ + | (cast(Instruction, k)<<POS_k) #define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \ | (cast(Instruction, a)<<POS_A) \ @@ -134,26 +137,10 @@ enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ | (cast(Instruction, a)<<POS_Ax)) -/* -** Macros to operate RK indices -*/ - -/* this bit 1 means constant (0 means register) */ -#define BITRK (1 << (SIZE_C - 1)) - -/* test whether value is a constant */ -#define ISK(x) ((x) & BITRK) - -/* gets the index of the constant */ -#define INDEXK(r) ((int)(r) & ~BITRK) - #if !defined(MAXINDEXRK) /* (for debugging only) */ -#define MAXINDEXRK (BITRK - 1) +#define MAXINDEXRK MAXARG_B #endif -/* code a constant index as a RK value */ -#define RKASK(x) ((x) | BITRK) - /* ** invalid register that fits in 8 bits @@ -164,7 +151,7 @@ enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ /* ** R(x) - register ** K(x) - constant (in constant table) -** RK(x) == if ISK(x) then K(INDEXK(x)) else R(x) +** RK(x) == if k(i) then K(x) else R(x) */ @@ -200,13 +187,13 @@ 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):string] */ -OP_ADDI,/* A B C R(A) := R(B) + C */ -OP_SUBI,/* A B C R(A) := R(B) - C */ -OP_MULI,/* A B C R(A) := R(B) * C */ -OP_MODI,/* A B C R(A) := R(B) % C */ -OP_POWI,/* A B C R(A) := R(B) ^ C */ -OP_DIVI,/* A B C R(A) := R(B) / C */ -OP_IDIVI,/* A B C R(A) := R(B) // C */ +OP_ADDI,/* A B sC R(A) := R(B) + C */ +OP_SUBI,/* A B sC R(A) := R(B) - C */ +OP_MULI,/* A B sC R(A) := R(B) * C */ +OP_MODI,/* A B sC R(A) := R(B) % C */ +OP_POWI,/* A B sC R(A) := R(B) ^ C */ +OP_DIVI,/* A B sC R(A) := R(B) / C */ +OP_IDIVI,/* A B sC R(A) := R(B) // C */ OP_ADD,/* A B C R(A) := R(B) + R(C) */ OP_SUB,/* A B C R(A) := R(B) - R(C) */ diff --git a/ltests.c b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 2.223 2017/06/29 15:06:44 roberto Exp roberto $ +** $Id: ltests.c,v 2.224 2017/10/01 19:17:51 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -541,8 +541,9 @@ static char *buildop (Proto *p, int pc, char *buff) { sprintf(buff, "(%4d) %4d - ", line, pc); switch (getOpMode(o)) { case iABC: - sprintf(buff+strlen(buff), "%-12s%4d %4d %4d", name, - GETARG_A(i), GETARG_B(i), GETARG_C(i)); + sprintf(buff+strlen(buff), "%-12s%4d %4d %4d%s", name, + GETARG_A(i), GETARG_B(i), GETARG_C(i), + GETARG_k(i) ? " (k)" : ""); break; case iABx: sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i)); diff --git a/lvm.c b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.297 2017/10/01 19:13:43 roberto Exp roberto $ +** $Id: lvm.c,v 2.298 2017/10/04 15:49:24 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -742,7 +742,7 @@ void luaV_finishOp (lua_State *L) { #define RC(i) (base+GETARG_C(i)) #define vRC(i) s2v(RC(i)) #define KC(i) (k+GETARG_C(i)) -#define RKC(i) ((GETARG_Ck(i)) ? k + GETARG_Cr(i) : s2v(base + GETARG_Cr(i))) +#define RKC(i) ((GETARG_k(i)) ? k + GETARG_C(i) : s2v(base + GETARG_C(i))) @@ -992,7 +992,7 @@ void luaV_execute (lua_State *L) { } vmcase(OP_ADDI) { TValue *rb = vRB(i); - int ic = GETARG_Cr(i); + int ic = GETARG_sC(i); lua_Number nb; if (ttisinteger(rb)) { setivalue(s2v(ra), intop(+, ivalue(rb), ic)); @@ -1001,12 +1001,12 @@ void luaV_execute (lua_State *L) { setfltvalue(s2v(ra), luai_numadd(L, nb, cast_num(ic))); } else - Protect(luaT_trybiniTM(L, rb, ic, GETARG_Ck(i), ra, TM_ADD)); + Protect(luaT_trybiniTM(L, rb, ic, GETARG_k(i), ra, TM_ADD)); vmbreak; } vmcase(OP_SUBI) { TValue *rb = vRB(i); - int ic = GETARG_Cr(i); + int ic = GETARG_sC(i); lua_Number nb; if (ttisinteger(rb)) { setivalue(s2v(ra), intop(-, ivalue(rb), ic)); @@ -1020,7 +1020,7 @@ void luaV_execute (lua_State *L) { } vmcase(OP_MULI) { TValue *rb = vRB(i); - int ic = GETARG_Cr(i); + int ic = GETARG_sC(i); lua_Number nb; if (ttisinteger(rb)) { setivalue(s2v(ra), intop(*, ivalue(rb), ic)); @@ -1029,12 +1029,12 @@ void luaV_execute (lua_State *L) { setfltvalue(s2v(ra), luai_nummul(L, nb, cast_num(ic))); } else - Protect(luaT_trybiniTM(L, rb, ic, GETARG_Ck(i), ra, TM_MUL)); + Protect(luaT_trybiniTM(L, rb, ic, GETARG_k(i), ra, TM_MUL)); vmbreak; } vmcase(OP_MODI) { TValue *rb = vRB(i); - int ic = GETARG_Cr(i); + int ic = GETARG_sC(i); lua_Number nb; if (ttisinteger(rb)) { setivalue(s2v(ra), luaV_mod(L, ivalue(rb), ic)); @@ -1051,7 +1051,7 @@ void luaV_execute (lua_State *L) { } vmcase(OP_POWI) { TValue *rb = vRB(i); - int ic = GETARG_Cr(i); + int ic = GETARG_sC(i); lua_Number nb; if (tonumberns(rb, nb)) { lua_Number nc = cast_num(ic); @@ -1063,7 +1063,7 @@ void luaV_execute (lua_State *L) { } vmcase(OP_DIVI) { TValue *rb = vRB(i); - int ic = GETARG_Cr(i); + int ic = GETARG_sC(i); lua_Number nb; if (tonumberns(rb, nb)) { lua_Number nc = cast_num(ic); @@ -1075,7 +1075,7 @@ void luaV_execute (lua_State *L) { } vmcase(OP_IDIVI) { TValue *rb = vRB(i); - int ic = GETARG_Cr(i); + int ic = GETARG_sC(i); lua_Number nb; if (ttisinteger(rb)) { setivalue(s2v(ra), luaV_div(L, ivalue(rb), ic));