mirror of https://github.com/rusefi/lua.git
Avoid computing invalid addresses
luaV_execute should compute 'ra' only when the instruction uses it. Computing an illegal address is undefined behavior even if the address is never dereferenced.
This commit is contained in:
parent
1f3c6f4534
commit
8426d9b4d4
69
lvm.c
69
lvm.c
|
@ -898,6 +898,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** operation, 'fop' is the float operation.
|
** operation, 'fop' is the float operation.
|
||||||
*/
|
*/
|
||||||
#define op_arithI(L,iop,fop) { \
|
#define op_arithI(L,iop,fop) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
TValue *v1 = vRB(i); \
|
TValue *v1 = vRB(i); \
|
||||||
int imm = GETARG_sC(i); \
|
int imm = GETARG_sC(i); \
|
||||||
if (ttisinteger(v1)) { \
|
if (ttisinteger(v1)) { \
|
||||||
|
@ -926,6 +927,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** Arithmetic operations over floats and others with register operands.
|
** Arithmetic operations over floats and others with register operands.
|
||||||
*/
|
*/
|
||||||
#define op_arithf(L,fop) { \
|
#define op_arithf(L,fop) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
TValue *v1 = vRB(i); \
|
TValue *v1 = vRB(i); \
|
||||||
TValue *v2 = vRC(i); \
|
TValue *v2 = vRC(i); \
|
||||||
op_arithf_aux(L, v1, v2, fop); }
|
op_arithf_aux(L, v1, v2, fop); }
|
||||||
|
@ -935,6 +937,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** Arithmetic operations with K operands for floats.
|
** Arithmetic operations with K operands for floats.
|
||||||
*/
|
*/
|
||||||
#define op_arithfK(L,fop) { \
|
#define op_arithfK(L,fop) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
TValue *v1 = vRB(i); \
|
TValue *v1 = vRB(i); \
|
||||||
TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \
|
TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \
|
||||||
op_arithf_aux(L, v1, v2, fop); }
|
op_arithf_aux(L, v1, v2, fop); }
|
||||||
|
@ -944,6 +947,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** Arithmetic operations over integers and floats.
|
** Arithmetic operations over integers and floats.
|
||||||
*/
|
*/
|
||||||
#define op_arith_aux(L,v1,v2,iop,fop) { \
|
#define op_arith_aux(L,v1,v2,iop,fop) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
if (ttisinteger(v1) && ttisinteger(v2)) { \
|
if (ttisinteger(v1) && ttisinteger(v2)) { \
|
||||||
lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \
|
lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \
|
||||||
pc++; setivalue(s2v(ra), iop(L, i1, i2)); \
|
pc++; setivalue(s2v(ra), iop(L, i1, i2)); \
|
||||||
|
@ -973,6 +977,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** Bitwise operations with constant operand.
|
** Bitwise operations with constant operand.
|
||||||
*/
|
*/
|
||||||
#define op_bitwiseK(L,op) { \
|
#define op_bitwiseK(L,op) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
TValue *v1 = vRB(i); \
|
TValue *v1 = vRB(i); \
|
||||||
TValue *v2 = KC(i); \
|
TValue *v2 = KC(i); \
|
||||||
lua_Integer i1; \
|
lua_Integer i1; \
|
||||||
|
@ -986,6 +991,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** Bitwise operations with register operands.
|
** Bitwise operations with register operands.
|
||||||
*/
|
*/
|
||||||
#define op_bitwise(L,op) { \
|
#define op_bitwise(L,op) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
TValue *v1 = vRB(i); \
|
TValue *v1 = vRB(i); \
|
||||||
TValue *v2 = vRC(i); \
|
TValue *v2 = vRC(i); \
|
||||||
lua_Integer i1; lua_Integer i2; \
|
lua_Integer i1; lua_Integer i2; \
|
||||||
|
@ -1000,6 +1006,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** integers.
|
** integers.
|
||||||
*/
|
*/
|
||||||
#define op_order(L,opi,opn,other) { \
|
#define op_order(L,opi,opn,other) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
int cond; \
|
int cond; \
|
||||||
TValue *rb = vRB(i); \
|
TValue *rb = vRB(i); \
|
||||||
if (ttisinteger(s2v(ra)) && ttisinteger(rb)) { \
|
if (ttisinteger(s2v(ra)) && ttisinteger(rb)) { \
|
||||||
|
@ -1019,6 +1026,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** always small enough to have an exact representation as a float.)
|
** always small enough to have an exact representation as a float.)
|
||||||
*/
|
*/
|
||||||
#define op_orderI(L,opi,opf,inv,tm) { \
|
#define op_orderI(L,opi,opf,inv,tm) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
int cond; \
|
int cond; \
|
||||||
int im = GETARG_sB(i); \
|
int im = GETARG_sB(i); \
|
||||||
if (ttisinteger(s2v(ra))) \
|
if (ttisinteger(s2v(ra))) \
|
||||||
|
@ -1128,7 +1136,6 @@ void luaV_finishOp (lua_State *L) {
|
||||||
updatebase(ci); /* correct stack */ \
|
updatebase(ci); /* correct stack */ \
|
||||||
} \
|
} \
|
||||||
i = *(pc++); \
|
i = *(pc++); \
|
||||||
ra = RA(i); /* WARNING: any stack reallocation invalidates 'ra' */ \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define vmdispatch(o) switch(o)
|
#define vmdispatch(o) switch(o)
|
||||||
|
@ -1164,7 +1171,6 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
/* main loop of interpreter */
|
/* main loop of interpreter */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Instruction i; /* instruction being executed */
|
Instruction i; /* instruction being executed */
|
||||||
StkId ra; /* instruction's A register */
|
|
||||||
vmfetch();
|
vmfetch();
|
||||||
#if 0
|
#if 0
|
||||||
/* low-level line tracing for debugging Lua */
|
/* low-level line tracing for debugging Lua */
|
||||||
|
@ -1176,44 +1182,53 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
lua_assert(isIT(i) || (cast_void(L->top = base), 1));
|
lua_assert(isIT(i) || (cast_void(L->top = base), 1));
|
||||||
vmdispatch (GET_OPCODE(i)) {
|
vmdispatch (GET_OPCODE(i)) {
|
||||||
vmcase(OP_MOVE) {
|
vmcase(OP_MOVE) {
|
||||||
|
StkId ra = RA(i);
|
||||||
setobjs2s(L, ra, RB(i));
|
setobjs2s(L, ra, RB(i));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LOADI) {
|
vmcase(OP_LOADI) {
|
||||||
|
StkId ra = RA(i);
|
||||||
lua_Integer b = GETARG_sBx(i);
|
lua_Integer b = GETARG_sBx(i);
|
||||||
setivalue(s2v(ra), b);
|
setivalue(s2v(ra), b);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LOADF) {
|
vmcase(OP_LOADF) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int b = GETARG_sBx(i);
|
int b = GETARG_sBx(i);
|
||||||
setfltvalue(s2v(ra), cast_num(b));
|
setfltvalue(s2v(ra), cast_num(b));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LOADK) {
|
vmcase(OP_LOADK) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = k + GETARG_Bx(i);
|
TValue *rb = k + GETARG_Bx(i);
|
||||||
setobj2s(L, ra, rb);
|
setobj2s(L, ra, rb);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LOADKX) {
|
vmcase(OP_LOADKX) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb;
|
TValue *rb;
|
||||||
rb = k + GETARG_Ax(*pc); pc++;
|
rb = k + GETARG_Ax(*pc); pc++;
|
||||||
setobj2s(L, ra, rb);
|
setobj2s(L, ra, rb);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LOADFALSE) {
|
vmcase(OP_LOADFALSE) {
|
||||||
|
StkId ra = RA(i);
|
||||||
setbfvalue(s2v(ra));
|
setbfvalue(s2v(ra));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LFALSESKIP) {
|
vmcase(OP_LFALSESKIP) {
|
||||||
|
StkId ra = RA(i);
|
||||||
setbfvalue(s2v(ra));
|
setbfvalue(s2v(ra));
|
||||||
pc++; /* skip next instruction */
|
pc++; /* skip next instruction */
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LOADTRUE) {
|
vmcase(OP_LOADTRUE) {
|
||||||
|
StkId ra = RA(i);
|
||||||
setbtvalue(s2v(ra));
|
setbtvalue(s2v(ra));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LOADNIL) {
|
vmcase(OP_LOADNIL) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
do {
|
do {
|
||||||
setnilvalue(s2v(ra++));
|
setnilvalue(s2v(ra++));
|
||||||
|
@ -1221,17 +1236,20 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_GETUPVAL) {
|
vmcase(OP_GETUPVAL) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
setobj2s(L, ra, cl->upvals[b]->v);
|
setobj2s(L, ra, cl->upvals[b]->v);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_SETUPVAL) {
|
vmcase(OP_SETUPVAL) {
|
||||||
|
StkId ra = RA(i);
|
||||||
UpVal *uv = cl->upvals[GETARG_B(i)];
|
UpVal *uv = cl->upvals[GETARG_B(i)];
|
||||||
setobj(L, uv->v, s2v(ra));
|
setobj(L, uv->v, s2v(ra));
|
||||||
luaC_barrier(L, uv, s2v(ra));
|
luaC_barrier(L, uv, s2v(ra));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_GETTABUP) {
|
vmcase(OP_GETTABUP) {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *upval = cl->upvals[GETARG_B(i)]->v;
|
TValue *upval = cl->upvals[GETARG_B(i)]->v;
|
||||||
TValue *rc = KC(i);
|
TValue *rc = KC(i);
|
||||||
|
@ -1244,6 +1262,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_GETTABLE) {
|
vmcase(OP_GETTABLE) {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
TValue *rc = vRC(i);
|
TValue *rc = vRC(i);
|
||||||
|
@ -1258,6 +1277,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_GETI) {
|
vmcase(OP_GETI) {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
int c = GETARG_C(i);
|
int c = GETARG_C(i);
|
||||||
|
@ -1272,6 +1292,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_GETFIELD) {
|
vmcase(OP_GETFIELD) {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
TValue *rc = KC(i);
|
TValue *rc = KC(i);
|
||||||
|
@ -1297,6 +1318,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_SETTABLE) {
|
vmcase(OP_SETTABLE) {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *rb = vRB(i); /* key (table is in 'ra') */
|
TValue *rb = vRB(i); /* key (table is in 'ra') */
|
||||||
TValue *rc = RKC(i); /* value */
|
TValue *rc = RKC(i); /* value */
|
||||||
|
@ -1311,6 +1333,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_SETI) {
|
vmcase(OP_SETI) {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
int c = GETARG_B(i);
|
int c = GETARG_B(i);
|
||||||
TValue *rc = RKC(i);
|
TValue *rc = RKC(i);
|
||||||
|
@ -1325,6 +1348,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_SETFIELD) {
|
vmcase(OP_SETFIELD) {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *rb = KB(i);
|
TValue *rb = KB(i);
|
||||||
TValue *rc = RKC(i);
|
TValue *rc = RKC(i);
|
||||||
|
@ -1337,6 +1361,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_NEWTABLE) {
|
vmcase(OP_NEWTABLE) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int b = GETARG_B(i); /* log2(hash size) + 1 */
|
int b = GETARG_B(i); /* log2(hash size) + 1 */
|
||||||
int c = GETARG_C(i); /* array size */
|
int c = GETARG_C(i); /* array size */
|
||||||
Table *t;
|
Table *t;
|
||||||
|
@ -1355,6 +1380,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_SELF) {
|
vmcase(OP_SELF) {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
TValue *rc = RKC(i);
|
TValue *rc = RKC(i);
|
||||||
|
@ -1412,6 +1438,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_SHRI) {
|
vmcase(OP_SHRI) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
int ic = GETARG_sC(i);
|
int ic = GETARG_sC(i);
|
||||||
lua_Integer ib;
|
lua_Integer ib;
|
||||||
|
@ -1421,6 +1448,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_SHLI) {
|
vmcase(OP_SHLI) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
int ic = GETARG_sC(i);
|
int ic = GETARG_sC(i);
|
||||||
lua_Integer ib;
|
lua_Integer ib;
|
||||||
|
@ -1478,6 +1506,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_MMBIN) {
|
vmcase(OP_MMBIN) {
|
||||||
|
StkId ra = RA(i);
|
||||||
Instruction pi = *(pc - 2); /* original arith. expression */
|
Instruction pi = *(pc - 2); /* original arith. expression */
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
TMS tm = (TMS)GETARG_C(i);
|
TMS tm = (TMS)GETARG_C(i);
|
||||||
|
@ -1487,6 +1516,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_MMBINI) {
|
vmcase(OP_MMBINI) {
|
||||||
|
StkId ra = RA(i);
|
||||||
Instruction pi = *(pc - 2); /* original arith. expression */
|
Instruction pi = *(pc - 2); /* original arith. expression */
|
||||||
int imm = GETARG_sB(i);
|
int imm = GETARG_sB(i);
|
||||||
TMS tm = (TMS)GETARG_C(i);
|
TMS tm = (TMS)GETARG_C(i);
|
||||||
|
@ -1496,6 +1526,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_MMBINK) {
|
vmcase(OP_MMBINK) {
|
||||||
|
StkId ra = RA(i);
|
||||||
Instruction pi = *(pc - 2); /* original arith. expression */
|
Instruction pi = *(pc - 2); /* original arith. expression */
|
||||||
TValue *imm = KB(i);
|
TValue *imm = KB(i);
|
||||||
TMS tm = (TMS)GETARG_C(i);
|
TMS tm = (TMS)GETARG_C(i);
|
||||||
|
@ -1505,6 +1536,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_UNM) {
|
vmcase(OP_UNM) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
lua_Number nb;
|
lua_Number nb;
|
||||||
if (ttisinteger(rb)) {
|
if (ttisinteger(rb)) {
|
||||||
|
@ -1519,6 +1551,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_BNOT) {
|
vmcase(OP_BNOT) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
lua_Integer ib;
|
lua_Integer ib;
|
||||||
if (tointegerns(rb, &ib)) {
|
if (tointegerns(rb, &ib)) {
|
||||||
|
@ -1529,6 +1562,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_NOT) {
|
vmcase(OP_NOT) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
if (l_isfalse(rb))
|
if (l_isfalse(rb))
|
||||||
setbtvalue(s2v(ra));
|
setbtvalue(s2v(ra));
|
||||||
|
@ -1537,10 +1571,12 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LEN) {
|
vmcase(OP_LEN) {
|
||||||
|
StkId ra = RA(i);
|
||||||
Protect(luaV_objlen(L, ra, vRB(i)));
|
Protect(luaV_objlen(L, ra, vRB(i)));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_CONCAT) {
|
vmcase(OP_CONCAT) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int n = GETARG_B(i); /* number of elements to concatenate */
|
int n = GETARG_B(i); /* number of elements to concatenate */
|
||||||
L->top = ra + n; /* mark the end of concat operands */
|
L->top = ra + n; /* mark the end of concat operands */
|
||||||
ProtectNT(luaV_concat(L, n));
|
ProtectNT(luaV_concat(L, n));
|
||||||
|
@ -1548,10 +1584,12 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_CLOSE) {
|
vmcase(OP_CLOSE) {
|
||||||
|
StkId ra = RA(i);
|
||||||
Protect(luaF_close(L, ra, LUA_OK, 1));
|
Protect(luaF_close(L, ra, LUA_OK, 1));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_TBC) {
|
vmcase(OP_TBC) {
|
||||||
|
StkId ra = RA(i);
|
||||||
/* create new to-be-closed upvalue */
|
/* create new to-be-closed upvalue */
|
||||||
halfProtect(luaF_newtbcupval(L, ra));
|
halfProtect(luaF_newtbcupval(L, ra));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
|
@ -1561,6 +1599,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_EQ) {
|
vmcase(OP_EQ) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int cond;
|
int cond;
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
Protect(cond = luaV_equalobj(L, s2v(ra), rb));
|
Protect(cond = luaV_equalobj(L, s2v(ra), rb));
|
||||||
|
@ -1576,6 +1615,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_EQK) {
|
vmcase(OP_EQK) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = KB(i);
|
TValue *rb = KB(i);
|
||||||
/* basic types do not use '__eq'; we can use raw equality */
|
/* basic types do not use '__eq'; we can use raw equality */
|
||||||
int cond = luaV_rawequalobj(s2v(ra), rb);
|
int cond = luaV_rawequalobj(s2v(ra), rb);
|
||||||
|
@ -1583,6 +1623,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_EQI) {
|
vmcase(OP_EQI) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int cond;
|
int cond;
|
||||||
int im = GETARG_sB(i);
|
int im = GETARG_sB(i);
|
||||||
if (ttisinteger(s2v(ra)))
|
if (ttisinteger(s2v(ra)))
|
||||||
|
@ -1611,11 +1652,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_TEST) {
|
vmcase(OP_TEST) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int cond = !l_isfalse(s2v(ra));
|
int cond = !l_isfalse(s2v(ra));
|
||||||
docondjump();
|
docondjump();
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_TESTSET) {
|
vmcase(OP_TESTSET) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
if (l_isfalse(rb) == GETARG_k(i))
|
if (l_isfalse(rb) == GETARG_k(i))
|
||||||
pc++;
|
pc++;
|
||||||
|
@ -1626,6 +1669,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_CALL) {
|
vmcase(OP_CALL) {
|
||||||
|
StkId ra = RA(i);
|
||||||
CallInfo *newci;
|
CallInfo *newci;
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
int nresults = GETARG_C(i) - 1;
|
int nresults = GETARG_C(i) - 1;
|
||||||
|
@ -1642,6 +1686,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_TAILCALL) {
|
vmcase(OP_TAILCALL) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int b = GETARG_B(i); /* number of arguments + 1 (function) */
|
int b = GETARG_B(i); /* number of arguments + 1 (function) */
|
||||||
int n; /* number of results when calling a C function */
|
int n; /* number of results when calling a C function */
|
||||||
int nparams1 = GETARG_C(i);
|
int nparams1 = GETARG_C(i);
|
||||||
|
@ -1667,6 +1712,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vmcase(OP_RETURN) {
|
vmcase(OP_RETURN) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int n = GETARG_B(i) - 1; /* number of results */
|
int n = GETARG_B(i) - 1; /* number of results */
|
||||||
int nparams1 = GETARG_C(i);
|
int nparams1 = GETARG_C(i);
|
||||||
if (n < 0) /* not fixed? */
|
if (n < 0) /* not fixed? */
|
||||||
|
@ -1689,6 +1735,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
}
|
}
|
||||||
vmcase(OP_RETURN0) {
|
vmcase(OP_RETURN0) {
|
||||||
if (l_unlikely(L->hookmask)) {
|
if (l_unlikely(L->hookmask)) {
|
||||||
|
StkId ra = RA(i);
|
||||||
L->top = ra;
|
L->top = ra;
|
||||||
savepc(ci);
|
savepc(ci);
|
||||||
luaD_poscall(L, ci, 0); /* no hurry... */
|
luaD_poscall(L, ci, 0); /* no hurry... */
|
||||||
|
@ -1705,6 +1752,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
}
|
}
|
||||||
vmcase(OP_RETURN1) {
|
vmcase(OP_RETURN1) {
|
||||||
if (l_unlikely(L->hookmask)) {
|
if (l_unlikely(L->hookmask)) {
|
||||||
|
StkId ra = RA(i);
|
||||||
L->top = ra + 1;
|
L->top = ra + 1;
|
||||||
savepc(ci);
|
savepc(ci);
|
||||||
luaD_poscall(L, ci, 1); /* no hurry... */
|
luaD_poscall(L, ci, 1); /* no hurry... */
|
||||||
|
@ -1716,6 +1764,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
if (nres == 0)
|
if (nres == 0)
|
||||||
L->top = base - 1; /* asked for no results */
|
L->top = base - 1; /* asked for no results */
|
||||||
else {
|
else {
|
||||||
|
StkId ra = RA(i);
|
||||||
setobjs2s(L, base - 1, ra); /* at least this result */
|
setobjs2s(L, base - 1, ra); /* at least this result */
|
||||||
L->top = base;
|
L->top = base;
|
||||||
for (; l_unlikely(nres > 1); nres--)
|
for (; l_unlikely(nres > 1); nres--)
|
||||||
|
@ -1731,6 +1780,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vmcase(OP_FORLOOP) {
|
vmcase(OP_FORLOOP) {
|
||||||
|
StkId ra = RA(i);
|
||||||
if (ttisinteger(s2v(ra + 2))) { /* integer loop? */
|
if (ttisinteger(s2v(ra + 2))) { /* integer loop? */
|
||||||
lua_Unsigned count = l_castS2U(ivalue(s2v(ra + 1)));
|
lua_Unsigned count = l_castS2U(ivalue(s2v(ra + 1)));
|
||||||
if (count > 0) { /* still more iterations? */
|
if (count > 0) { /* still more iterations? */
|
||||||
|
@ -1749,12 +1799,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_FORPREP) {
|
vmcase(OP_FORPREP) {
|
||||||
|
StkId ra = RA(i);
|
||||||
savestate(L, ci); /* in case of errors */
|
savestate(L, ci); /* in case of errors */
|
||||||
if (forprep(L, ra))
|
if (forprep(L, ra))
|
||||||
pc += GETARG_Bx(i) + 1; /* skip the loop */
|
pc += GETARG_Bx(i) + 1; /* skip the loop */
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_TFORPREP) {
|
vmcase(OP_TFORPREP) {
|
||||||
|
StkId ra = RA(i);
|
||||||
/* create to-be-closed upvalue (if needed) */
|
/* create to-be-closed upvalue (if needed) */
|
||||||
halfProtect(luaF_newtbcupval(L, ra + 3));
|
halfProtect(luaF_newtbcupval(L, ra + 3));
|
||||||
pc += GETARG_Bx(i);
|
pc += GETARG_Bx(i);
|
||||||
|
@ -1763,7 +1815,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
goto l_tforcall;
|
goto l_tforcall;
|
||||||
}
|
}
|
||||||
vmcase(OP_TFORCALL) {
|
vmcase(OP_TFORCALL) {
|
||||||
l_tforcall:
|
l_tforcall: {
|
||||||
|
StkId ra = RA(i);
|
||||||
/* 'ra' has the iterator function, 'ra + 1' has the state,
|
/* 'ra' has the iterator function, 'ra + 1' has the state,
|
||||||
'ra + 2' has the control variable, and 'ra + 3' has the
|
'ra + 2' has the control variable, and 'ra + 3' has the
|
||||||
to-be-closed variable. The call will use the stack after
|
to-be-closed variable. The call will use the stack after
|
||||||
|
@ -1777,16 +1830,18 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
i = *(pc++); /* go to next instruction */
|
i = *(pc++); /* go to next instruction */
|
||||||
lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i));
|
lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i));
|
||||||
goto l_tforloop;
|
goto l_tforloop;
|
||||||
}
|
}}
|
||||||
vmcase(OP_TFORLOOP) {
|
vmcase(OP_TFORLOOP) {
|
||||||
l_tforloop:
|
l_tforloop: {
|
||||||
|
StkId ra = RA(i);
|
||||||
if (!ttisnil(s2v(ra + 4))) { /* continue loop? */
|
if (!ttisnil(s2v(ra + 4))) { /* continue loop? */
|
||||||
setobjs2s(L, ra + 2, ra + 4); /* save control variable */
|
setobjs2s(L, ra + 2, ra + 4); /* save control variable */
|
||||||
pc -= GETARG_Bx(i); /* jump back */
|
pc -= GETARG_Bx(i); /* jump back */
|
||||||
}
|
}
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}}
|
||||||
vmcase(OP_SETLIST) {
|
vmcase(OP_SETLIST) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int n = GETARG_B(i);
|
int n = GETARG_B(i);
|
||||||
unsigned int last = GETARG_C(i);
|
unsigned int last = GETARG_C(i);
|
||||||
Table *h = hvalue(s2v(ra));
|
Table *h = hvalue(s2v(ra));
|
||||||
|
@ -1810,12 +1865,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_CLOSURE) {
|
vmcase(OP_CLOSURE) {
|
||||||
|
StkId ra = RA(i);
|
||||||
Proto *p = cl->p->p[GETARG_Bx(i)];
|
Proto *p = cl->p->p[GETARG_Bx(i)];
|
||||||
halfProtect(pushclosure(L, p, cl->upvals, base, ra));
|
halfProtect(pushclosure(L, p, cl->upvals, base, ra));
|
||||||
checkGC(L, ra + 1);
|
checkGC(L, ra + 1);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_VARARG) {
|
vmcase(OP_VARARG) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int n = GETARG_C(i) - 1; /* required results */
|
int n = GETARG_C(i) - 1; /* required results */
|
||||||
Protect(luaT_getvarargs(L, ci, ra, n));
|
Protect(luaT_getvarargs(L, ci, ra, n));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
|
|
Loading…
Reference in New Issue