Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0016d4836a | ||
|
|
66bc684738 | ||
|
|
44e377c981 | ||
|
|
91de633633 | ||
|
|
f1047f9e76 | ||
|
|
864e28fcf7 | ||
|
|
b2b0ca17d3 | ||
|
|
9b879e31e2 | ||
|
|
8e5633a23f | ||
|
|
8bcada1fda | ||
|
|
771152b919 | ||
|
|
b4277c88c1 | ||
|
|
63026cc11d | ||
|
|
b8385d1579 | ||
|
|
916cc9d8ca | ||
|
|
347000a326 | ||
|
|
4967313720 | ||
|
|
19b64a8b61 | ||
|
|
6a7b2b9721 |
No files matched your search
+41
-17
@@ -519,6 +519,23 @@ LUA_API int lua_pushthread (lua_State *L) {
|
|||||||
** get functions (Lua -> stack)
|
** get functions (Lua -> stack)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static void auxgetstr (lua_State *L, const TValue *t, const char *k) {
|
||||||
|
const TValue *slot;
|
||||||
|
TValue key;
|
||||||
|
TString *str = luaS_new(L, k);
|
||||||
|
api_checkvalidindex(L, t);
|
||||||
|
if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
|
||||||
|
setobj2s(L, L->top, slot);
|
||||||
|
api_incr_top(L);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setsvalue(L, &key, str);
|
||||||
|
luaV_finishget(L, t, L->top, L->top, slot);
|
||||||
|
api_incr_top(L);
|
||||||
|
}
|
||||||
|
lua_unlock(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LUA_API void lua_gettable (lua_State *L, int idx) {
|
LUA_API void lua_gettable (lua_State *L, int idx) {
|
||||||
StkId t;
|
StkId t;
|
||||||
@@ -531,15 +548,8 @@ LUA_API void lua_gettable (lua_State *L, int idx) {
|
|||||||
|
|
||||||
|
|
||||||
LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
|
LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
|
||||||
StkId t;
|
|
||||||
TValue key;
|
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = index2adr(L, idx);
|
auxgetstr(L, index2adr(L, idx), k);
|
||||||
api_checkvalidindex(L, t);
|
|
||||||
setsvalue(L, &key, luaS_new(L, k));
|
|
||||||
luaV_gettable(L, t, &key, L->top);
|
|
||||||
api_incr_top(L);
|
|
||||||
lua_unlock(L);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -630,6 +640,26 @@ LUA_API void lua_getfenv (lua_State *L, int idx) {
|
|||||||
** set functions (stack -> Lua)
|
** set functions (stack -> Lua)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||||
|
static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
|
||||||
|
TValue key;
|
||||||
|
const TValue *slot;
|
||||||
|
TString *str = luaS_new(L, k);
|
||||||
|
api_checknelems(L, 1);
|
||||||
|
api_checkvalidindex(L, t);
|
||||||
|
if (luaV_fastset(L, t, str, slot, luaH_setstr, L->top)) {
|
||||||
|
setobj2t(L, cast(TValue *, slot), L->top - 1);
|
||||||
|
L->top--; /* pop value */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setsvalue2s(L, &key, str);
|
||||||
|
luaV_finishset(L, t, &key, L->top - 1, slot);
|
||||||
|
L->top--; /* pop value */
|
||||||
|
}
|
||||||
|
lua_unlock(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LUA_API void lua_settable (lua_State *L, int idx) {
|
LUA_API void lua_settable (lua_State *L, int idx) {
|
||||||
StkId t;
|
StkId t;
|
||||||
@@ -642,18 +672,12 @@ LUA_API void lua_settable (lua_State *L, int idx) {
|
|||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
|
||||||
LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
|
LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
|
||||||
StkId t;
|
|
||||||
TValue key;
|
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
auxsetstr(L, index2adr(L, idx), k);
|
||||||
t = index2adr(L, idx);
|
|
||||||
api_checkvalidindex(L, t);
|
|
||||||
setsvalue(L, &key, luaS_new(L, k));
|
|
||||||
luaV_settable(L, t, &key, L->top - 1);
|
|
||||||
L->top--; /* pop value */
|
|
||||||
lua_unlock(L);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+15
-3
@@ -20,6 +20,7 @@
|
|||||||
#define lauxlib_c
|
#define lauxlib_c
|
||||||
#define LUA_LIB
|
#define LUA_LIB
|
||||||
|
|
||||||
|
#include "ldebug.h"
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
|
|
||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
@@ -468,8 +469,19 @@ LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
|
|||||||
|
|
||||||
|
|
||||||
LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
|
LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
|
||||||
while (l--)
|
while (l) {
|
||||||
luaL_addchar(B, *s++);
|
size_t space = bufffree(B);
|
||||||
|
if (space == 0) {
|
||||||
|
luaL_prepbuffer(B);
|
||||||
|
lua_assert(bufffree(B) == LUAL_BUFFERSIZE);
|
||||||
|
space = LUAL_BUFFERSIZE;
|
||||||
|
}
|
||||||
|
if (space > l) space = l;
|
||||||
|
memcpy(B->p, s, space);
|
||||||
|
B->p += space;
|
||||||
|
s += space;
|
||||||
|
l -= space;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -686,6 +698,6 @@ static int panic (lua_State *L) {
|
|||||||
|
|
||||||
LUALIB_API lua_State *luaL_newstate (void) {
|
LUALIB_API lua_State *luaL_newstate (void) {
|
||||||
lua_State *L = lua_newstate(l_alloc, NULL);
|
lua_State *L = lua_newstate(l_alloc, NULL);
|
||||||
if (L) lua_atpanic(L, &panic);
|
if (l_likely(L)) lua_atpanic(L, &panic);
|
||||||
return L;
|
return L;
|
||||||
}
|
}
|
||||||
+25
-12
@@ -626,8 +626,20 @@ static void codenot (FuncState *fs, expdesc *e) {
|
|||||||
removevalues(fs, e->t);
|
removevalues(fs, e->t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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.s.info]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Create expression 't[k]'. 't' must have its final result already in a
|
||||||
|
** register or upvalue. Upvalues can only be indexed by literal strings.
|
||||||
|
*/
|
||||||
void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
|
void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
|
||||||
|
if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non string? */
|
||||||
|
luaK_exp2anyreg(fs, t); /* put it in a register */
|
||||||
t->u.s.aux = luaK_exp2RK(fs, k);
|
t->u.s.aux = luaK_exp2RK(fs, k);
|
||||||
t->k = VINDEXED;
|
t->k = VINDEXED;
|
||||||
}
|
}
|
||||||
@@ -790,18 +802,19 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
|
|||||||
case OPR_BXOR: codearith(fs, OP_BXOR, e1, e2); break;
|
case OPR_BXOR: codearith(fs, OP_BXOR, e1, e2); break;
|
||||||
case OPR_BSHL: codearith(fs, OP_BSHL, e1, e2); break;
|
case OPR_BSHL: codearith(fs, OP_BSHL, e1, e2); break;
|
||||||
case OPR_BSHR: codearith(fs, OP_BSHR, e1, e2); break;
|
case OPR_BSHR: codearith(fs, OP_BSHR, e1, e2); break;
|
||||||
case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;
|
case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
|
||||||
case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
|
case OPR_MOD: case OPR_POW: {
|
||||||
case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
|
codearith(fs, op - OPR_ADD + OP_ADD, e1, e2);
|
||||||
case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
|
break;
|
||||||
case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
|
}
|
||||||
case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
|
case OPR_EQ: case OPR_LT: case OPR_LE: {
|
||||||
case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
|
codecomp(fs, op - OPR_EQ + OP_EQ, 1, e1, e2);
|
||||||
case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
|
break;
|
||||||
case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
|
}
|
||||||
case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
|
case OPR_NE: case OPR_GT: case OPR_GE: {
|
||||||
case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
|
codecomp(fs, op - OPR_NE + OP_EQ, 0, e1, e2);
|
||||||
case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
|
break;
|
||||||
|
}
|
||||||
default: lua_assert(0);
|
default: lua_assert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -21,13 +21,13 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** grep "ORDER OPR" if you change these enums
|
** grep "ORDER OPR" if you change these enums (ORDER OP)
|
||||||
*/
|
*/
|
||||||
typedef enum BinOpr {
|
typedef enum BinOpr {
|
||||||
OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
|
OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
|
||||||
OPR_CONCAT,
|
OPR_CONCAT,
|
||||||
OPR_NE, OPR_EQ,
|
OPR_EQ, OPR_LT, OPR_LE,
|
||||||
OPR_LT, OPR_LE, OPR_GT, OPR_GE,
|
OPR_NE, OPR_GT, OPR_GE,
|
||||||
OPR_AND, OPR_OR,
|
OPR_AND, OPR_OR,
|
||||||
OPR_BAND, OPR_BOR, OPR_BXOR,
|
OPR_BAND, OPR_BOR, OPR_BXOR,
|
||||||
OPR_BSHL, OPR_BSHR,
|
OPR_BSHL, OPR_BSHR,
|
||||||
|
|||||||
+28
-5
@@ -542,16 +542,39 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
|
|||||||
|
|
||||||
|
|
||||||
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
|
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
|
||||||
|
TMS tm = 0;
|
||||||
Instruction i;
|
Instruction i;
|
||||||
if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1))
|
if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1))
|
||||||
return NULL; /* calling function is not Lua (or is unknown) */
|
return NULL; /* calling function is not Lua (or is unknown) */
|
||||||
ci--; /* calling function */
|
ci--; /* calling function */
|
||||||
i = ci_func(ci)->l.p->code[currentpc(L, ci)];
|
i = ci_func(ci)->l.p->code[currentpc(L, ci)];
|
||||||
if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
|
switch (GET_OPCODE(i)) {
|
||||||
GET_OPCODE(i) == OP_TFORLOOP)
|
case OP_CALL:
|
||||||
return getobjname(L, ci, GETARG_A(i), name);
|
case OP_TAILCALL:
|
||||||
else
|
case OP_TFORLOOP:
|
||||||
return NULL; /* no useful name can be found */
|
return getobjname(L, ci, GETARG_A(i), name);
|
||||||
|
case OP_GETGLOBAL:
|
||||||
|
case OP_SELF:
|
||||||
|
case OP_GETTABLE: tm = TM_INDEX; break;
|
||||||
|
case OP_SETGLOBAL:
|
||||||
|
case OP_SETTABLE: tm = TM_NEWINDEX; break;
|
||||||
|
case OP_EQ: tm = TM_EQ; break;
|
||||||
|
case OP_ADD: tm = TM_ADD; break;
|
||||||
|
case OP_SUB: tm = TM_SUB; break;
|
||||||
|
case OP_MUL: tm = TM_MUL; break;
|
||||||
|
case OP_DIV: tm = TM_DIV; break;
|
||||||
|
case OP_MOD: tm = TM_MOD; break;
|
||||||
|
case OP_POW: tm = TM_POW; break;
|
||||||
|
case OP_UNM: tm = TM_UNM; break;
|
||||||
|
case OP_LEN: tm = TM_LEN; break;
|
||||||
|
case OP_LT: tm = TM_LT; break;
|
||||||
|
case OP_LE: tm = TM_LE; break;
|
||||||
|
case OP_CONCAT: tm = TM_CONCAT; break;
|
||||||
|
default:
|
||||||
|
return NULL; /* else no useful name can be found */
|
||||||
|
}
|
||||||
|
*name = getstr(G(L)->tmname[tm]);
|
||||||
|
return "metamethod";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -164,7 +164,7 @@ void luaD_reallocCI (lua_State *L, int newsize) {
|
|||||||
|
|
||||||
|
|
||||||
void luaD_growstack (lua_State *L, int n) {
|
void luaD_growstack (lua_State *L, int n) {
|
||||||
if (l_likely(n <= L->stacksize)) /* double size is enough? */
|
if (n <= L->stacksize) /* double size is enough? */
|
||||||
luaD_reallocstack(L, 2*L->stacksize);
|
luaD_reallocstack(L, 2*L->stacksize);
|
||||||
else
|
else
|
||||||
luaD_reallocstack(L, L->stacksize + n);
|
luaD_reallocstack(L, L->stacksize + n);
|
||||||
@@ -318,7 +318,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
|
|||||||
ci->top = L->top + LUA_MINSTACK;
|
ci->top = L->top + LUA_MINSTACK;
|
||||||
lua_assert(ci->top <= L->stack_last);
|
lua_assert(ci->top <= L->stack_last);
|
||||||
ci->nresults = nresults;
|
ci->nresults = nresults;
|
||||||
if (L->hookmask & LUA_MASKCALL)
|
if (l_unlikely(L->hookmask & LUA_MASKCALL))
|
||||||
luaD_callhook(L, LUA_HOOKCALL, -1);
|
luaD_callhook(L, LUA_HOOKCALL, -1);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
n = (*curr_func(L)->c.f)(L); /* do the actual call */
|
n = (*curr_func(L)->c.f)(L); /* do the actual call */
|
||||||
|
|||||||
+10
-9
@@ -356,20 +356,21 @@ static int read_line (lua_State *L, FILE *f) {
|
|||||||
|
|
||||||
|
|
||||||
static int read_chars (lua_State *L, FILE *f, size_t n) {
|
static int read_chars (lua_State *L, FILE *f, size_t n) {
|
||||||
size_t rlen; /* how much to read */
|
size_t tbr = n; /* number of chars to be read */
|
||||||
size_t nr; /* number of chars actually read */
|
size_t rlen; /* how much to read in each cycle */
|
||||||
|
size_t nr; /* number of chars actually read in each cycle */
|
||||||
luaL_Buffer b;
|
luaL_Buffer b;
|
||||||
luaL_buffinit(L, &b);
|
luaL_buffinit(L, &b);
|
||||||
rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
|
rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
|
||||||
do {
|
do {
|
||||||
char *p = luaL_prepbuffer(&b);
|
char *p = luaL_prepbuffer(&b);
|
||||||
if (rlen > n) rlen = n; /* cannot read more than asked */
|
if (rlen > tbr) rlen = tbr; /* cannot read more than asked */
|
||||||
nr = fread(p, sizeof(char), rlen, f);
|
nr = fread(p, sizeof(char), rlen, f);
|
||||||
luaL_addsize(&b, nr);
|
luaL_addsize(&b, nr);
|
||||||
n -= nr; /* still have to read `n' chars */
|
tbr -= nr; /* still have to read 'tbr' chars */
|
||||||
} while (n > 0 && nr == rlen); /* until end of count or eof */
|
} while (tbr > 0 && nr == rlen); /* until end of count or eof */
|
||||||
luaL_pushresult(&b); /* close buffer */
|
luaL_pushresult(&b); /* close buffer */
|
||||||
return (n == 0 || lua_objlen(L, -1) > 0);
|
return (tbr == 0 || tbr < n); /* true iff read something */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -432,13 +433,13 @@ static int f_read (lua_State *L) {
|
|||||||
|
|
||||||
static int io_readline (lua_State *L) {
|
static int io_readline (lua_State *L) {
|
||||||
FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
|
FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
|
||||||
int sucess;
|
int success;
|
||||||
if (f == NULL) /* file is already closed? */
|
if (f == NULL) /* file is already closed? */
|
||||||
luaL_error(L, "file is already closed");
|
luaL_error(L, "file is already closed");
|
||||||
sucess = read_line(L, f);
|
success = read_line(L, f);
|
||||||
if (ferror(f))
|
if (ferror(f))
|
||||||
return luaL_error(L, "%s", strerror(errno));
|
return luaL_error(L, "%s", strerror(errno));
|
||||||
if (sucess) return 1;
|
if (success) return 1;
|
||||||
else { /* EOF */
|
else { /* EOF */
|
||||||
if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
|
if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
|
||||||
lua_settop(L, 0);
|
lua_settop(L, 0);
|
||||||
|
|||||||
@@ -232,6 +232,8 @@ OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
|
|||||||
(*) In OP_SETLIST, if (B == 0) then B = `top';
|
(*) In OP_SETLIST, if (B == 0) then B = `top';
|
||||||
if (C == 0) then next `instruction' is real C
|
if (C == 0) then next `instruction' is real C
|
||||||
|
|
||||||
|
(*) In OP_SELF, the index must be a string.
|
||||||
|
|
||||||
(*) For comparisons, A specifies what condition the test should accept
|
(*) For comparisons, A specifies what condition the test should accept
|
||||||
(true or false).
|
(true or false).
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -881,10 +881,10 @@ static const struct {
|
|||||||
lu_byte right; /* right priority */
|
lu_byte right; /* right priority */
|
||||||
} priority[] = { /* ORDER OPR */
|
} priority[] = { /* ORDER OPR */
|
||||||
{6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */
|
{6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */
|
||||||
{10, 9}, {5, 4}, /* power and concat (right associative) */
|
{10, 9}, {5, 4}, /* ^, .. (right associative) */
|
||||||
{3, 3}, {3, 3}, /* equality and inequality */
|
{3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */
|
||||||
{3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
|
{3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */
|
||||||
{2, 2}, {1, 1} /* logical (and/or) */
|
{2, 2}, {1, 1} /* and, or */
|
||||||
,{6, 6}, {6, 6}, {6, 6}, /* bit-wise (band/bor/bxor) */
|
,{6, 6}, {6, 6}, {6, 6}, /* bit-wise (band/bor/bxor) */
|
||||||
{7, 7}, {7, 7} /* shl/shr */
|
{7, 7}, {7, 7} /* shl/shr */
|
||||||
};
|
};
|
||||||
|
|||||||
+58
-4
@@ -51,7 +51,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
|
|||||||
unsigned int h) {
|
unsigned int h) {
|
||||||
TString *ts;
|
TString *ts;
|
||||||
stringtable *tb;
|
stringtable *tb;
|
||||||
if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
|
if (l_unlikely(l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)))
|
||||||
luaM_toobig(L);
|
luaM_toobig(L);
|
||||||
ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
|
ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
|
||||||
ts->tsv.len = l;
|
ts->tsv.len = l;
|
||||||
@@ -72,18 +72,72 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
|
// string hash taken from luaJIT
|
||||||
GCObject *o;
|
|
||||||
|
/* Unaligned load of uint32_t. */
|
||||||
|
static inline __attribute__((always_inline)) uint32_t getu32(const void* ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
memcpy(&result, ptr, 4);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// smol macro to look a little less messy lul
|
||||||
|
#define getu8(p) *cast(const uint8_t *, p)
|
||||||
|
|
||||||
|
/* Keyed sparse ARX string hash. Constant time. */
|
||||||
|
static unsigned hash_sparse(const char *str, size_t len)
|
||||||
|
{
|
||||||
|
/* Constants taken from lookup3 hash by Bob Jenkins. */
|
||||||
|
unsigned int a, b, h = cast(unsigned int, len);
|
||||||
|
#define rol(x, n) (((x)<<(n)) | ((x)>>(-cast(int, n)&(8*sizeof(x)-1))))
|
||||||
|
if (len >= 4) { /* Caveat: unaligned access! */
|
||||||
|
a = getu32(str);
|
||||||
|
h ^= getu32(str+len-4);
|
||||||
|
b = getu32(str+(len>>1)-2);
|
||||||
|
h ^= b; h -= rol(b, 14);
|
||||||
|
b += getu32(str+(len>>2)-1);
|
||||||
|
} else if (len > 0) {
|
||||||
|
a = getu8(str);
|
||||||
|
h ^= getu8(str+len-1);
|
||||||
|
b = getu8(str+(len>>1));
|
||||||
|
h ^= b; h -= rol(b, 14);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
a ^= h; a -= rol(h, 11);
|
||||||
|
b ^= a; b -= rol(a, 25);
|
||||||
|
h ^= b; h -= rol(b, 16);
|
||||||
|
#undef rol
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef getu8
|
||||||
|
|
||||||
|
|
||||||
|
static inline __attribute__((always_inline)) unsigned luaS_hash (const char *str, size_t l) {
|
||||||
|
#if 0
|
||||||
unsigned int h = cast(unsigned int, l); /* seed */
|
unsigned int h = cast(unsigned int, l); /* seed */
|
||||||
size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
|
size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
|
||||||
size_t l1;
|
size_t l1;
|
||||||
for (l1=l; l1>=step; l1-=step) /* compute hash */
|
for (l1=l; l1>=step; l1-=step) /* compute hash */
|
||||||
h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
|
h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
|
||||||
|
return h;
|
||||||
|
#else
|
||||||
|
return hash_sparse(str, l);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
|
||||||
|
GCObject *o;
|
||||||
|
unsigned int h = luaS_hash(str, l);
|
||||||
for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
|
for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
|
||||||
o != NULL;
|
o != NULL;
|
||||||
o = o->gch.next) {
|
o = o->gch.next) {
|
||||||
TString *ts = rawgco2ts(o);
|
TString *ts = rawgco2ts(o);
|
||||||
if (l_unlikely(ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0))) {
|
if (ts->tsv.hash == h &&
|
||||||
|
ts->tsv.len == l &&
|
||||||
|
(memcmp(str, getstr(ts), l) == 0)) {
|
||||||
/* string may be dead */
|
/* string may be dead */
|
||||||
if (isdead(G(L), o)) changewhite(o);
|
if (isdead(G(L), o)) changewhite(o);
|
||||||
return ts;
|
return ts;
|
||||||
|
|||||||
+1
-1
@@ -61,7 +61,7 @@ TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TValue *luaT_gettmbyobj (lua_State *L, TValue *o, TMS event) {
|
TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
|
||||||
Table *mt;
|
Table *mt;
|
||||||
switch (ttype(o)) {
|
switch (ttype(o)) {
|
||||||
case LUA_TTABLE:
|
case LUA_TTABLE:
|
||||||
|
|||||||
+1
-1
@@ -55,7 +55,7 @@ LUAI_DATA const char *const luaT_typenames[];
|
|||||||
|
|
||||||
|
|
||||||
LUAI_FUNC TValue *luaT_gettm (Table *events, TMS event, TString *ename);
|
LUAI_FUNC TValue *luaT_gettm (Table *events, TMS event, TString *ename);
|
||||||
LUAI_FUNC TValue *luaT_gettmbyobj (lua_State *L, TValue *o, TMS event);
|
LUAI_FUNC TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event);
|
||||||
LUAI_FUNC void luaT_init (lua_State *L);
|
LUAI_FUNC void luaT_init (lua_State *L);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+145
-54
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* limit for table tag-method chains (to avoid loops) */
|
/* limit for table tag-method chains (to avoid infinite loops) */
|
||||||
#define MAXTAGLOOP 100
|
#define MAXTAGLOOP 100
|
||||||
|
|
||||||
|
|
||||||
@@ -105,61 +105,94 @@ static void callTM (lua_State *L, const TValue *f, const TValue *p1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaV_gettable (lua_State *L, TValue *t, TValue *key, StkId val) {
|
/*
|
||||||
int loop;
|
** Finish the table access 'val = t[key]'.
|
||||||
|
** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to
|
||||||
|
** t[k] entry (which must be nil).
|
||||||
|
*/
|
||||||
|
void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
|
||||||
|
const TValue *slot) {
|
||||||
|
int loop; /* counter to avoid infinite loops */
|
||||||
|
const TValue *tm; /* metamethod */
|
||||||
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
||||||
TValue *tm;
|
if (slot == NULL) { /* 't' is not a table? */
|
||||||
if (ttistable(t)) { /* `t' is a table? */
|
lua_assert(!ttistable(t));
|
||||||
Table *h = hvalue(t);
|
tm = luaT_gettmbyobj(L, t, TM_INDEX);
|
||||||
const TValue *res = luaH_get(h, key); /* do a primitive get */
|
if (l_unlikely(ttisnil(tm)))
|
||||||
if (!ttisnil(res) || /* result is no nil? */
|
luaG_typeerror(L, t, "index"); /* no metamethod */
|
||||||
(tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
|
/* else will try the metamethod */
|
||||||
setobj2s(L, val, res);
|
}
|
||||||
|
else { /* 't' is a table */
|
||||||
|
lua_assert(ttisnil(slot));
|
||||||
|
tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */
|
||||||
|
if (tm == NULL) { /* no metamethod? */
|
||||||
|
setnilvalue(val); /* result is nil */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* else will try the tag method */
|
/* else will try the metamethod */
|
||||||
}
|
}
|
||||||
else if (l_unlikely(ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))))
|
if (ttisfunction(tm)) { /* is metamethod a function? */
|
||||||
luaG_typeerror(L, t, "index");
|
callTMres(L, val, tm, t, key); /* call it */
|
||||||
if (ttisfunction(tm)) {
|
|
||||||
callTMres(L, val, tm, t, key);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
t = tm; /* else repeat with `tm' */
|
t = tm; /* else try to access 'tm[key]' */
|
||||||
|
if (luaV_fastget(L,t,key,slot,luaH_get)) { /* fast track? */
|
||||||
|
setobj2s(L, val, slot); /* done */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* else repeat (tail call 'luaV_finishget') */
|
||||||
}
|
}
|
||||||
luaG_runerror(L, "loop in gettable");
|
luaG_runerror(L, "'__index' chain too long; possible loop");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void luaV_settable (lua_State *L, TValue *t, TValue *key, StkId val) {
|
** Finish a table assignment 't[key] = val'.
|
||||||
int loop;
|
** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points
|
||||||
|
** to the entry 't[key]', or to 'luaO_nilobject' if there is no such
|
||||||
|
** entry. (The value at 'slot' must be nil, otherwise 'luaV_fastset'
|
||||||
|
** would have done the job.)
|
||||||
|
*/
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||||
|
void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
|
||||||
|
StkId val, const TValue *slot) {
|
||||||
|
int loop; /* counter to avoid infinite loops */
|
||||||
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
||||||
TValue *tm = NULL;
|
const TValue *tm;
|
||||||
if (ttistable(t)) { /* `t' is a table? */
|
if (slot != NULL) {
|
||||||
|
lua_assert(ttistable(t) && ttisnil(slot));
|
||||||
Table *h = hvalue(t);
|
Table *h = hvalue(t);
|
||||||
TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
|
/* must check the metamethod */
|
||||||
/* oldval is nil=> look for newindex, oldval is not nil => look for usedindex */
|
/* slot is nil=> look for newindex, slot is not nil => look for usedindex */
|
||||||
if (!((ttisnil(oldval) && ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) != NULL)) ||
|
if (!((ttisnil(slot) && ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) != NULL)) ||
|
||||||
((!ttisnil(oldval)) && ((tm = fasttm(L, h->metatable, TM_USEDINDEX)) != NULL)))) {
|
((!ttisnil(slot)) && ((tm = fasttm(L, h->metatable, TM_USEDINDEX)) != NULL)))) {
|
||||||
setobj2t(L, oldval, val);
|
/* no metamethod and (now) there is an entry with given key */
|
||||||
|
setobj2t(L, cast(TValue *, slot), val);
|
||||||
luaC_barriert(L, h, val);
|
luaC_barriert(L, h, val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* else will try the tag method */
|
/* else will try the metamethod */
|
||||||
}
|
}
|
||||||
else if (l_unlikely(ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))))
|
else { /* not a table; check metamethod */
|
||||||
luaG_typeerror(L, t, "index");
|
if (l_unlikely(ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))))
|
||||||
|
luaG_typeerror(L, t, "index");
|
||||||
|
}
|
||||||
|
/* try the metamethod */
|
||||||
if (ttisfunction(tm)) {
|
if (ttisfunction(tm)) {
|
||||||
callTM(L, tm, t, key, val);
|
callTM(L, tm, t, key, val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
t = tm; /* else repeat with `tm' */
|
t = tm; /* else repeat assignment over 'tm' */
|
||||||
|
if (luaV_fastset(L, t, key, slot, luaH_set, val))
|
||||||
|
return; /* done */
|
||||||
|
/* else loop */
|
||||||
}
|
}
|
||||||
luaG_runerror(L, "loop in settable");
|
luaG_runerror(L, "settable chain too long; possible loop");
|
||||||
}
|
}
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
|
||||||
static int call_binTM (lua_State *L, TValue *p1, TValue *p2,
|
static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
|
||||||
StkId res, TMS event) {
|
StkId res, TMS event) {
|
||||||
const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
|
const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
|
||||||
if (ttisnil(tm))
|
if (ttisnil(tm))
|
||||||
@@ -184,7 +217,7 @@ static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int call_orderTM (lua_State *L, TValue *p1, TValue *p2,
|
static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
|
||||||
TMS event) {
|
TMS event) {
|
||||||
const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
|
const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
|
||||||
const TValue *tm2;
|
const TValue *tm2;
|
||||||
@@ -366,6 +399,7 @@ static void Arith (lua_State *L, StkId ra, TValue *rb,
|
|||||||
|
|
||||||
|
|
||||||
#define arith_op(op,tm) { \
|
#define arith_op(op,tm) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
TValue *rb = RKB(i); \
|
TValue *rb = RKB(i); \
|
||||||
TValue *rc = RKC(i); \
|
TValue *rc = RKC(i); \
|
||||||
if (ttisnumber(rb) && ttisnumber(rc)) { \
|
if (ttisnumber(rb) && ttisnumber(rc)) { \
|
||||||
@@ -377,6 +411,24 @@ static void Arith (lua_State *L, StkId ra, TValue *rb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** copy of 'luaV_gettable', but protecting call to potential metamethod
|
||||||
|
** (which can reallocate the stack)
|
||||||
|
*/
|
||||||
|
#define gettableProtected(L,t,k,v) { const TValue *slot; \
|
||||||
|
if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
|
||||||
|
else Protect(luaV_finishget(L,t,k,v,slot)); }
|
||||||
|
|
||||||
|
|
||||||
|
/* same for 'luaV_settable' */
|
||||||
|
#define settableProtected(L,t,k,v) { const TValue *slot; \
|
||||||
|
if (!luaV_fastset(L,t,k,slot,luaH_set,v)) \
|
||||||
|
Protect(luaV_finishset(L,t,k,v,slot)); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void luaV_execute (lua_State *L, int nexeccalls) {
|
void luaV_execute (lua_State *L, int nexeccalls) {
|
||||||
LClosure *cl;
|
LClosure *cl;
|
||||||
@@ -386,13 +438,12 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
reentry: /* entry point */
|
reentry: /* entry point */
|
||||||
lua_assert(isLua(L->ci));
|
lua_assert(isLua(L->ci));
|
||||||
pc = L->savedpc;
|
pc = L->savedpc;
|
||||||
cl = &clvalue(L->ci->func)->l;
|
cl = &clvalue(L->ci->func)->l; /* local reference to function's closure */
|
||||||
base = L->base;
|
k = cl->p->k; /* local reference to function's constant table */
|
||||||
k = cl->p->k;
|
base = L->base; /* local copy of function's base */
|
||||||
/* main loop of interpreter */
|
/* main loop of interpreter */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
const Instruction i = *pc++;
|
const Instruction i = *pc++;
|
||||||
StkId ra;
|
|
||||||
if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
|
if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
|
||||||
(--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
|
(--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
|
||||||
traceexec(L, pc);
|
traceexec(L, pc);
|
||||||
@@ -402,26 +453,28 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
}
|
}
|
||||||
base = L->base;
|
base = L->base;
|
||||||
}
|
}
|
||||||
/* warning!! several calls may realloc the stack and invalidate `ra' */
|
|
||||||
ra = RA(i);
|
|
||||||
lua_assert(base == L->base && L->base == L->ci->base);
|
lua_assert(base == L->base && L->base == L->ci->base);
|
||||||
lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
|
lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
|
||||||
lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
|
lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
|
||||||
switch (GET_OPCODE(i)) {
|
switch (GET_OPCODE(i)) {
|
||||||
case OP_MOVE: {
|
case OP_MOVE: {
|
||||||
|
StkId ra = RA(i);
|
||||||
setobjs2s(L, ra, RB(i));
|
setobjs2s(L, ra, RB(i));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_LOADK: {
|
case OP_LOADK: {
|
||||||
|
StkId ra = RA(i);
|
||||||
setobj2s(L, ra, KBx(i));
|
setobj2s(L, ra, KBx(i));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_LOADBOOL: {
|
case OP_LOADBOOL: {
|
||||||
|
StkId ra = RA(i);
|
||||||
setbvalue(ra, GETARG_B(i));
|
setbvalue(ra, GETARG_B(i));
|
||||||
if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
|
if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_LOADNIL: {
|
case OP_LOADNIL: {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = RB(i);
|
TValue *rb = RB(i);
|
||||||
do {
|
do {
|
||||||
setnilvalue(rb--);
|
setnilvalue(rb--);
|
||||||
@@ -429,11 +482,13 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_GETUPVAL: {
|
case 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);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_GETGLOBAL: {
|
case OP_GETGLOBAL: {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue g;
|
TValue g;
|
||||||
TValue *rb = KBx(i);
|
TValue *rb = KBx(i);
|
||||||
sethvalue(L, &g, cl->env);
|
sethvalue(L, &g, cl->env);
|
||||||
@@ -442,10 +497,14 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_GETTABLE: {
|
case OP_GETTABLE: {
|
||||||
Protect(luaV_gettable(L, RB(i), RKC(i), ra));
|
StkId ra = RA(i);
|
||||||
|
StkId rb = RB(i);
|
||||||
|
TValue *rc = RKC(i);
|
||||||
|
gettableProtected(L, rb, rc, ra);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_SETGLOBAL: {
|
case OP_SETGLOBAL: {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue g;
|
TValue g;
|
||||||
sethvalue(L, &g, cl->env);
|
sethvalue(L, &g, cl->env);
|
||||||
lua_assert(ttisstring(KBx(i)));
|
lua_assert(ttisstring(KBx(i)));
|
||||||
@@ -453,16 +512,21 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_SETUPVAL: {
|
case OP_SETUPVAL: {
|
||||||
|
StkId ra = RA(i);
|
||||||
UpVal *uv = cl->upvals[GETARG_B(i)];
|
UpVal *uv = cl->upvals[GETARG_B(i)];
|
||||||
setobj(L, uv->v, ra);
|
setobj(L, uv->v, ra);
|
||||||
luaC_barrier(L, uv, ra);
|
luaC_barrier(L, uv, ra);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_SETTABLE: {
|
case OP_SETTABLE: {
|
||||||
Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
|
StkId ra = RA(i);
|
||||||
|
TValue *rb = RKB(i);
|
||||||
|
TValue *rc = RKC(i);
|
||||||
|
settableProtected(L, ra, rb, rc);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_NEWTABLE: {
|
case OP_NEWTABLE: {
|
||||||
|
StkId ra = RA(i);
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
int c = GETARG_C(i);
|
int c = GETARG_C(i);
|
||||||
sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
|
sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
|
||||||
@@ -470,9 +534,16 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_SELF: {
|
case OP_SELF: {
|
||||||
|
StkId ra = RA(i);
|
||||||
|
const TValue *slot;
|
||||||
StkId rb = RB(i);
|
StkId rb = RB(i);
|
||||||
setobjs2s(L, ra+1, rb);
|
TValue *rc = RKC(i);
|
||||||
Protect(luaV_gettable(L, rb, RKC(i), ra));
|
TString *key = rawtsvalue(rc); /* key must be a string */
|
||||||
|
setobjs2s(L, ra + 1, rb);
|
||||||
|
if (luaV_fastget(L, rb, key, slot, luaH_getstr)) {
|
||||||
|
setobj2s(L, ra, slot);
|
||||||
|
}
|
||||||
|
else Protect(luaV_finishget(L, rb, rc, ra, slot));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_ADD: {
|
case OP_ADD: {
|
||||||
@@ -488,6 +559,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_DIV: {
|
case OP_DIV: {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = RKB(i);
|
TValue *rb = RKB(i);
|
||||||
TValue *rc = RKC(i);
|
TValue *rc = RKC(i);
|
||||||
if (ttisnumber(rb) && ttisnumber(rc)) {
|
if (ttisnumber(rb) && ttisnumber(rc)) {
|
||||||
@@ -503,6 +575,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_MOD: {
|
case OP_MOD: {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = RKB(i);
|
TValue *rb = RKB(i);
|
||||||
TValue *rc = RKC(i);
|
TValue *rc = RKC(i);
|
||||||
if (ttisnumber(rb) && ttisnumber(rc)) {
|
if (ttisnumber(rb) && ttisnumber(rc)) {
|
||||||
@@ -522,26 +595,27 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_BAND: {
|
case OP_BAND: {
|
||||||
arith_op(luai_numand, TM_AND);
|
arith_op(luai_numand, TM_AND);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_BOR: {
|
case OP_BOR: {
|
||||||
arith_op(luai_numor, TM_OR);
|
arith_op(luai_numor, TM_OR);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_BXOR: {
|
case OP_BXOR: {
|
||||||
arith_op(luai_numxor, TM_XOR);
|
arith_op(luai_numxor, TM_XOR);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_BSHL: {
|
case OP_BSHL: {
|
||||||
arith_op(luai_numshl, TM_SHL);
|
arith_op(luai_numshl, TM_SHL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_BSHR: {
|
case OP_BSHR: {
|
||||||
arith_op(luai_numshr, TM_SHR);
|
arith_op(luai_numshr, TM_SHR);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_BNOT: {
|
case OP_BNOT: {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = RB(i);
|
TValue *rb = RB(i);
|
||||||
if (ttisnumber(rb)) {
|
if (ttisnumber(rb)) {
|
||||||
lua_Number nb = nvalue(rb);
|
lua_Number nb = nvalue(rb);
|
||||||
@@ -553,6 +627,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_UNM: {
|
case OP_UNM: {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = RB(i);
|
TValue *rb = RB(i);
|
||||||
if (ttisnumber(rb)) {
|
if (ttisnumber(rb)) {
|
||||||
lua_Number nb = nvalue(rb);
|
lua_Number nb = nvalue(rb);
|
||||||
@@ -564,11 +639,13 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_NOT: {
|
case OP_NOT: {
|
||||||
|
StkId ra = RA(i);
|
||||||
int res = l_isfalse(RB(i)); /* next assignment may change this value */
|
int res = l_isfalse(RB(i)); /* next assignment may change this value */
|
||||||
setbvalue(ra, res);
|
setbvalue(ra, res);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_LEN: {
|
case OP_LEN: {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = RB(i);
|
TValue *rb = RB(i);
|
||||||
switch (ttype(rb)) {
|
switch (ttype(rb)) {
|
||||||
case LUA_TTABLE: {
|
case LUA_TTABLE: {
|
||||||
@@ -626,12 +703,14 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_TEST: {
|
case OP_TEST: {
|
||||||
|
StkId ra = RA(i);
|
||||||
if (l_isfalse(ra) != GETARG_C(i))
|
if (l_isfalse(ra) != GETARG_C(i))
|
||||||
dojump(L, pc, GETARG_sBx(*pc));
|
dojump(L, pc, GETARG_sBx(*pc));
|
||||||
pc++;
|
pc++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_TESTSET: {
|
case OP_TESTSET: {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = RB(i);
|
TValue *rb = RB(i);
|
||||||
if (l_isfalse(rb) != GETARG_C(i)) {
|
if (l_isfalse(rb) != GETARG_C(i)) {
|
||||||
setobjs2s(L, ra, rb);
|
setobjs2s(L, ra, rb);
|
||||||
@@ -641,6 +720,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_CALL: {
|
case OP_CALL: {
|
||||||
|
StkId ra = RA(i);
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
int nresults = GETARG_C(i) - 1;
|
int nresults = GETARG_C(i) - 1;
|
||||||
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
||||||
@@ -662,6 +742,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case OP_TAILCALL: {
|
case OP_TAILCALL: {
|
||||||
|
StkId ra = RA(i);
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
||||||
L->savedpc = pc;
|
L->savedpc = pc;
|
||||||
@@ -694,6 +775,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case OP_RETURN: {
|
case OP_RETURN: {
|
||||||
|
StkId ra = RA(i);
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
if (b != 0) L->top = ra+b-1;
|
if (b != 0) L->top = ra+b-1;
|
||||||
if (L->openupval) luaF_close(L, base);
|
if (L->openupval) luaF_close(L, base);
|
||||||
@@ -709,6 +791,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case OP_FORLOOP: {
|
case OP_FORLOOP: {
|
||||||
|
StkId ra = RA(i);
|
||||||
lua_Number step = nvalue(ra+2);
|
lua_Number step = nvalue(ra+2);
|
||||||
lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
|
lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
|
||||||
lua_Number limit = nvalue(ra+1);
|
lua_Number limit = nvalue(ra+1);
|
||||||
@@ -721,6 +804,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_FORPREP: {
|
case OP_FORPREP: {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *init = ra;
|
const TValue *init = ra;
|
||||||
const TValue *plimit = ra+1;
|
const TValue *plimit = ra+1;
|
||||||
const TValue *pstep = ra+2;
|
const TValue *pstep = ra+2;
|
||||||
@@ -737,6 +821,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_TFORLOOP: {
|
case OP_TFORLOOP: {
|
||||||
|
StkId ra = RA(i);
|
||||||
StkId cb = ra + 3; /* call base */
|
StkId cb = ra + 3; /* call base */
|
||||||
setobjs2s(L, cb+2, ra+2);
|
setobjs2s(L, cb+2, ra+2);
|
||||||
setobjs2s(L, cb+1, ra+1);
|
setobjs2s(L, cb+1, ra+1);
|
||||||
@@ -753,6 +838,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_SETLIST: {
|
case OP_SETLIST: {
|
||||||
|
StkId ra = RA(i);
|
||||||
int n = GETARG_B(i);
|
int n = GETARG_B(i);
|
||||||
int c = GETARG_C(i);
|
int c = GETARG_C(i);
|
||||||
int last;
|
int last;
|
||||||
@@ -775,10 +861,12 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_CLOSE: {
|
case OP_CLOSE: {
|
||||||
|
StkId ra = RA(i);
|
||||||
luaF_close(L, ra);
|
luaF_close(L, ra);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_CLOSURE: {
|
case OP_CLOSURE: {
|
||||||
|
StkId ra = RA(i);
|
||||||
Proto *p;
|
Proto *p;
|
||||||
Closure *ncl;
|
Closure *ncl;
|
||||||
int nup, j;
|
int nup, j;
|
||||||
@@ -799,6 +887,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OP_VARARG: {
|
case OP_VARARG: {
|
||||||
|
StkId ra = RA(i);
|
||||||
int b = GETARG_B(i) - 1;
|
int b = GETARG_B(i) - 1;
|
||||||
int j;
|
int j;
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
@@ -822,3 +911,5 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
+51
-4
@@ -22,14 +22,61 @@
|
|||||||
(ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
|
(ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** fast track for 'gettable': if 't' is a table and 't[k]' is not nil,
|
||||||
|
** return 1 with 'slot' pointing to 't[k]' (final result). Otherwise,
|
||||||
|
** return 0 (meaning it will have to check metamethod) with 'slot'
|
||||||
|
** pointing to a nil 't[k]' (if 't' is a table) or NULL (otherwise).
|
||||||
|
** 'f' is the raw get function to use.
|
||||||
|
*/
|
||||||
|
#define luaV_fastget(L,t,k,slot,f) \
|
||||||
|
(!ttistable(t) \
|
||||||
|
? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
|
||||||
|
: (slot = f(hvalue(t), k), /* else, do raw access */ \
|
||||||
|
!ttisnil(slot))) /* result not nil? */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** standard implementation for 'gettable'
|
||||||
|
*/
|
||||||
|
#define luaV_gettable(L,t,k,v) { const TValue *slot; \
|
||||||
|
if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
|
||||||
|
else luaV_finishget(L,t,k,v,slot); }
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Fast track for set table. If 't' is a table and 't[k]' is not nil,
|
||||||
|
** call GC barrier, do a raw 't[k]=v', and return true; otherwise,
|
||||||
|
** return false with 'slot' equal to NULL (if 't' is not a table) or
|
||||||
|
** 'nil'. (This is needed by 'luaV_finishget'.) Note that, if the macro
|
||||||
|
** returns true, there is no need to 'invalidateTMcache', because the
|
||||||
|
** call is not creating a new entry.
|
||||||
|
*/
|
||||||
|
#define luaV_fastset(L,t,k,slot,f,v) \
|
||||||
|
(!ttistable(t) \
|
||||||
|
? (slot = NULL, 0) \
|
||||||
|
: (slot = f(L, hvalue(t), k), \
|
||||||
|
ttisnil(slot) ? 0 \
|
||||||
|
: (__extension__ ({ \
|
||||||
|
if (valiswhite(v) && isblack(obj2gco(hvalue(t)))) \
|
||||||
|
luaC_barrierback(L, hvalue(t)); \
|
||||||
|
setobj2t(L, cast(TValue *,slot), v); \
|
||||||
|
1; \
|
||||||
|
}))))
|
||||||
|
|
||||||
|
#define luaV_settable(L,t,k,v) { const TValue *slot; \
|
||||||
|
if (!luaV_fastset(L,t,k,slot,luaH_set,v)) \
|
||||||
|
luaV_finishset(L,t,k,v,slot); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LUAI_FUNC int luaV_lessthan (lua_State *L, TValue *l, TValue *r);
|
LUAI_FUNC int luaV_lessthan (lua_State *L, TValue *l, TValue *r);
|
||||||
LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
|
LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
|
||||||
LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
|
LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
|
||||||
LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
|
LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
|
||||||
LUAI_FUNC void luaV_gettable (lua_State *L, TValue *t, TValue *key,
|
LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
|
||||||
StkId val);
|
StkId val, const TValue *tm);
|
||||||
LUAI_FUNC void luaV_settable (lua_State *L, TValue *t, TValue *key,
|
LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
|
||||||
StkId val);
|
StkId val, const TValue *oldval);
|
||||||
LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls);
|
LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls);
|
||||||
LUAI_FUNC void luaV_concat (lua_State *L, int total, int last);
|
LUAI_FUNC void luaV_concat (lua_State *L, int total, int last);
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user