mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-28 00:02:28 +00:00
Bring Lua to 5.4.6. (#1214)
This essentially re-does the work of #875 on top of master. This is what I did to check that Cosmo's Lua extensions still worked: ``` $ build/bootstrap/make MODE=aarch64 o/aarch64/third_party/lua/lua $ ape o/aarch64/third_party/lua/lua >: 10 10 >: 010 8 >: 0b10 2 >: string.byte("\e") 27 >: "Hello, %s" % {"world"} Hello, world >: "*" * 3 *** ``` `luaL_traceback2` was used to show the stack trace with parameter values; it's used in `LuaCallWithTrace`, which is used in Redbean to run Lua code. You should be able to see the extended stack trace by running something like this: `redbean -e "function a(b)c()end a(2)"` (with "params" indicating the extended stack trace): ``` stack traceback: [string "function a(b)c()end a(2)"]:1: in function 'a', params: b = 2; [string "function a(b)c()end a(2)"]:1: in main chunk ``` @pkulchenko confirmed that I get the expected result with the updated code. This is what I did to check that Lua itself still worked: ``` $ cd third_party/lua/test/ $ ape ../../../o/aarch64/third_party/lua/lua all.lua ``` There's one test failure, in `files.lua`: ``` ***** FILE 'files.lua'***** testing i/o ../../../o/aarch64/third_party/lua/lua: files.lua:84: assertion failed! stack traceback: [C]: in function 'assert' files.lua:84: in main chunk (...tail calls...) all.lua:195: in main chunk [C]: in ? .>>> closing state <<< ``` That isn't a result of these changes; the same test is failing in master. The failure is here: ```lua if not _port then -- invalid seek local status, msg, code = io.stdin:seek("set", 1000) assert(not status and type(msg) == "string" and type(code) == "number") end ``` The test expects a seek to offset 1,000 on stdin to fail — but it doesn't. `status` ends up being the new offset rather than `nil`. If I comment out that one test, the remaining tests succeed.
This commit is contained in:
parent
3a599bfbe1
commit
0dbf01bf1d
90 changed files with 2741 additions and 1376 deletions
234
third_party/lua/lvm.c
vendored
234
third_party/lua/lvm.c
vendored
|
@ -3,7 +3,7 @@
|
|||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Lua │
|
||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
||||
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
|
@ -27,6 +27,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#define lvm_c
|
||||
#define LUA_CORE
|
||||
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/lua/ldebug.h"
|
||||
#include "third_party/lua/ldo.h"
|
||||
|
@ -419,7 +420,7 @@ static int l_strcmp (const TString *ls, const TString *rs) {
|
|||
** from float to int.)
|
||||
** When 'f' is NaN, comparisons must result in false.
|
||||
*/
|
||||
static int LTintfloat (lua_Integer i, lua_Number f) {
|
||||
l_sinline int LTintfloat (lua_Integer i, lua_Number f) {
|
||||
if (l_intfitsf(i))
|
||||
return luai_numlt(cast_num(i), f); /* compare them as floats */
|
||||
else { /* i < f <=> i < ceil(f) */
|
||||
|
@ -436,7 +437,7 @@ static int LTintfloat (lua_Integer i, lua_Number f) {
|
|||
** Check whether integer 'i' is less than or equal to float 'f'.
|
||||
** See comments on previous function.
|
||||
*/
|
||||
static int LEintfloat (lua_Integer i, lua_Number f) {
|
||||
l_sinline int LEintfloat (lua_Integer i, lua_Number f) {
|
||||
if (l_intfitsf(i))
|
||||
return luai_numle(cast_num(i), f); /* compare them as floats */
|
||||
else { /* i <= f <=> i <= floor(f) */
|
||||
|
@ -453,7 +454,7 @@ static int LEintfloat (lua_Integer i, lua_Number f) {
|
|||
** Check whether float 'f' is less than integer 'i'.
|
||||
** See comments on previous function.
|
||||
*/
|
||||
static int LTfloatint (lua_Number f, lua_Integer i) {
|
||||
l_sinline int LTfloatint (lua_Number f, lua_Integer i) {
|
||||
if (l_intfitsf(i))
|
||||
return luai_numlt(f, cast_num(i)); /* compare them as floats */
|
||||
else { /* f < i <=> floor(f) < i */
|
||||
|
@ -470,7 +471,7 @@ static int LTfloatint (lua_Number f, lua_Integer i) {
|
|||
** Check whether float 'f' is less than or equal to integer 'i'.
|
||||
** See comments on previous function.
|
||||
*/
|
||||
static int LEfloatint (lua_Number f, lua_Integer i) {
|
||||
l_sinline int LEfloatint (lua_Number f, lua_Integer i) {
|
||||
if (l_intfitsf(i))
|
||||
return luai_numle(f, cast_num(i)); /* compare them as floats */
|
||||
else { /* f <= i <=> ceil(f) <= i */
|
||||
|
@ -486,7 +487,7 @@ static int LEfloatint (lua_Number f, lua_Integer i) {
|
|||
/*
|
||||
** Return 'l < r', for numbers.
|
||||
*/
|
||||
static int LTnum (const TValue *l, const TValue *r) {
|
||||
l_sinline int LTnum (const TValue *l, const TValue *r) {
|
||||
lua_assert(ttisnumber(l) && ttisnumber(r));
|
||||
if (ttisinteger(l)) {
|
||||
lua_Integer li = ivalue(l);
|
||||
|
@ -508,7 +509,7 @@ static int LTnum (const TValue *l, const TValue *r) {
|
|||
/*
|
||||
** Return 'l <= r', for numbers.
|
||||
*/
|
||||
static int LEnum (const TValue *l, const TValue *r) {
|
||||
l_sinline int LEnum (const TValue *l, const TValue *r) {
|
||||
lua_assert(ttisnumber(l) && ttisnumber(r));
|
||||
if (ttisinteger(l)) {
|
||||
lua_Integer li = ivalue(l);
|
||||
|
@ -621,8 +622,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
|
|||
if (tm == NULL) /* no TM? */
|
||||
return 0; /* objects are different */
|
||||
else {
|
||||
luaT_callTMres(L, tm, t1, t2, L->top); /* call TM */
|
||||
return !l_isfalse(s2v(L->top));
|
||||
luaT_callTMres(L, tm, t1, t2, L->top.p); /* call TM */
|
||||
return !l_isfalse(s2v(L->top.p));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -646,17 +647,17 @@ static void copy2buff (StkId top, int n, char *buff) {
|
|||
|
||||
/*
|
||||
** Main operation for concatenation: concat 'total' values in the stack,
|
||||
** from 'L->top - total' up to 'L->top - 1'.
|
||||
** from 'L->top.p - total' up to 'L->top.p - 1'.
|
||||
*/
|
||||
void luaV_concat (lua_State *L, int total) {
|
||||
if (total == 1)
|
||||
return; /* "all" values already concatenated */
|
||||
do {
|
||||
StkId top = L->top;
|
||||
StkId top = L->top.p;
|
||||
int n = 2; /* number of elements handled in this pass (at least 2) */
|
||||
if (!(ttisstring(s2v(top - 2)) || cvt2str(s2v(top - 2))) ||
|
||||
!tostring(L, s2v(top - 1)))
|
||||
luaT_tryconcatTM(L);
|
||||
luaT_tryconcatTM(L); /* may invalidate 'top' */
|
||||
else if (isemptystr(s2v(top - 1))) /* second operand is empty? */
|
||||
cast_void(tostring(L, s2v(top - 2))); /* result is first operand */
|
||||
else if (isemptystr(s2v(top - 2))) { /* first operand is empty string? */
|
||||
|
@ -669,8 +670,10 @@ void luaV_concat (lua_State *L, int total) {
|
|||
/* collect total length and number of strings */
|
||||
for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) {
|
||||
size_t l = vslen(s2v(top - n - 1));
|
||||
if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl))
|
||||
if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) {
|
||||
L->top.p = top - total; /* pop strings to avoid wasting stack */
|
||||
luaG_runerror(L, "string length overflow");
|
||||
}
|
||||
tl += l;
|
||||
}
|
||||
if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */
|
||||
|
@ -684,8 +687,8 @@ void luaV_concat (lua_State *L, int total) {
|
|||
}
|
||||
setsvalue2s(L, top - n, ts); /* create result */
|
||||
}
|
||||
total -= n-1; /* got 'n' strings to create 1 new */
|
||||
L->top -= n-1; /* popped 'n' strings and pushed one */
|
||||
total -= n - 1; /* got 'n' strings to create one new */
|
||||
L->top.p -= n - 1; /* popped 'n' strings and pushed one */
|
||||
} while (total > 1); /* repeat until only 1 result left */
|
||||
}
|
||||
|
||||
|
@ -776,11 +779,10 @@ lua_Number luaV_modf (lua_State *L, lua_Number m, lua_Number n) {
|
|||
/* number of bits in an integer */
|
||||
#define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT)
|
||||
|
||||
|
||||
/*
|
||||
** Shift left operation. (Shift right just negates 'y'.)
|
||||
*/
|
||||
#define luaV_shiftr(x,y) luaV_shiftl(x,-(y))
|
||||
|
||||
lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) {
|
||||
if (y < 0) { /* shift right? */
|
||||
if (y <= -NBITS) return 0;
|
||||
|
@ -820,26 +822,26 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
|
|||
*/
|
||||
void luaV_finishOp (lua_State *L) {
|
||||
CallInfo *ci = L->ci;
|
||||
StkId base = ci->func + 1;
|
||||
StkId base = ci->func.p + 1;
|
||||
Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */
|
||||
OpCode op = GET_OPCODE(inst);
|
||||
switch (op) { /* finish its execution */
|
||||
case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: {
|
||||
setobjs2s(L, base + GETARG_A(*(ci->u.l.savedpc - 2)), --L->top);
|
||||
setobjs2s(L, base + GETARG_A(*(ci->u.l.savedpc - 2)), --L->top.p);
|
||||
break;
|
||||
}
|
||||
case OP_UNM: case OP_BNOT: case OP_LEN:
|
||||
case OP_GETTABUP: case OP_GETTABLE: case OP_GETI:
|
||||
case OP_GETFIELD: case OP_SELF: {
|
||||
setobjs2s(L, base + GETARG_A(inst), --L->top);
|
||||
setobjs2s(L, base + GETARG_A(inst), --L->top.p);
|
||||
break;
|
||||
}
|
||||
case OP_LT: case OP_LE:
|
||||
case OP_LTI: case OP_LEI:
|
||||
case OP_GTI: case OP_GEI:
|
||||
case OP_EQ: { /* note that 'OP_EQI'/'OP_EQK' cannot yield */
|
||||
int res = !l_isfalse(s2v(L->top - 1));
|
||||
L->top--;
|
||||
int res = !l_isfalse(s2v(L->top.p - 1));
|
||||
L->top.p--;
|
||||
#if defined(LUA_COMPAT_LT_LE)
|
||||
if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */
|
||||
ci->callstatus ^= CIST_LEQ; /* clear mark */
|
||||
|
@ -852,18 +854,27 @@ void luaV_finishOp (lua_State *L) {
|
|||
break;
|
||||
}
|
||||
case OP_CONCAT: {
|
||||
StkId top = L->top - 1; /* top when 'luaT_tryconcatTM' was called */
|
||||
StkId top = L->top.p - 1; /* top when 'luaT_tryconcatTM' was called */
|
||||
int a = GETARG_A(inst); /* first element to concatenate */
|
||||
int total = cast_int(top - 1 - (base + a)); /* yet to concatenate */
|
||||
setobjs2s(L, top - 2, top); /* put TM result in proper position */
|
||||
L->top = top - 1; /* top is one after last element (at top-2) */
|
||||
L->top.p = top - 1; /* top is one after last element (at top-2) */
|
||||
luaV_concat(L, total); /* concat them (may yield again) */
|
||||
break;
|
||||
}
|
||||
case OP_CLOSE: case OP_RETURN: { /* yielded closing variables */
|
||||
case OP_CLOSE: { /* yielded closing variables */
|
||||
ci->u.l.savedpc--; /* repeat instruction to close other vars. */
|
||||
break;
|
||||
}
|
||||
case OP_RETURN: { /* yielded closing variables */
|
||||
StkId ra = base + GETARG_A(inst);
|
||||
/* adjust top to signal correct number of returns, in case the
|
||||
return is "up to top" ('isIT') */
|
||||
L->top.p = ra + ci->u2.nres;
|
||||
/* repeat instruction to close other vars. and complete the return */
|
||||
ci->u.l.savedpc--;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
/* only these other opcodes can yield */
|
||||
lua_assert(op == OP_TFORCALL || op == OP_CALL ||
|
||||
|
@ -901,6 +912,7 @@ void luaV_finishOp (lua_State *L) {
|
|||
** operation, 'fop' is the float operation.
|
||||
*/
|
||||
#define op_arithI(L,iop,fop) { \
|
||||
StkId ra = RA(i); \
|
||||
TValue *v1 = vRB(i); \
|
||||
int imm = GETARG_sC(i); \
|
||||
if (ttisinteger(v1)) { \
|
||||
|
@ -929,6 +941,7 @@ void luaV_finishOp (lua_State *L) {
|
|||
** Arithmetic operations over floats and others with register operands.
|
||||
*/
|
||||
#define op_arithf(L,fop) { \
|
||||
StkId ra = RA(i); \
|
||||
TValue *v1 = vRB(i); \
|
||||
TValue *v2 = vRC(i); \
|
||||
op_arithf_aux(L, v1, v2, fop); }
|
||||
|
@ -938,6 +951,7 @@ void luaV_finishOp (lua_State *L) {
|
|||
** Arithmetic operations with K operands for floats.
|
||||
*/
|
||||
#define op_arithfK(L,fop) { \
|
||||
StkId ra = RA(i); \
|
||||
TValue *v1 = vRB(i); \
|
||||
TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \
|
||||
op_arithf_aux(L, v1, v2, fop); }
|
||||
|
@ -947,6 +961,7 @@ void luaV_finishOp (lua_State *L) {
|
|||
** Arithmetic operations over integers and floats.
|
||||
*/
|
||||
#define op_arith_aux(L,v1,v2,iop,fop) { \
|
||||
StkId ra = RA(i); \
|
||||
if (ttisinteger(v1) && ttisinteger(v2)) { \
|
||||
lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \
|
||||
pc++; setivalue(s2v(ra), iop(L, i1, i2)); \
|
||||
|
@ -976,6 +991,7 @@ void luaV_finishOp (lua_State *L) {
|
|||
** Bitwise operations with constant operand.
|
||||
*/
|
||||
#define op_bitwiseK(L,op) { \
|
||||
StkId ra = RA(i); \
|
||||
TValue *v1 = vRB(i); \
|
||||
TValue *v2 = KC(i); \
|
||||
lua_Integer i1; \
|
||||
|
@ -989,6 +1005,7 @@ void luaV_finishOp (lua_State *L) {
|
|||
** Bitwise operations with register operands.
|
||||
*/
|
||||
#define op_bitwise(L,op) { \
|
||||
StkId ra = RA(i); \
|
||||
TValue *v1 = vRB(i); \
|
||||
TValue *v2 = vRC(i); \
|
||||
lua_Integer i1; lua_Integer i2; \
|
||||
|
@ -1003,6 +1020,7 @@ void luaV_finishOp (lua_State *L) {
|
|||
** integers.
|
||||
*/
|
||||
#define op_order(L,opi,opn,other) { \
|
||||
StkId ra = RA(i); \
|
||||
int cond; \
|
||||
TValue *rb = vRB(i); \
|
||||
if (ttisinteger(s2v(ra)) && ttisinteger(rb)) { \
|
||||
|
@ -1022,6 +1040,7 @@ void luaV_finishOp (lua_State *L) {
|
|||
** always small enough to have an exact representation as a float.)
|
||||
*/
|
||||
#define op_orderI(L,opi,opf,inv,tm) { \
|
||||
StkId ra = RA(i); \
|
||||
int cond; \
|
||||
int im = GETARG_sB(i); \
|
||||
if (ttisinteger(s2v(ra))) \
|
||||
|
@ -1064,7 +1083,7 @@ void luaV_finishOp (lua_State *L) {
|
|||
|
||||
#define updatetrap(ci) (trap = ci->u.l.trap)
|
||||
|
||||
#define updatebase(ci) (base = ci->func + 1)
|
||||
#define updatebase(ci) (base = ci->func.p + 1)
|
||||
|
||||
|
||||
#define updatestack(ci) \
|
||||
|
@ -1099,7 +1118,7 @@ void luaV_finishOp (lua_State *L) {
|
|||
** Whenever code can raise errors, the global 'pc' and the global
|
||||
** 'top' must be correct to report occasional errors.
|
||||
*/
|
||||
#define savestate(L,ci) (savepc(L), L->top = ci->top)
|
||||
#define savestate(L,ci) (savepc(L), L->top.p = ci->top.p)
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1112,14 +1131,14 @@ void luaV_finishOp (lua_State *L) {
|
|||
#define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci))
|
||||
|
||||
/*
|
||||
** Protect code that can only raise errors. (That is, it cannnot change
|
||||
** Protect code that can only raise errors. (That is, it cannot change
|
||||
** the stack or hooks.)
|
||||
*/
|
||||
#define halfProtect(exp) (savestate(L,ci), (exp))
|
||||
|
||||
/* 'c' is the limit of live values in the stack */
|
||||
#define checkGC(L,c) \
|
||||
{ luaC_condGC(L, (savepc(L), L->top = (c)), \
|
||||
{ luaC_condGC(L, (savepc(L), L->top.p = (c)), \
|
||||
updatetrap(ci)); \
|
||||
luai_threadyield(L); }
|
||||
|
||||
|
@ -1131,7 +1150,6 @@ void luaV_finishOp (lua_State *L) {
|
|||
updatebase(ci); /* correct stack */ \
|
||||
} \
|
||||
i = *(pc++); \
|
||||
ra = RA(i); /* WARNING: any stack reallocation invalidates 'ra' */ \
|
||||
}
|
||||
|
||||
#define vmdispatch(o) switch(o)
|
||||
|
@ -1151,7 +1169,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
startfunc:
|
||||
trap = L->hookmask;
|
||||
returning: /* trap already set */
|
||||
cl = clLvalue(s2v(ci->func));
|
||||
cl = clLvalue(s2v(ci->func.p));
|
||||
k = cl->p->k;
|
||||
pc = ci->u.l.savedpc;
|
||||
if (l_unlikely(trap)) {
|
||||
|
@ -1163,58 +1181,68 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
}
|
||||
ci->u.l.trap = 1; /* assume trap is on, for now */
|
||||
}
|
||||
base = ci->func + 1;
|
||||
base = ci->func.p + 1;
|
||||
/* main loop of interpreter */
|
||||
for (;;) {
|
||||
Instruction i; /* instruction being executed */
|
||||
StkId ra; /* instruction's A register */
|
||||
vmfetch();
|
||||
// low-level line tracing for debugging Lua
|
||||
// printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p)));
|
||||
lua_assert(base == ci->func + 1);
|
||||
lua_assert(base <= L->top && L->top < L->stack_last);
|
||||
#if 0
|
||||
/* low-level line tracing for debugging Lua */
|
||||
printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p)));
|
||||
#endif
|
||||
lua_assert(base == ci->func.p + 1);
|
||||
lua_assert(base <= L->top.p && L->top.p <= L->stack_last.p);
|
||||
/* invalidate top for instructions not expecting it */
|
||||
lua_assert(isIT(i) || (cast_void(L->top = base), 1));
|
||||
lua_assert(isIT(i) || (cast_void(L->top.p = base), 1));
|
||||
vmdispatch (GET_OPCODE(i)) {
|
||||
vmcase(OP_MOVE) {
|
||||
StkId ra = RA(i);
|
||||
setobjs2s(L, ra, RB(i));
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_LOADI) {
|
||||
StkId ra = RA(i);
|
||||
lua_Integer b = GETARG_sBx(i);
|
||||
setivalue(s2v(ra), b);
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_LOADF) {
|
||||
StkId ra = RA(i);
|
||||
int b = GETARG_sBx(i);
|
||||
setfltvalue(s2v(ra), cast_num(b));
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_LOADK) {
|
||||
StkId ra = RA(i);
|
||||
TValue *rb = k + GETARG_Bx(i);
|
||||
setobj2s(L, ra, rb);
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_LOADKX) {
|
||||
StkId ra = RA(i);
|
||||
TValue *rb;
|
||||
rb = k + GETARG_Ax(*pc); pc++;
|
||||
setobj2s(L, ra, rb);
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_LOADFALSE) {
|
||||
StkId ra = RA(i);
|
||||
setbfvalue(s2v(ra));
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_LFALSESKIP) {
|
||||
StkId ra = RA(i);
|
||||
setbfvalue(s2v(ra));
|
||||
pc++; /* skip next instruction */
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_LOADTRUE) {
|
||||
StkId ra = RA(i);
|
||||
setbtvalue(s2v(ra));
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_LOADNIL) {
|
||||
StkId ra = RA(i);
|
||||
int b = GETARG_B(i);
|
||||
do {
|
||||
setnilvalue(s2v(ra++));
|
||||
|
@ -1222,19 +1250,22 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_GETUPVAL) {
|
||||
StkId ra = RA(i);
|
||||
int b = GETARG_B(i);
|
||||
setobj2s(L, ra, cl->upvals[b]->v);
|
||||
setobj2s(L, ra, cl->upvals[b]->v.p);
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_SETUPVAL) {
|
||||
StkId ra = RA(i);
|
||||
UpVal *uv = cl->upvals[GETARG_B(i)];
|
||||
setobj(L, uv->v, s2v(ra));
|
||||
setobj(L, uv->v.p, s2v(ra));
|
||||
luaC_barrier(L, uv, s2v(ra));
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_GETTABUP) {
|
||||
StkId ra = RA(i);
|
||||
const TValue *slot;
|
||||
TValue *upval = cl->upvals[GETARG_B(i)]->v;
|
||||
TValue *upval = cl->upvals[GETARG_B(i)]->v.p;
|
||||
TValue *rc = KC(i);
|
||||
TString *key = tsvalue(rc); /* key must be a string */
|
||||
if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) {
|
||||
|
@ -1245,6 +1276,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_GETTABLE) {
|
||||
StkId ra = RA(i);
|
||||
const TValue *slot;
|
||||
TValue *rb = vRB(i);
|
||||
TValue *rc = vRC(i);
|
||||
|
@ -1259,6 +1291,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_GETI) {
|
||||
StkId ra = RA(i);
|
||||
const TValue *slot;
|
||||
TValue *rb = vRB(i);
|
||||
int c = GETARG_C(i);
|
||||
|
@ -1273,6 +1306,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_GETFIELD) {
|
||||
StkId ra = RA(i);
|
||||
const TValue *slot;
|
||||
TValue *rb = vRB(i);
|
||||
TValue *rc = KC(i);
|
||||
|
@ -1286,7 +1320,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
}
|
||||
vmcase(OP_SETTABUP) {
|
||||
const TValue *slot;
|
||||
TValue *upval = cl->upvals[GETARG_A(i)]->v;
|
||||
TValue *upval = cl->upvals[GETARG_A(i)]->v.p;
|
||||
TValue *rb = KB(i);
|
||||
TValue *rc = RKC(i);
|
||||
TString *key = tsvalue(rb); /* key must be a string */
|
||||
|
@ -1298,6 +1332,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_SETTABLE) {
|
||||
StkId ra = RA(i);
|
||||
const TValue *slot;
|
||||
TValue *rb = vRB(i); /* key (table is in 'ra') */
|
||||
TValue *rc = RKC(i); /* value */
|
||||
|
@ -1312,6 +1347,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_SETI) {
|
||||
StkId ra = RA(i);
|
||||
const TValue *slot;
|
||||
int c = GETARG_B(i);
|
||||
TValue *rc = RKC(i);
|
||||
|
@ -1326,6 +1362,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_SETFIELD) {
|
||||
StkId ra = RA(i);
|
||||
const TValue *slot;
|
||||
TValue *rb = KB(i);
|
||||
TValue *rc = RKC(i);
|
||||
|
@ -1338,6 +1375,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_NEWTABLE) {
|
||||
StkId ra = RA(i);
|
||||
int b = GETARG_B(i); /* log2(hash size) + 1 */
|
||||
int c = GETARG_C(i); /* array size */
|
||||
Table *t;
|
||||
|
@ -1347,7 +1385,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
if (TESTARG_k(i)) /* non-zero extra argument? */
|
||||
c += GETARG_Ax(*pc) * (MAXARG_C + 1); /* add it to size */
|
||||
pc++; /* skip extra argument */
|
||||
L->top = ra + 1; /* correct top in case of emergency GC */
|
||||
L->top.p = ra + 1; /* correct top in case of emergency GC */
|
||||
t = luaH_new(L); /* memory allocation */
|
||||
sethvalue2s(L, ra, t);
|
||||
if (b != 0 || c != 0)
|
||||
|
@ -1356,6 +1394,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_SELF) {
|
||||
StkId ra = RA(i);
|
||||
const TValue *slot;
|
||||
TValue *rb = vRB(i);
|
||||
TValue *rc = RKC(i);
|
||||
|
@ -1385,6 +1424,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_MODK) {
|
||||
savestate(L, ci); /* in case of division by 0 */
|
||||
op_arithK(L, luaV_mod, luaV_modf);
|
||||
vmbreak;
|
||||
}
|
||||
|
@ -1397,6 +1437,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_IDIVK) {
|
||||
savestate(L, ci); /* in case of division by 0 */
|
||||
op_arithK(L, luaV_idiv, luai_numidiv);
|
||||
vmbreak;
|
||||
}
|
||||
|
@ -1413,6 +1454,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_SHRI) {
|
||||
StkId ra = RA(i);
|
||||
TValue *rb = vRB(i);
|
||||
int ic = GETARG_sC(i);
|
||||
lua_Integer ib;
|
||||
|
@ -1422,6 +1464,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_SHLI) {
|
||||
StkId ra = RA(i);
|
||||
TValue *rb = vRB(i);
|
||||
int ic = GETARG_sC(i);
|
||||
lua_Integer ib;
|
||||
|
@ -1443,6 +1486,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_MOD) {
|
||||
savestate(L, ci); /* in case of division by 0 */
|
||||
op_arith(L, luaV_mod, luaV_modf);
|
||||
vmbreak;
|
||||
}
|
||||
|
@ -1455,6 +1499,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_IDIV) { /* floor division */
|
||||
savestate(L, ci); /* in case of division by 0 */
|
||||
op_arith(L, luaV_idiv, luai_numidiv);
|
||||
vmbreak;
|
||||
}
|
||||
|
@ -1479,6 +1524,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_MMBIN) {
|
||||
StkId ra = RA(i);
|
||||
Instruction pi = *(pc - 2); /* original arith. expression */
|
||||
TValue *rb = vRB(i);
|
||||
TMS tm = (TMS)GETARG_C(i);
|
||||
|
@ -1488,6 +1534,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_MMBINI) {
|
||||
StkId ra = RA(i);
|
||||
Instruction pi = *(pc - 2); /* original arith. expression */
|
||||
int imm = GETARG_sB(i);
|
||||
TMS tm = (TMS)GETARG_C(i);
|
||||
|
@ -1497,6 +1544,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_MMBINK) {
|
||||
StkId ra = RA(i);
|
||||
Instruction pi = *(pc - 2); /* original arith. expression */
|
||||
TValue *imm = KB(i);
|
||||
TMS tm = (TMS)GETARG_C(i);
|
||||
|
@ -1506,6 +1554,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_UNM) {
|
||||
StkId ra = RA(i);
|
||||
TValue *rb = vRB(i);
|
||||
lua_Number nb;
|
||||
if (ttisinteger(rb)) {
|
||||
|
@ -1520,6 +1569,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_BNOT) {
|
||||
StkId ra = RA(i);
|
||||
TValue *rb = vRB(i);
|
||||
lua_Integer ib;
|
||||
if (tointegerns(rb, &ib)) {
|
||||
|
@ -1530,6 +1580,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_NOT) {
|
||||
StkId ra = RA(i);
|
||||
TValue *rb = vRB(i);
|
||||
if (l_isfalse(rb))
|
||||
setbtvalue(s2v(ra));
|
||||
|
@ -1538,21 +1589,25 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_LEN) {
|
||||
StkId ra = RA(i);
|
||||
Protect(luaV_objlen(L, ra, vRB(i)));
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_CONCAT) {
|
||||
StkId ra = RA(i);
|
||||
int n = GETARG_B(i); /* number of elements to concatenate */
|
||||
L->top = ra + n; /* mark the end of concat operands */
|
||||
L->top.p = ra + n; /* mark the end of concat operands */
|
||||
ProtectNT(luaV_concat(L, n));
|
||||
checkGC(L, L->top); /* 'luaV_concat' ensures correct top */
|
||||
checkGC(L, L->top.p); /* 'luaV_concat' ensures correct top */
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_CLOSE) {
|
||||
StkId ra = RA(i);
|
||||
Protect(luaF_close(L, ra, LUA_OK, 1));
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_TBC) {
|
||||
StkId ra = RA(i);
|
||||
/* create new to-be-closed upvalue */
|
||||
halfProtect(luaF_newtbcupval(L, ra));
|
||||
vmbreak;
|
||||
|
@ -1562,6 +1617,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_EQ) {
|
||||
StkId ra = RA(i);
|
||||
int cond;
|
||||
TValue *rb = vRB(i);
|
||||
Protect(cond = luaV_equalobj(L, s2v(ra), rb));
|
||||
|
@ -1577,6 +1633,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_EQK) {
|
||||
StkId ra = RA(i);
|
||||
TValue *rb = KB(i);
|
||||
/* basic types do not use '__eq'; we can use raw equality */
|
||||
int cond = luaV_rawequalobj(s2v(ra), rb);
|
||||
|
@ -1584,6 +1641,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_EQI) {
|
||||
StkId ra = RA(i);
|
||||
int cond;
|
||||
int im = GETARG_sB(i);
|
||||
if (ttisinteger(s2v(ra)))
|
||||
|
@ -1612,11 +1670,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_TEST) {
|
||||
StkId ra = RA(i);
|
||||
int cond = !l_isfalse(s2v(ra));
|
||||
docondjump();
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_TESTSET) {
|
||||
StkId ra = RA(i);
|
||||
TValue *rb = vRB(i);
|
||||
if (l_isfalse(rb) == GETARG_k(i))
|
||||
pc++;
|
||||
|
@ -1627,78 +1687,74 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_CALL) {
|
||||
StkId ra = RA(i);
|
||||
CallInfo *newci;
|
||||
int b = GETARG_B(i);
|
||||
int nresults = GETARG_C(i) - 1;
|
||||
if (b != 0) /* fixed number of arguments? */
|
||||
L->top = ra + b; /* top signals number of arguments */
|
||||
L->top.p = ra + b; /* top signals number of arguments */
|
||||
/* else previous instruction set top */
|
||||
savepc(L); /* in case of errors */
|
||||
if ((newci = luaD_precall(L, ra, nresults)) == NULL)
|
||||
updatetrap(ci); /* C call; nothing else to be done */
|
||||
else { /* Lua call: run function in this same C frame */
|
||||
ci = newci;
|
||||
ci->callstatus = 0; /* call re-uses 'luaV_execute' */
|
||||
goto startfunc;
|
||||
}
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_TAILCALL) {
|
||||
StkId ra = RA(i);
|
||||
int b = GETARG_B(i); /* number of arguments + 1 (function) */
|
||||
int n; /* number of results when calling a C function */
|
||||
int nparams1 = GETARG_C(i);
|
||||
/* delta is virtual 'func' - real 'func' (vararg functions) */
|
||||
int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0;
|
||||
if (b != 0)
|
||||
L->top = ra + b;
|
||||
L->top.p = ra + b;
|
||||
else /* previous instruction set top */
|
||||
b = cast_int(L->top - ra);
|
||||
b = cast_int(L->top.p - ra);
|
||||
savepc(ci); /* several calls here can raise errors */
|
||||
if (TESTARG_k(i)) {
|
||||
luaF_closeupval(L, base); /* close upvalues from current call */
|
||||
lua_assert(L->tbclist < base); /* no pending tbc variables */
|
||||
lua_assert(base == ci->func + 1);
|
||||
lua_assert(L->tbclist.p < base); /* no pending tbc variables */
|
||||
lua_assert(base == ci->func.p + 1);
|
||||
}
|
||||
while (!ttisfunction(s2v(ra))) { /* not a function? */
|
||||
luaD_tryfuncTM(L, ra); /* try '__call' metamethod */
|
||||
b++; /* there is now one extra argument */
|
||||
checkstackGCp(L, 1, ra);
|
||||
}
|
||||
if (!ttisLclosure(s2v(ra))) { /* C function? */
|
||||
luaD_precall(L, ra, LUA_MULTRET); /* call it */
|
||||
updatetrap(ci);
|
||||
updatestack(ci); /* stack may have been relocated */
|
||||
ci->func -= delta; /* restore 'func' (if vararg) */
|
||||
luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */
|
||||
if ((n = luaD_pretailcall(L, ci, ra, b, delta)) < 0) /* Lua function? */
|
||||
goto startfunc; /* execute the callee */
|
||||
else { /* C function? */
|
||||
ci->func.p -= delta; /* restore 'func' (if vararg) */
|
||||
luaD_poscall(L, ci, n); /* finish caller */
|
||||
updatetrap(ci); /* 'luaD_poscall' can change hooks */
|
||||
goto ret; /* caller returns after the tail call */
|
||||
}
|
||||
ci->func -= delta; /* restore 'func' (if vararg) */
|
||||
luaD_pretailcall(L, ci, ra, b); /* prepare call frame */
|
||||
goto startfunc; /* execute the callee */
|
||||
}
|
||||
vmcase(OP_RETURN) {
|
||||
StkId ra = RA(i);
|
||||
int n = GETARG_B(i) - 1; /* number of results */
|
||||
int nparams1 = GETARG_C(i);
|
||||
if (n < 0) /* not fixed? */
|
||||
n = cast_int(L->top - ra); /* get what is available */
|
||||
n = cast_int(L->top.p - ra); /* get what is available */
|
||||
savepc(ci);
|
||||
if (TESTARG_k(i)) { /* may there be open upvalues? */
|
||||
if (L->top < ci->top)
|
||||
L->top = ci->top;
|
||||
ci->u2.nres = n; /* save number of returns */
|
||||
if (L->top.p < ci->top.p)
|
||||
L->top.p = ci->top.p;
|
||||
luaF_close(L, base, CLOSEKTOP, 1);
|
||||
updatetrap(ci);
|
||||
updatestack(ci);
|
||||
}
|
||||
if (nparams1) /* vararg function? */
|
||||
ci->func -= ci->u.l.nextraargs + nparams1;
|
||||
L->top = ra + n; /* set call for 'luaD_poscall' */
|
||||
ci->func.p -= ci->u.l.nextraargs + nparams1;
|
||||
L->top.p = ra + n; /* set call for 'luaD_poscall' */
|
||||
luaD_poscall(L, ci, n);
|
||||
updatetrap(ci); /* 'luaD_poscall' can change hooks */
|
||||
goto ret;
|
||||
}
|
||||
vmcase(OP_RETURN0) {
|
||||
if (l_unlikely(L->hookmask)) {
|
||||
L->top = ra;
|
||||
StkId ra = RA(i);
|
||||
L->top.p = ra;
|
||||
savepc(ci);
|
||||
luaD_poscall(L, ci, 0); /* no hurry... */
|
||||
trap = 1;
|
||||
|
@ -1706,15 +1762,16 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
else { /* do the 'poscall' here */
|
||||
int nres;
|
||||
L->ci = ci->previous; /* back to caller */
|
||||
L->top = base - 1;
|
||||
L->top.p = base - 1;
|
||||
for (nres = ci->nresults; l_unlikely(nres > 0); nres--)
|
||||
setnilvalue(s2v(L->top++)); /* all results are nil */
|
||||
setnilvalue(s2v(L->top.p++)); /* all results are nil */
|
||||
}
|
||||
goto ret;
|
||||
}
|
||||
vmcase(OP_RETURN1) {
|
||||
if (l_unlikely(L->hookmask)) {
|
||||
L->top = ra + 1;
|
||||
StkId ra = RA(i);
|
||||
L->top.p = ra + 1;
|
||||
savepc(ci);
|
||||
luaD_poscall(L, ci, 1); /* no hurry... */
|
||||
trap = 1;
|
||||
|
@ -1723,12 +1780,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
int nres = ci->nresults;
|
||||
L->ci = ci->previous; /* back to caller */
|
||||
if (nres == 0)
|
||||
L->top = base - 1; /* asked for no results */
|
||||
L->top.p = base - 1; /* asked for no results */
|
||||
else {
|
||||
StkId ra = RA(i);
|
||||
setobjs2s(L, base - 1, ra); /* at least this result */
|
||||
L->top = base;
|
||||
L->top.p = base;
|
||||
for (; l_unlikely(nres > 1); nres--)
|
||||
setnilvalue(s2v(L->top++)); /* complete missing results */
|
||||
setnilvalue(s2v(L->top.p++)); /* complete missing results */
|
||||
}
|
||||
}
|
||||
ret: /* return from a Lua function */
|
||||
|
@ -1740,6 +1798,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
}
|
||||
}
|
||||
vmcase(OP_FORLOOP) {
|
||||
StkId ra = RA(i);
|
||||
if (ttisinteger(s2v(ra + 2))) { /* integer loop? */
|
||||
lua_Unsigned count = l_castS2U(ivalue(s2v(ra + 1)));
|
||||
if (count > 0) { /* still more iterations? */
|
||||
|
@ -1758,12 +1817,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_FORPREP) {
|
||||
StkId ra = RA(i);
|
||||
savestate(L, ci); /* in case of errors */
|
||||
if (forprep(L, ra))
|
||||
pc += GETARG_Bx(i) + 1; /* skip the loop */
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_TFORPREP) {
|
||||
StkId ra = RA(i);
|
||||
/* create to-be-closed upvalue (if needed) */
|
||||
halfProtect(luaF_newtbcupval(L, ra + 3));
|
||||
pc += GETARG_Bx(i);
|
||||
|
@ -1772,7 +1833,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
goto l_tforcall;
|
||||
}
|
||||
vmcase(OP_TFORCALL) {
|
||||
l_tforcall:
|
||||
l_tforcall: {
|
||||
StkId ra = RA(i);
|
||||
/* 'ra' has the iterator function, 'ra + 1' has the state,
|
||||
'ra + 2' has the control variable, and 'ra + 3' has the
|
||||
to-be-closed variable. The call will use the stack after
|
||||
|
@ -1780,29 +1842,31 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
*/
|
||||
/* push function, state, and control variable */
|
||||
memcpy(ra + 4, ra, 3 * sizeof(*ra));
|
||||
L->top = ra + 4 + 3;
|
||||
L->top.p = ra + 4 + 3;
|
||||
ProtectNT(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */
|
||||
updatestack(ci); /* stack may have changed */
|
||||
i = *(pc++); /* go to next instruction */
|
||||
lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i));
|
||||
goto l_tforloop;
|
||||
}
|
||||
}}
|
||||
vmcase(OP_TFORLOOP) {
|
||||
l_tforloop:
|
||||
l_tforloop: {
|
||||
StkId ra = RA(i);
|
||||
if (!ttisnil(s2v(ra + 4))) { /* continue loop? */
|
||||
setobjs2s(L, ra + 2, ra + 4); /* save control variable */
|
||||
pc -= GETARG_Bx(i); /* jump back */
|
||||
}
|
||||
vmbreak;
|
||||
}
|
||||
}}
|
||||
vmcase(OP_SETLIST) {
|
||||
StkId ra = RA(i);
|
||||
int n = GETARG_B(i);
|
||||
unsigned int last = GETARG_C(i);
|
||||
Table *h = hvalue(s2v(ra));
|
||||
if (n == 0)
|
||||
n = cast_int(L->top - ra) - 1; /* get up to the top */
|
||||
n = cast_int(L->top.p - ra) - 1; /* get up to the top */
|
||||
else
|
||||
L->top = ci->top; /* correct top in case of emergency GC */
|
||||
L->top.p = ci->top.p; /* correct top in case of emergency GC */
|
||||
last += n;
|
||||
if (TESTARG_k(i)) {
|
||||
last += GETARG_Ax(*pc) * (MAXARG_C + 1);
|
||||
|
@ -1819,12 +1883,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
vmbreak;
|
||||
}
|
||||
vmcase(OP_CLOSURE) {
|
||||
StkId ra = RA(i);
|
||||
Proto *p = cl->p->p[GETARG_Bx(i)];
|
||||
halfProtect(pushclosure(L, p, cl->upvals, base, ra));
|
||||
checkGC(L, ra + 1);
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_VARARG) {
|
||||
StkId ra = RA(i);
|
||||
int n = GETARG_C(i) - 1; /* required results */
|
||||
Protect(luaT_getvarargs(L, ci, ra, n));
|
||||
vmbreak;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue