mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-25 12:43:09 +00:00
update to lua 5.3.1
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
PLAT= none
|
PLAT= none
|
||||||
|
|
||||||
CC= gcc -std=gnu99
|
CC= gcc -std=gnu99
|
||||||
CFLAGS= -O2 -Wall -Wextra $(SYSCFLAGS) $(MYCFLAGS)
|
CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_2 $(SYSCFLAGS) $(MYCFLAGS)
|
||||||
LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
|
LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
|
||||||
LIBS= -lm $(SYSLIBS) $(MYLIBS)
|
LIBS= -lm $(SYSLIBS) $(MYLIBS)
|
||||||
|
|
||||||
@@ -130,68 +130,68 @@ solaris:
|
|||||||
# DO NOT DELETE
|
# DO NOT DELETE
|
||||||
|
|
||||||
lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
||||||
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \
|
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \
|
||||||
ltable.h lundump.h lvm.h
|
ltable.h lundump.h lvm.h
|
||||||
lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h
|
lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h
|
||||||
lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||||
lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||||
lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
|
lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
|
||||||
llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
|
llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
|
||||||
ldo.h lgc.h lstring.h ltable.h lvm.h
|
ldo.h lgc.h lstring.h ltable.h lvm.h
|
||||||
lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||||
lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h
|
lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h
|
||||||
ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||||
ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
||||||
lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \
|
lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \
|
||||||
ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h
|
ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h
|
||||||
ldo.o: ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
ldo.o: ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
||||||
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \
|
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \
|
||||||
lparser.h lstring.h ltable.h lundump.h lvm.h
|
lparser.h lstring.h ltable.h lundump.h lvm.h
|
||||||
ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \
|
ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \
|
||||||
ltm.h lzio.h lmem.h lundump.h
|
ltm.h lzio.h lmem.h lundump.h
|
||||||
lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \
|
lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \
|
||||||
lgc.h lstate.h ltm.h lzio.h lmem.h
|
lgc.h lstate.h ltm.h lzio.h lmem.h
|
||||||
lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
||||||
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
|
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
|
||||||
linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h
|
linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h
|
||||||
liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||||
llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldo.h \
|
llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h \
|
||||||
lobject.h lstate.h ltm.h lzio.h lmem.h lgc.h llex.h lparser.h lstring.h \
|
lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h llex.h lparser.h \
|
||||||
ltable.h
|
lstring.h ltable.h
|
||||||
lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||||
lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
||||||
llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h
|
llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h
|
||||||
loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||||
lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \
|
lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \
|
||||||
ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \
|
ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \
|
||||||
lvm.h
|
lvm.h
|
||||||
lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h
|
lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h
|
||||||
loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||||
lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
|
lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
|
||||||
llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
|
llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
|
||||||
ldo.h lfunc.h lstring.h lgc.h ltable.h
|
ldo.h lfunc.h lstring.h lgc.h ltable.h
|
||||||
lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
||||||
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \
|
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \
|
||||||
lstring.h ltable.h
|
lstring.h ltable.h
|
||||||
lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
|
lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
|
||||||
lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h
|
lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h
|
||||||
lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||||
ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
||||||
llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
|
llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
|
||||||
ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||||
ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
||||||
llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h
|
llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h
|
||||||
lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||||
luac.o: luac.c lprefix.h lua.h luaconf.h lauxlib.h lobject.h llimits.h \
|
luac.o: luac.c lprefix.h lua.h luaconf.h lauxlib.h lobject.h llimits.h \
|
||||||
lstate.h ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h
|
lstate.h ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h
|
||||||
lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
|
lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
|
||||||
lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \
|
lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \
|
||||||
lundump.h
|
lundump.h
|
||||||
lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||||
lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
||||||
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \
|
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \
|
||||||
ltable.h lvm.h
|
ltable.h lvm.h
|
||||||
lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \
|
lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \
|
||||||
lobject.h ltm.h lzio.h
|
lobject.h ltm.h lzio.h
|
||||||
|
|
||||||
# (end of Makefile)
|
# (end of Makefile)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
This is a modify version of lua 5.3.0 (http://www.lua.org/ftp/lua-5.3.0.tar.gz) .
|
This is a modify version of lua 5.3.1 (http://www.lua.org/ftp/lua-5.3.1.tar.gz) .
|
||||||
|
|
||||||
For detail : http://lua-users.org/lists/lua-l/2014-03/msg00489.html
|
For detail : http://lua-users.org/lists/lua-l/2014-03/msg00489.html
|
||||||
|
|
||||||
|
|||||||
179
3rd/lua/lapi.c
179
3rd/lua/lapi.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lapi.c,v 2.244 2014/12/26 14:43:45 roberto Exp $
|
** $Id: lapi.c,v 2.249 2015/04/06 12:23:48 roberto Exp $
|
||||||
** Lua API
|
** Lua API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -28,7 +28,6 @@
|
|||||||
#include "ltm.h"
|
#include "ltm.h"
|
||||||
#include "lundump.h"
|
#include "lundump.h"
|
||||||
#include "lvm.h"
|
#include "lvm.h"
|
||||||
#include "lfunc.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -52,29 +51,29 @@ const char lua_ident[] =
|
|||||||
/* test for valid but not pseudo index */
|
/* test for valid but not pseudo index */
|
||||||
#define isstackindex(i, o) (isvalid(o) && !ispseudo(i))
|
#define isstackindex(i, o) (isvalid(o) && !ispseudo(i))
|
||||||
|
|
||||||
#define api_checkvalidindex(o) api_check(isvalid(o), "invalid index")
|
#define api_checkvalidindex(l,o) api_check(l, isvalid(o), "invalid index")
|
||||||
|
|
||||||
#define api_checkstackindex(i, o) \
|
#define api_checkstackindex(l, i, o) \
|
||||||
api_check(isstackindex(i, o), "index not in the stack")
|
api_check(l, isstackindex(i, o), "index not in the stack")
|
||||||
|
|
||||||
|
|
||||||
static TValue *index2addr (lua_State *L, int idx) {
|
static TValue *index2addr (lua_State *L, int idx) {
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
if (idx > 0) {
|
if (idx > 0) {
|
||||||
TValue *o = ci->func + idx;
|
TValue *o = ci->func + idx;
|
||||||
api_check(idx <= ci->top - (ci->func + 1), "unacceptable index");
|
api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
|
||||||
if (o >= L->top) return NONVALIDVALUE;
|
if (o >= L->top) return NONVALIDVALUE;
|
||||||
else return o;
|
else return o;
|
||||||
}
|
}
|
||||||
else if (!ispseudo(idx)) { /* negative index */
|
else if (!ispseudo(idx)) { /* negative index */
|
||||||
api_check(idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
|
api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
|
||||||
return L->top + idx;
|
return L->top + idx;
|
||||||
}
|
}
|
||||||
else if (idx == LUA_REGISTRYINDEX)
|
else if (idx == LUA_REGISTRYINDEX)
|
||||||
return &G(L)->l_registry;
|
return &G(L)->l_registry;
|
||||||
else { /* upvalues */
|
else { /* upvalues */
|
||||||
idx = LUA_REGISTRYINDEX - idx;
|
idx = LUA_REGISTRYINDEX - idx;
|
||||||
api_check(idx <= MAXUPVAL + 1, "upvalue index too large");
|
api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
|
||||||
if (ttislcf(ci->func)) /* light C function? */
|
if (ttislcf(ci->func)) /* light C function? */
|
||||||
return NONVALIDVALUE; /* it has no upvalues */
|
return NONVALIDVALUE; /* it has no upvalues */
|
||||||
else {
|
else {
|
||||||
@@ -99,7 +98,7 @@ LUA_API int lua_checkstack (lua_State *L, int n) {
|
|||||||
int res;
|
int res;
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_check(n >= 0, "negative 'n'");
|
api_check(L, n >= 0, "negative 'n'");
|
||||||
if (L->stack_last - L->top > n) /* stack large enough? */
|
if (L->stack_last - L->top > n) /* stack large enough? */
|
||||||
res = 1; /* yes; check is OK */
|
res = 1; /* yes; check is OK */
|
||||||
else { /* no; need to grow stack */
|
else { /* no; need to grow stack */
|
||||||
@@ -121,11 +120,12 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
|
|||||||
if (from == to) return;
|
if (from == to) return;
|
||||||
lua_lock(to);
|
lua_lock(to);
|
||||||
api_checknelems(from, n);
|
api_checknelems(from, n);
|
||||||
api_check(G(from) == G(to), "moving among independent states");
|
api_check(from, G(from) == G(to), "moving among independent states");
|
||||||
api_check(to->ci->top - to->top >= n, "not enough elements to move");
|
api_check(from, to->ci->top - to->top >= n, "not enough elements to move");
|
||||||
from->top -= n;
|
from->top -= n;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
setobj2s(to, to->top++, from->top + i);
|
setobj2s(to, to->top, from->top + i);
|
||||||
|
api_incr_top(to);
|
||||||
}
|
}
|
||||||
lua_unlock(to);
|
lua_unlock(to);
|
||||||
}
|
}
|
||||||
@@ -160,7 +160,7 @@ LUA_API const lua_Number *lua_version (lua_State *L) {
|
|||||||
LUA_API int lua_absindex (lua_State *L, int idx) {
|
LUA_API int lua_absindex (lua_State *L, int idx) {
|
||||||
return (idx > 0 || ispseudo(idx))
|
return (idx > 0 || ispseudo(idx))
|
||||||
? idx
|
? idx
|
||||||
: cast_int(L->top - L->ci->func + idx);
|
: cast_int(L->top - L->ci->func) + idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -173,13 +173,13 @@ LUA_API void lua_settop (lua_State *L, int idx) {
|
|||||||
StkId func = L->ci->func;
|
StkId func = L->ci->func;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
api_check(idx <= L->stack_last - (func + 1), "new top too large");
|
api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
|
||||||
while (L->top < (func + 1) + idx)
|
while (L->top < (func + 1) + idx)
|
||||||
setnilvalue(L->top++);
|
setnilvalue(L->top++);
|
||||||
L->top = (func + 1) + idx;
|
L->top = (func + 1) + idx;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
api_check(-(idx+1) <= (L->top - (func + 1)), "invalid new top");
|
api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
|
||||||
L->top += idx+1; /* 'subtract' index (index is negative) */
|
L->top += idx+1; /* 'subtract' index (index is negative) */
|
||||||
}
|
}
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
@@ -209,8 +209,8 @@ LUA_API void lua_rotate (lua_State *L, int idx, int n) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = L->top - 1; /* end of stack segment being rotated */
|
t = L->top - 1; /* end of stack segment being rotated */
|
||||||
p = index2addr(L, idx); /* start of segment */
|
p = index2addr(L, idx); /* start of segment */
|
||||||
api_checkstackindex(idx, p);
|
api_checkstackindex(L, idx, p);
|
||||||
api_check((n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
|
api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
|
||||||
m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */
|
m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */
|
||||||
reverse(L, p, m); /* reverse the prefix with length 'n' */
|
reverse(L, p, m); /* reverse the prefix with length 'n' */
|
||||||
reverse(L, m + 1, t); /* reverse the suffix */
|
reverse(L, m + 1, t); /* reverse the suffix */
|
||||||
@@ -224,7 +224,7 @@ LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
fr = index2addr(L, fromidx);
|
fr = index2addr(L, fromidx);
|
||||||
to = index2addr(L, toidx);
|
to = index2addr(L, toidx);
|
||||||
api_checkvalidindex(to);
|
api_checkvalidindex(L, to);
|
||||||
setobj(L, to, fr);
|
setobj(L, to, fr);
|
||||||
if (isupvalue(toidx)) /* function upvalue? */
|
if (isupvalue(toidx)) /* function upvalue? */
|
||||||
luaC_barrier(L, clCvalue(L->ci->func), fr);
|
luaC_barrier(L, clCvalue(L->ci->func), fr);
|
||||||
@@ -256,7 +256,7 @@ LUA_API int lua_type (lua_State *L, int idx) {
|
|||||||
|
|
||||||
LUA_API const char *lua_typename (lua_State *L, int t) {
|
LUA_API const char *lua_typename (lua_State *L, int t) {
|
||||||
UNUSED(L);
|
UNUSED(L);
|
||||||
api_check(LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag");
|
api_check(L, LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag");
|
||||||
return ttypename(t);
|
return ttypename(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,7 +306,7 @@ LUA_API void lua_arith (lua_State *L, int op) {
|
|||||||
else { /* for unary operations, add fake 2nd operand */
|
else { /* for unary operations, add fake 2nd operand */
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
setobjs2s(L, L->top, L->top - 1);
|
setobjs2s(L, L->top, L->top - 1);
|
||||||
L->top++;
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
/* first operand at top - 2, second at top - 1; result go to top - 2 */
|
/* first operand at top - 2, second at top - 1; result go to top - 2 */
|
||||||
luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2);
|
luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2);
|
||||||
@@ -326,7 +326,7 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
|
|||||||
case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
|
case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
|
||||||
case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
|
case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
|
||||||
case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
|
case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
|
||||||
default: api_check(0, "invalid option");
|
default: api_check(L, 0, "invalid option");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
@@ -383,15 +383,17 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
|
|||||||
luaO_tostring(L, o);
|
luaO_tostring(L, o);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
if (len != NULL) *len = tsvalue(o)->len;
|
if (len != NULL)
|
||||||
|
*len = vslen(o);
|
||||||
return svalue(o);
|
return svalue(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LUA_API size_t lua_rawlen (lua_State *L, int idx) {
|
LUA_API size_t lua_rawlen (lua_State *L, int idx) {
|
||||||
StkId o = index2addr(L, idx);
|
StkId o = index2addr(L, idx);
|
||||||
switch (ttnov(o)) {
|
switch (ttype(o)) {
|
||||||
case LUA_TSTRING: return tsvalue(o)->len;
|
case LUA_TSHRSTR: return tsvalue(o)->shrlen;
|
||||||
|
case LUA_TLNGSTR: return tsvalue(o)->u.lnglen;
|
||||||
case LUA_TUSERDATA: return uvalue(o)->len;
|
case LUA_TUSERDATA: return uvalue(o)->len;
|
||||||
case LUA_TTABLE: return luaH_getn(hvalue(o));
|
case LUA_TTABLE: return luaH_getn(hvalue(o));
|
||||||
default: return 0;
|
default: return 0;
|
||||||
@@ -432,9 +434,8 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) {
|
|||||||
case LUA_TCCL: return clCvalue(o);
|
case LUA_TCCL: return clCvalue(o);
|
||||||
case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
|
case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
|
||||||
case LUA_TTHREAD: return thvalue(o);
|
case LUA_TTHREAD: return thvalue(o);
|
||||||
case LUA_TUSERDATA:
|
case LUA_TUSERDATA: return getudatamem(uvalue(o));
|
||||||
case LUA_TLIGHTUSERDATA:
|
case LUA_TLIGHTUSERDATA: return pvalue(o);
|
||||||
return lua_touserdata(L, idx);
|
|
||||||
default: return NULL;
|
default: return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -483,20 +484,19 @@ LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
|
|||||||
|
|
||||||
|
|
||||||
LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
|
LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
|
||||||
if (s == NULL) {
|
lua_lock(L);
|
||||||
lua_pushnil(L);
|
if (s == NULL)
|
||||||
return NULL;
|
setnilvalue(L->top);
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
TString *ts;
|
TString *ts;
|
||||||
lua_lock(L);
|
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
ts = luaS_new(L, s);
|
ts = luaS_new(L, s);
|
||||||
setsvalue2s(L, L->top, ts);
|
setsvalue2s(L, L->top, ts);
|
||||||
api_incr_top(L);
|
s = getstr(ts); /* internal copy's address */
|
||||||
lua_unlock(L);
|
|
||||||
return getstr(ts);
|
|
||||||
}
|
}
|
||||||
|
api_incr_top(L);
|
||||||
|
lua_unlock(L);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -532,7 +532,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
|||||||
else {
|
else {
|
||||||
CClosure *cl;
|
CClosure *cl;
|
||||||
api_checknelems(L, n);
|
api_checknelems(L, n);
|
||||||
api_check(n <= MAXUPVAL, "upvalue index too large");
|
api_check(L, n <= MAXUPVAL, "upvalue index too large");
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
cl = luaF_newCclosure(L, n);
|
cl = luaF_newCclosure(L, n);
|
||||||
cl->f = fn;
|
cl->f = fn;
|
||||||
@@ -584,7 +584,8 @@ LUA_API int lua_getglobal (lua_State *L, const char *name) {
|
|||||||
const TValue *gt; /* global table */
|
const TValue *gt; /* global table */
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
|
gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
|
||||||
setsvalue2s(L, L->top++, luaS_new(L, name));
|
setsvalue2s(L, L->top, luaS_new(L, name));
|
||||||
|
api_incr_top(L);
|
||||||
luaV_gettable(L, gt, L->top - 1, L->top - 1);
|
luaV_gettable(L, gt, L->top - 1, L->top - 1);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ttnov(L->top - 1);
|
return ttnov(L->top - 1);
|
||||||
@@ -629,7 +630,7 @@ LUA_API int lua_rawget (lua_State *L, int idx) {
|
|||||||
StkId t;
|
StkId t;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = index2addr(L, idx);
|
t = index2addr(L, idx);
|
||||||
api_check(ttistable(t), "table expected");
|
api_check(L, ttistable(t), "table expected");
|
||||||
setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
|
setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ttnov(L->top - 1);
|
return ttnov(L->top - 1);
|
||||||
@@ -640,7 +641,7 @@ LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
|
|||||||
StkId t;
|
StkId t;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = index2addr(L, idx);
|
t = index2addr(L, idx);
|
||||||
api_check(ttistable(t), "table expected");
|
api_check(L, ttistable(t), "table expected");
|
||||||
setobj2s(L, L->top, luaH_getint(hvalue(t), n));
|
setobj2s(L, L->top, luaH_getint(hvalue(t), n));
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
@@ -653,7 +654,7 @@ LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
|
|||||||
TValue k;
|
TValue k;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = index2addr(L, idx);
|
t = index2addr(L, idx);
|
||||||
api_check(ttistable(t), "table expected");
|
api_check(L, ttistable(t), "table expected");
|
||||||
setpvalue(&k, cast(void *, p));
|
setpvalue(&k, cast(void *, p));
|
||||||
setobj2s(L, L->top, luaH_get(hvalue(t), &k));
|
setobj2s(L, L->top, luaH_get(hvalue(t), &k));
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
@@ -706,7 +707,7 @@ LUA_API int lua_getuservalue (lua_State *L, int idx) {
|
|||||||
StkId o;
|
StkId o;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
o = index2addr(L, idx);
|
o = index2addr(L, idx);
|
||||||
api_check(ttisfulluserdata(o), "full userdata expected");
|
api_check(L, ttisfulluserdata(o), "full userdata expected");
|
||||||
getuservalue(L, uvalue(o), L->top);
|
getuservalue(L, uvalue(o), L->top);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
@@ -725,7 +726,8 @@ LUA_API void lua_setglobal (lua_State *L, const char *name) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
|
gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
|
||||||
setsvalue2s(L, L->top++, luaS_new(L, name));
|
setsvalue2s(L, L->top, luaS_new(L, name));
|
||||||
|
api_incr_top(L);
|
||||||
luaV_settable(L, gt, L->top - 1, L->top - 2);
|
luaV_settable(L, gt, L->top - 1, L->top - 2);
|
||||||
L->top -= 2; /* pop value and key */
|
L->top -= 2; /* pop value and key */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
@@ -748,7 +750,8 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
t = index2addr(L, idx);
|
t = index2addr(L, idx);
|
||||||
setsvalue2s(L, L->top++, luaS_new(L, k));
|
setsvalue2s(L, L->top, luaS_new(L, k));
|
||||||
|
api_incr_top(L);
|
||||||
luaV_settable(L, t, L->top - 1, L->top - 2);
|
luaV_settable(L, t, L->top - 1, L->top - 2);
|
||||||
L->top -= 2; /* pop value and key */
|
L->top -= 2; /* pop value and key */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
@@ -760,7 +763,8 @@ LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
t = index2addr(L, idx);
|
t = index2addr(L, idx);
|
||||||
setivalue(L->top++, n);
|
setivalue(L->top, n);
|
||||||
|
api_incr_top(L);
|
||||||
luaV_settable(L, t, L->top - 1, L->top - 2);
|
luaV_settable(L, t, L->top - 1, L->top - 2);
|
||||||
L->top -= 2; /* pop value and key */
|
L->top -= 2; /* pop value and key */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
@@ -773,7 +777,7 @@ LUA_API void lua_rawset (lua_State *L, int idx) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 2);
|
api_checknelems(L, 2);
|
||||||
o = index2addr(L, idx);
|
o = index2addr(L, idx);
|
||||||
api_check(ttistable(o), "table expected");
|
api_check(L, ttistable(o), "table expected");
|
||||||
t = hvalue(o);
|
t = hvalue(o);
|
||||||
setobj2t(L, luaH_set(L, t, L->top-2), L->top-1);
|
setobj2t(L, luaH_set(L, t, L->top-2), L->top-1);
|
||||||
invalidateTMcache(t);
|
invalidateTMcache(t);
|
||||||
@@ -789,7 +793,7 @@ LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
o = index2addr(L, idx);
|
o = index2addr(L, idx);
|
||||||
api_check(ttistable(o), "table expected");
|
api_check(L, ttistable(o), "table expected");
|
||||||
t = hvalue(o);
|
t = hvalue(o);
|
||||||
luaH_setint(L, t, n, L->top - 1);
|
luaH_setint(L, t, n, L->top - 1);
|
||||||
luaC_barrierback(L, t, L->top-1);
|
luaC_barrierback(L, t, L->top-1);
|
||||||
@@ -805,7 +809,7 @@ LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
o = index2addr(L, idx);
|
o = index2addr(L, idx);
|
||||||
api_check(ttistable(o), "table expected");
|
api_check(L, ttistable(o), "table expected");
|
||||||
t = hvalue(o);
|
t = hvalue(o);
|
||||||
setpvalue(&k, cast(void *, p));
|
setpvalue(&k, cast(void *, p));
|
||||||
setobj2t(L, luaH_set(L, t, &k), L->top - 1);
|
setobj2t(L, luaH_set(L, t, &k), L->top - 1);
|
||||||
@@ -824,7 +828,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
|
|||||||
if (ttisnil(L->top - 1))
|
if (ttisnil(L->top - 1))
|
||||||
mt = NULL;
|
mt = NULL;
|
||||||
else {
|
else {
|
||||||
api_check(ttistable(L->top - 1), "table expected");
|
api_check(L, ttistable(L->top - 1), "table expected");
|
||||||
mt = hvalue(L->top - 1);
|
mt = hvalue(L->top - 1);
|
||||||
}
|
}
|
||||||
switch (ttnov(obj)) {
|
switch (ttnov(obj)) {
|
||||||
@@ -860,7 +864,7 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
o = index2addr(L, idx);
|
o = index2addr(L, idx);
|
||||||
api_check(ttisfulluserdata(o), "full userdata expected");
|
api_check(L, ttisfulluserdata(o), "full userdata expected");
|
||||||
setuservalue(L, uvalue(o), L->top - 1);
|
setuservalue(L, uvalue(o), L->top - 1);
|
||||||
luaC_barrier(L, gcvalue(o), L->top - 1);
|
luaC_barrier(L, gcvalue(o), L->top - 1);
|
||||||
L->top--;
|
L->top--;
|
||||||
@@ -874,7 +878,7 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) {
|
|||||||
|
|
||||||
|
|
||||||
#define checkresults(L,na,nr) \
|
#define checkresults(L,na,nr) \
|
||||||
api_check((nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
|
api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
|
||||||
"results from function overflow current stack size")
|
"results from function overflow current stack size")
|
||||||
|
|
||||||
|
|
||||||
@@ -882,10 +886,10 @@ LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
|
|||||||
lua_KContext ctx, lua_KFunction k) {
|
lua_KContext ctx, lua_KFunction k) {
|
||||||
StkId func;
|
StkId func;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_check(k == NULL || !isLua(L->ci),
|
api_check(L, k == NULL || !isLua(L->ci),
|
||||||
"cannot use continuations inside hooks");
|
"cannot use continuations inside hooks");
|
||||||
api_checknelems(L, nargs+1);
|
api_checknelems(L, nargs+1);
|
||||||
api_check(L->status == LUA_OK, "cannot do calls on non-normal thread");
|
api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
|
||||||
checkresults(L, nargs, nresults);
|
checkresults(L, nargs, nresults);
|
||||||
func = L->top - (nargs+1);
|
func = L->top - (nargs+1);
|
||||||
if (k != NULL && L->nny == 0) { /* need to prepare continuation? */
|
if (k != NULL && L->nny == 0) { /* need to prepare continuation? */
|
||||||
@@ -923,16 +927,16 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
|
|||||||
int status;
|
int status;
|
||||||
ptrdiff_t func;
|
ptrdiff_t func;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_check(k == NULL || !isLua(L->ci),
|
api_check(L, k == NULL || !isLua(L->ci),
|
||||||
"cannot use continuations inside hooks");
|
"cannot use continuations inside hooks");
|
||||||
api_checknelems(L, nargs+1);
|
api_checknelems(L, nargs+1);
|
||||||
api_check(L->status == LUA_OK, "cannot do calls on non-normal thread");
|
api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
|
||||||
checkresults(L, nargs, nresults);
|
checkresults(L, nargs, nresults);
|
||||||
if (errfunc == 0)
|
if (errfunc == 0)
|
||||||
func = 0;
|
func = 0;
|
||||||
else {
|
else {
|
||||||
StkId o = index2addr(L, errfunc);
|
StkId o = index2addr(L, errfunc);
|
||||||
api_checkstackindex(errfunc, o);
|
api_checkstackindex(L, errfunc, o);
|
||||||
func = savestack(L, o);
|
func = savestack(L, o);
|
||||||
}
|
}
|
||||||
c.func = L->top - (nargs+1); /* function to be called */
|
c.func = L->top - (nargs+1); /* function to be called */
|
||||||
@@ -985,59 +989,6 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Proto * cloneproto (lua_State *L, const Proto *src) {
|
|
||||||
/* copy constants and nested proto */
|
|
||||||
int i,n;
|
|
||||||
Proto *f = luaF_newproto(L, src->sp);
|
|
||||||
n = src->sp->sizek;
|
|
||||||
f->k=luaM_newvector(L,n,TValue);
|
|
||||||
for (i=0; i<n; i++) setnilvalue(&f->k[i]);
|
|
||||||
for (i=0; i<n; i++) {
|
|
||||||
const TValue *s=&src->k[i];
|
|
||||||
TValue *o=&f->k[i];
|
|
||||||
if (ttisstring(s)) {
|
|
||||||
TString * str = luaS_newlstr(L,svalue(s),tsvalue(s)->len);
|
|
||||||
setsvalue2n(L,o,str);
|
|
||||||
} else {
|
|
||||||
setobj(L,o,s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n = src->sp->sizep;
|
|
||||||
f->p=luaM_newvector(L,n,struct Proto *);
|
|
||||||
for (i=0; i<n; i++) f->p[i]=NULL;
|
|
||||||
for (i=0; i<n; i++) {
|
|
||||||
f->p[i]=cloneproto(L, src->p[i]);
|
|
||||||
}
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
LUA_API void lua_clonefunction (lua_State *L, const void * fp) {
|
|
||||||
LClosure *cl;
|
|
||||||
LClosure *f = cast(LClosure *, fp);
|
|
||||||
lua_lock(L);
|
|
||||||
if (f->p->sp->l_G == G(L)) {
|
|
||||||
setclLvalue(L,L->top,f);
|
|
||||||
api_incr_top(L);
|
|
||||||
lua_unlock(L);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cl = luaF_newLclosure(L,f->nupvalues);
|
|
||||||
cl->p = cloneproto(L, f->p);
|
|
||||||
setclLvalue(L,L->top,cl);
|
|
||||||
api_incr_top(L);
|
|
||||||
luaF_initupvals(L, cl);
|
|
||||||
|
|
||||||
if (cl->nupvalues >= 1) { /* does it have an upvalue? */
|
|
||||||
/* get global table from registry */
|
|
||||||
Table *reg = hvalue(&G(L)->l_registry);
|
|
||||||
const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
|
|
||||||
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
|
|
||||||
setobj(L, cl->upvals[0]->v, gt);
|
|
||||||
luaC_upvalbarrier(L, cl->upvals[0]);
|
|
||||||
}
|
|
||||||
lua_unlock(L);
|
|
||||||
}
|
|
||||||
|
|
||||||
LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
|
LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
|
||||||
int status;
|
int status;
|
||||||
TValue *o;
|
TValue *o;
|
||||||
@@ -1150,7 +1101,7 @@ LUA_API int lua_next (lua_State *L, int idx) {
|
|||||||
int more;
|
int more;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = index2addr(L, idx);
|
t = index2addr(L, idx);
|
||||||
api_check(ttistable(t), "table expected");
|
api_check(L, ttistable(t), "table expected");
|
||||||
more = luaH_next(L, hvalue(t), L->top - 1);
|
more = luaH_next(L, hvalue(t), L->top - 1);
|
||||||
if (more) {
|
if (more) {
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
@@ -1232,7 +1183,7 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val,
|
|||||||
case LUA_TLCL: { /* Lua closure */
|
case LUA_TLCL: { /* Lua closure */
|
||||||
LClosure *f = clLvalue(fi);
|
LClosure *f = clLvalue(fi);
|
||||||
TString *name;
|
TString *name;
|
||||||
SharedProto *p = f->p->sp;
|
Proto *p = f->p;
|
||||||
if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
|
if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
|
||||||
*val = f->upvals[n-1]->v;
|
*val = f->upvals[n-1]->v;
|
||||||
if (uv) *uv = f->upvals[n - 1];
|
if (uv) *uv = f->upvals[n - 1];
|
||||||
@@ -1282,9 +1233,9 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
|
|||||||
static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
|
static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
|
||||||
LClosure *f;
|
LClosure *f;
|
||||||
StkId fi = index2addr(L, fidx);
|
StkId fi = index2addr(L, fidx);
|
||||||
api_check(ttisLclosure(fi), "Lua function expected");
|
api_check(L, ttisLclosure(fi), "Lua function expected");
|
||||||
f = clLvalue(fi);
|
f = clLvalue(fi);
|
||||||
api_check((1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
|
api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
|
||||||
if (pf) *pf = f;
|
if (pf) *pf = f;
|
||||||
return &f->upvals[n - 1]; /* get its upvalue pointer */
|
return &f->upvals[n - 1]; /* get its upvalue pointer */
|
||||||
}
|
}
|
||||||
@@ -1298,11 +1249,11 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
|
|||||||
}
|
}
|
||||||
case LUA_TCCL: { /* C closure */
|
case LUA_TCCL: { /* C closure */
|
||||||
CClosure *f = clCvalue(fi);
|
CClosure *f = clCvalue(fi);
|
||||||
api_check(1 <= n && n <= f->nupvalues, "invalid upvalue index");
|
api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
|
||||||
return &f->upvalue[n - 1];
|
return &f->upvalue[n - 1];
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
api_check(0, "closure expected");
|
api_check(L, 0, "closure expected");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lapi.h,v 2.8 2014/07/15 21:26:50 roberto Exp $
|
** $Id: lapi.h,v 2.9 2015/03/06 19:49:50 roberto Exp $
|
||||||
** Auxiliary functions from Lua API
|
** Auxiliary functions from Lua API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -11,13 +11,13 @@
|
|||||||
#include "llimits.h"
|
#include "llimits.h"
|
||||||
#include "lstate.h"
|
#include "lstate.h"
|
||||||
|
|
||||||
#define api_incr_top(L) {L->top++; api_check(L->top <= L->ci->top, \
|
#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \
|
||||||
"stack overflow");}
|
"stack overflow");}
|
||||||
|
|
||||||
#define adjustresults(L,nres) \
|
#define adjustresults(L,nres) \
|
||||||
{ if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
|
{ if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
|
||||||
|
|
||||||
#define api_checknelems(L,n) api_check((n) < (L->top - L->ci->func), \
|
#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \
|
||||||
"not enough elements in the stack")
|
"not enough elements in the stack")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lauxlib.c,v 1.279 2014/12/14 18:32:26 roberto Exp $
|
** $Id: lauxlib.c,v 1.280 2015/02/03 17:38:24 roberto Exp $
|
||||||
** Auxiliary functions for building Lua libraries
|
** Auxiliary functions for building Lua libraries
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -286,7 +286,7 @@ LUALIB_API int luaL_execresult (lua_State *L, int stat) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
|
LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
|
||||||
if (luaL_getmetatable(L, tname)) /* name already in use? */
|
if (luaL_getmetatable(L, tname) != LUA_TNIL) /* name already in use? */
|
||||||
return 0; /* leave previous value on top, but return 0 */
|
return 0; /* leave previous value on top, but return 0 */
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
lua_newtable(L); /* create metatable */
|
lua_newtable(L); /* create metatable */
|
||||||
@@ -638,7 +638,7 @@ static int skipcomment (LoadF *lf, int *cp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int luaL_loadfilex_ (lua_State *L, const char *filename,
|
LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
|
||||||
const char *mode) {
|
const char *mode) {
|
||||||
LoadF lf;
|
LoadF lf;
|
||||||
int status, readstatus;
|
int status, readstatus;
|
||||||
@@ -970,123 +970,3 @@ LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) {
|
|||||||
ver, *v);
|
ver, *v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// use clonefunction
|
|
||||||
|
|
||||||
#define LOCK(q) while (__sync_lock_test_and_set(&(q)->lock,1)) {}
|
|
||||||
#define UNLOCK(q) __sync_lock_release(&(q)->lock);
|
|
||||||
|
|
||||||
struct codecache {
|
|
||||||
int lock;
|
|
||||||
lua_State *L;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct codecache CC = { 0 , NULL };
|
|
||||||
|
|
||||||
static void
|
|
||||||
clearcache() {
|
|
||||||
if (CC.L == NULL)
|
|
||||||
return;
|
|
||||||
LOCK(&CC)
|
|
||||||
lua_close(CC.L);
|
|
||||||
CC.L = luaL_newstate();
|
|
||||||
UNLOCK(&CC)
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
init() {
|
|
||||||
CC.lock = 0;
|
|
||||||
CC.L = luaL_newstate();
|
|
||||||
}
|
|
||||||
|
|
||||||
static const void *
|
|
||||||
load(const char *key) {
|
|
||||||
if (CC.L == NULL)
|
|
||||||
return NULL;
|
|
||||||
LOCK(&CC)
|
|
||||||
lua_State *L = CC.L;
|
|
||||||
lua_pushstring(L, key);
|
|
||||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
|
||||||
const void * result = lua_touserdata(L, -1);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
UNLOCK(&CC)
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const void *
|
|
||||||
save(const char *key, const void * proto) {
|
|
||||||
lua_State *L;
|
|
||||||
const void * result = NULL;
|
|
||||||
|
|
||||||
LOCK(&CC)
|
|
||||||
if (CC.L == NULL) {
|
|
||||||
init();
|
|
||||||
L = CC.L;
|
|
||||||
} else {
|
|
||||||
L = CC.L;
|
|
||||||
lua_pushstring(L, key);
|
|
||||||
lua_pushvalue(L, -1);
|
|
||||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
|
||||||
result = lua_touserdata(L, -1); /* stack: key oldvalue */
|
|
||||||
if (result == NULL) {
|
|
||||||
lua_pop(L,1);
|
|
||||||
lua_pushlightuserdata(L, (void *)proto);
|
|
||||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
|
||||||
} else {
|
|
||||||
lua_pop(L,2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UNLOCK(&CC)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
|
|
||||||
const char *mode) {
|
|
||||||
const void * proto = load(filename);
|
|
||||||
if (proto) {
|
|
||||||
lua_clonefunction(L, proto);
|
|
||||||
return LUA_OK;
|
|
||||||
}
|
|
||||||
lua_State * eL = luaL_newstate();
|
|
||||||
if (eL == NULL) {
|
|
||||||
lua_pushliteral(L, "New state failed");
|
|
||||||
return LUA_ERRMEM;
|
|
||||||
}
|
|
||||||
int err = luaL_loadfilex_(eL, filename, mode);
|
|
||||||
if (err != LUA_OK) {
|
|
||||||
size_t sz = 0;
|
|
||||||
const char * msg = lua_tolstring(eL, -1, &sz);
|
|
||||||
lua_pushlstring(L, msg, sz);
|
|
||||||
lua_close(eL);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
proto = lua_topointer(eL, -1);
|
|
||||||
const void * oldv = save(filename, proto);
|
|
||||||
if (oldv) {
|
|
||||||
lua_close(eL);
|
|
||||||
lua_clonefunction(L, oldv);
|
|
||||||
} else {
|
|
||||||
lua_clonefunction(L, proto);
|
|
||||||
/* Never close it. notice: memory leak */
|
|
||||||
}
|
|
||||||
|
|
||||||
return LUA_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
cache_clear(lua_State *L) {
|
|
||||||
(void)(L);
|
|
||||||
clearcache();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
LUAMOD_API int luaopen_cache(lua_State *L) {
|
|
||||||
luaL_Reg l[] = {
|
|
||||||
{ "clear", cache_clear },
|
|
||||||
{ NULL, NULL },
|
|
||||||
};
|
|
||||||
luaL_newlib(L,l);
|
|
||||||
lua_getglobal(L, "loadfile");
|
|
||||||
lua_setfield(L, -2, "loadfile");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lbaselib.c,v 1.309 2014/12/10 12:26:42 roberto Exp $
|
** $Id: lbaselib.c,v 1.310 2015/03/28 19:14:47 roberto Exp $
|
||||||
** Basic library
|
** Basic library
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -55,7 +55,7 @@ static const char *b_str2int (const char *s, int base, lua_Integer *pn) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
do {
|
do {
|
||||||
int digit = (isdigit((unsigned char)*s)) ? *s - '0'
|
int digit = (isdigit((unsigned char)*s)) ? *s - '0'
|
||||||
: toupper((unsigned char)*s) - 'A' + 10;
|
: (toupper((unsigned char)*s) - 'A') + 10;
|
||||||
if (digit >= base) return NULL; /* invalid numeral */
|
if (digit >= base) return NULL; /* invalid numeral */
|
||||||
n = n * base + digit;
|
n = n * base + digit;
|
||||||
s++;
|
s++;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lcode.c,v 2.99 2014/12/29 16:49:25 roberto Exp $
|
** $Id: lcode.c,v 2.101 2015/04/29 18:24:11 roberto Exp $
|
||||||
** Code generator for Lua
|
** Code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -29,8 +29,8 @@
|
|||||||
#include "lvm.h"
|
#include "lvm.h"
|
||||||
|
|
||||||
|
|
||||||
/* Maximum number of registers in a Lua function */
|
/* Maximum number of registers in a Lua function (must fit in 8 bits) */
|
||||||
#define MAXREGS 250
|
#define MAXREGS 255
|
||||||
|
|
||||||
|
|
||||||
#define hasjumps(e) ((e)->t != (e)->f)
|
#define hasjumps(e) ((e)->t != (e)->f)
|
||||||
@@ -55,7 +55,7 @@ void luaK_nil (FuncState *fs, int from, int n) {
|
|||||||
Instruction *previous;
|
Instruction *previous;
|
||||||
int l = from + n - 1; /* last register to set nil */
|
int l = from + n - 1; /* last register to set nil */
|
||||||
if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
|
if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
|
||||||
previous = &fs->f->sp->code[fs->pc-1];
|
previous = &fs->f->code[fs->pc-1];
|
||||||
if (GET_OPCODE(*previous) == OP_LOADNIL) {
|
if (GET_OPCODE(*previous) == OP_LOADNIL) {
|
||||||
int pfrom = GETARG_A(*previous);
|
int pfrom = GETARG_A(*previous);
|
||||||
int pl = pfrom + GETARG_B(*previous);
|
int pl = pfrom + GETARG_B(*previous);
|
||||||
@@ -95,7 +95,7 @@ static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
|
|||||||
|
|
||||||
|
|
||||||
static void fixjump (FuncState *fs, int pc, int dest) {
|
static void fixjump (FuncState *fs, int pc, int dest) {
|
||||||
Instruction *jmp = &fs->f->sp->code[pc];
|
Instruction *jmp = &fs->f->code[pc];
|
||||||
int offset = dest-(pc+1);
|
int offset = dest-(pc+1);
|
||||||
lua_assert(dest != NO_JUMP);
|
lua_assert(dest != NO_JUMP);
|
||||||
if (abs(offset) > MAXARG_sBx)
|
if (abs(offset) > MAXARG_sBx)
|
||||||
@@ -115,7 +115,7 @@ int luaK_getlabel (FuncState *fs) {
|
|||||||
|
|
||||||
|
|
||||||
static int getjump (FuncState *fs, int pc) {
|
static int getjump (FuncState *fs, int pc) {
|
||||||
int offset = GETARG_sBx(fs->f->sp->code[pc]);
|
int offset = GETARG_sBx(fs->f->code[pc]);
|
||||||
if (offset == NO_JUMP) /* point to itself represents end of list */
|
if (offset == NO_JUMP) /* point to itself represents end of list */
|
||||||
return NO_JUMP; /* end of list */
|
return NO_JUMP; /* end of list */
|
||||||
else
|
else
|
||||||
@@ -124,7 +124,7 @@ static int getjump (FuncState *fs, int pc) {
|
|||||||
|
|
||||||
|
|
||||||
static Instruction *getjumpcontrol (FuncState *fs, int pc) {
|
static Instruction *getjumpcontrol (FuncState *fs, int pc) {
|
||||||
Instruction *pi = &fs->f->sp->code[pc];
|
Instruction *pi = &fs->f->code[pc];
|
||||||
if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
|
if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
|
||||||
return pi-1;
|
return pi-1;
|
||||||
else
|
else
|
||||||
@@ -197,10 +197,10 @@ void luaK_patchclose (FuncState *fs, int list, int level) {
|
|||||||
level++; /* argument is +1 to reserve 0 as non-op */
|
level++; /* argument is +1 to reserve 0 as non-op */
|
||||||
while (list != NO_JUMP) {
|
while (list != NO_JUMP) {
|
||||||
int next = getjump(fs, list);
|
int next = getjump(fs, list);
|
||||||
lua_assert(GET_OPCODE(fs->f->sp->code[list]) == OP_JMP &&
|
lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
|
||||||
(GETARG_A(fs->f->sp->code[list]) == 0 ||
|
(GETARG_A(fs->f->code[list]) == 0 ||
|
||||||
GETARG_A(fs->f->sp->code[list]) >= level));
|
GETARG_A(fs->f->code[list]) >= level));
|
||||||
SETARG_A(fs->f->sp->code[list], level);
|
SETARG_A(fs->f->code[list], level);
|
||||||
list = next;
|
list = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,13 +230,13 @@ static int luaK_code (FuncState *fs, Instruction i) {
|
|||||||
Proto *f = fs->f;
|
Proto *f = fs->f;
|
||||||
dischargejpc(fs); /* 'pc' will change */
|
dischargejpc(fs); /* 'pc' will change */
|
||||||
/* put new instruction in code array */
|
/* put new instruction in code array */
|
||||||
luaM_growvector(fs->ls->L, f->sp->code, fs->pc, f->sp->sizecode, Instruction,
|
luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
|
||||||
MAX_INT, "opcodes");
|
MAX_INT, "opcodes");
|
||||||
f->sp->code[fs->pc] = i;
|
f->code[fs->pc] = i;
|
||||||
/* save corresponding line information */
|
/* save corresponding line information */
|
||||||
luaM_growvector(fs->ls->L, f->sp->lineinfo, fs->pc, f->sp->sizelineinfo, int,
|
luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
|
||||||
MAX_INT, "opcodes");
|
MAX_INT, "opcodes");
|
||||||
f->sp->lineinfo[fs->pc] = fs->ls->lastline;
|
f->lineinfo[fs->pc] = fs->ls->lastline;
|
||||||
return fs->pc++;
|
return fs->pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,10 +277,11 @@ int luaK_codek (FuncState *fs, int reg, int k) {
|
|||||||
|
|
||||||
void luaK_checkstack (FuncState *fs, int n) {
|
void luaK_checkstack (FuncState *fs, int n) {
|
||||||
int newstack = fs->freereg + n;
|
int newstack = fs->freereg + n;
|
||||||
if (newstack > fs->f->sp->maxstacksize) {
|
if (newstack > fs->f->maxstacksize) {
|
||||||
if (newstack >= MAXREGS)
|
if (newstack >= MAXREGS)
|
||||||
luaX_syntaxerror(fs->ls, "function or expression too complex");
|
luaX_syntaxerror(fs->ls,
|
||||||
fs->f->sp->maxstacksize = cast_byte(newstack);
|
"function or expression needs too many registers");
|
||||||
|
fs->f->maxstacksize = cast_byte(newstack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,13 +323,13 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
|
|||||||
return k; /* reuse index */
|
return k; /* reuse index */
|
||||||
}
|
}
|
||||||
/* constant not found; create a new entry */
|
/* constant not found; create a new entry */
|
||||||
oldsize = f->sp->sizek;
|
oldsize = f->sizek;
|
||||||
k = fs->nk;
|
k = fs->nk;
|
||||||
/* numerical value does not need GC barrier;
|
/* numerical value does not need GC barrier;
|
||||||
table has no metatable, so it does not need to invalidate cache */
|
table has no metatable, so it does not need to invalidate cache */
|
||||||
setivalue(idx, k);
|
setivalue(idx, k);
|
||||||
luaM_growvector(L, f->k, k, f->sp->sizek, TValue, MAXARG_Ax, "constants");
|
luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
|
||||||
while (oldsize < f->sp->sizek) setnilvalue(&f->k[oldsize++]);
|
while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
|
||||||
setobj(L, &f->k[k], v);
|
setobj(L, &f->k[k], v);
|
||||||
fs->nk++;
|
fs->nk++;
|
||||||
luaC_barrier(L, f, v);
|
luaC_barrier(L, f, v);
|
||||||
@@ -573,8 +574,8 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) {
|
|||||||
case VKFLT: {
|
case VKFLT: {
|
||||||
e->u.info = luaK_numberK(fs, e->u.nval);
|
e->u.info = luaK_numberK(fs, e->u.nval);
|
||||||
e->k = VK;
|
e->k = VK;
|
||||||
/* go through */
|
|
||||||
}
|
}
|
||||||
|
/* FALLTHROUGH */
|
||||||
case VK: {
|
case VK: {
|
||||||
vk:
|
vk:
|
||||||
if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */
|
if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */
|
||||||
@@ -793,7 +794,7 @@ static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
|
|||||||
static void codeexpval (FuncState *fs, OpCode op,
|
static void codeexpval (FuncState *fs, OpCode op,
|
||||||
expdesc *e1, expdesc *e2, int line) {
|
expdesc *e1, expdesc *e2, int line) {
|
||||||
lua_assert(op >= OP_ADD);
|
lua_assert(op >= OP_ADD);
|
||||||
if (op <= OP_BNOT && constfolding(fs, op - OP_ADD + LUA_OPADD, e1, e2))
|
if (op <= OP_BNOT && constfolding(fs, (op - OP_ADD) + LUA_OPADD, e1, e2))
|
||||||
return; /* result has been folded */
|
return; /* result has been folded */
|
||||||
else {
|
else {
|
||||||
int o1, o2;
|
int o1, o2;
|
||||||
@@ -920,11 +921,11 @@ void luaK_posfix (FuncState *fs, BinOpr op,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPR_EQ: case OPR_LT: case OPR_LE: {
|
case OPR_EQ: case OPR_LT: case OPR_LE: {
|
||||||
codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2);
|
codecomp(fs, cast(OpCode, (op - OPR_EQ) + OP_EQ), 1, e1, e2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPR_NE: case OPR_GT: case OPR_GE: {
|
case OPR_NE: case OPR_GT: case OPR_GE: {
|
||||||
codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2);
|
codecomp(fs, cast(OpCode, (op - OPR_NE) + OP_EQ), 0, e1, e2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: lua_assert(0);
|
default: lua_assert(0);
|
||||||
@@ -933,7 +934,7 @@ void luaK_posfix (FuncState *fs, BinOpr op,
|
|||||||
|
|
||||||
|
|
||||||
void luaK_fixline (FuncState *fs, int line) {
|
void luaK_fixline (FuncState *fs, int line) {
|
||||||
fs->f->sp->lineinfo[fs->pc - 1] = line;
|
fs->f->lineinfo[fs->pc - 1] = line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ typedef enum BinOpr {
|
|||||||
typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
|
typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
|
||||||
|
|
||||||
|
|
||||||
#define getcode(fs,e) ((fs)->f->sp->code[(e)->u.info])
|
#define getcode(fs,e) ((fs)->f->code[(e)->u.info])
|
||||||
|
|
||||||
#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
|
#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldblib.c,v 1.148 2015/01/02 12:52:22 roberto Exp $
|
** $Id: ldblib.c,v 1.149 2015/02/19 17:06:21 roberto Exp $
|
||||||
** Interface from Lua to its debug API
|
** Interface from Lua to its debug API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -27,6 +27,17 @@
|
|||||||
static const int HOOKKEY = 0;
|
static const int HOOKKEY = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** If L1 != L, L1 can be in any state, and therefore there is no
|
||||||
|
** garanties about its stack space; any push in L1 must be
|
||||||
|
** checked.
|
||||||
|
*/
|
||||||
|
static void checkstack (lua_State *L, lua_State *L1, int n) {
|
||||||
|
if (L != L1 && !lua_checkstack(L1, n))
|
||||||
|
luaL_error(L, "stack overflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int db_getregistry (lua_State *L) {
|
static int db_getregistry (lua_State *L) {
|
||||||
lua_pushvalue(L, LUA_REGISTRYINDEX);
|
lua_pushvalue(L, LUA_REGISTRYINDEX);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -127,12 +138,16 @@ static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Calls 'lua_getinfo' and collects all results in a new table.
|
** Calls 'lua_getinfo' and collects all results in a new table.
|
||||||
|
** L1 needs stack space for an optional input (function) plus
|
||||||
|
** two optional outputs (function and line table) from function
|
||||||
|
** 'lua_getinfo'.
|
||||||
*/
|
*/
|
||||||
static int db_getinfo (lua_State *L) {
|
static int db_getinfo (lua_State *L) {
|
||||||
lua_Debug ar;
|
lua_Debug ar;
|
||||||
int arg;
|
int arg;
|
||||||
lua_State *L1 = getthread(L, &arg);
|
lua_State *L1 = getthread(L, &arg);
|
||||||
const char *options = luaL_optstring(L, arg+2, "flnStu");
|
const char *options = luaL_optstring(L, arg+2, "flnStu");
|
||||||
|
checkstack(L, L1, 3);
|
||||||
if (lua_isfunction(L, arg + 1)) { /* info about a function? */
|
if (lua_isfunction(L, arg + 1)) { /* info about a function? */
|
||||||
options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */
|
options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */
|
||||||
lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */
|
lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */
|
||||||
@@ -190,6 +205,7 @@ static int db_getlocal (lua_State *L) {
|
|||||||
int level = (int)luaL_checkinteger(L, arg + 1);
|
int level = (int)luaL_checkinteger(L, arg + 1);
|
||||||
if (!lua_getstack(L1, level, &ar)) /* out of range? */
|
if (!lua_getstack(L1, level, &ar)) /* out of range? */
|
||||||
return luaL_argerror(L, arg+1, "level out of range");
|
return luaL_argerror(L, arg+1, "level out of range");
|
||||||
|
checkstack(L, L1, 1);
|
||||||
name = lua_getlocal(L1, &ar, nvar);
|
name = lua_getlocal(L1, &ar, nvar);
|
||||||
if (name) {
|
if (name) {
|
||||||
lua_xmove(L1, L, 1); /* move local value */
|
lua_xmove(L1, L, 1); /* move local value */
|
||||||
@@ -216,6 +232,7 @@ static int db_setlocal (lua_State *L) {
|
|||||||
return luaL_argerror(L, arg+1, "level out of range");
|
return luaL_argerror(L, arg+1, "level out of range");
|
||||||
luaL_checkany(L, arg+3);
|
luaL_checkany(L, arg+3);
|
||||||
lua_settop(L, arg+3);
|
lua_settop(L, arg+3);
|
||||||
|
checkstack(L, L1, 1);
|
||||||
lua_xmove(L, L1, 1);
|
lua_xmove(L, L1, 1);
|
||||||
name = lua_setlocal(L1, &ar, nvar);
|
name = lua_setlocal(L1, &ar, nvar);
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
@@ -350,6 +367,7 @@ static int db_sethook (lua_State *L) {
|
|||||||
lua_pushvalue(L, -1);
|
lua_pushvalue(L, -1);
|
||||||
lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */
|
lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */
|
||||||
}
|
}
|
||||||
|
checkstack(L, L1, 1);
|
||||||
lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */
|
lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */
|
||||||
lua_pushvalue(L, arg + 1); /* value (hook function) */
|
lua_pushvalue(L, arg + 1); /* value (hook function) */
|
||||||
lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */
|
lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */
|
||||||
@@ -370,6 +388,7 @@ static int db_gethook (lua_State *L) {
|
|||||||
lua_pushliteral(L, "external hook");
|
lua_pushliteral(L, "external hook");
|
||||||
else { /* hook table must exist */
|
else { /* hook table must exist */
|
||||||
lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY);
|
lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY);
|
||||||
|
checkstack(L, L1, 1);
|
||||||
lua_pushthread(L1); lua_xmove(L1, L, 1);
|
lua_pushthread(L1); lua_xmove(L1, L, 1);
|
||||||
lua_rawget(L, -2); /* 1st result = hooktable[L1] */
|
lua_rawget(L, -2); /* 1st result = hooktable[L1] */
|
||||||
lua_remove(L, -2); /* remove hook table */
|
lua_remove(L, -2); /* remove hook table */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldebug.c,v 2.110 2015/01/02 12:52:22 roberto Exp $
|
** $Id: ldebug.c,v 2.115 2015/05/22 17:45:56 roberto Exp $
|
||||||
** Debug Interface
|
** Debug Interface
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -34,6 +34,10 @@
|
|||||||
#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL)
|
#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL)
|
||||||
|
|
||||||
|
|
||||||
|
/* Active Lua function (given call info) */
|
||||||
|
#define ci_func(ci) (clLvalue((ci)->func))
|
||||||
|
|
||||||
|
|
||||||
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
|
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
|
||||||
|
|
||||||
|
|
||||||
@@ -114,15 +118,15 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
|
|||||||
|
|
||||||
|
|
||||||
static const char *upvalname (Proto *p, int uv) {
|
static const char *upvalname (Proto *p, int uv) {
|
||||||
TString *s = check_exp(uv < p->sizeupvalues, p->sp->upvalues[uv].name);
|
TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
|
||||||
if (s == NULL) return "?";
|
if (s == NULL) return "?";
|
||||||
else return getstr(s);
|
else return getstr(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
|
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
|
||||||
int nparams = clLvalue(ci->func)->p->sp->numparams;
|
int nparams = clLvalue(ci->func)->p->numparams;
|
||||||
if (n >= ci->u.l.base - ci->func - nparams)
|
if (n >= cast_int(ci->u.l.base - ci->func) - nparams)
|
||||||
return NULL; /* no such vararg */
|
return NULL; /* no such vararg */
|
||||||
else {
|
else {
|
||||||
*pos = ci->func + nparams + n;
|
*pos = ci->func + nparams + n;
|
||||||
@@ -168,7 +172,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
|
|||||||
name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
|
name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
|
||||||
}
|
}
|
||||||
else { /* active function; get information through 'ar' */
|
else { /* active function; get information through 'ar' */
|
||||||
StkId pos = 0; /* to avoid warnings */
|
StkId pos = NULL; /* to avoid warnings */
|
||||||
name = findlocal(L, ar->i_ci, n, &pos);
|
name = findlocal(L, ar->i_ci, n, &pos);
|
||||||
if (name) {
|
if (name) {
|
||||||
setobj2s(L, L->top, pos);
|
setobj2s(L, L->top, pos);
|
||||||
@@ -182,7 +186,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
|
|||||||
|
|
||||||
|
|
||||||
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
|
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
|
||||||
StkId pos = 0; /* to avoid warnings */
|
StkId pos = NULL; /* to avoid warnings */
|
||||||
const char *name;
|
const char *name;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
swapextra(L);
|
swapextra(L);
|
||||||
@@ -205,7 +209,7 @@ static void funcinfo (lua_Debug *ar, Closure *cl) {
|
|||||||
ar->what = "C";
|
ar->what = "C";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SharedProto *p = cl->l.p->sp;
|
Proto *p = cl->l.p;
|
||||||
ar->source = p->source ? getstr(p->source) : "=?";
|
ar->source = p->source ? getstr(p->source) : "=?";
|
||||||
ar->linedefined = p->linedefined;
|
ar->linedefined = p->linedefined;
|
||||||
ar->lastlinedefined = p->lastlinedefined;
|
ar->lastlinedefined = p->lastlinedefined;
|
||||||
@@ -223,12 +227,12 @@ static void collectvalidlines (lua_State *L, Closure *f) {
|
|||||||
else {
|
else {
|
||||||
int i;
|
int i;
|
||||||
TValue v;
|
TValue v;
|
||||||
int *lineinfo = f->l.p->sp->lineinfo;
|
int *lineinfo = f->l.p->lineinfo;
|
||||||
Table *t = luaH_new(L); /* new table to store active lines */
|
Table *t = luaH_new(L); /* new table to store active lines */
|
||||||
sethvalue(L, L->top, t); /* push it on stack */
|
sethvalue(L, L->top, t); /* push it on stack */
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
|
setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
|
||||||
for (i = 0; i < f->l.p->sp->sizelineinfo; i++) /* for all lines with code */
|
for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */
|
||||||
luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */
|
luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,8 +258,8 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
|
|||||||
ar->nparams = 0;
|
ar->nparams = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ar->isvararg = f->l.p->sp->is_vararg;
|
ar->isvararg = f->l.p->is_vararg;
|
||||||
ar->nparams = f->l.p->sp->numparams;
|
ar->nparams = f->l.p->numparams;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -295,7 +299,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
|
|||||||
if (*what == '>') {
|
if (*what == '>') {
|
||||||
ci = NULL;
|
ci = NULL;
|
||||||
func = L->top - 1;
|
func = L->top - 1;
|
||||||
api_check(ttisfunction(func), "function expected");
|
api_check(L, ttisfunction(func), "function expected");
|
||||||
what++; /* skip the '>' */
|
what++; /* skip the '>' */
|
||||||
L->top--; /* pop function */
|
L->top--; /* pop function */
|
||||||
}
|
}
|
||||||
@@ -366,7 +370,7 @@ static int findsetreg (Proto *p, int lastpc, int reg) {
|
|||||||
int setreg = -1; /* keep last instruction that changed 'reg' */
|
int setreg = -1; /* keep last instruction that changed 'reg' */
|
||||||
int jmptarget = 0; /* any code before this address is conditional */
|
int jmptarget = 0; /* any code before this address is conditional */
|
||||||
for (pc = 0; pc < lastpc; pc++) {
|
for (pc = 0; pc < lastpc; pc++) {
|
||||||
Instruction i = p->sp->code[pc];
|
Instruction i = p->code[pc];
|
||||||
OpCode op = GET_OPCODE(i);
|
OpCode op = GET_OPCODE(i);
|
||||||
int a = GETARG_A(i);
|
int a = GETARG_A(i);
|
||||||
switch (op) {
|
switch (op) {
|
||||||
@@ -416,7 +420,7 @@ static const char *getobjname (Proto *p, int lastpc, int reg,
|
|||||||
/* else try symbolic execution */
|
/* else try symbolic execution */
|
||||||
pc = findsetreg(p, lastpc, reg);
|
pc = findsetreg(p, lastpc, reg);
|
||||||
if (pc != -1) { /* could find instruction? */
|
if (pc != -1) { /* could find instruction? */
|
||||||
Instruction i = p->sp->code[pc];
|
Instruction i = p->code[pc];
|
||||||
OpCode op = GET_OPCODE(i);
|
OpCode op = GET_OPCODE(i);
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case OP_MOVE: {
|
case OP_MOVE: {
|
||||||
@@ -442,7 +446,7 @@ static const char *getobjname (Proto *p, int lastpc, int reg,
|
|||||||
case OP_LOADK:
|
case OP_LOADK:
|
||||||
case OP_LOADKX: {
|
case OP_LOADKX: {
|
||||||
int b = (op == OP_LOADK) ? GETARG_Bx(i)
|
int b = (op == OP_LOADK) ? GETARG_Bx(i)
|
||||||
: GETARG_Ax(p->sp->code[pc + 1]);
|
: GETARG_Ax(p->code[pc + 1]);
|
||||||
if (ttisstring(&p->k[b])) {
|
if (ttisstring(&p->k[b])) {
|
||||||
*name = svalue(&p->k[b]);
|
*name = svalue(&p->k[b]);
|
||||||
return "constant";
|
return "constant";
|
||||||
@@ -465,7 +469,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
|
|||||||
TMS tm = (TMS)0; /* to avoid warnings */
|
TMS tm = (TMS)0; /* to avoid warnings */
|
||||||
Proto *p = ci_func(ci)->p; /* calling function */
|
Proto *p = ci_func(ci)->p; /* calling function */
|
||||||
int pc = currentpc(ci); /* calling instruction index */
|
int pc = currentpc(ci); /* calling instruction index */
|
||||||
Instruction i = p->sp->code[pc]; /* calling instruction */
|
Instruction i = p->code[pc]; /* calling instruction */
|
||||||
if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
|
if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
|
||||||
*name = "?";
|
*name = "?";
|
||||||
return "hook";
|
return "hook";
|
||||||
@@ -595,19 +599,16 @@ l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void addinfo (lua_State *L, const char *msg) {
|
/* add src:line information to 'msg' */
|
||||||
CallInfo *ci = L->ci;
|
const char *luaG_addinfo (lua_State *L, const char *msg, TString *src,
|
||||||
if (isLua(ci)) { /* is Lua code? */
|
int line) {
|
||||||
char buff[LUA_IDSIZE]; /* add file:line information */
|
char buff[LUA_IDSIZE];
|
||||||
int line = currentline(ci);
|
if (src)
|
||||||
TString *src = ci_func(ci)->p->sp->source;
|
luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
|
||||||
if (src)
|
else { /* no source available; use "?" instead */
|
||||||
luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
|
buff[0] = '?'; buff[1] = '\0';
|
||||||
else { /* no source available; use "?" instead */
|
|
||||||
buff[0] = '?'; buff[1] = '\0';
|
|
||||||
}
|
|
||||||
luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
|
|
||||||
}
|
}
|
||||||
|
return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -624,10 +625,14 @@ l_noret luaG_errormsg (lua_State *L) {
|
|||||||
|
|
||||||
|
|
||||||
l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
|
l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
|
||||||
|
CallInfo *ci = L->ci;
|
||||||
|
const char *msg;
|
||||||
va_list argp;
|
va_list argp;
|
||||||
va_start(argp, fmt);
|
va_start(argp, fmt);
|
||||||
addinfo(L, luaO_pushvfstring(L, fmt, argp));
|
msg = luaO_pushvfstring(L, fmt, argp); /* format message */
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
|
if (isLua(ci)) /* if Lua function, add source:line information */
|
||||||
|
luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci));
|
||||||
luaG_errormsg(L);
|
luaG_errormsg(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldebug.h,v 2.12 2014/11/10 14:46:05 roberto Exp $
|
** $Id: ldebug.h,v 2.14 2015/05/22 17:45:56 roberto Exp $
|
||||||
** Auxiliary functions from Debug Interface module
|
** Auxiliary functions from Debug Interface module
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -11,15 +11,12 @@
|
|||||||
#include "lstate.h"
|
#include "lstate.h"
|
||||||
|
|
||||||
|
|
||||||
#define pcRel(pc, p) (cast(int, (pc) - (p)->sp->code) - 1)
|
#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
|
||||||
|
|
||||||
#define getfuncline(f,pc) (((f)->sp->lineinfo) ? (f)->sp->lineinfo[pc] : -1)
|
#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1)
|
||||||
|
|
||||||
#define resethookcount(L) (L->hookcount = L->basehookcount)
|
#define resethookcount(L) (L->hookcount = L->basehookcount)
|
||||||
|
|
||||||
/* Active Lua function (given call info) */
|
|
||||||
#define ci_func(ci) (clLvalue((ci)->func))
|
|
||||||
|
|
||||||
|
|
||||||
LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
|
LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
|
||||||
const char *opname);
|
const char *opname);
|
||||||
@@ -33,6 +30,8 @@ LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1,
|
|||||||
LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
|
LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
|
||||||
const TValue *p2);
|
const TValue *p2);
|
||||||
LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
|
LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
|
||||||
|
LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg,
|
||||||
|
TString *src, int line);
|
||||||
LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
|
LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
|
||||||
LUAI_FUNC void luaG_traceexec (lua_State *L);
|
LUAI_FUNC void luaG_traceexec (lua_State *L);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldo.c,v 2.135 2014/11/11 17:13:39 roberto Exp $
|
** $Id: ldo.c,v 2.138 2015/05/22 17:48:19 roberto Exp $
|
||||||
** Stack and Call structure of Lua
|
** Stack and Call structure of Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -269,7 +269,7 @@ static void callhook (lua_State *L, CallInfo *ci) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static StkId adjust_varargs (lua_State *L, SharedProto *p, int actual) {
|
static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
|
||||||
int i;
|
int i;
|
||||||
int nfixargs = p->numparams;
|
int nfixargs = p->numparams;
|
||||||
StkId base, fixed;
|
StkId base, fixed;
|
||||||
@@ -323,6 +323,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
|
|||||||
case LUA_TCCL: { /* C closure */
|
case LUA_TCCL: { /* C closure */
|
||||||
f = clCvalue(func)->f;
|
f = clCvalue(func)->f;
|
||||||
Cfunc:
|
Cfunc:
|
||||||
|
luaC_checkGC(L); /* stack grow uses memory */
|
||||||
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
||||||
ci = next_ci(L); /* now 'enter' new function */
|
ci = next_ci(L); /* now 'enter' new function */
|
||||||
ci->nresults = nresults;
|
ci->nresults = nresults;
|
||||||
@@ -330,20 +331,20 @@ 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->callstatus = 0;
|
ci->callstatus = 0;
|
||||||
luaC_checkGC(L); /* stack grow uses memory */
|
|
||||||
if (L->hookmask & LUA_MASKCALL)
|
if (L->hookmask & LUA_MASKCALL)
|
||||||
luaD_hook(L, LUA_HOOKCALL, -1);
|
luaD_hook(L, LUA_HOOKCALL, -1);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
n = (*f)(L); /* do the actual call */
|
n = (*f)(L); /* do the actual call */
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, n);
|
api_checknelems(L, n);
|
||||||
luaD_poscall(L, L->top - n);
|
luaD_poscall(L, L->top - n, n);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
case LUA_TLCL: { /* Lua function: prepare its call */
|
case LUA_TLCL: { /* Lua function: prepare its call */
|
||||||
StkId base;
|
StkId base;
|
||||||
SharedProto *p = clLvalue(func)->p->sp;
|
Proto *p = clLvalue(func)->p;
|
||||||
n = cast_int(L->top - func) - 1; /* number of real arguments */
|
n = cast_int(L->top - func) - 1; /* number of real arguments */
|
||||||
|
luaC_checkGC(L); /* stack grow uses memory */
|
||||||
luaD_checkstack(L, p->maxstacksize);
|
luaD_checkstack(L, p->maxstacksize);
|
||||||
for (; n < p->numparams; n++)
|
for (; n < p->numparams; n++)
|
||||||
setnilvalue(L->top++); /* complete missing arguments */
|
setnilvalue(L->top++); /* complete missing arguments */
|
||||||
@@ -364,7 +365,6 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
|
|||||||
ci->u.l.savedpc = p->code; /* starting point */
|
ci->u.l.savedpc = p->code; /* starting point */
|
||||||
ci->callstatus = CIST_LUA;
|
ci->callstatus = CIST_LUA;
|
||||||
L->top = ci->top;
|
L->top = ci->top;
|
||||||
luaC_checkGC(L); /* stack grow uses memory */
|
|
||||||
if (L->hookmask & LUA_MASKCALL)
|
if (L->hookmask & LUA_MASKCALL)
|
||||||
callhook(L, ci);
|
callhook(L, ci);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -379,7 +379,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int luaD_poscall (lua_State *L, StkId firstResult) {
|
int luaD_poscall (lua_State *L, StkId firstResult, int nres) {
|
||||||
StkId res;
|
StkId res;
|
||||||
int wanted, i;
|
int wanted, i;
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
@@ -393,9 +393,9 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
|
|||||||
}
|
}
|
||||||
res = ci->func; /* res == final position of 1st result */
|
res = ci->func; /* res == final position of 1st result */
|
||||||
wanted = ci->nresults;
|
wanted = ci->nresults;
|
||||||
L->ci = ci = ci->previous; /* back to caller */
|
L->ci = ci->previous; /* back to caller */
|
||||||
/* move results to correct place */
|
/* move results to correct place */
|
||||||
for (i = wanted; i != 0 && firstResult < L->top; i--)
|
for (i = wanted; i != 0 && nres-- > 0; i--)
|
||||||
setobjs2s(L, res++, firstResult++);
|
setobjs2s(L, res++, firstResult++);
|
||||||
while (i-- > 0)
|
while (i-- > 0)
|
||||||
setnilvalue(res++);
|
setnilvalue(res++);
|
||||||
@@ -449,7 +449,7 @@ static void finishCcall (lua_State *L, int status) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, n);
|
api_checknelems(L, n);
|
||||||
/* finish 'luaD_precall' */
|
/* finish 'luaD_precall' */
|
||||||
luaD_poscall(L, L->top - n);
|
luaD_poscall(L, L->top - n, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -533,7 +533,8 @@ static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
|
|||||||
*/
|
*/
|
||||||
static void resume (lua_State *L, void *ud) {
|
static void resume (lua_State *L, void *ud) {
|
||||||
int nCcalls = L->nCcalls;
|
int nCcalls = L->nCcalls;
|
||||||
StkId firstArg = cast(StkId, ud);
|
int n = *(cast(int*, ud)); /* number of arguments */
|
||||||
|
StkId firstArg = L->top - n; /* first argument */
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
if (nCcalls >= LUAI_MAXCCALLS)
|
if (nCcalls >= LUAI_MAXCCALLS)
|
||||||
resume_error(L, "C stack overflow", firstArg);
|
resume_error(L, "C stack overflow", firstArg);
|
||||||
@@ -553,14 +554,13 @@ static void resume (lua_State *L, void *ud) {
|
|||||||
luaV_execute(L); /* just continue running Lua code */
|
luaV_execute(L); /* just continue running Lua code */
|
||||||
else { /* 'common' yield */
|
else { /* 'common' yield */
|
||||||
if (ci->u.c.k != NULL) { /* does it have a continuation function? */
|
if (ci->u.c.k != NULL) { /* does it have a continuation function? */
|
||||||
int n;
|
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */
|
n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, n);
|
api_checknelems(L, n);
|
||||||
firstArg = L->top - n; /* yield results come from continuation */
|
firstArg = L->top - n; /* yield results come from continuation */
|
||||||
}
|
}
|
||||||
luaD_poscall(L, firstArg); /* finish 'luaD_precall' */
|
luaD_poscall(L, firstArg, n); /* finish 'luaD_precall' */
|
||||||
}
|
}
|
||||||
unroll(L, NULL); /* run continuation */
|
unroll(L, NULL); /* run continuation */
|
||||||
}
|
}
|
||||||
@@ -576,7 +576,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
|
|||||||
L->nCcalls = (from) ? from->nCcalls + 1 : 1;
|
L->nCcalls = (from) ? from->nCcalls + 1 : 1;
|
||||||
L->nny = 0; /* allow yields */
|
L->nny = 0; /* allow yields */
|
||||||
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
|
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
|
||||||
status = luaD_rawrunprotected(L, resume, L->top - nargs);
|
status = luaD_rawrunprotected(L, resume, &nargs);
|
||||||
if (status == -1) /* error calling 'lua_resume'? */
|
if (status == -1) /* error calling 'lua_resume'? */
|
||||||
status = LUA_ERRRUN;
|
status = LUA_ERRRUN;
|
||||||
else { /* continue running after recoverable errors */
|
else { /* continue running after recoverable errors */
|
||||||
@@ -619,7 +619,7 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
|
|||||||
L->status = LUA_YIELD;
|
L->status = LUA_YIELD;
|
||||||
ci->extra = savestack(L, ci->func); /* save current 'func' */
|
ci->extra = savestack(L, ci->func); /* save current 'func' */
|
||||||
if (isLua(ci)) { /* inside a hook? */
|
if (isLua(ci)) { /* inside a hook? */
|
||||||
api_check(k == NULL, "hooks cannot continue after yielding");
|
api_check(L, k == NULL, "hooks cannot continue after yielding");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((ci->u.c.k = k) != NULL) /* is there a continuation? */
|
if ((ci->u.c.k = k) != NULL) /* is there a continuation? */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldo.h,v 2.21 2014/10/25 11:50:46 roberto Exp $
|
** $Id: ldo.h,v 2.22 2015/05/22 17:48:19 roberto Exp $
|
||||||
** Stack and Call structure of Lua
|
** Stack and Call structure of Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -34,7 +34,7 @@ LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults,
|
|||||||
int allowyield);
|
int allowyield);
|
||||||
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
|
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
|
||||||
ptrdiff_t oldtop, ptrdiff_t ef);
|
ptrdiff_t oldtop, ptrdiff_t ef);
|
||||||
LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
|
LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult, int nres);
|
||||||
LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
|
LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
|
||||||
LUAI_FUNC void luaD_growstack (lua_State *L, int n);
|
LUAI_FUNC void luaD_growstack (lua_State *L, int n);
|
||||||
LUAI_FUNC void luaD_shrinkstack (lua_State *L);
|
LUAI_FUNC void luaD_shrinkstack (lua_State *L);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldump.c,v 2.34 2014/11/02 19:19:04 roberto Exp $
|
** $Id: ldump.c,v 2.36 2015/03/30 15:43:51 roberto Exp $
|
||||||
** save precompiled Lua chunks
|
** save precompiled Lua chunks
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -74,19 +74,20 @@ static void DumpString (const TString *s, DumpState *D) {
|
|||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
DumpByte(0, D);
|
DumpByte(0, D);
|
||||||
else {
|
else {
|
||||||
size_t size = s->len + 1; /* include trailing '\0' */
|
size_t size = tsslen(s) + 1; /* include trailing '\0' */
|
||||||
|
const char *str = getstr(s);
|
||||||
if (size < 0xFF)
|
if (size < 0xFF)
|
||||||
DumpByte(cast_int(size), D);
|
DumpByte(cast_int(size), D);
|
||||||
else {
|
else {
|
||||||
DumpByte(0xFF, D);
|
DumpByte(0xFF, D);
|
||||||
DumpVar(size, D);
|
DumpVar(size, D);
|
||||||
}
|
}
|
||||||
DumpVector(getstr(s), size - 1, D); /* no need to save '\0' */
|
DumpVector(str, size - 1, D); /* no need to save '\0' */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void DumpCode (const SharedProto *f, DumpState *D) {
|
static void DumpCode (const Proto *f, DumpState *D) {
|
||||||
DumpInt(f->sizecode, D);
|
DumpInt(f->sizecode, D);
|
||||||
DumpVector(f->code, f->sizecode, D);
|
DumpVector(f->code, f->sizecode, D);
|
||||||
}
|
}
|
||||||
@@ -96,7 +97,7 @@ static void DumpFunction(const Proto *f, TString *psource, DumpState *D);
|
|||||||
|
|
||||||
static void DumpConstants (const Proto *f, DumpState *D) {
|
static void DumpConstants (const Proto *f, DumpState *D) {
|
||||||
int i;
|
int i;
|
||||||
int n = f->sp->sizek;
|
int n = f->sizek;
|
||||||
DumpInt(n, D);
|
DumpInt(n, D);
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
const TValue *o = &f->k[i];
|
const TValue *o = &f->k[i];
|
||||||
@@ -126,14 +127,14 @@ static void DumpConstants (const Proto *f, DumpState *D) {
|
|||||||
|
|
||||||
static void DumpProtos (const Proto *f, DumpState *D) {
|
static void DumpProtos (const Proto *f, DumpState *D) {
|
||||||
int i;
|
int i;
|
||||||
int n = f->sp->sizep;
|
int n = f->sizep;
|
||||||
DumpInt(n, D);
|
DumpInt(n, D);
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
DumpFunction(f->p[i], f->sp->source, D);
|
DumpFunction(f->p[i], f->source, D);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void DumpUpvalues (const SharedProto *f, DumpState *D) {
|
static void DumpUpvalues (const Proto *f, DumpState *D) {
|
||||||
int i, n = f->sizeupvalues;
|
int i, n = f->sizeupvalues;
|
||||||
DumpInt(n, D);
|
DumpInt(n, D);
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
@@ -143,7 +144,7 @@ static void DumpUpvalues (const SharedProto *f, DumpState *D) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void DumpDebug (const SharedProto *f, DumpState *D) {
|
static void DumpDebug (const Proto *f, DumpState *D) {
|
||||||
int i, n;
|
int i, n;
|
||||||
n = (D->strip) ? 0 : f->sizelineinfo;
|
n = (D->strip) ? 0 : f->sizelineinfo;
|
||||||
DumpInt(n, D);
|
DumpInt(n, D);
|
||||||
@@ -162,8 +163,7 @@ static void DumpDebug (const SharedProto *f, DumpState *D) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void DumpFunction (const Proto *fp, TString *psource, DumpState *D) {
|
static void DumpFunction (const Proto *f, TString *psource, DumpState *D) {
|
||||||
const SharedProto *f = fp->sp;
|
|
||||||
if (D->strip || f->source == psource)
|
if (D->strip || f->source == psource)
|
||||||
DumpString(NULL, D); /* no debug info or same source as its parent */
|
DumpString(NULL, D); /* no debug info or same source as its parent */
|
||||||
else
|
else
|
||||||
@@ -174,9 +174,9 @@ static void DumpFunction (const Proto *fp, TString *psource, DumpState *D) {
|
|||||||
DumpByte(f->is_vararg, D);
|
DumpByte(f->is_vararg, D);
|
||||||
DumpByte(f->maxstacksize, D);
|
DumpByte(f->maxstacksize, D);
|
||||||
DumpCode(f, D);
|
DumpCode(f, D);
|
||||||
DumpConstants(fp, D);
|
DumpConstants(f, D);
|
||||||
DumpUpvalues(f, D);
|
DumpUpvalues(f, D);
|
||||||
DumpProtos(fp, D);
|
DumpProtos(f, D);
|
||||||
DumpDebug(f, D);
|
DumpDebug(f, D);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +208,7 @@ int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
|
|||||||
D.strip = strip;
|
D.strip = strip;
|
||||||
D.status = 0;
|
D.status = 0;
|
||||||
DumpHeader(&D);
|
DumpHeader(&D);
|
||||||
DumpByte(f->sp->sizeupvalues, &D);
|
DumpByte(f->sizeupvalues, &D);
|
||||||
DumpFunction(f, NULL, &D);
|
DumpFunction(f, NULL, &D);
|
||||||
return D.status;
|
return D.status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,52 +96,39 @@ void luaF_close (lua_State *L, StkId level) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Proto *luaF_newproto (lua_State *L, SharedProto *sp) {
|
Proto *luaF_newproto (lua_State *L) {
|
||||||
GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto));
|
GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto));
|
||||||
Proto *f = gco2p(o);
|
Proto *f = gco2p(o);
|
||||||
f->sp = NULL;
|
|
||||||
f->k = NULL;
|
f->k = NULL;
|
||||||
|
f->sizek = 0;
|
||||||
f->p = NULL;
|
f->p = NULL;
|
||||||
|
f->sizep = 0;
|
||||||
|
f->code = NULL;
|
||||||
f->cache = NULL;
|
f->cache = NULL;
|
||||||
if (sp == NULL) {
|
f->sizecode = 0;
|
||||||
sp = luaM_new(L, SharedProto);
|
f->lineinfo = NULL;
|
||||||
sp->l_G = G(L);
|
f->sizelineinfo = 0;
|
||||||
sp->sizek = 0;
|
f->upvalues = NULL;
|
||||||
sp->sizep = 0;
|
f->sizeupvalues = 0;
|
||||||
sp->code = NULL;
|
f->numparams = 0;
|
||||||
sp->sizecode = 0;
|
f->is_vararg = 0;
|
||||||
sp->lineinfo = NULL;
|
f->maxstacksize = 0;
|
||||||
sp->sizelineinfo = 0;
|
f->locvars = NULL;
|
||||||
sp->upvalues = NULL;
|
f->sizelocvars = 0;
|
||||||
sp->sizeupvalues = 0;
|
f->linedefined = 0;
|
||||||
sp->numparams = 0;
|
f->lastlinedefined = 0;
|
||||||
sp->is_vararg = 0;
|
f->source = NULL;
|
||||||
sp->maxstacksize = 0;
|
|
||||||
sp->locvars = NULL;
|
|
||||||
sp->sizelocvars = 0;
|
|
||||||
sp->linedefined = 0;
|
|
||||||
sp->lastlinedefined = 0;
|
|
||||||
sp->source = NULL;
|
|
||||||
}
|
|
||||||
f->sp = sp;
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void freesharedproto (lua_State *L, SharedProto *f) {
|
|
||||||
if (f == NULL || G(L) != f->l_G)
|
|
||||||
return;
|
|
||||||
luaM_freearray(L, f->code, f->sizecode);
|
|
||||||
luaM_freearray(L, f->lineinfo, f->sizelineinfo);
|
|
||||||
luaM_freearray(L, f->locvars, f->sizelocvars);
|
|
||||||
luaM_freearray(L, f->upvalues, f->sizeupvalues);
|
|
||||||
luaM_free(L, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void luaF_freeproto (lua_State *L, Proto *f) {
|
void luaF_freeproto (lua_State *L, Proto *f) {
|
||||||
luaM_freearray(L, f->p, f->sp->sizep);
|
luaM_freearray(L, f->code, f->sizecode);
|
||||||
luaM_freearray(L, f->k, f->sp->sizek);
|
luaM_freearray(L, f->p, f->sizep);
|
||||||
freesharedproto(L, f->sp);
|
luaM_freearray(L, f->k, f->sizek);
|
||||||
|
luaM_freearray(L, f->lineinfo, f->sizelineinfo);
|
||||||
|
luaM_freearray(L, f->locvars, f->sizelocvars);
|
||||||
|
luaM_freearray(L, f->upvalues, f->sizeupvalues);
|
||||||
luaM_free(L, f);
|
luaM_free(L, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,9 +137,8 @@ void luaF_freeproto (lua_State *L, Proto *f) {
|
|||||||
** Look for n-th local variable at line 'line' in function 'func'.
|
** Look for n-th local variable at line 'line' in function 'func'.
|
||||||
** Returns NULL if not found.
|
** Returns NULL if not found.
|
||||||
*/
|
*/
|
||||||
const char *luaF_getlocalname (const Proto *fp, int local_number, int pc) {
|
const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
|
||||||
int i;
|
int i;
|
||||||
const SharedProto *f = fp->sp;
|
|
||||||
for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
|
for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
|
||||||
if (pc < f->locvars[i].endpc) { /* is variable active? */
|
if (pc < f->locvars[i].endpc) { /* is variable active? */
|
||||||
local_number--;
|
local_number--;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lfunc.h,v 2.14 2014/06/19 18:27:20 roberto Exp $
|
** $Id: lfunc.h,v 2.15 2015/01/13 15:49:11 roberto Exp $
|
||||||
** Auxiliary functions to manipulate prototypes and closures
|
** Auxiliary functions to manipulate prototypes and closures
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -22,6 +22,13 @@
|
|||||||
#define isintwups(L) (L->twups != L)
|
#define isintwups(L) (L->twups != L)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** maximum number of upvalues in a closure (both C and Lua). (Value
|
||||||
|
** must fit in a VM register.)
|
||||||
|
*/
|
||||||
|
#define MAXUPVAL 255
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Upvalues for Lua closures
|
** Upvalues for Lua closures
|
||||||
*/
|
*/
|
||||||
@@ -40,7 +47,7 @@ struct UpVal {
|
|||||||
#define upisopen(up) ((up)->v != &(up)->u.value)
|
#define upisopen(up) ((up)->v != &(up)->u.value)
|
||||||
|
|
||||||
|
|
||||||
LUAI_FUNC Proto *luaF_newproto (lua_State *L, SharedProto *sp);
|
LUAI_FUNC Proto *luaF_newproto (lua_State *L);
|
||||||
LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems);
|
LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems);
|
||||||
LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems);
|
LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems);
|
||||||
LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl);
|
LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lgc.c,v 2.201 2014/12/20 13:58:15 roberto Exp $
|
** $Id: lgc.c,v 2.205 2015/03/25 13:42:19 roberto Exp $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -83,8 +83,13 @@
|
|||||||
#define markvalue(g,o) { checkconsistency(o); \
|
#define markvalue(g,o) { checkconsistency(o); \
|
||||||
if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
|
if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
|
||||||
|
|
||||||
#define markobject(g,t) \
|
#define markobject(g,t) { if (iswhite(t)) reallymarkobject(g, obj2gco(t)); }
|
||||||
{ if ((t) && iswhite(t)) reallymarkobject(g, obj2gco(t)); }
|
|
||||||
|
/*
|
||||||
|
** mark an object that can be NULL (either because it is really optional,
|
||||||
|
** or it was stripped as debug info, or inside an uncompleted structure)
|
||||||
|
*/
|
||||||
|
#define markobjectN(g,t) { if (t) markobject(g,t); }
|
||||||
|
|
||||||
static void reallymarkobject (global_State *g, GCObject *o);
|
static void reallymarkobject (global_State *g, GCObject *o);
|
||||||
|
|
||||||
@@ -226,15 +231,19 @@ static void reallymarkobject (global_State *g, GCObject *o) {
|
|||||||
reentry:
|
reentry:
|
||||||
white2gray(o);
|
white2gray(o);
|
||||||
switch (o->tt) {
|
switch (o->tt) {
|
||||||
case LUA_TSHRSTR:
|
case LUA_TSHRSTR: {
|
||||||
|
gray2black(o);
|
||||||
|
g->GCmemtrav += sizelstring(gco2ts(o)->shrlen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case LUA_TLNGSTR: {
|
case LUA_TLNGSTR: {
|
||||||
gray2black(o);
|
gray2black(o);
|
||||||
g->GCmemtrav += sizestring(gco2ts(o));
|
g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_TUSERDATA: {
|
case LUA_TUSERDATA: {
|
||||||
TValue uvalue;
|
TValue uvalue;
|
||||||
markobject(g, gco2u(o)->metatable); /* mark its metatable */
|
markobjectN(g, gco2u(o)->metatable); /* mark its metatable */
|
||||||
gray2black(o);
|
gray2black(o);
|
||||||
g->GCmemtrav += sizeudata(gco2u(o));
|
g->GCmemtrav += sizeudata(gco2u(o));
|
||||||
getuservalue(g->mainthread, gco2u(o), &uvalue);
|
getuservalue(g->mainthread, gco2u(o), &uvalue);
|
||||||
@@ -275,7 +284,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
|
|||||||
static void markmt (global_State *g) {
|
static void markmt (global_State *g) {
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i < LUA_NUMTAGS; i++)
|
for (i=0; i < LUA_NUMTAGS; i++)
|
||||||
markobject(g, g->mt[i]);
|
markobjectN(g, g->mt[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -437,7 +446,7 @@ static void traversestrongtable (global_State *g, Table *h) {
|
|||||||
static lu_mem traversetable (global_State *g, Table *h) {
|
static lu_mem traversetable (global_State *g, Table *h) {
|
||||||
const char *weakkey, *weakvalue;
|
const char *weakkey, *weakvalue;
|
||||||
const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
|
const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
|
||||||
markobject(g, h->metatable);
|
markobjectN(g, h->metatable);
|
||||||
if (mode && ttisstring(mode) && /* is there a weak mode? */
|
if (mode && ttisstring(mode) && /* is there a weak mode? */
|
||||||
((weakkey = strchr(svalue(mode), 'k')),
|
((weakkey = strchr(svalue(mode), 'k')),
|
||||||
(weakvalue = strchr(svalue(mode), 'v')),
|
(weakvalue = strchr(svalue(mode), 'v')),
|
||||||
@@ -456,32 +465,31 @@ static lu_mem traversetable (global_State *g, Table *h) {
|
|||||||
sizeof(Node) * cast(size_t, sizenode(h));
|
sizeof(Node) * cast(size_t, sizenode(h));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int marksharedproto (global_State *g, SharedProto *f) {
|
|
||||||
int i;
|
|
||||||
if (g != f->l_G)
|
|
||||||
return 0;
|
|
||||||
markobject(g, f->source);
|
|
||||||
for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */
|
|
||||||
markobject(g, f->upvalues[i].name);
|
|
||||||
for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */
|
|
||||||
markobject(g, f->locvars[i].varname);
|
|
||||||
return sizeof(Instruction) * f->sizecode +
|
|
||||||
sizeof(int) * f->sizelineinfo +
|
|
||||||
sizeof(LocVar) * f->sizelocvars +
|
|
||||||
sizeof(Upvaldesc) * f->sizeupvalues;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Traverse a prototype. (While a prototype is being build, its
|
||||||
|
** arrays can be larger than needed; the extra slots are filled with
|
||||||
|
** NULL, so the use of 'markobjectN')
|
||||||
|
*/
|
||||||
static int traverseproto (global_State *g, Proto *f) {
|
static int traverseproto (global_State *g, Proto *f) {
|
||||||
int i;
|
int i;
|
||||||
if (f->cache && iswhite(f->cache))
|
if (f->cache && iswhite(f->cache))
|
||||||
f->cache = NULL; /* allow cache to be collected */
|
f->cache = NULL; /* allow cache to be collected */
|
||||||
for (i = 0; i < f->sp->sizek; i++) /* mark literals */
|
markobjectN(g, f->source);
|
||||||
|
for (i = 0; i < f->sizek; i++) /* mark literals */
|
||||||
markvalue(g, &f->k[i]);
|
markvalue(g, &f->k[i]);
|
||||||
for (i = 0; i < f->sp->sizep; i++) /* mark nested protos */
|
for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */
|
||||||
markobject(g, f->p[i]);
|
markobjectN(g, f->upvalues[i].name);
|
||||||
return sizeof(Proto) + sizeof(Proto *) * f->sp->sizep +
|
for (i = 0; i < f->sizep; i++) /* mark nested protos */
|
||||||
sizeof(TValue) * f->sp->sizek +
|
markobjectN(g, f->p[i]);
|
||||||
marksharedproto(g, f->sp);
|
for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */
|
||||||
|
markobjectN(g, f->locvars[i].varname);
|
||||||
|
return sizeof(Proto) + sizeof(Instruction) * f->sizecode +
|
||||||
|
sizeof(Proto *) * f->sizep +
|
||||||
|
sizeof(TValue) * f->sizek +
|
||||||
|
sizeof(int) * f->sizelineinfo +
|
||||||
|
sizeof(LocVar) * f->sizelocvars +
|
||||||
|
sizeof(Upvaldesc) * f->sizeupvalues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -500,7 +508,7 @@ static lu_mem traverseCclosure (global_State *g, CClosure *cl) {
|
|||||||
*/
|
*/
|
||||||
static lu_mem traverseLclosure (global_State *g, LClosure *cl) {
|
static lu_mem traverseLclosure (global_State *g, LClosure *cl) {
|
||||||
int i;
|
int i;
|
||||||
markobject(g, cl->p); /* mark its prototype */
|
markobjectN(g, cl->p); /* mark its prototype */
|
||||||
for (i = 0; i < cl->nupvalues; i++) { /* mark its upvalues */
|
for (i = 0; i < cl->nupvalues; i++) { /* mark its upvalues */
|
||||||
UpVal *uv = cl->upvals[i];
|
UpVal *uv = cl->upvals[i];
|
||||||
if (uv != NULL) {
|
if (uv != NULL) {
|
||||||
@@ -695,9 +703,10 @@ static void freeobj (lua_State *L, GCObject *o) {
|
|||||||
case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
|
case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
|
||||||
case LUA_TSHRSTR:
|
case LUA_TSHRSTR:
|
||||||
luaS_remove(L, gco2ts(o)); /* remove it from hash table */
|
luaS_remove(L, gco2ts(o)); /* remove it from hash table */
|
||||||
/* go through */
|
luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen));
|
||||||
|
break;
|
||||||
case LUA_TLNGSTR: {
|
case LUA_TLNGSTR: {
|
||||||
luaM_freemem(L, o, sizestring(gco2ts(o)));
|
luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: lua_assert(0);
|
default: lua_assert(0);
|
||||||
@@ -1008,6 +1017,7 @@ static l_mem atomic (lua_State *L) {
|
|||||||
/* clear values from resurrected weak tables */
|
/* clear values from resurrected weak tables */
|
||||||
clearvalues(g, g->weak, origweak);
|
clearvalues(g, g->weak, origweak);
|
||||||
clearvalues(g, g->allweak, origall);
|
clearvalues(g, g->allweak, origall);
|
||||||
|
luaS_clearcache(g);
|
||||||
g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
|
g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
|
||||||
work += g->GCmemtrav; /* complete counting */
|
work += g->GCmemtrav; /* complete counting */
|
||||||
return work; /* estimate of memory marked by 'atomic' */
|
return work; /* estimate of memory marked by 'atomic' */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: liolib.c,v 2.142 2015/01/02 12:50:28 roberto Exp $
|
** $Id: liolib.c,v 2.144 2015/04/03 18:41:57 roberto Exp $
|
||||||
** Standard I/O (and system) library
|
** Standard I/O (and system) library
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -410,12 +410,6 @@ static int readdigits (RN *rn, int hex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* access to locale "radix character" (decimal point) */
|
|
||||||
#if !defined(l_getlocaledecpoint)
|
|
||||||
#define l_getlocaledecpoint() (localeconv()->decimal_point[0])
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Read a number: first reads a valid prefix of a numeral into a buffer.
|
** Read a number: first reads a valid prefix of a numeral into a buffer.
|
||||||
** Then it calls 'lua_stringtonumber' to check whether the format is
|
** Then it calls 'lua_stringtonumber' to check whether the format is
|
||||||
@@ -425,9 +419,10 @@ static int read_number (lua_State *L, FILE *f) {
|
|||||||
RN rn;
|
RN rn;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int hex = 0;
|
int hex = 0;
|
||||||
char decp[2] = ".";
|
char decp[2];
|
||||||
rn.f = f; rn.n = 0;
|
rn.f = f; rn.n = 0;
|
||||||
decp[0] = l_getlocaledecpoint(); /* get decimal point from locale */
|
decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */
|
||||||
|
decp[1] = '\0';
|
||||||
l_lockfile(rn.f);
|
l_lockfile(rn.f);
|
||||||
do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */
|
do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */
|
||||||
test2(&rn, "-+"); /* optional signal */
|
test2(&rn, "-+"); /* optional signal */
|
||||||
@@ -457,7 +452,7 @@ static int read_number (lua_State *L, FILE *f) {
|
|||||||
static int test_eof (lua_State *L, FILE *f) {
|
static int test_eof (lua_State *L, FILE *f) {
|
||||||
int c = getc(f);
|
int c = getc(f);
|
||||||
ungetc(c, f); /* no-op when c == EOF */
|
ungetc(c, f); /* no-op when c == EOF */
|
||||||
lua_pushlstring(L, NULL, 0);
|
lua_pushliteral(L, "");
|
||||||
return (c != EOF);
|
return (c != EOF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: llex.c,v 2.89 2014/11/14 16:06:09 roberto Exp $
|
** $Id: llex.c,v 2.93 2015/05/22 17:45:56 roberto Exp $
|
||||||
** Lexical Analyzer
|
** Lexical Analyzer
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
|
|
||||||
#include "lctype.h"
|
#include "lctype.h"
|
||||||
|
#include "ldebug.h"
|
||||||
#include "ldo.h"
|
#include "ldo.h"
|
||||||
#include "lgc.h"
|
#include "lgc.h"
|
||||||
#include "llex.h"
|
#include "llex.h"
|
||||||
@@ -68,7 +69,7 @@ static void save (LexState *ls, int c) {
|
|||||||
|
|
||||||
void luaX_init (lua_State *L) {
|
void luaX_init (lua_State *L) {
|
||||||
int i;
|
int i;
|
||||||
TString *e = luaS_new(L, LUA_ENV); /* create env name */
|
TString *e = luaS_newliteral(L, LUA_ENV); /* create env name */
|
||||||
luaC_fix(L, obj2gco(e)); /* never collect this name */
|
luaC_fix(L, obj2gco(e)); /* never collect this name */
|
||||||
for (i=0; i<NUM_RESERVED; i++) {
|
for (i=0; i<NUM_RESERVED; i++) {
|
||||||
TString *ts = luaS_new(L, luaX_tokens[i]);
|
TString *ts = luaS_new(L, luaX_tokens[i]);
|
||||||
@@ -106,9 +107,7 @@ static const char *txtToken (LexState *ls, int token) {
|
|||||||
|
|
||||||
|
|
||||||
static l_noret lexerror (LexState *ls, const char *msg, int token) {
|
static l_noret lexerror (LexState *ls, const char *msg, int token) {
|
||||||
char buff[LUA_IDSIZE];
|
msg = luaG_addinfo(ls->L, msg, ls->source, ls->linenumber);
|
||||||
luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE);
|
|
||||||
msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
|
|
||||||
if (token)
|
if (token)
|
||||||
luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
|
luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
|
||||||
luaD_throw(ls->L, LUA_ERRSYNTAX);
|
luaD_throw(ls->L, LUA_ERRSYNTAX);
|
||||||
@@ -172,7 +171,7 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
|
|||||||
ls->linenumber = 1;
|
ls->linenumber = 1;
|
||||||
ls->lastline = 1;
|
ls->lastline = 1;
|
||||||
ls->source = source;
|
ls->source = source;
|
||||||
ls->envn = luaS_new(L, LUA_ENV); /* get env name */
|
ls->envn = luaS_newliteral(L, LUA_ENV); /* get env name */
|
||||||
luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
|
luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,11 +220,6 @@ static void buffreplace (LexState *ls, char from, char to) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if !defined(l_getlocaledecpoint)
|
|
||||||
#define l_getlocaledecpoint() (localeconv()->decimal_point[0])
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define buff2num(b,o) (luaO_str2num(luaZ_buffer(b), o) != 0)
|
#define buff2num(b,o) (luaO_str2num(luaZ_buffer(b), o) != 0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -234,7 +228,7 @@ static void buffreplace (LexState *ls, char from, char to) {
|
|||||||
*/
|
*/
|
||||||
static void trydecpoint (LexState *ls, TValue *o) {
|
static void trydecpoint (LexState *ls, TValue *o) {
|
||||||
char old = ls->decpoint;
|
char old = ls->decpoint;
|
||||||
ls->decpoint = l_getlocaledecpoint();
|
ls->decpoint = lua_getlocaledecpoint();
|
||||||
buffreplace(ls, old, ls->decpoint); /* try new decimal separator */
|
buffreplace(ls, old, ls->decpoint); /* try new decimal separator */
|
||||||
if (!buff2num(ls->buff, o)) {
|
if (!buff2num(ls->buff, o)) {
|
||||||
/* format error with correct decimal point: no more options */
|
/* format error with correct decimal point: no more options */
|
||||||
@@ -283,8 +277,9 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** skip a sequence '[=*[' or ']=*]' and return its number of '='s or
|
** skip a sequence '[=*[' or ']=*]'; if sequence is wellformed, return
|
||||||
** -1 if sequence is malformed
|
** its number of '='s; otherwise, return a negative number (-1 iff there
|
||||||
|
** are no '='s after initial bracket)
|
||||||
*/
|
*/
|
||||||
static int skip_sep (LexState *ls) {
|
static int skip_sep (LexState *ls) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@@ -501,8 +496,9 @@ static int llex (LexState *ls, SemInfo *seminfo) {
|
|||||||
read_long_string(ls, seminfo, sep);
|
read_long_string(ls, seminfo, sep);
|
||||||
return TK_STRING;
|
return TK_STRING;
|
||||||
}
|
}
|
||||||
else if (sep == -1) return '[';
|
else if (sep != -1) /* '[=...' missing second bracket */
|
||||||
else lexerror(ls, "invalid long string delimiter", TK_STRING);
|
lexerror(ls, "invalid long string delimiter", TK_STRING);
|
||||||
|
return '[';
|
||||||
}
|
}
|
||||||
case '=': {
|
case '=': {
|
||||||
next(ls);
|
next(ls);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: llimits.h,v 1.125 2014/12/19 13:30:23 roberto Exp $
|
** $Id: llimits.h,v 1.135 2015/06/09 14:21:00 roberto Exp $
|
||||||
** Limits, basic types, and some other 'installation-dependent' definitions
|
** Limits, basic types, and some other 'installation-dependent' definitions
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -52,11 +52,11 @@ typedef unsigned char lu_byte;
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** conversion of pointer to integer:
|
** conversion of pointer to unsigned integer:
|
||||||
** this is for hashing only; there is no problem if the integer
|
** this is for hashing only; there is no problem if the integer
|
||||||
** cannot hold the whole pointer value
|
** cannot hold the whole pointer value
|
||||||
*/
|
*/
|
||||||
#define point2int(p) ((unsigned int)((size_t)(p) & UINT_MAX))
|
#define point2uint(p) ((unsigned int)((size_t)(p) & UINT_MAX))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -88,22 +88,20 @@ typedef LUAI_UACINT l_uacInt;
|
|||||||
/*
|
/*
|
||||||
** assertion for checking API calls
|
** assertion for checking API calls
|
||||||
*/
|
*/
|
||||||
#if defined(LUA_USE_APICHECK)
|
#if !defined(luai_apicheck)
|
||||||
#include <assert.h>
|
#define luai_apicheck(l,e) lua_assert(e)
|
||||||
#define luai_apicheck(e) assert(e)
|
|
||||||
#else
|
|
||||||
#define luai_apicheck(e) lua_assert(e)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define api_check(l,e,msg) luai_apicheck(l,(e) && msg)
|
||||||
#define api_check(e,msg) luai_apicheck((e) && msg)
|
|
||||||
|
|
||||||
|
|
||||||
|
/* macro to avoid warnings about unused variables */
|
||||||
#if !defined(UNUSED)
|
#if !defined(UNUSED)
|
||||||
#define UNUSED(x) ((void)(x)) /* to avoid warnings */
|
#define UNUSED(x) ((void)(x))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* type casts (a macro highlights casts in the code) */
|
||||||
#define cast(t, exp) ((t)(exp))
|
#define cast(t, exp) ((t)(exp))
|
||||||
|
|
||||||
#define cast_void(i) cast(void, (i))
|
#define cast_void(i) cast(void, (i))
|
||||||
@@ -149,11 +147,6 @@ typedef LUAI_UACINT l_uacInt;
|
|||||||
#define LUAI_MAXCCALLS 200
|
#define LUAI_MAXCCALLS 200
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
** maximum number of upvalues in a closure (both C and Lua). (Value
|
|
||||||
** must fit in an unsigned char.)
|
|
||||||
*/
|
|
||||||
#define MAXUPVAL UCHAR_MAX
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -168,10 +161,33 @@ typedef unsigned long Instruction;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Maximum length for short strings, that is, strings that are
|
||||||
|
** internalized. (Cannot be smaller than reserved words or tags for
|
||||||
|
** metamethods, as these strings must be internalized;
|
||||||
|
** #("function") = 8, #("__newindex") = 10.)
|
||||||
|
*/
|
||||||
|
#if !defined(LUAI_MAXSHORTLEN)
|
||||||
|
#define LUAI_MAXSHORTLEN 40
|
||||||
|
#endif
|
||||||
|
|
||||||
/* minimum size for the string table (must be power of 2) */
|
|
||||||
|
/*
|
||||||
|
** Initial size for the string table (must be power of 2).
|
||||||
|
** The Lua core alone registers ~50 strings (reserved words +
|
||||||
|
** metaevent keys + a few others). Libraries would typically add
|
||||||
|
** a few dozens more.
|
||||||
|
*/
|
||||||
#if !defined(MINSTRTABSIZE)
|
#if !defined(MINSTRTABSIZE)
|
||||||
#define MINSTRTABSIZE 64 /* minimum size for "predefined" strings */
|
#define MINSTRTABSIZE 128
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Size of cache for strings in the API (better be a prime)
|
||||||
|
*/
|
||||||
|
#if !defined(STRCACHE_SIZE)
|
||||||
|
#define STRCACHE_SIZE 127
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -181,11 +197,19 @@ typedef unsigned long Instruction;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** macros that are executed whenether program enters the Lua core
|
||||||
|
** ('lua_lock') and leaves the core ('lua_unlock')
|
||||||
|
*/
|
||||||
#if !defined(lua_lock)
|
#if !defined(lua_lock)
|
||||||
#define lua_lock(L) ((void) 0)
|
#define lua_lock(L) ((void) 0)
|
||||||
#define lua_unlock(L) ((void) 0)
|
#define lua_unlock(L) ((void) 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** macro executed during Lua functions at points where the
|
||||||
|
** function can yield.
|
||||||
|
*/
|
||||||
#if !defined(luai_threadyield)
|
#if !defined(luai_threadyield)
|
||||||
#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
|
#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
|
||||||
#endif
|
#endif
|
||||||
@@ -222,6 +246,53 @@ typedef unsigned long Instruction;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The luai_num* macros define the primitive operations over numbers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* floor division (defined as 'floor(a/b)') */
|
||||||
|
#if !defined(luai_numidiv)
|
||||||
|
#define luai_numidiv(L,a,b) ((void)L, l_floor(luai_numdiv(L,a,b)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* float division */
|
||||||
|
#if !defined(luai_numdiv)
|
||||||
|
#define luai_numdiv(L,a,b) ((a)/(b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** modulo: defined as 'a - floor(a/b)*b'; this definition gives NaN when
|
||||||
|
** 'b' is huge, but the result should be 'a'. 'fmod' gives the result of
|
||||||
|
** 'a - trunc(a/b)*b', and therefore must be corrected when 'trunc(a/b)
|
||||||
|
** ~= floor(a/b)'. That happens when the division has a non-integer
|
||||||
|
** negative result, which is equivalent to the test below.
|
||||||
|
*/
|
||||||
|
#if !defined(luai_nummod)
|
||||||
|
#define luai_nummod(L,a,b,m) \
|
||||||
|
{ (m) = l_mathop(fmod)(a,b); if ((m)*(b) < 0) (m) += (b); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* exponentiation */
|
||||||
|
#if !defined(luai_numpow)
|
||||||
|
#define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* the others are quite standard operations */
|
||||||
|
#if !defined(luai_numadd)
|
||||||
|
#define luai_numadd(L,a,b) ((a)+(b))
|
||||||
|
#define luai_numsub(L,a,b) ((a)-(b))
|
||||||
|
#define luai_nummul(L,a,b) ((a)*(b))
|
||||||
|
#define luai_numunm(L,a) (-(a))
|
||||||
|
#define luai_numeq(a,b) ((a)==(b))
|
||||||
|
#define luai_numlt(a,b) ((a)<(b))
|
||||||
|
#define luai_numle(a,b) ((a)<=(b))
|
||||||
|
#define luai_numisnan(a) (!luai_numeq((a), (a)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** macro to control inclusion of some hard tests on stack reallocation
|
** macro to control inclusion of some hard tests on stack reallocation
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lmathlib.c,v 1.114 2014/12/27 20:32:26 roberto Exp $
|
** $Id: lmathlib.c,v 1.115 2015/03/12 14:04:04 roberto Exp $
|
||||||
** Standard mathematical library
|
** Standard mathematical library
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -183,6 +183,9 @@ static int math_log (lua_State *L) {
|
|||||||
res = l_mathop(log)(x);
|
res = l_mathop(log)(x);
|
||||||
else {
|
else {
|
||||||
lua_Number base = luaL_checknumber(L, 2);
|
lua_Number base = luaL_checknumber(L, 2);
|
||||||
|
#if !defined(LUA_USE_C89)
|
||||||
|
if (base == 2.0) res = l_mathop(log2)(x); else
|
||||||
|
#endif
|
||||||
if (base == 10.0) res = l_mathop(log10)(x);
|
if (base == 10.0) res = l_mathop(log10)(x);
|
||||||
else res = l_mathop(log)(x)/l_mathop(log)(base);
|
else res = l_mathop(log)(x)/l_mathop(log)(base);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lmem.c,v 1.89 2014/11/02 19:33:33 roberto Exp $
|
** $Id: lmem.c,v 1.91 2015/03/06 19:45:54 roberto Exp $
|
||||||
** Interface to Memory Manager
|
** Interface to Memory Manager
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -85,10 +85,11 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
|
|||||||
#endif
|
#endif
|
||||||
newblock = (*g->frealloc)(g->ud, block, osize, nsize);
|
newblock = (*g->frealloc)(g->ud, block, osize, nsize);
|
||||||
if (newblock == NULL && nsize > 0) {
|
if (newblock == NULL && nsize > 0) {
|
||||||
api_check( nsize > realosize,
|
lua_assert(nsize > realosize); /* cannot fail when shrinking a block */
|
||||||
"realloc cannot fail when shrinking a block");
|
if (g->version) { /* is state fully built? */
|
||||||
luaC_fullgc(L, 1); /* try to free some memory... */
|
luaC_fullgc(L, 1); /* try to free some memory... */
|
||||||
newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
|
newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
|
||||||
|
}
|
||||||
if (newblock == NULL)
|
if (newblock == NULL)
|
||||||
luaD_throw(L, LUA_ERRMEM);
|
luaD_throw(L, LUA_ERRMEM);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: loadlib.c,v 1.124 2015/01/05 13:51:39 roberto Exp $
|
** $Id: loadlib.c,v 1.126 2015/02/16 13:14:33 roberto Exp $
|
||||||
** Dynamic library loader for Lua
|
** Dynamic library loader for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
**
|
**
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -136,8 +137,8 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym);
|
|||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Macro to covert pointer to void* to pointer to function. This cast
|
** Macro to convert pointer-to-void* to pointer-to-function. This cast
|
||||||
** is undefined according to ISO C, but POSIX assumes that it must work.
|
** is undefined according to ISO C, but POSIX assumes that it works.
|
||||||
** (The '__extension__' in gnu compilers is only to avoid warnings.)
|
** (The '__extension__' in gnu compilers is only to avoid warnings.)
|
||||||
*/
|
*/
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.c,v 2.101 2014/12/26 14:43:45 roberto Exp $
|
** $Id: lobject.c,v 2.104 2015/04/11 18:30:08 roberto Exp $
|
||||||
** Some generic functions over Lua objects
|
** Some generic functions over Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -10,6 +10,8 @@
|
|||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#include <math.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -39,8 +41,12 @@ LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
|
|||||||
int luaO_int2fb (unsigned int x) {
|
int luaO_int2fb (unsigned int x) {
|
||||||
int e = 0; /* exponent */
|
int e = 0; /* exponent */
|
||||||
if (x < 8) return x;
|
if (x < 8) return x;
|
||||||
while (x >= 0x10) {
|
while (x >= (8 << 4)) { /* coarse steps */
|
||||||
x = (x+1) >> 1;
|
x = (x + 0xf) >> 4; /* x = ceil(x / 16) */
|
||||||
|
e += 4;
|
||||||
|
}
|
||||||
|
while (x >= (8 << 1)) { /* fine steps */
|
||||||
|
x = (x + 1) >> 1; /* x = ceil(x / 2) */
|
||||||
e++;
|
e++;
|
||||||
}
|
}
|
||||||
return ((e+1) << 3) | (cast_int(x) - 8);
|
return ((e+1) << 3) | (cast_int(x) - 8);
|
||||||
@@ -55,8 +61,11 @@ int luaO_fb2int (int x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Computes ceil(log2(x))
|
||||||
|
*/
|
||||||
int luaO_ceillog2 (unsigned int x) {
|
int luaO_ceillog2 (unsigned int x) {
|
||||||
static const lu_byte log_2[256] = {
|
static const lu_byte log_2[256] = { /* log_2[i] = ceil(log2(i - 1)) */
|
||||||
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
||||||
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
@@ -149,13 +158,13 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
|
|||||||
}
|
}
|
||||||
/* could not perform raw operation; try metamethod */
|
/* could not perform raw operation; try metamethod */
|
||||||
lua_assert(L != NULL); /* should not fail when folding (compile time) */
|
lua_assert(L != NULL); /* should not fail when folding (compile time) */
|
||||||
luaT_trybinTM(L, p1, p2, res, cast(TMS, op - LUA_OPADD + TM_ADD));
|
luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int luaO_hexavalue (int c) {
|
int luaO_hexavalue (int c) {
|
||||||
if (lisdigit(c)) return c - '0';
|
if (lisdigit(c)) return c - '0';
|
||||||
else return ltolower(c) - 'a' + 10;
|
else return (ltolower(c) - 'a') + 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -172,9 +181,8 @@ static int isneg (const char **s) {
|
|||||||
** Lua's implementation for 'lua_strx2number'
|
** Lua's implementation for 'lua_strx2number'
|
||||||
** ===================================================================
|
** ===================================================================
|
||||||
*/
|
*/
|
||||||
#if !defined(lua_strx2number)
|
|
||||||
|
|
||||||
#include <math.h>
|
#if !defined(lua_strx2number)
|
||||||
|
|
||||||
/* maximum number of significant digits to read (to avoid overflows
|
/* maximum number of significant digits to read (to avoid overflows
|
||||||
even with single floats) */
|
even with single floats) */
|
||||||
@@ -185,21 +193,22 @@ static int isneg (const char **s) {
|
|||||||
** C99 specification for 'strtod'
|
** C99 specification for 'strtod'
|
||||||
*/
|
*/
|
||||||
static lua_Number lua_strx2number (const char *s, char **endptr) {
|
static lua_Number lua_strx2number (const char *s, char **endptr) {
|
||||||
|
int dot = lua_getlocaledecpoint();
|
||||||
lua_Number r = 0.0; /* result (accumulator) */
|
lua_Number r = 0.0; /* result (accumulator) */
|
||||||
int sigdig = 0; /* number of significant digits */
|
int sigdig = 0; /* number of significant digits */
|
||||||
int nosigdig = 0; /* number of non-significant digits */
|
int nosigdig = 0; /* number of non-significant digits */
|
||||||
int e = 0; /* exponent correction */
|
int e = 0; /* exponent correction */
|
||||||
int neg; /* 1 if number is negative */
|
int neg; /* 1 if number is negative */
|
||||||
int dot = 0; /* true after seen a dot */
|
int hasdot = 0; /* true after seen a dot */
|
||||||
*endptr = cast(char *, s); /* nothing is valid yet */
|
*endptr = cast(char *, s); /* nothing is valid yet */
|
||||||
while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
|
while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
|
||||||
neg = isneg(&s); /* check signal */
|
neg = isneg(&s); /* check signal */
|
||||||
if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
|
if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
|
||||||
return 0.0; /* invalid format (no '0x') */
|
return 0.0; /* invalid format (no '0x') */
|
||||||
for (s += 2; ; s++) { /* skip '0x' and read numeral */
|
for (s += 2; ; s++) { /* skip '0x' and read numeral */
|
||||||
if (*s == '.') {
|
if (*s == dot) {
|
||||||
if (dot) break; /* second dot? stop loop */
|
if (hasdot) break; /* second dot? stop loop */
|
||||||
else dot = 1;
|
else hasdot = 1;
|
||||||
}
|
}
|
||||||
else if (lisxdigit(cast_uchar(*s))) {
|
else if (lisxdigit(cast_uchar(*s))) {
|
||||||
if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */
|
if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */
|
||||||
@@ -207,7 +216,7 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
|
|||||||
else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */
|
else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */
|
||||||
r = (r * cast_num(16.0)) + luaO_hexavalue(*s);
|
r = (r * cast_num(16.0)) + luaO_hexavalue(*s);
|
||||||
else e++; /* too many digits; ignore, but still count for exponent */
|
else e++; /* too many digits; ignore, but still count for exponent */
|
||||||
if (dot) e--; /* decimal digit? correct exponent */
|
if (hasdot) e--; /* decimal digit? correct exponent */
|
||||||
}
|
}
|
||||||
else break; /* neither a dot nor a digit */
|
else break; /* neither a dot nor a digit */
|
||||||
}
|
}
|
||||||
@@ -244,7 +253,7 @@ static const char *l_str2d (const char *s, lua_Number *result) {
|
|||||||
*result = lua_strx2number(s, &endptr);
|
*result = lua_strx2number(s, &endptr);
|
||||||
else
|
else
|
||||||
*result = lua_str2number(s, &endptr);
|
*result = lua_str2number(s, &endptr);
|
||||||
if (endptr == s) return 0; /* nothing recognized */
|
if (endptr == s) return NULL; /* nothing recognized */
|
||||||
while (lisspace(cast_uchar(*endptr))) endptr++;
|
while (lisspace(cast_uchar(*endptr))) endptr++;
|
||||||
return (*endptr == '\0' ? endptr : NULL); /* OK if no trailing characters */
|
return (*endptr == '\0' ? endptr : NULL); /* OK if no trailing characters */
|
||||||
}
|
}
|
||||||
@@ -290,7 +299,7 @@ size_t luaO_str2num (const char *s, TValue *o) {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
return 0; /* conversion failed */
|
return 0; /* conversion failed */
|
||||||
return (e - s + 1); /* success; return string size */
|
return (e - s) + 1; /* success; return string size */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -329,7 +338,7 @@ void luaO_tostring (lua_State *L, StkId obj) {
|
|||||||
len = lua_number2str(buff, fltvalue(obj));
|
len = lua_number2str(buff, fltvalue(obj));
|
||||||
#if !defined(LUA_COMPAT_FLOATSTRING)
|
#if !defined(LUA_COMPAT_FLOATSTRING)
|
||||||
if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */
|
if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */
|
||||||
buff[len++] = '.';
|
buff[len++] = lua_getlocaledecpoint();
|
||||||
buff[len++] = '0'; /* adds '.0' to result */
|
buff[len++] = '0'; /* adds '.0' to result */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.h,v 2.106 2015/01/05 13:52:37 roberto Exp $
|
** $Id: lobject.h,v 2.111 2015/06/09 14:21:42 roberto Exp $
|
||||||
** Type definitions for Lua objects
|
** Type definitions for Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -35,8 +35,6 @@
|
|||||||
** bit 6: whether value is collectable
|
** bit 6: whether value is collectable
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VARBITS (3 << 4)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** LUA_TFUNCTION variants:
|
** LUA_TFUNCTION variants:
|
||||||
@@ -190,9 +188,15 @@ typedef struct lua_TValue TValue;
|
|||||||
#define setfltvalue(obj,x) \
|
#define setfltvalue(obj,x) \
|
||||||
{ TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_TNUMFLT); }
|
{ TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_TNUMFLT); }
|
||||||
|
|
||||||
|
#define chgfltvalue(obj,x) \
|
||||||
|
{ TValue *io=(obj); lua_assert(ttisfloat(io)); val_(io).n=(x); }
|
||||||
|
|
||||||
#define setivalue(obj,x) \
|
#define setivalue(obj,x) \
|
||||||
{ TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); }
|
{ TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); }
|
||||||
|
|
||||||
|
#define chgivalue(obj,x) \
|
||||||
|
{ TValue *io=(obj); lua_assert(ttisinteger(io)); val_(io).i=(x); }
|
||||||
|
|
||||||
#define setnilvalue(obj) settt_(obj, LUA_TNIL)
|
#define setnilvalue(obj) settt_(obj, LUA_TNIL)
|
||||||
|
|
||||||
#define setfvalue(obj,x) \
|
#define setfvalue(obj,x) \
|
||||||
@@ -303,9 +307,12 @@ typedef TValue *StkId; /* index to stack elements */
|
|||||||
typedef struct TString {
|
typedef struct TString {
|
||||||
CommonHeader;
|
CommonHeader;
|
||||||
lu_byte extra; /* reserved words for short strings; "has hash" for longs */
|
lu_byte extra; /* reserved words for short strings; "has hash" for longs */
|
||||||
|
lu_byte shrlen; /* length for short strings */
|
||||||
unsigned int hash;
|
unsigned int hash;
|
||||||
size_t len; /* number of characters in string */
|
union {
|
||||||
struct TString *hnext; /* linked list for hash table */
|
size_t lnglen; /* length for long strings */
|
||||||
|
struct TString *hnext; /* linked list for hash table */
|
||||||
|
} u;
|
||||||
} TString;
|
} TString;
|
||||||
|
|
||||||
|
|
||||||
@@ -329,6 +336,12 @@ typedef union UTString {
|
|||||||
/* get the actual string (array of bytes) from a Lua value */
|
/* get the actual string (array of bytes) from a Lua value */
|
||||||
#define svalue(o) getstr(tsvalue(o))
|
#define svalue(o) getstr(tsvalue(o))
|
||||||
|
|
||||||
|
/* get string length from 'TString *s' */
|
||||||
|
#define tsslen(s) ((s)->tt == LUA_TSHRSTR ? (s)->shrlen : (s)->u.lnglen)
|
||||||
|
|
||||||
|
/* get string length from 'TValue *o' */
|
||||||
|
#define vslen(o) tsslen(tsvalue(o))
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Header for userdata; memory area follows the end of this structure
|
** Header for userdata; memory area follows the end of this structure
|
||||||
@@ -361,13 +374,13 @@ typedef union UUdata {
|
|||||||
|
|
||||||
#define setuservalue(L,u,o) \
|
#define setuservalue(L,u,o) \
|
||||||
{ const TValue *io=(o); Udata *iu = (u); \
|
{ const TValue *io=(o); Udata *iu = (u); \
|
||||||
iu->user_ = io->value_; iu->ttuv_ = io->tt_; \
|
iu->user_ = io->value_; iu->ttuv_ = rttype(io); \
|
||||||
checkliveness(G(L),io); }
|
checkliveness(G(L),io); }
|
||||||
|
|
||||||
|
|
||||||
#define getuservalue(L,u,o) \
|
#define getuservalue(L,u,o) \
|
||||||
{ TValue *io=(o); const Udata *iu = (u); \
|
{ TValue *io=(o); const Udata *iu = (u); \
|
||||||
io->value_ = iu->user_; io->tt_ = iu->ttuv_; \
|
io->value_ = iu->user_; settt_(io, iu->ttuv_); \
|
||||||
checkliveness(G(L),io); }
|
checkliveness(G(L),io); }
|
||||||
|
|
||||||
|
|
||||||
@@ -376,7 +389,7 @@ typedef union UUdata {
|
|||||||
*/
|
*/
|
||||||
typedef struct Upvaldesc {
|
typedef struct Upvaldesc {
|
||||||
TString *name; /* upvalue name (for debug information) */
|
TString *name; /* upvalue name (for debug information) */
|
||||||
lu_byte instack; /* whether it is in stack */
|
lu_byte instack; /* whether it is in stack (register) */
|
||||||
lu_byte idx; /* index of upvalue (in stack or in outer function's list) */
|
lu_byte idx; /* index of upvalue (in stack or in outer function's list) */
|
||||||
} Upvaldesc;
|
} Upvaldesc;
|
||||||
|
|
||||||
@@ -392,10 +405,14 @@ typedef struct LocVar {
|
|||||||
} LocVar;
|
} LocVar;
|
||||||
|
|
||||||
|
|
||||||
typedef struct SharedProto {
|
/*
|
||||||
|
** Function Prototypes
|
||||||
|
*/
|
||||||
|
typedef struct Proto {
|
||||||
|
CommonHeader;
|
||||||
lu_byte numparams; /* number of fixed parameters */
|
lu_byte numparams; /* number of fixed parameters */
|
||||||
lu_byte is_vararg;
|
lu_byte is_vararg;
|
||||||
lu_byte maxstacksize; /* maximum stack used by this function */
|
lu_byte maxstacksize; /* number of registers needed by this function */
|
||||||
int sizeupvalues; /* size of 'upvalues' */
|
int sizeupvalues; /* size of 'upvalues' */
|
||||||
int sizek; /* size of 'k' */
|
int sizek; /* size of 'k' */
|
||||||
int sizecode;
|
int sizecode;
|
||||||
@@ -404,23 +421,14 @@ typedef struct SharedProto {
|
|||||||
int sizelocvars;
|
int sizelocvars;
|
||||||
int linedefined;
|
int linedefined;
|
||||||
int lastlinedefined;
|
int lastlinedefined;
|
||||||
void *l_G; /* global state belongs to */
|
TValue *k; /* constants used by the function */
|
||||||
Instruction *code;
|
Instruction *code; /* opcodes */
|
||||||
|
struct Proto **p; /* functions defined inside the function */
|
||||||
int *lineinfo; /* map from opcodes to source lines (debug information) */
|
int *lineinfo; /* map from opcodes to source lines (debug information) */
|
||||||
LocVar *locvars; /* information about local variables (debug information) */
|
LocVar *locvars; /* information about local variables (debug information) */
|
||||||
Upvaldesc *upvalues; /* upvalue information */
|
Upvaldesc *upvalues; /* upvalue information */
|
||||||
|
struct LClosure *cache; /* last-created closure with this prototype */
|
||||||
TString *source; /* used for debug information */
|
TString *source; /* used for debug information */
|
||||||
} SharedProto;
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Function Prototypes
|
|
||||||
*/
|
|
||||||
typedef struct Proto {
|
|
||||||
CommonHeader;
|
|
||||||
struct SharedProto *sp;
|
|
||||||
TValue *k; /* constants used by the function */
|
|
||||||
struct Proto **p; /* functions defined inside the function */
|
|
||||||
struct LClosure *cache; /* last created closure with this prototype */
|
|
||||||
GCObject *gclist;
|
GCObject *gclist;
|
||||||
} Proto;
|
} Proto;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: loslib.c,v 1.54 2014/12/26 14:46:07 roberto Exp $
|
** $Id: loslib.c,v 1.57 2015/04/10 17:41:04 roberto Exp $
|
||||||
** Standard Operating System library
|
** Standard Operating System library
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -22,10 +22,12 @@
|
|||||||
#include "lualib.h"
|
#include "lualib.h"
|
||||||
|
|
||||||
|
|
||||||
#if !defined(LUA_STRFTIMEOPTIONS) /* { */
|
|
||||||
/*
|
/*
|
||||||
|
** {==================================================================
|
||||||
** list of valid conversion specifiers for the 'strftime' function
|
** list of valid conversion specifiers for the 'strftime' function
|
||||||
|
** ===================================================================
|
||||||
*/
|
*/
|
||||||
|
#if !defined(LUA_STRFTIMEOPTIONS) /* { */
|
||||||
|
|
||||||
#if defined(LUA_USE_C89)
|
#if defined(LUA_USE_C89)
|
||||||
#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" }
|
#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" }
|
||||||
@@ -37,8 +39,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* } */
|
#endif /* } */
|
||||||
|
/* }================================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** {==================================================================
|
||||||
|
** Configuration for time-related stuff
|
||||||
|
** ===================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
#if !defined(l_time_t) /* { */
|
#if !defined(l_time_t) /* { */
|
||||||
/*
|
/*
|
||||||
@@ -51,15 +59,41 @@
|
|||||||
#endif /* } */
|
#endif /* } */
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(l_gmtime) /* { */
|
||||||
#if !defined(lua_tmpnam) /* { */
|
|
||||||
/*
|
/*
|
||||||
** By default, Lua uses tmpnam except when POSIX is available, where it
|
** By default, Lua uses gmtime/localtime, except when POSIX is available,
|
||||||
** uses mkstemp.
|
** where it uses gmtime_r/localtime_r
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LUA_USE_POSIX) /* { */
|
#if defined(LUA_USE_POSIX) /* { */
|
||||||
|
|
||||||
|
#define l_gmtime(t,r) gmtime_r(t,r)
|
||||||
|
#define l_localtime(t,r) localtime_r(t,r)
|
||||||
|
|
||||||
|
#else /* }{ */
|
||||||
|
|
||||||
|
/* ISO C definitions */
|
||||||
|
#define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t))
|
||||||
|
#define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t))
|
||||||
|
|
||||||
|
#endif /* } */
|
||||||
|
|
||||||
|
#endif /* } */
|
||||||
|
|
||||||
|
/* }================================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** {==================================================================
|
||||||
|
** Configuration for 'tmpnam':
|
||||||
|
** By default, Lua uses tmpnam except when POSIX is available, where
|
||||||
|
** it uses mkstemp.
|
||||||
|
** ===================================================================
|
||||||
|
*/
|
||||||
|
#if !defined(lua_tmpnam) /* { */
|
||||||
|
|
||||||
|
#if defined(LUA_USE_POSIX) /* { */
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define LUA_TMPNAMBUFSIZE 32
|
#define LUA_TMPNAMBUFSIZE 32
|
||||||
@@ -83,31 +117,10 @@
|
|||||||
#endif /* } */
|
#endif /* } */
|
||||||
|
|
||||||
#endif /* } */
|
#endif /* } */
|
||||||
|
/* }================================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if !defined(l_gmtime) /* { */
|
|
||||||
/*
|
|
||||||
** By default, Lua uses gmtime/localtime, except when POSIX is available,
|
|
||||||
** where it uses gmtime_r/localtime_r
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(LUA_USE_POSIX) /* { */
|
|
||||||
|
|
||||||
#define l_gmtime(t,r) gmtime_r(t,r)
|
|
||||||
#define l_localtime(t,r) localtime_r(t,r)
|
|
||||||
|
|
||||||
#else /* }{ */
|
|
||||||
|
|
||||||
/* ISO C definitions */
|
|
||||||
#define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t))
|
|
||||||
#define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t))
|
|
||||||
|
|
||||||
#endif /* } */
|
|
||||||
|
|
||||||
#endif /* } */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int os_execute (lua_State *L) {
|
static int os_execute (lua_State *L) {
|
||||||
const char *cmd = luaL_optstring(L, 1, NULL);
|
const char *cmd = luaL_optstring(L, 1, NULL);
|
||||||
@@ -287,7 +300,7 @@ static int os_time (lua_State *L) {
|
|||||||
t = mktime(&ts);
|
t = mktime(&ts);
|
||||||
}
|
}
|
||||||
if (t != (time_t)(l_timet)t)
|
if (t != (time_t)(l_timet)t)
|
||||||
luaL_error(L, "time result cannot be represented in this Lua instalation");
|
luaL_error(L, "time result cannot be represented in this Lua installation");
|
||||||
else if (t == (time_t)(-1))
|
else if (t == (time_t)(-1))
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
else
|
else
|
||||||
@@ -297,8 +310,9 @@ static int os_time (lua_State *L) {
|
|||||||
|
|
||||||
|
|
||||||
static int os_difftime (lua_State *L) {
|
static int os_difftime (lua_State *L) {
|
||||||
double res = difftime((l_checktime(L, 1)), (l_checktime(L, 2)));
|
time_t t1 = l_checktime(L, 1);
|
||||||
lua_pushnumber(L, (lua_Number)res);
|
time_t t2 = l_checktime(L, 2);
|
||||||
|
lua_pushnumber(L, (lua_Number)difftime(t1, t2));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ static l_noret error_expected (LexState *ls, int token) {
|
|||||||
static l_noret errorlimit (FuncState *fs, int limit, const char *what) {
|
static l_noret errorlimit (FuncState *fs, int limit, const char *what) {
|
||||||
lua_State *L = fs->ls->L;
|
lua_State *L = fs->ls->L;
|
||||||
const char *msg;
|
const char *msg;
|
||||||
int line = fs->f->sp->linedefined;
|
int line = fs->f->linedefined;
|
||||||
const char *where = (line == 0)
|
const char *where = (line == 0)
|
||||||
? "main function"
|
? "main function"
|
||||||
: luaO_pushfstring(L, "function at line %d", line);
|
: luaO_pushfstring(L, "function at line %d", line);
|
||||||
@@ -160,14 +160,13 @@ static void checkname (LexState *ls, expdesc *e) {
|
|||||||
|
|
||||||
static int registerlocalvar (LexState *ls, TString *varname) {
|
static int registerlocalvar (LexState *ls, TString *varname) {
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
Proto *fp = fs->f;
|
Proto *f = fs->f;
|
||||||
SharedProto *f = fp->sp;
|
|
||||||
int oldsize = f->sizelocvars;
|
int oldsize = f->sizelocvars;
|
||||||
luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
|
luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
|
||||||
LocVar, SHRT_MAX, "local variables");
|
LocVar, SHRT_MAX, "local variables");
|
||||||
while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
|
while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
|
||||||
f->locvars[fs->nlocvars].varname = varname;
|
f->locvars[fs->nlocvars].varname = varname;
|
||||||
luaC_objbarrier(ls->L, fp, varname);
|
luaC_objbarrier(ls->L, f, varname);
|
||||||
return fs->nlocvars++;
|
return fs->nlocvars++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +194,7 @@ static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) {
|
|||||||
static LocVar *getlocvar (FuncState *fs, int i) {
|
static LocVar *getlocvar (FuncState *fs, int i) {
|
||||||
int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx;
|
int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx;
|
||||||
lua_assert(idx < fs->nlocvars);
|
lua_assert(idx < fs->nlocvars);
|
||||||
return &fs->f->sp->locvars[idx];
|
return &fs->f->locvars[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -217,7 +216,7 @@ static void removevars (FuncState *fs, int tolevel) {
|
|||||||
|
|
||||||
static int searchupvalue (FuncState *fs, TString *name) {
|
static int searchupvalue (FuncState *fs, TString *name) {
|
||||||
int i;
|
int i;
|
||||||
Upvaldesc *up = fs->f->sp->upvalues;
|
Upvaldesc *up = fs->f->upvalues;
|
||||||
for (i = 0; i < fs->nups; i++) {
|
for (i = 0; i < fs->nups; i++) {
|
||||||
if (eqstr(up[i].name, name)) return i;
|
if (eqstr(up[i].name, name)) return i;
|
||||||
}
|
}
|
||||||
@@ -226,8 +225,7 @@ static int searchupvalue (FuncState *fs, TString *name) {
|
|||||||
|
|
||||||
|
|
||||||
static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
|
static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
|
||||||
Proto *fp = fs->f;
|
Proto *f = fs->f;
|
||||||
SharedProto *f = fp->sp;
|
|
||||||
int oldsize = f->sizeupvalues;
|
int oldsize = f->sizeupvalues;
|
||||||
checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
|
checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
|
||||||
luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
|
luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
|
||||||
@@ -236,7 +234,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
|
|||||||
f->upvalues[fs->nups].instack = (v->k == VLOCAL);
|
f->upvalues[fs->nups].instack = (v->k == VLOCAL);
|
||||||
f->upvalues[fs->nups].idx = cast_byte(v->u.info);
|
f->upvalues[fs->nups].idx = cast_byte(v->u.info);
|
||||||
f->upvalues[fs->nups].name = name;
|
f->upvalues[fs->nups].name = name;
|
||||||
luaC_objbarrier(fs->ls->L, fp, name);
|
luaC_objbarrier(fs->ls->L, f, name);
|
||||||
return fs->nups++;
|
return fs->nups++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,12 +496,12 @@ static Proto *addprototype (LexState *ls) {
|
|||||||
lua_State *L = ls->L;
|
lua_State *L = ls->L;
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
Proto *f = fs->f; /* prototype of current function */
|
Proto *f = fs->f; /* prototype of current function */
|
||||||
if (fs->np >= f->sp->sizep) {
|
if (fs->np >= f->sizep) {
|
||||||
int oldsize = f->sp->sizep;
|
int oldsize = f->sizep;
|
||||||
luaM_growvector(L, f->p, fs->np, f->sp->sizep, Proto *, MAXARG_Bx, "functions");
|
luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions");
|
||||||
while (oldsize < f->sp->sizep) f->p[oldsize++] = NULL;
|
while (oldsize < f->sizep) f->p[oldsize++] = NULL;
|
||||||
}
|
}
|
||||||
f->p[fs->np++] = clp = luaF_newproto(L, NULL);
|
f->p[fs->np++] = clp = luaF_newproto(L);
|
||||||
luaC_objbarrier(L, f, clp);
|
luaC_objbarrier(L, f, clp);
|
||||||
return clp;
|
return clp;
|
||||||
}
|
}
|
||||||
@@ -523,7 +521,7 @@ static void codeclosure (LexState *ls, expdesc *v) {
|
|||||||
|
|
||||||
|
|
||||||
static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
|
static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
|
||||||
SharedProto *f;
|
Proto *f;
|
||||||
fs->prev = ls->fs; /* linked list of funcstates */
|
fs->prev = ls->fs; /* linked list of funcstates */
|
||||||
fs->ls = ls;
|
fs->ls = ls;
|
||||||
ls->fs = fs;
|
ls->fs = fs;
|
||||||
@@ -538,7 +536,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
|
|||||||
fs->nactvar = 0;
|
fs->nactvar = 0;
|
||||||
fs->firstlocal = ls->dyd->actvar.n;
|
fs->firstlocal = ls->dyd->actvar.n;
|
||||||
fs->bl = NULL;
|
fs->bl = NULL;
|
||||||
f = fs->f->sp;
|
f = fs->f;
|
||||||
f->source = ls->source;
|
f->source = ls->source;
|
||||||
f->maxstacksize = 2; /* registers 0/1 are always valid */
|
f->maxstacksize = 2; /* registers 0/1 are always valid */
|
||||||
enterblock(fs, bl, 0);
|
enterblock(fs, bl, 0);
|
||||||
@@ -549,21 +547,20 @@ static void close_func (LexState *ls) {
|
|||||||
lua_State *L = ls->L;
|
lua_State *L = ls->L;
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
Proto *f = fs->f;
|
Proto *f = fs->f;
|
||||||
SharedProto *sp = f->sp;
|
|
||||||
luaK_ret(fs, 0, 0); /* final return */
|
luaK_ret(fs, 0, 0); /* final return */
|
||||||
leaveblock(fs);
|
leaveblock(fs);
|
||||||
luaM_reallocvector(L, sp->code, sp->sizecode, fs->pc, Instruction);
|
luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
|
||||||
sp->sizecode = fs->pc;
|
f->sizecode = fs->pc;
|
||||||
luaM_reallocvector(L, sp->lineinfo, sp->sizelineinfo, fs->pc, int);
|
luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
|
||||||
sp->sizelineinfo = fs->pc;
|
f->sizelineinfo = fs->pc;
|
||||||
luaM_reallocvector(L, f->k, sp->sizek, fs->nk, TValue);
|
luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
|
||||||
sp->sizek = fs->nk;
|
f->sizek = fs->nk;
|
||||||
luaM_reallocvector(L, f->p, sp->sizep, fs->np, Proto *);
|
luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
|
||||||
sp->sizep = fs->np;
|
f->sizep = fs->np;
|
||||||
luaM_reallocvector(L, sp->locvars, sp->sizelocvars, fs->nlocvars, LocVar);
|
luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
|
||||||
sp->sizelocvars = fs->nlocvars;
|
f->sizelocvars = fs->nlocvars;
|
||||||
luaM_reallocvector(L, sp->upvalues, sp->sizeupvalues, fs->nups, Upvaldesc);
|
luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);
|
||||||
sp->sizeupvalues = fs->nups;
|
f->sizeupvalues = fs->nups;
|
||||||
lua_assert(fs->bl == NULL);
|
lua_assert(fs->bl == NULL);
|
||||||
ls->fs = fs->prev;
|
ls->fs = fs->prev;
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
@@ -739,8 +736,8 @@ static void constructor (LexState *ls, expdesc *t) {
|
|||||||
} while (testnext(ls, ',') || testnext(ls, ';'));
|
} while (testnext(ls, ',') || testnext(ls, ';'));
|
||||||
check_match(ls, '}', '{', line);
|
check_match(ls, '}', '{', line);
|
||||||
lastlistfield(fs, &cc);
|
lastlistfield(fs, &cc);
|
||||||
SETARG_B(fs->f->sp->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
|
SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
|
||||||
SETARG_C(fs->f->sp->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
|
SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* }====================================================================== */
|
/* }====================================================================== */
|
||||||
@@ -750,7 +747,7 @@ static void constructor (LexState *ls, expdesc *t) {
|
|||||||
static void parlist (LexState *ls) {
|
static void parlist (LexState *ls) {
|
||||||
/* parlist -> [ param { ',' param } ] */
|
/* parlist -> [ param { ',' param } ] */
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
SharedProto *f = fs->f->sp;
|
Proto *f = fs->f;
|
||||||
int nparams = 0;
|
int nparams = 0;
|
||||||
f->is_vararg = 0;
|
f->is_vararg = 0;
|
||||||
if (ls->t.token != ')') { /* is 'parlist' not empty? */
|
if (ls->t.token != ')') { /* is 'parlist' not empty? */
|
||||||
@@ -781,7 +778,7 @@ static void body (LexState *ls, expdesc *e, int ismethod, int line) {
|
|||||||
FuncState new_fs;
|
FuncState new_fs;
|
||||||
BlockCnt bl;
|
BlockCnt bl;
|
||||||
new_fs.f = addprototype(ls);
|
new_fs.f = addprototype(ls);
|
||||||
new_fs.f->sp->linedefined = line;
|
new_fs.f->linedefined = line;
|
||||||
open_func(ls, &new_fs, &bl);
|
open_func(ls, &new_fs, &bl);
|
||||||
checknext(ls, '(');
|
checknext(ls, '(');
|
||||||
if (ismethod) {
|
if (ismethod) {
|
||||||
@@ -791,7 +788,7 @@ static void body (LexState *ls, expdesc *e, int ismethod, int line) {
|
|||||||
parlist(ls);
|
parlist(ls);
|
||||||
checknext(ls, ')');
|
checknext(ls, ')');
|
||||||
statlist(ls);
|
statlist(ls);
|
||||||
new_fs.f->sp->lastlinedefined = ls->linenumber;
|
new_fs.f->lastlinedefined = ls->linenumber;
|
||||||
check_match(ls, TK_END, TK_FUNCTION, line);
|
check_match(ls, TK_END, TK_FUNCTION, line);
|
||||||
codeclosure(ls, e);
|
codeclosure(ls, e);
|
||||||
close_func(ls);
|
close_func(ls);
|
||||||
@@ -957,7 +954,7 @@ static void simpleexp (LexState *ls, expdesc *v) {
|
|||||||
}
|
}
|
||||||
case TK_DOTS: { /* vararg */
|
case TK_DOTS: { /* vararg */
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
check_condition(ls, fs->f->sp->is_vararg,
|
check_condition(ls, fs->f->is_vararg,
|
||||||
"cannot use '...' outside a vararg function");
|
"cannot use '...' outside a vararg function");
|
||||||
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
|
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
|
||||||
break;
|
break;
|
||||||
@@ -1613,7 +1610,7 @@ static void mainfunc (LexState *ls, FuncState *fs) {
|
|||||||
BlockCnt bl;
|
BlockCnt bl;
|
||||||
expdesc v;
|
expdesc v;
|
||||||
open_func(ls, fs, &bl);
|
open_func(ls, fs, &bl);
|
||||||
fs->f->sp->is_vararg = 1; /* main function is always vararg */
|
fs->f->is_vararg = 1; /* main function is always vararg */
|
||||||
init_exp(&v, VLOCAL, 0); /* create and... */
|
init_exp(&v, VLOCAL, 0); /* create and... */
|
||||||
newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */
|
newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */
|
||||||
luaX_next(ls); /* read first token */
|
luaX_next(ls); /* read first token */
|
||||||
@@ -1633,13 +1630,13 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
|
|||||||
lexstate.h = luaH_new(L); /* create table for scanner */
|
lexstate.h = luaH_new(L); /* create table for scanner */
|
||||||
sethvalue(L, L->top, lexstate.h); /* anchor it */
|
sethvalue(L, L->top, lexstate.h); /* anchor it */
|
||||||
incr_top(L);
|
incr_top(L);
|
||||||
funcstate.f = cl->p = luaF_newproto(L, NULL);
|
funcstate.f = cl->p = luaF_newproto(L);
|
||||||
funcstate.f->sp->source = luaS_new(L, name); /* create and anchor TString */
|
funcstate.f->source = luaS_new(L, name); /* create and anchor TString */
|
||||||
lua_assert(iswhite(funcstate.f)); /* do not need barrier here */
|
lua_assert(iswhite(funcstate.f)); /* do not need barrier here */
|
||||||
lexstate.buff = buff;
|
lexstate.buff = buff;
|
||||||
lexstate.dyd = dyd;
|
lexstate.dyd = dyd;
|
||||||
dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
|
dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
|
||||||
luaX_setinput(L, &lexstate, z, funcstate.f->sp->source, firstchar);
|
luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar);
|
||||||
mainfunc(&lexstate, &funcstate);
|
mainfunc(&lexstate, &funcstate);
|
||||||
lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
|
lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
|
||||||
/* all scopes should be correctly finished */
|
/* all scopes should be correctly finished */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstate.c,v 2.127 2014/11/02 19:33:33 roberto Exp $
|
** $Id: lstate.c,v 2.128 2015/03/04 13:31:21 roberto Exp $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -37,9 +37,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define MEMERRMSG "not enough memory"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** a macro to help the creation of a unique random seed when a state is
|
** a macro to help the creation of a unique random seed when a state is
|
||||||
** created; the seed is used to randomize hashes.
|
** created; the seed is used to randomize hashes.
|
||||||
@@ -200,12 +197,9 @@ static void f_luaopen (lua_State *L, void *ud) {
|
|||||||
UNUSED(ud);
|
UNUSED(ud);
|
||||||
stack_init(L, L); /* init stack */
|
stack_init(L, L); /* init stack */
|
||||||
init_registry(L, g);
|
init_registry(L, g);
|
||||||
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
|
luaS_init(L);
|
||||||
luaT_init(L);
|
luaT_init(L);
|
||||||
luaX_init(L);
|
luaX_init(L);
|
||||||
/* pre-create memory-error message */
|
|
||||||
g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
|
|
||||||
luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */
|
|
||||||
g->gcrunning = 1; /* allow gc */
|
g->gcrunning = 1; /* allow gc */
|
||||||
g->version = lua_version(NULL);
|
g->version = lua_version(NULL);
|
||||||
luai_userstateopen(L);
|
luai_userstateopen(L);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstate.h,v 2.119 2014/10/30 18:53:28 roberto Exp $
|
** $Id: lstate.h,v 2.122 2015/06/01 16:34:37 roberto Exp $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -141,6 +141,7 @@ typedef struct global_State {
|
|||||||
TString *memerrmsg; /* memory-error message */
|
TString *memerrmsg; /* memory-error message */
|
||||||
TString *tmname[TM_N]; /* array with tag-method names */
|
TString *tmname[TM_N]; /* array with tag-method names */
|
||||||
struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
|
struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
|
||||||
|
TString *strcache[STRCACHE_SIZE][1]; /* cache for strings in API */
|
||||||
} global_State;
|
} global_State;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstring.c,v 2.45 2014/11/02 19:19:04 roberto Exp $
|
** $Id: lstring.c,v 2.49 2015/06/01 16:34:37 roberto Exp $
|
||||||
** String table (keeps all strings handled by Lua)
|
** String table (keeps all strings handled by Lua)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -22,6 +22,8 @@
|
|||||||
#include "lstring.h"
|
#include "lstring.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define MEMERRMSG "not enough memory"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to
|
** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to
|
||||||
@@ -36,10 +38,10 @@
|
|||||||
** equality for long strings
|
** equality for long strings
|
||||||
*/
|
*/
|
||||||
int luaS_eqlngstr (TString *a, TString *b) {
|
int luaS_eqlngstr (TString *a, TString *b) {
|
||||||
size_t len = a->len;
|
size_t len = a->u.lnglen;
|
||||||
lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR);
|
lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR);
|
||||||
return (a == b) || /* same instance or... */
|
return (a == b) || /* same instance or... */
|
||||||
((len == b->len) && /* equal length and ... */
|
((len == b->u.lnglen) && /* equal length and ... */
|
||||||
(memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */
|
(memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,9 +71,9 @@ void luaS_resize (lua_State *L, int newsize) {
|
|||||||
TString *p = tb->hash[i];
|
TString *p = tb->hash[i];
|
||||||
tb->hash[i] = NULL;
|
tb->hash[i] = NULL;
|
||||||
while (p) { /* for each node in the list */
|
while (p) { /* for each node in the list */
|
||||||
TString *hnext = p->hnext; /* save next */
|
TString *hnext = p->u.hnext; /* save next */
|
||||||
unsigned int h = lmod(p->hash, newsize); /* new position */
|
unsigned int h = lmod(p->hash, newsize); /* new position */
|
||||||
p->hnext = tb->hash[h]; /* chain it */
|
p->u.hnext = tb->hash[h]; /* chain it */
|
||||||
tb->hash[h] = p;
|
tb->hash[h] = p;
|
||||||
p = hnext;
|
p = hnext;
|
||||||
}
|
}
|
||||||
@@ -85,6 +87,34 @@ void luaS_resize (lua_State *L, int newsize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Clear API string cache. (Entries cannot be empty, so fill them with
|
||||||
|
** a non-collectable string.)
|
||||||
|
*/
|
||||||
|
void luaS_clearcache (global_State *g) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < STRCACHE_SIZE; i++) {
|
||||||
|
if (iswhite(g->strcache[i][0])) /* will entry be collected? */
|
||||||
|
g->strcache[i][0] = g->memerrmsg; /* replace it with something fixed */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Initialize the string table and the string cache
|
||||||
|
*/
|
||||||
|
void luaS_init (lua_State *L) {
|
||||||
|
global_State *g = G(L);
|
||||||
|
int i;
|
||||||
|
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
|
||||||
|
/* pre-create memory-error message */
|
||||||
|
g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
|
||||||
|
luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */
|
||||||
|
for (i = 0; i < STRCACHE_SIZE; i++) /* fill cache with valid strings */
|
||||||
|
g->strcache[i][0] = g->memerrmsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** creates a new string object
|
** creates a new string object
|
||||||
@@ -97,7 +127,6 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l,
|
|||||||
totalsize = sizelstring(l);
|
totalsize = sizelstring(l);
|
||||||
o = luaC_newobj(L, tag, totalsize);
|
o = luaC_newobj(L, tag, totalsize);
|
||||||
ts = gco2ts(o);
|
ts = gco2ts(o);
|
||||||
ts->len = l;
|
|
||||||
ts->hash = h;
|
ts->hash = h;
|
||||||
ts->extra = 0;
|
ts->extra = 0;
|
||||||
memcpy(getaddrstr(ts), str, l * sizeof(char));
|
memcpy(getaddrstr(ts), str, l * sizeof(char));
|
||||||
@@ -110,8 +139,8 @@ void luaS_remove (lua_State *L, TString *ts) {
|
|||||||
stringtable *tb = &G(L)->strt;
|
stringtable *tb = &G(L)->strt;
|
||||||
TString **p = &tb->hash[lmod(ts->hash, tb->size)];
|
TString **p = &tb->hash[lmod(ts->hash, tb->size)];
|
||||||
while (*p != ts) /* find previous element */
|
while (*p != ts) /* find previous element */
|
||||||
p = &(*p)->hnext;
|
p = &(*p)->u.hnext;
|
||||||
*p = (*p)->hnext; /* remove element from its list */
|
*p = (*p)->u.hnext; /* remove element from its list */
|
||||||
tb->nuse--;
|
tb->nuse--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,8 +153,8 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
|
|||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
unsigned int h = luaS_hash(str, l, g->seed);
|
unsigned int h = luaS_hash(str, l, g->seed);
|
||||||
TString **list = &g->strt.hash[lmod(h, g->strt.size)];
|
TString **list = &g->strt.hash[lmod(h, g->strt.size)];
|
||||||
for (ts = *list; ts != NULL; ts = ts->hnext) {
|
for (ts = *list; ts != NULL; ts = ts->u.hnext) {
|
||||||
if (l == ts->len &&
|
if (l == ts->shrlen &&
|
||||||
(memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
|
(memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
|
||||||
/* found! */
|
/* found! */
|
||||||
if (isdead(g, ts)) /* dead (but not collected yet)? */
|
if (isdead(g, ts)) /* dead (but not collected yet)? */
|
||||||
@@ -138,7 +167,8 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
|
|||||||
list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
|
list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
|
||||||
}
|
}
|
||||||
ts = createstrobj(L, str, l, LUA_TSHRSTR, h);
|
ts = createstrobj(L, str, l, LUA_TSHRSTR, h);
|
||||||
ts->hnext = *list;
|
ts->shrlen = cast_byte(l);
|
||||||
|
ts->u.hnext = *list;
|
||||||
*list = ts;
|
*list = ts;
|
||||||
g->strt.nuse++;
|
g->strt.nuse++;
|
||||||
return ts;
|
return ts;
|
||||||
@@ -152,18 +182,32 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
|
|||||||
if (l <= LUAI_MAXSHORTLEN) /* short string? */
|
if (l <= LUAI_MAXSHORTLEN) /* short string? */
|
||||||
return internshrstr(L, str, l);
|
return internshrstr(L, str, l);
|
||||||
else {
|
else {
|
||||||
|
TString *ts;
|
||||||
if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char))
|
if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char))
|
||||||
luaM_toobig(L);
|
luaM_toobig(L);
|
||||||
return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed);
|
ts = createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed);
|
||||||
|
ts->u.lnglen = l;
|
||||||
|
return ts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** new zero-terminated string
|
** Create or reuse a zero-terminated string, first checking in the
|
||||||
|
** cache (using the string address as a key). The cache can contain
|
||||||
|
** only zero-terminated strings, so it is safe to use 'strcmp' to
|
||||||
|
** check hits.
|
||||||
*/
|
*/
|
||||||
TString *luaS_new (lua_State *L, const char *str) {
|
TString *luaS_new (lua_State *L, const char *str) {
|
||||||
return luaS_newlstr(L, str, strlen(str));
|
unsigned int i = point2uint(str) % STRCACHE_SIZE; /* hash */
|
||||||
|
TString **p = G(L)->strcache[i];
|
||||||
|
if (strcmp(str, getstr(p[0])) == 0) /* hit? */
|
||||||
|
return p[0]; /* that it is */
|
||||||
|
else { /* normal route */
|
||||||
|
TString *s = luaS_newlstr(L, str, strlen(str));
|
||||||
|
p[0] = s;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstring.h,v 1.56 2014/07/18 14:46:47 roberto Exp $
|
** $Id: lstring.h,v 1.59 2015/03/25 13:42:19 roberto Exp $
|
||||||
** String table (keep all strings handled by Lua)
|
** String table (keep all strings handled by Lua)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
|
|
||||||
#define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char))
|
#define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char))
|
||||||
#define sizestring(s) sizelstring((s)->len)
|
|
||||||
|
|
||||||
#define sizeludata(l) (sizeof(union UUdata) + (l))
|
#define sizeludata(l) (sizeof(union UUdata) + (l))
|
||||||
#define sizeudata(u) sizeludata((u)->len)
|
#define sizeudata(u) sizeludata((u)->len)
|
||||||
@@ -37,6 +36,8 @@
|
|||||||
LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
|
LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
|
||||||
LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);
|
LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);
|
||||||
LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
|
LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
|
||||||
|
LUAI_FUNC void luaS_clearcache (global_State *g);
|
||||||
|
LUAI_FUNC void luaS_init (lua_State *L);
|
||||||
LUAI_FUNC void luaS_remove (lua_State *L, TString *ts);
|
LUAI_FUNC void luaS_remove (lua_State *L, TString *ts);
|
||||||
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s);
|
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s);
|
||||||
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
|
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstrlib.c,v 1.221 2014/12/11 14:03:07 roberto Exp $
|
** $Id: lstrlib.c,v 1.229 2015/05/20 17:39:23 roberto Exp $
|
||||||
** Standard library for string operations and pattern-matching
|
** Standard library for string operations and pattern-matching
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <float.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -70,7 +71,7 @@ static int str_sub (lua_State *L) {
|
|||||||
if (start < 1) start = 1;
|
if (start < 1) start = 1;
|
||||||
if (end > (lua_Integer)l) end = l;
|
if (end > (lua_Integer)l) end = l;
|
||||||
if (start <= end)
|
if (start <= end)
|
||||||
lua_pushlstring(L, s + start - 1, (size_t)(end - start + 1));
|
lua_pushlstring(L, s + start - 1, (size_t)(end - start) + 1);
|
||||||
else lua_pushliteral(L, "");
|
else lua_pushliteral(L, "");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -149,9 +150,9 @@ static int str_byte (lua_State *L) {
|
|||||||
if (posi < 1) posi = 1;
|
if (posi < 1) posi = 1;
|
||||||
if (pose > (lua_Integer)l) pose = l;
|
if (pose > (lua_Integer)l) pose = l;
|
||||||
if (posi > pose) return 0; /* empty interval; return no values */
|
if (posi > pose) return 0; /* empty interval; return no values */
|
||||||
n = (int)(pose - posi + 1);
|
if (pose - posi >= INT_MAX) /* arithmetic overflow? */
|
||||||
if (posi + n <= pose) /* arithmetic overflow? */
|
|
||||||
return luaL_error(L, "string slice too long");
|
return luaL_error(L, "string slice too long");
|
||||||
|
n = (int)(pose - posi) + 1;
|
||||||
luaL_checkstack(L, n, "string slice too long");
|
luaL_checkstack(L, n, "string slice too long");
|
||||||
for (i=0; i<n; i++)
|
for (i=0; i<n; i++)
|
||||||
lua_pushinteger(L, uchar(s[posi+i-1]));
|
lua_pushinteger(L, uchar(s[posi+i-1]));
|
||||||
@@ -499,7 +500,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) {
|
|||||||
}
|
}
|
||||||
case '+': /* 1 or more repetitions */
|
case '+': /* 1 or more repetitions */
|
||||||
s++; /* 1 match already done */
|
s++; /* 1 match already done */
|
||||||
/* go through */
|
/* FALLTHROUGH */
|
||||||
case '*': /* 0 or more repetitions */
|
case '*': /* 0 or more repetitions */
|
||||||
s = max_expand(ms, s, p, ep);
|
s = max_expand(ms, s, p, ep);
|
||||||
break;
|
break;
|
||||||
@@ -554,7 +555,7 @@ static void push_onecapture (MatchState *ms, int i, const char *s,
|
|||||||
ptrdiff_t l = ms->capture[i].len;
|
ptrdiff_t l = ms->capture[i].len;
|
||||||
if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
|
if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
|
||||||
if (l == CAP_POSITION)
|
if (l == CAP_POSITION)
|
||||||
lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
|
lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1);
|
||||||
else
|
else
|
||||||
lua_pushlstring(ms->L, ms->capture[i].init, l);
|
lua_pushlstring(ms->L, ms->capture[i].init, l);
|
||||||
}
|
}
|
||||||
@@ -598,8 +599,8 @@ static int str_find_aux (lua_State *L, int find) {
|
|||||||
/* do a plain search */
|
/* do a plain search */
|
||||||
const char *s2 = lmemfind(s + init - 1, ls - (size_t)init + 1, p, lp);
|
const char *s2 = lmemfind(s + init - 1, ls - (size_t)init + 1, p, lp);
|
||||||
if (s2) {
|
if (s2) {
|
||||||
lua_pushinteger(L, s2 - s + 1);
|
lua_pushinteger(L, (s2 - s) + 1);
|
||||||
lua_pushinteger(L, s2 - s + lp);
|
lua_pushinteger(L, (s2 - s) + lp);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -621,7 +622,7 @@ static int str_find_aux (lua_State *L, int find) {
|
|||||||
lua_assert(ms.matchdepth == MAXCCALLS);
|
lua_assert(ms.matchdepth == MAXCCALLS);
|
||||||
if ((res=match(&ms, s1, p)) != NULL) {
|
if ((res=match(&ms, s1, p)) != NULL) {
|
||||||
if (find) {
|
if (find) {
|
||||||
lua_pushinteger(L, s1 - s + 1); /* start */
|
lua_pushinteger(L, (s1 - s) + 1); /* start */
|
||||||
lua_pushinteger(L, res - s); /* end */
|
lua_pushinteger(L, res - s); /* end */
|
||||||
return push_captures(&ms, NULL, 0) + 2;
|
return push_captures(&ms, NULL, 0) + 2;
|
||||||
}
|
}
|
||||||
@@ -797,18 +798,100 @@ static int str_gsub (lua_State *L) {
|
|||||||
** =======================================================
|
** =======================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
|
#if !defined(lua_number2strx) /* { */
|
||||||
#define MAX_ITEM \
|
|
||||||
(sizeof(lua_Number) <= 4 ? 150 : sizeof(lua_Number) <= 8 ? 450 : 5050)
|
/*
|
||||||
|
** Hexadecimal floating-point formatter
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char))
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Number of bits that goes into the first digit. It can be any value
|
||||||
|
** between 1 and 4; the following definition tries to align the number
|
||||||
|
** to nibble boundaries by making what is left after that first digit a
|
||||||
|
** multiple of 4.
|
||||||
|
*/
|
||||||
|
#define L_NBFD ((l_mathlim(MANT_DIG) - 1)%4 + 1)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Add integer part of 'x' to buffer and return new 'x'
|
||||||
|
*/
|
||||||
|
static lua_Number adddigit (char *buff, int n, lua_Number x) {
|
||||||
|
lua_Number dd = l_mathop(floor)(x); /* get integer part from 'x' */
|
||||||
|
int d = (int)dd;
|
||||||
|
buff[n] = (d < 10 ? d + '0' : d - 10 + 'a'); /* add to buffer */
|
||||||
|
return x - dd; /* return what is left */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int num2straux (char *buff, lua_Number x) {
|
||||||
|
if (x != x || x == HUGE_VAL || x == -HUGE_VAL) /* inf or NaN? */
|
||||||
|
return sprintf(buff, LUA_NUMBER_FMT, x); /* equal to '%g' */
|
||||||
|
else if (x == 0) { /* can be -0... */
|
||||||
|
sprintf(buff, LUA_NUMBER_FMT, x);
|
||||||
|
strcat(buff, "x0p+0"); /* reuses '0/-0' from 'sprintf'... */
|
||||||
|
return strlen(buff);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int e;
|
||||||
|
lua_Number m = l_mathop(frexp)(x, &e); /* 'x' fraction and exponent */
|
||||||
|
int n = 0; /* character count */
|
||||||
|
if (m < 0) { /* is number negative? */
|
||||||
|
buff[n++] = '-'; /* add signal */
|
||||||
|
m = -m; /* make it positive */
|
||||||
|
}
|
||||||
|
buff[n++] = '0'; buff[n++] = 'x'; /* add "0x" */
|
||||||
|
m = adddigit(buff, n++, m * (1 << L_NBFD)); /* add first digit */
|
||||||
|
e -= L_NBFD; /* this digit goes before the radix point */
|
||||||
|
if (m > 0) { /* more digits? */
|
||||||
|
buff[n++] = lua_getlocaledecpoint(); /* add radix point */
|
||||||
|
do { /* add as many digits as needed */
|
||||||
|
m = adddigit(buff, n++, m * 16);
|
||||||
|
} while (m > 0);
|
||||||
|
}
|
||||||
|
n += sprintf(buff + n, "p%+d", e); /* add exponent */
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int lua_number2strx (lua_State *L, char *buff, const char *fmt,
|
||||||
|
lua_Number x) {
|
||||||
|
int n = num2straux(buff, x);
|
||||||
|
if (fmt[SIZELENMOD] == 'A') {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
buff[i] = toupper(uchar(buff[i]));
|
||||||
|
}
|
||||||
|
else if (fmt[SIZELENMOD] != 'a')
|
||||||
|
luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented");
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* } */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Maximum size of each formatted item. This maximum size is produced
|
||||||
|
** by format('%.99f', minfloat), and is equal to 99 + 2 ('-' and '.') +
|
||||||
|
** number of decimal digits to represent minfloat.
|
||||||
|
*/
|
||||||
|
#define MAX_ITEM (120 + l_mathlim(MAX_10_EXP))
|
||||||
|
|
||||||
|
|
||||||
/* valid flags in a format specification */
|
/* valid flags in a format specification */
|
||||||
#define FLAGS "-+ #0"
|
#define FLAGS "-+ #0"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** maximum size of each format specification (such as "%-099.99d")
|
** maximum size of each format specification (such as "%-099.99d")
|
||||||
** (+2 for length modifiers; +10 accounts for %99.99x plus margin of error)
|
|
||||||
*/
|
*/
|
||||||
#define MAX_FORMAT (sizeof(FLAGS) + 2 + 10)
|
#define MAX_FORMAT 32
|
||||||
|
|
||||||
|
|
||||||
static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
|
static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
|
||||||
@@ -850,8 +933,8 @@ static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
|
|||||||
if (isdigit(uchar(*p)))
|
if (isdigit(uchar(*p)))
|
||||||
luaL_error(L, "invalid format (width or precision too long)");
|
luaL_error(L, "invalid format (width or precision too long)");
|
||||||
*(form++) = '%';
|
*(form++) = '%';
|
||||||
memcpy(form, strfrmt, (p - strfrmt + 1) * sizeof(char));
|
memcpy(form, strfrmt, ((p - strfrmt) + 1) * sizeof(char));
|
||||||
form += p - strfrmt + 1;
|
form += (p - strfrmt) + 1;
|
||||||
*form = '\0';
|
*form = '\0';
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@@ -902,9 +985,10 @@ static int str_format (lua_State *L) {
|
|||||||
nb = sprintf(buff, form, n);
|
nb = sprintf(buff, form, n);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if defined(LUA_USE_AFORMAT)
|
|
||||||
case 'a': case 'A':
|
case 'a': case 'A':
|
||||||
#endif
|
addlenmod(form, LUA_NUMBER_FRMLEN);
|
||||||
|
nb = lua_number2strx(L, buff, form, luaL_checknumber(L, arg));
|
||||||
|
break;
|
||||||
case 'e': case 'E': case 'f':
|
case 'e': case 'E': case 'f':
|
||||||
case 'g': case 'G': {
|
case 'g': case 'G': {
|
||||||
addlenmod(form, LUA_NUMBER_FRMLEN);
|
addlenmod(form, LUA_NUMBER_FRMLEN);
|
||||||
@@ -922,13 +1006,12 @@ static int str_format (lua_State *L) {
|
|||||||
/* no precision and string is too long to be formatted;
|
/* no precision and string is too long to be formatted;
|
||||||
keep original string */
|
keep original string */
|
||||||
luaL_addvalue(&b);
|
luaL_addvalue(&b);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
nb = sprintf(buff, form, s);
|
nb = sprintf(buff, form, s);
|
||||||
lua_pop(L, 1); /* remove result from 'luaL_tolstring' */
|
lua_pop(L, 1); /* remove result from 'luaL_tolstring' */
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
default: { /* also treat cases 'pnLlh' */
|
default: { /* also treat cases 'pnLlh' */
|
||||||
return luaL_error(L, "invalid option '%%%c' to 'format'",
|
return luaL_error(L, "invalid option '%%%c' to 'format'",
|
||||||
@@ -1250,7 +1333,7 @@ static int str_pack (lua_State *L) {
|
|||||||
totalsize += len + 1;
|
totalsize += len + 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Kpadding: luaL_addchar(&b, LUA_PACKPADBYTE); /* go through */
|
case Kpadding: luaL_addchar(&b, LUA_PACKPADBYTE); /* FALLTHROUGH */
|
||||||
case Kpaddalign: case Knop:
|
case Kpaddalign: case Knop:
|
||||||
arg--; /* undo increment */
|
arg--; /* undo increment */
|
||||||
break;
|
break;
|
||||||
|
|||||||
123
3rd/lua/ltable.c
123
3rd/lua/ltable.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltable.c,v 2.100 2015/01/05 13:52:37 roberto Exp $
|
** $Id: ltable.c,v 2.111 2015/06/09 14:21:13 roberto Exp $
|
||||||
** Lua tables (hash)
|
** Lua tables (hash)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -14,8 +14,8 @@
|
|||||||
** Implementation of tables (aka arrays, objects, or hash tables).
|
** Implementation of tables (aka arrays, objects, or hash tables).
|
||||||
** Tables keep its elements in two parts: an array part and a hash part.
|
** Tables keep its elements in two parts: an array part and a hash part.
|
||||||
** Non-negative integer keys are all candidates to be kept in the array
|
** Non-negative integer keys are all candidates to be kept in the array
|
||||||
** part. The actual size of the array is the largest 'n' such that at
|
** part. The actual size of the array is the largest 'n' such that
|
||||||
** least half the slots between 0 and n are in use.
|
** more than half the slots between 1 and n are in use.
|
||||||
** Hash uses a mix of chained scatter table with Brent's variation.
|
** Hash uses a mix of chained scatter table with Brent's variation.
|
||||||
** A main invariant of these tables is that, if an element is not
|
** A main invariant of these tables is that, if an element is not
|
||||||
** in its main position (i.e. the 'original' position that its hash gives
|
** in its main position (i.e. the 'original' position that its hash gives
|
||||||
@@ -23,9 +23,7 @@
|
|||||||
** Hence even when the load factor reaches 100%, performance remains good.
|
** Hence even when the load factor reaches 100%, performance remains good.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <float.h>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
@@ -71,7 +69,7 @@
|
|||||||
#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
|
#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
|
||||||
|
|
||||||
|
|
||||||
#define hashpointer(t,p) hashmod(t, point2int(p))
|
#define hashpointer(t,p) hashmod(t, point2uint(p))
|
||||||
|
|
||||||
|
|
||||||
#define dummynode (&dummynode_)
|
#define dummynode (&dummynode_)
|
||||||
@@ -85,31 +83,33 @@ static const Node dummynode_ = {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Checks whether a float has a value representable as a lua_Integer
|
** Hash for floating-point numbers.
|
||||||
** (and does the conversion if so)
|
** The main computation should be just
|
||||||
|
** n = frepx(n, &i); return (n * INT_MAX) + i
|
||||||
|
** but there are some numerical subtleties.
|
||||||
|
** In a two-complement representation, INT_MAX does not has an exact
|
||||||
|
** representation as a float, but INT_MIN does; because the absolute
|
||||||
|
** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the
|
||||||
|
** absolute value of the product 'frexp * -INT_MIN' is smaller or equal
|
||||||
|
** to INT_MAX. Next, the use of 'unsigned int' avoids overflows when
|
||||||
|
** adding 'i'; the use of '~u' (instead of '-u') avoids problems with
|
||||||
|
** INT_MIN.
|
||||||
*/
|
*/
|
||||||
static int numisinteger (lua_Number x, lua_Integer *p) {
|
#if !defined(l_hashfloat)
|
||||||
if ((x) == l_floor(x)) /* integral value? */
|
static int l_hashfloat (lua_Number n) {
|
||||||
return lua_numbertointeger(x, p); /* try as an integer */
|
|
||||||
else return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** hash for floating-point numbers
|
|
||||||
*/
|
|
||||||
static Node *hashfloat (const Table *t, lua_Number n) {
|
|
||||||
int i;
|
int i;
|
||||||
n = l_mathop(frexp)(n, &i) * cast_num(INT_MAX - DBL_MAX_EXP);
|
lua_Integer ni;
|
||||||
i += cast_int(n);
|
n = l_mathop(frexp)(n, &i) * -cast_num(INT_MIN);
|
||||||
if (i < 0) {
|
if (!lua_numbertointeger(n, &ni)) { /* is 'n' inf/-inf/NaN? */
|
||||||
if (cast(unsigned int, i) == 0u - i) /* use unsigned to avoid overflows */
|
lua_assert(luai_numisnan(n) || l_mathop(fabs)(n) == HUGE_VAL);
|
||||||
i = 0; /* handle INT_MIN */
|
return 0;
|
||||||
i = -i; /* must be a positive value */
|
}
|
||||||
|
else { /* normal case */
|
||||||
|
unsigned int u = cast(unsigned int, i) + cast(unsigned int, ni);
|
||||||
|
return cast_int(u <= cast(unsigned int, INT_MAX) ? u : ~u);
|
||||||
}
|
}
|
||||||
return hashmod(t, i);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -121,13 +121,13 @@ static Node *mainposition (const Table *t, const TValue *key) {
|
|||||||
case LUA_TNUMINT:
|
case LUA_TNUMINT:
|
||||||
return hashint(t, ivalue(key));
|
return hashint(t, ivalue(key));
|
||||||
case LUA_TNUMFLT:
|
case LUA_TNUMFLT:
|
||||||
return hashfloat(t, fltvalue(key));
|
return hashmod(t, l_hashfloat(fltvalue(key)));
|
||||||
case LUA_TSHRSTR:
|
case LUA_TSHRSTR:
|
||||||
return hashstr(t, tsvalue(key));
|
return hashstr(t, tsvalue(key));
|
||||||
case LUA_TLNGSTR: {
|
case LUA_TLNGSTR: {
|
||||||
TString *s = tsvalue(key);
|
TString *s = tsvalue(key);
|
||||||
if (s->extra == 0) { /* no hash? */
|
if (s->extra == 0) { /* no hash? */
|
||||||
s->hash = luaS_hash(getstr(s), s->len, s->hash);
|
s->hash = luaS_hash(getstr(s), s->u.lnglen, s->hash);
|
||||||
s->extra = 1; /* now it has its hash */
|
s->extra = 1; /* now it has its hash */
|
||||||
}
|
}
|
||||||
return hashstr(t, tsvalue(key));
|
return hashstr(t, tsvalue(key));
|
||||||
@@ -219,28 +219,29 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
|
|||||||
/*
|
/*
|
||||||
** Compute the optimal size for the array part of table 't'. 'nums' is a
|
** Compute the optimal size for the array part of table 't'. 'nums' is a
|
||||||
** "count array" where 'nums[i]' is the number of integers in the table
|
** "count array" where 'nums[i]' is the number of integers in the table
|
||||||
** between 2^(i - 1) + 1 and 2^i. Put in '*narray' the optimal size, and
|
** between 2^(i - 1) + 1 and 2^i. 'pna' enters with the total number of
|
||||||
** return the number of elements that will go to that part.
|
** integer keys in the table and leaves with the number of keys that
|
||||||
|
** will go to the array part; return the optimal size.
|
||||||
*/
|
*/
|
||||||
static unsigned int computesizes (unsigned int nums[], unsigned int *narray) {
|
static unsigned int computesizes (unsigned int nums[], unsigned int *pna) {
|
||||||
int i;
|
int i;
|
||||||
unsigned int twotoi; /* 2^i */
|
unsigned int twotoi; /* 2^i (candidate for optimal size) */
|
||||||
unsigned int a = 0; /* number of elements smaller than 2^i */
|
unsigned int a = 0; /* number of elements smaller than 2^i */
|
||||||
unsigned int na = 0; /* number of elements to go to array part */
|
unsigned int na = 0; /* number of elements to go to array part */
|
||||||
unsigned int n = 0; /* optimal size for array part */
|
unsigned int optimal = 0; /* optimal size for array part */
|
||||||
for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
|
/* loop while keys can fill more than half of total size */
|
||||||
|
for (i = 0, twotoi = 1; *pna > twotoi / 2; i++, twotoi *= 2) {
|
||||||
if (nums[i] > 0) {
|
if (nums[i] > 0) {
|
||||||
a += nums[i];
|
a += nums[i];
|
||||||
if (a > twotoi/2) { /* more than half elements present? */
|
if (a > twotoi/2) { /* more than half elements present? */
|
||||||
n = twotoi; /* optimal size (till now) */
|
optimal = twotoi; /* optimal size (till now) */
|
||||||
na = a; /* all elements up to 'n' will go to array part */
|
na = a; /* all elements up to 'optimal' will go to array part */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (a == *narray) break; /* all elements already counted */
|
|
||||||
}
|
}
|
||||||
*narray = n;
|
lua_assert((optimal == 0 || optimal / 2 < na) && na <= optimal);
|
||||||
lua_assert(*narray/2 <= na && na <= *narray);
|
*pna = na;
|
||||||
return na;
|
return optimal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -255,6 +256,11 @@ static int countint (const TValue *key, unsigned int *nums) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Count keys in array part of table 't': Fill 'nums[i]' with
|
||||||
|
** number of keys that will go into corresponding slice and return
|
||||||
|
** total number of non-nil keys.
|
||||||
|
*/
|
||||||
static unsigned int numusearray (const Table *t, unsigned int *nums) {
|
static unsigned int numusearray (const Table *t, unsigned int *nums) {
|
||||||
int lg;
|
int lg;
|
||||||
unsigned int ttlg; /* 2^lg */
|
unsigned int ttlg; /* 2^lg */
|
||||||
@@ -281,8 +287,7 @@ static unsigned int numusearray (const Table *t, unsigned int *nums) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int numusehash (const Table *t, unsigned int *nums,
|
static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) {
|
||||||
unsigned int *pnasize) {
|
|
||||||
int totaluse = 0; /* total number of elements */
|
int totaluse = 0; /* total number of elements */
|
||||||
int ause = 0; /* elements added to 'nums' (can go to array part) */
|
int ause = 0; /* elements added to 'nums' (can go to array part) */
|
||||||
int i = sizenode(t);
|
int i = sizenode(t);
|
||||||
@@ -293,7 +298,7 @@ static int numusehash (const Table *t, unsigned int *nums,
|
|||||||
totaluse++;
|
totaluse++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*pnasize += ause;
|
*pna += ause;
|
||||||
return totaluse;
|
return totaluse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,7 +368,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isdummy(nold))
|
if (!isdummy(nold))
|
||||||
luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old array */
|
luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old hash */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -376,21 +381,22 @@ void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) {
|
|||||||
** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i
|
** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i
|
||||||
*/
|
*/
|
||||||
static void rehash (lua_State *L, Table *t, const TValue *ek) {
|
static void rehash (lua_State *L, Table *t, const TValue *ek) {
|
||||||
unsigned int nasize, na;
|
unsigned int asize; /* optimal size for array part */
|
||||||
|
unsigned int na; /* number of keys in the array part */
|
||||||
unsigned int nums[MAXABITS + 1];
|
unsigned int nums[MAXABITS + 1];
|
||||||
int i;
|
int i;
|
||||||
int totaluse;
|
int totaluse;
|
||||||
for (i = 0; i <= MAXABITS; i++) nums[i] = 0; /* reset counts */
|
for (i = 0; i <= MAXABITS; i++) nums[i] = 0; /* reset counts */
|
||||||
nasize = numusearray(t, nums); /* count keys in array part */
|
na = numusearray(t, nums); /* count keys in array part */
|
||||||
totaluse = nasize; /* all those keys are integer keys */
|
totaluse = na; /* all those keys are integer keys */
|
||||||
totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */
|
totaluse += numusehash(t, nums, &na); /* count keys in hash part */
|
||||||
/* count extra key */
|
/* count extra key */
|
||||||
nasize += countint(ek, nums);
|
na += countint(ek, nums);
|
||||||
totaluse++;
|
totaluse++;
|
||||||
/* compute new size for array part */
|
/* compute new size for array part */
|
||||||
na = computesizes(nums, &nasize);
|
asize = computesizes(nums, &na);
|
||||||
/* resize the table to new computed sizes */
|
/* resize the table to new computed sizes */
|
||||||
luaH_resize(L, t, nasize, totaluse - na);
|
luaH_resize(L, t, asize, totaluse - na);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -443,14 +449,13 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
|
|||||||
TValue aux;
|
TValue aux;
|
||||||
if (ttisnil(key)) luaG_runerror(L, "table index is nil");
|
if (ttisnil(key)) luaG_runerror(L, "table index is nil");
|
||||||
else if (ttisfloat(key)) {
|
else if (ttisfloat(key)) {
|
||||||
lua_Number n = fltvalue(key);
|
|
||||||
lua_Integer k;
|
lua_Integer k;
|
||||||
if (luai_numisnan(n))
|
if (luaV_tointeger(key, &k, 0)) { /* index is int? */
|
||||||
luaG_runerror(L, "table index is NaN");
|
|
||||||
if (numisinteger(n, &k)) { /* index is int? */
|
|
||||||
setivalue(&aux, k);
|
setivalue(&aux, k);
|
||||||
key = &aux; /* insert it as an integer */
|
key = &aux; /* insert it as an integer */
|
||||||
}
|
}
|
||||||
|
else if (luai_numisnan(fltvalue(key)))
|
||||||
|
luaG_runerror(L, "table index is NaN");
|
||||||
}
|
}
|
||||||
mp = mainposition(t, key);
|
mp = mainposition(t, key);
|
||||||
if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */
|
if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */
|
||||||
@@ -544,10 +549,10 @@ const TValue *luaH_get (Table *t, const TValue *key) {
|
|||||||
case LUA_TNIL: return luaO_nilobject;
|
case LUA_TNIL: return luaO_nilobject;
|
||||||
case LUA_TNUMFLT: {
|
case LUA_TNUMFLT: {
|
||||||
lua_Integer k;
|
lua_Integer k;
|
||||||
if (numisinteger(fltvalue(key), &k)) /* index is int? */
|
if (luaV_tointeger(key, &k, 0)) /* index is int? */
|
||||||
return luaH_getint(t, k); /* use specialized version */
|
return luaH_getint(t, k); /* use specialized version */
|
||||||
/* else go through */
|
/* else... */
|
||||||
}
|
} /* FALLTHROUGH */
|
||||||
default: {
|
default: {
|
||||||
Node *n = mainposition(t, key);
|
Node *n = mainposition(t, key);
|
||||||
for (;;) { /* check whether 'key' is somewhere in the chain */
|
for (;;) { /* check whether 'key' is somewhere in the chain */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltablib.c,v 1.79 2014/11/02 19:19:04 roberto Exp $
|
** $Id: ltablib.c,v 1.80 2015/01/13 16:27:29 roberto Exp $
|
||||||
** Library for Table Manipulation
|
** Library for Table Manipulation
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -124,8 +124,6 @@ static int tmove (lua_State *L) {
|
|||||||
lua_Integer e = luaL_checkinteger(L, 3);
|
lua_Integer e = luaL_checkinteger(L, 3);
|
||||||
lua_Integer t = luaL_checkinteger(L, 4);
|
lua_Integer t = luaL_checkinteger(L, 4);
|
||||||
int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */
|
int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */
|
||||||
/* the following restriction avoids several problems with overflows */
|
|
||||||
luaL_argcheck(L, f > 0, 2, "initial position must be positive");
|
|
||||||
if (e >= f) { /* otherwise, nothing to move */
|
if (e >= f) { /* otherwise, nothing to move */
|
||||||
lua_Integer n, i;
|
lua_Integer n, i;
|
||||||
ta.geti = (luaL_getmetafield(L, 1, "__index") == LUA_TNIL)
|
ta.geti = (luaL_getmetafield(L, 1, "__index") == LUA_TNIL)
|
||||||
@@ -134,7 +132,11 @@ static int tmove (lua_State *L) {
|
|||||||
ta.seti = (luaL_getmetafield(L, tt, "__newindex") == LUA_TNIL)
|
ta.seti = (luaL_getmetafield(L, tt, "__newindex") == LUA_TNIL)
|
||||||
? (luaL_checktype(L, tt, LUA_TTABLE), lua_rawseti)
|
? (luaL_checktype(L, tt, LUA_TTABLE), lua_rawseti)
|
||||||
: lua_seti;
|
: lua_seti;
|
||||||
|
luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3,
|
||||||
|
"too many elements to move");
|
||||||
n = e - f + 1; /* number of elements to move */
|
n = e - f + 1; /* number of elements to move */
|
||||||
|
luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4,
|
||||||
|
"destination wrap around");
|
||||||
if (t > f) {
|
if (t > f) {
|
||||||
for (i = n - 1; i >= 0; i--) {
|
for (i = n - 1; i >= 0; i--) {
|
||||||
(*ta.geti)(L, 1, f + i);
|
(*ta.geti)(L, 1, f + i);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltm.c,v 2.33 2014/11/21 12:15:57 roberto Exp $
|
** $Id: ltm.c,v 2.34 2015/03/30 15:42:27 roberto Exp $
|
||||||
** Tag methods
|
** Tag methods
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -117,6 +117,7 @@ void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
|
|||||||
switch (event) {
|
switch (event) {
|
||||||
case TM_CONCAT:
|
case TM_CONCAT:
|
||||||
luaG_concaterror(L, p1, p2);
|
luaG_concaterror(L, p1, p2);
|
||||||
|
/* call never returns, but to avoid warnings: *//* FALLTHROUGH */
|
||||||
case TM_BAND: case TM_BOR: case TM_BXOR:
|
case TM_BAND: case TM_BOR: case TM_BXOR:
|
||||||
case TM_SHL: case TM_SHR: case TM_BNOT: {
|
case TM_SHL: case TM_SHR: case TM_BNOT: {
|
||||||
lua_Number dummy;
|
lua_Number dummy;
|
||||||
@@ -124,8 +125,8 @@ void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
|
|||||||
luaG_tointerror(L, p1, p2);
|
luaG_tointerror(L, p1, p2);
|
||||||
else
|
else
|
||||||
luaG_opinterror(L, p1, p2, "perform bitwise operation on");
|
luaG_opinterror(L, p1, p2, "perform bitwise operation on");
|
||||||
/* else go through */
|
|
||||||
}
|
}
|
||||||
|
/* calls never return, but to avoid warnings: *//* FALLTHROUGH */
|
||||||
default:
|
default:
|
||||||
luaG_opinterror(L, p1, p2, "perform arithmetic on");
|
luaG_opinterror(L, p1, p2, "perform arithmetic on");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lua.c,v 1.222 2014/11/11 19:41:27 roberto Exp $
|
** $Id: lua.c,v 1.225 2015/03/30 15:42:59 roberto Exp $
|
||||||
** Lua stand-alone interpreter
|
** Lua stand-alone interpreter
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -80,9 +80,7 @@
|
|||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
|
#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
|
||||||
#define lua_saveline(L,idx) \
|
#define lua_saveline(L,line) ((void)L, add_history(line))
|
||||||
if (lua_rawlen(L,idx) > 0) /* non-empty line? */ \
|
|
||||||
add_history(lua_tostring(L, idx)); /* add it to history */
|
|
||||||
#define lua_freeline(L,b) ((void)L, free(b))
|
#define lua_freeline(L,b) ((void)L, free(b))
|
||||||
|
|
||||||
#else /* }{ */
|
#else /* }{ */
|
||||||
@@ -90,7 +88,7 @@
|
|||||||
#define lua_readline(L,b,p) \
|
#define lua_readline(L,b,p) \
|
||||||
((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
|
((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
|
||||||
fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
|
fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
|
||||||
#define lua_saveline(L,idx) { (void)L; (void)idx; }
|
#define lua_saveline(L,line) { (void)L; (void)line; }
|
||||||
#define lua_freeline(L,b) { (void)L; (void)b; }
|
#define lua_freeline(L,b) { (void)L; (void)b; }
|
||||||
|
|
||||||
#endif /* } */
|
#endif /* } */
|
||||||
@@ -315,11 +313,11 @@ static int pushline (lua_State *L, int firstline) {
|
|||||||
lua_pop(L, 1); /* remove prompt */
|
lua_pop(L, 1); /* remove prompt */
|
||||||
l = strlen(b);
|
l = strlen(b);
|
||||||
if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
|
if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
|
||||||
b[l-1] = '\0'; /* remove it */
|
b[--l] = '\0'; /* remove it */
|
||||||
if (firstline && b[0] == '=') /* for compatibility with 5.2, ... */
|
if (firstline && b[0] == '=') /* for compatibility with 5.2, ... */
|
||||||
lua_pushfstring(L, "return %s", b + 1); /* change '=' to 'return' */
|
lua_pushfstring(L, "return %s", b + 1); /* change '=' to 'return' */
|
||||||
else
|
else
|
||||||
lua_pushstring(L, b);
|
lua_pushlstring(L, b, l);
|
||||||
lua_freeline(L, b);
|
lua_freeline(L, b);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -336,8 +334,12 @@ static int addreturn (lua_State *L) {
|
|||||||
lua_pushvalue(L, -2); /* duplicate line */
|
lua_pushvalue(L, -2); /* duplicate line */
|
||||||
lua_concat(L, 2); /* new line is "return ..." */
|
lua_concat(L, 2); /* new line is "return ..." */
|
||||||
line = lua_tolstring(L, -1, &len);
|
line = lua_tolstring(L, -1, &len);
|
||||||
if ((status = luaL_loadbuffer(L, line, len, "=stdin")) == LUA_OK)
|
if ((status = luaL_loadbuffer(L, line, len, "=stdin")) == LUA_OK) {
|
||||||
lua_remove(L, -3); /* remove original line */
|
lua_remove(L, -3); /* remove original line */
|
||||||
|
line += sizeof("return")/sizeof(char); /* remove 'return' for history */
|
||||||
|
if (line[0] != '\0') /* non empty? */
|
||||||
|
lua_saveline(L, line); /* keep history */
|
||||||
|
}
|
||||||
else
|
else
|
||||||
lua_pop(L, 2); /* remove result from 'luaL_loadbuffer' and new line */
|
lua_pop(L, 2); /* remove result from 'luaL_loadbuffer' and new line */
|
||||||
return status;
|
return status;
|
||||||
@@ -352,8 +354,10 @@ static int multiline (lua_State *L) {
|
|||||||
size_t len;
|
size_t len;
|
||||||
const char *line = lua_tolstring(L, 1, &len); /* get what it has */
|
const char *line = lua_tolstring(L, 1, &len); /* get what it has */
|
||||||
int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */
|
int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */
|
||||||
if (!incomplete(L, status) || !pushline(L, 0))
|
if (!incomplete(L, status) || !pushline(L, 0)) {
|
||||||
|
lua_saveline(L, line); /* keep history */
|
||||||
return status; /* cannot or should not try to add continuation line */
|
return status; /* cannot or should not try to add continuation line */
|
||||||
|
}
|
||||||
lua_pushliteral(L, "\n"); /* add newline... */
|
lua_pushliteral(L, "\n"); /* add newline... */
|
||||||
lua_insert(L, -2); /* ...between the two lines */
|
lua_insert(L, -2); /* ...between the two lines */
|
||||||
lua_concat(L, 3); /* join them */
|
lua_concat(L, 3); /* join them */
|
||||||
@@ -374,7 +378,6 @@ static int loadline (lua_State *L) {
|
|||||||
return -1; /* no input */
|
return -1; /* no input */
|
||||||
if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */
|
if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */
|
||||||
status = multiline(L); /* try as command, maybe with continuation lines */
|
status = multiline(L); /* try as command, maybe with continuation lines */
|
||||||
lua_saveline(L, 1); /* keep history */
|
|
||||||
lua_remove(L, 1); /* remove line from the stack */
|
lua_remove(L, 1); /* remove line from the stack */
|
||||||
lua_assert(lua_gettop(L) == 1);
|
lua_assert(lua_gettop(L) == 1);
|
||||||
return status;
|
return status;
|
||||||
@@ -482,14 +485,14 @@ static int collectargs (char **argv, int *first) {
|
|||||||
args |= has_E;
|
args |= has_E;
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
args |= has_i; /* goes through (-i implies -v) */
|
args |= has_i; /* (-i implies -v) *//* FALLTHROUGH */
|
||||||
case 'v':
|
case 'v':
|
||||||
if (argv[i][2] != '\0') /* extra characters after 1st? */
|
if (argv[i][2] != '\0') /* extra characters after 1st? */
|
||||||
return has_error; /* invalid option */
|
return has_error; /* invalid option */
|
||||||
args |= has_v;
|
args |= has_v;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
args |= has_e; /* go through */
|
args |= has_e; /* FALLTHROUGH */
|
||||||
case 'l': /* both options need an argument */
|
case 'l': /* both options need an argument */
|
||||||
if (argv[i][2] == '\0') { /* no concatenated argument? */
|
if (argv[i][2] == '\0') { /* no concatenated argument? */
|
||||||
i++; /* try next 'argv' */
|
i++; /* try next 'argv' */
|
||||||
@@ -513,17 +516,16 @@ static int collectargs (char **argv, int *first) {
|
|||||||
static int runargs (lua_State *L, char **argv, int n) {
|
static int runargs (lua_State *L, char **argv, int n) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 1; i < n; i++) {
|
for (i = 1; i < n; i++) {
|
||||||
int status;
|
|
||||||
int option = argv[i][1];
|
int option = argv[i][1];
|
||||||
lua_assert(argv[i][0] == '-'); /* already checked */
|
lua_assert(argv[i][0] == '-'); /* already checked */
|
||||||
if (option == 'e' || option == 'l') {
|
if (option == 'e' || option == 'l') {
|
||||||
|
int status;
|
||||||
const char *extra = argv[i] + 2; /* both options need an argument */
|
const char *extra = argv[i] + 2; /* both options need an argument */
|
||||||
if (*extra == '\0') extra = argv[++i];
|
if (*extra == '\0') extra = argv[++i];
|
||||||
lua_assert(extra != NULL);
|
lua_assert(extra != NULL);
|
||||||
if (option == 'e')
|
status = (option == 'e')
|
||||||
status = dostring(L, extra, "=(command line)");
|
? dostring(L, extra, "=(command line)")
|
||||||
else
|
: dolibrary(L, extra);
|
||||||
status = dolibrary(L, extra);
|
|
||||||
if (status != LUA_OK) return 0;
|
if (status != LUA_OK) return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lua.h,v 1.325 2014/12/26 17:24:27 roberto Exp $
|
** $Id: lua.h,v 1.328 2015/06/03 13:03:38 roberto Exp $
|
||||||
** Lua - A Scripting Language
|
** Lua - A Scripting Language
|
||||||
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
|
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
|
||||||
** See Copyright Notice at the end of this file
|
** See Copyright Notice at the end of this file
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
#define LUA_VERSION_MAJOR "5"
|
#define LUA_VERSION_MAJOR "5"
|
||||||
#define LUA_VERSION_MINOR "3"
|
#define LUA_VERSION_MINOR "3"
|
||||||
#define LUA_VERSION_NUM 503
|
#define LUA_VERSION_NUM 503
|
||||||
#define LUA_VERSION_RELEASE "0"
|
#define LUA_VERSION_RELEASE "1"
|
||||||
|
|
||||||
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
|
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
|
||||||
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
|
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
|
||||||
@@ -35,9 +35,11 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** pseudo-indices
|
** Pseudo-indices
|
||||||
|
** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
|
||||||
|
** space after that to help overflow detection)
|
||||||
*/
|
*/
|
||||||
#define LUA_REGISTRYINDEX LUAI_FIRSTPSEUDOIDX
|
#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000)
|
||||||
#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i))
|
#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i))
|
||||||
|
|
||||||
|
|
||||||
@@ -280,7 +282,6 @@ LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
|
|||||||
|
|
||||||
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
|
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
|
||||||
|
|
||||||
LUA_API void (lua_clonefunction) (lua_State *L, const void *eL);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** coroutine functions
|
** coroutine functions
|
||||||
@@ -357,8 +358,7 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
|
|||||||
#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
|
#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
|
||||||
#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
|
#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
|
||||||
|
|
||||||
#define lua_pushliteral(L, s) \
|
#define lua_pushliteral(L, s) lua_pushstring(L, "" s)
|
||||||
lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
|
|
||||||
|
|
||||||
#define lua_pushglobaltable(L) \
|
#define lua_pushglobaltable(L) \
|
||||||
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)
|
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)
|
||||||
@@ -458,11 +458,6 @@ struct lua_Debug {
|
|||||||
|
|
||||||
/* }====================================================================== */
|
/* }====================================================================== */
|
||||||
|
|
||||||
/* Add by skynet */
|
|
||||||
|
|
||||||
LUA_API lua_State * skynet_sig_L;
|
|
||||||
LUA_API void (lua_checksig_)(lua_State *L);
|
|
||||||
#define lua_checksig(L) if (skynet_sig_L) { lua_checksig_(L); }
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Copyright (C) 1994-2015 Lua.org, PUC-Rio.
|
* Copyright (C) 1994-2015 Lua.org, PUC-Rio.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: luac.c,v 1.72 2015/01/06 03:09:13 lhf Exp $
|
** $Id: luac.c,v 1.75 2015/03/12 01:58:27 lhf Exp $
|
||||||
** Lua compiler (saves bytecodes to files; also lists bytecodes)
|
** Lua compiler (saves bytecodes to files; also lists bytecodes)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -149,9 +149,9 @@ static const Proto* combine(lua_State* L, int n)
|
|||||||
for (i=0; i<n; i++)
|
for (i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
f->p[i]=toproto(L,i-n-1);
|
f->p[i]=toproto(L,i-n-1);
|
||||||
if (f->p[i]->sp->sizeupvalues>0) f->p[i]->sp->upvalues[0].instack=0;
|
if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0;
|
||||||
}
|
}
|
||||||
f->sp->sizelineinfo=0;
|
f->sizelineinfo=0;
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -206,7 +206,7 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** $Id: print.c,v 1.76 2015/01/05 16:12:50 lhf Exp $
|
** $Id: luac.c,v 1.75 2015/03/12 01:58:27 lhf Exp $
|
||||||
** print bytecodes
|
** print bytecodes
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -226,7 +226,7 @@ int main(int argc, char* argv[])
|
|||||||
static void PrintString(const TString* ts)
|
static void PrintString(const TString* ts)
|
||||||
{
|
{
|
||||||
const char* s=getstr(ts);
|
const char* s=getstr(ts);
|
||||||
size_t i,n=ts->len;
|
size_t i,n=tsslen(ts);
|
||||||
printf("%c",'"');
|
printf("%c",'"');
|
||||||
for (i=0; i<n; i++)
|
for (i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
@@ -282,14 +282,13 @@ static void PrintConstant(const Proto* f, int i)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UPVALNAME(x) ((f->sp->upvalues[x].name) ? getstr(f->sp->upvalues[x].name) : "-")
|
#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-")
|
||||||
#define MYK(x) (-1-(x))
|
#define MYK(x) (-1-(x))
|
||||||
|
|
||||||
static void PrintCode(const Proto* f)
|
static void PrintCode(const Proto* f)
|
||||||
{
|
{
|
||||||
const SharedProto *sp = f->sp;
|
const Instruction* code=f->code;
|
||||||
const Instruction* code=sp->code;
|
int pc,n=f->sizecode;
|
||||||
int pc,n=sp->sizecode;
|
|
||||||
for (pc=0; pc<n; pc++)
|
for (pc=0; pc<n; pc++)
|
||||||
{
|
{
|
||||||
Instruction i=code[pc];
|
Instruction i=code[pc];
|
||||||
@@ -393,7 +392,7 @@ static void PrintCode(const Proto* f)
|
|||||||
#define SS(x) ((x==1)?"":"s")
|
#define SS(x) ((x==1)?"":"s")
|
||||||
#define S(x) (int)(x),SS(x)
|
#define S(x) (int)(x),SS(x)
|
||||||
|
|
||||||
static void PrintHeader(const SharedProto* f)
|
static void PrintHeader(const Proto* f)
|
||||||
{
|
{
|
||||||
const char* s=f->source ? getstr(f->source) : "=?";
|
const char* s=f->source ? getstr(f->source) : "=?";
|
||||||
if (*s=='@' || *s=='=')
|
if (*s=='@' || *s=='=')
|
||||||
@@ -415,9 +414,8 @@ static void PrintHeader(const SharedProto* f)
|
|||||||
|
|
||||||
static void PrintDebug(const Proto* f)
|
static void PrintDebug(const Proto* f)
|
||||||
{
|
{
|
||||||
const SharedProto *sp = f->sp;
|
|
||||||
int i,n;
|
int i,n;
|
||||||
n=sp->sizek;
|
n=f->sizek;
|
||||||
printf("constants (%d) for %p:\n",n,VOID(f));
|
printf("constants (%d) for %p:\n",n,VOID(f));
|
||||||
for (i=0; i<n; i++)
|
for (i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
@@ -425,26 +423,26 @@ static void PrintDebug(const Proto* f)
|
|||||||
PrintConstant(f,i);
|
PrintConstant(f,i);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
n=sp->sizelocvars;
|
n=f->sizelocvars;
|
||||||
printf("locals (%d) for %p:\n",n,VOID(f));
|
printf("locals (%d) for %p:\n",n,VOID(f));
|
||||||
for (i=0; i<n; i++)
|
for (i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
printf("\t%d\t%s\t%d\t%d\n",
|
printf("\t%d\t%s\t%d\t%d\n",
|
||||||
i,getstr(sp->locvars[i].varname),sp->locvars[i].startpc+1,sp->locvars[i].endpc+1);
|
i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
|
||||||
}
|
}
|
||||||
n=f->sp->sizeupvalues;
|
n=f->sizeupvalues;
|
||||||
printf("upvalues (%d) for %p:\n",n,VOID(f));
|
printf("upvalues (%d) for %p:\n",n,VOID(f));
|
||||||
for (i=0; i<n; i++)
|
for (i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
printf("\t%d\t%s\t%d\t%d\n",
|
printf("\t%d\t%s\t%d\t%d\n",
|
||||||
i,UPVALNAME(i),sp->upvalues[i].instack,sp->upvalues[i].idx);
|
i,UPVALNAME(i),f->upvalues[i].instack,f->upvalues[i].idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PrintFunction(const Proto* f, int full)
|
static void PrintFunction(const Proto* f, int full)
|
||||||
{
|
{
|
||||||
int i,n=f->sp->sizep;
|
int i,n=f->sizep;
|
||||||
PrintHeader(f->sp);
|
PrintHeader(f);
|
||||||
PrintCode(f);
|
PrintCode(f);
|
||||||
if (full) PrintDebug(f);
|
if (full) PrintDebug(f);
|
||||||
for (i=0; i<n; i++) PrintFunction(f->p[i],full);
|
for (i=0; i<n; i++) PrintFunction(f->p[i],full);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: luaconf.h,v 1.238 2014/12/29 13:27:55 roberto Exp $
|
** $Id: luaconf.h,v 1.251 2015/05/20 17:39:23 roberto Exp $
|
||||||
** Configuration file for Lua
|
** Configuration file for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -96,10 +96,8 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ LUA_INT_INT / LUA_INT_LONG / LUA_INT_LONGLONG defines the type for
|
@@ LUA_INT_TYPE defines the type for Lua integers.
|
||||||
** Lua integers.
|
@@ LUA_FLOAT_TYPE defines the type for Lua floats.
|
||||||
@@ LUA_REAL_FLOAT / LUA_REAL_DOUBLE / LUA_REAL_LONGDOUBLE defines
|
|
||||||
** the type for Lua floats.
|
|
||||||
** Lua should work fine with any mix of these options (if supported
|
** Lua should work fine with any mix of these options (if supported
|
||||||
** by your C compiler). The usual configurations are 64-bit integers
|
** by your C compiler). The usual configurations are 64-bit integers
|
||||||
** and 'double' (the default), 32-bit integers and 'float' (for
|
** and 'double' (the default), 32-bit integers and 'float' (for
|
||||||
@@ -107,31 +105,46 @@
|
|||||||
** compliant with C99, which may not have support for 'long long').
|
** compliant with C99, which may not have support for 'long long').
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* predefined options for LUA_INT_TYPE */
|
||||||
|
#define LUA_INT_INT 1
|
||||||
|
#define LUA_INT_LONG 2
|
||||||
|
#define LUA_INT_LONGLONG 3
|
||||||
|
|
||||||
|
/* predefined options for LUA_FLOAT_TYPE */
|
||||||
|
#define LUA_FLOAT_FLOAT 1
|
||||||
|
#define LUA_FLOAT_DOUBLE 2
|
||||||
|
#define LUA_FLOAT_LONGDOUBLE 3
|
||||||
|
|
||||||
#if defined(LUA_32BITS) /* { */
|
#if defined(LUA_32BITS) /* { */
|
||||||
/*
|
/*
|
||||||
** 32-bit integers and 'float'
|
** 32-bit integers and 'float'
|
||||||
*/
|
*/
|
||||||
#if LUAI_BITSINT >= 32 /* use 'int' if big enough */
|
#if LUAI_BITSINT >= 32 /* use 'int' if big enough */
|
||||||
#define LUA_INT_INT
|
#define LUA_INT_TYPE LUA_INT_INT
|
||||||
#else /* otherwise use 'long' */
|
#else /* otherwise use 'long' */
|
||||||
#define LUA_INT_LONG
|
#define LUA_INT_TYPE LUA_INT_LONG
|
||||||
#endif
|
#endif
|
||||||
#define LUA_REAL_FLOAT
|
#define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT
|
||||||
|
|
||||||
#elif defined(LUA_C89_NUMBERS) /* }{ */
|
#elif defined(LUA_C89_NUMBERS) /* }{ */
|
||||||
/*
|
/*
|
||||||
** largest types available for C89 ('long' and 'double')
|
** largest types available for C89 ('long' and 'double')
|
||||||
*/
|
*/
|
||||||
#define LUA_INT_LONG
|
#define LUA_INT_TYPE LUA_INT_LONG
|
||||||
#define LUA_REAL_DOUBLE
|
#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE
|
||||||
|
|
||||||
|
#endif /* } */
|
||||||
|
|
||||||
|
|
||||||
#else /* }{ */
|
|
||||||
/*
|
/*
|
||||||
** default configuration for 64-bit Lua ('long long' and 'double')
|
** default configuration for 64-bit Lua ('long long' and 'double')
|
||||||
*/
|
*/
|
||||||
#define LUA_INT_LONGLONG
|
#if !defined(LUA_INT_TYPE)
|
||||||
#define LUA_REAL_DOUBLE
|
#define LUA_INT_TYPE LUA_INT_LONGLONG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(LUA_FLOAT_TYPE)
|
||||||
|
#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE
|
||||||
#endif /* } */
|
#endif /* } */
|
||||||
|
|
||||||
/* }================================================================== */
|
/* }================================================================== */
|
||||||
@@ -155,7 +168,7 @@
|
|||||||
** non-conventional directories.
|
** non-conventional directories.
|
||||||
*/
|
*/
|
||||||
#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
|
#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
|
||||||
#if defined(_WIN32) /* { */
|
#if defined(_WIN32) /* { */
|
||||||
/*
|
/*
|
||||||
** In Windows, any exclamation mark ('!') in the path is replaced by the
|
** In Windows, any exclamation mark ('!') in the path is replaced by the
|
||||||
** path of the directory of the executable file of the current process.
|
** path of the directory of the executable file of the current process.
|
||||||
@@ -300,20 +313,15 @@
|
|||||||
*/
|
*/
|
||||||
#define LUA_COMPAT_APIINTCASTS
|
#define LUA_COMPAT_APIINTCASTS
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a
|
|
||||||
@@ a float mark ('.0').
|
|
||||||
** This macro is not on by default even in compatibility mode,
|
|
||||||
** because this is not really an incompatibility.
|
|
||||||
*/
|
|
||||||
/* #define LUA_COMPAT_FLOATSTRING */
|
|
||||||
|
|
||||||
#endif /* } */
|
#endif /* } */
|
||||||
|
|
||||||
|
|
||||||
#if defined(LUA_COMPAT_5_1) /* { */
|
#if defined(LUA_COMPAT_5_1) /* { */
|
||||||
|
|
||||||
|
/* Incompatibilities from 5.2 -> 5.3 */
|
||||||
|
#define LUA_COMPAT_MATHLIB
|
||||||
|
#define LUA_COMPAT_APIINTCASTS
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
|
@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
|
||||||
** You can replace it with 'table.unpack'.
|
** You can replace it with 'table.unpack'.
|
||||||
@@ -373,6 +381,15 @@
|
|||||||
|
|
||||||
#endif /* } */
|
#endif /* } */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a
|
||||||
|
@@ a float mark ('.0').
|
||||||
|
** This macro is not on by default even in compatibility mode,
|
||||||
|
** because this is not really an incompatibility.
|
||||||
|
*/
|
||||||
|
/* #define LUA_COMPAT_FLOATSTRING */
|
||||||
|
|
||||||
/* }================================================================== */
|
/* }================================================================== */
|
||||||
|
|
||||||
|
|
||||||
@@ -380,30 +397,30 @@
|
|||||||
/*
|
/*
|
||||||
** {==================================================================
|
** {==================================================================
|
||||||
** Configuration for Numbers.
|
** Configuration for Numbers.
|
||||||
** Change these definitions if no predefined LUA_REAL_* / LUA_INT_*
|
** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_*
|
||||||
** satisfy your needs.
|
** satisfy your needs.
|
||||||
** ===================================================================
|
** ===================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ LUA_NUMBER is the floating-point type used by Lua.
|
@@ LUA_NUMBER is the floating-point type used by Lua.
|
||||||
**
|
|
||||||
@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
|
@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
|
||||||
@@ over a floating number.
|
@@ over a floating number.
|
||||||
**
|
@@ l_mathlim(x) corrects limit name 'x' to the proper float type
|
||||||
|
** by prefixing it with one of FLT/DBL/LDBL.
|
||||||
@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
|
@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
|
||||||
@@ LUA_NUMBER_FMT is the format for writing floats.
|
@@ LUA_NUMBER_FMT is the format for writing floats.
|
||||||
@@ lua_number2str converts a float to a string.
|
@@ lua_number2str converts a float to a string.
|
||||||
**
|
|
||||||
@@ l_mathop allows the addition of an 'l' or 'f' to all math operations.
|
@@ l_mathop allows the addition of an 'l' or 'f' to all math operations.
|
||||||
**
|
|
||||||
@@ lua_str2number converts a decimal numeric string to a number.
|
@@ lua_str2number converts a decimal numeric string to a number.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LUA_REAL_FLOAT) /* { single float */
|
#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT /* { single float */
|
||||||
|
|
||||||
#define LUA_NUMBER float
|
#define LUA_NUMBER float
|
||||||
|
|
||||||
|
#define l_mathlim(n) (FLT_##n)
|
||||||
|
|
||||||
#define LUAI_UACNUMBER double
|
#define LUAI_UACNUMBER double
|
||||||
|
|
||||||
#define LUA_NUMBER_FRMLEN ""
|
#define LUA_NUMBER_FRMLEN ""
|
||||||
@@ -414,10 +431,12 @@
|
|||||||
#define lua_str2number(s,p) strtof((s), (p))
|
#define lua_str2number(s,p) strtof((s), (p))
|
||||||
|
|
||||||
|
|
||||||
#elif defined(LUA_REAL_LONGDOUBLE) /* }{ long double */
|
#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE /* }{ long double */
|
||||||
|
|
||||||
#define LUA_NUMBER long double
|
#define LUA_NUMBER long double
|
||||||
|
|
||||||
|
#define l_mathlim(n) (LDBL_##n)
|
||||||
|
|
||||||
#define LUAI_UACNUMBER long double
|
#define LUAI_UACNUMBER long double
|
||||||
|
|
||||||
#define LUA_NUMBER_FRMLEN "L"
|
#define LUA_NUMBER_FRMLEN "L"
|
||||||
@@ -427,10 +446,12 @@
|
|||||||
|
|
||||||
#define lua_str2number(s,p) strtold((s), (p))
|
#define lua_str2number(s,p) strtold((s), (p))
|
||||||
|
|
||||||
#elif defined(LUA_REAL_DOUBLE) /* }{ double */
|
#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE /* }{ double */
|
||||||
|
|
||||||
#define LUA_NUMBER double
|
#define LUA_NUMBER double
|
||||||
|
|
||||||
|
#define l_mathlim(n) (DBL_##n)
|
||||||
|
|
||||||
#define LUAI_UACNUMBER double
|
#define LUAI_UACNUMBER double
|
||||||
|
|
||||||
#define LUA_NUMBER_FRMLEN ""
|
#define LUA_NUMBER_FRMLEN ""
|
||||||
@@ -440,9 +461,9 @@
|
|||||||
|
|
||||||
#define lua_str2number(s,p) strtod((s), (p))
|
#define lua_str2number(s,p) strtod((s), (p))
|
||||||
|
|
||||||
#else /* }{ */
|
#else /* }{ */
|
||||||
|
|
||||||
#error "numeric real type not defined"
|
#error "numeric float type not defined"
|
||||||
|
|
||||||
#endif /* } */
|
#endif /* } */
|
||||||
|
|
||||||
@@ -466,46 +487,6 @@
|
|||||||
(*(p) = (LUA_INTEGER)(n), 1))
|
(*(p) = (LUA_INTEGER)(n), 1))
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ The luai_num* macros define the primitive operations over numbers.
|
|
||||||
** They should work for any size of floating numbers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* the following operations need the math library */
|
|
||||||
#if defined(lobject_c) || defined(lvm_c)
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
/* floor division (defined as 'floor(a/b)') */
|
|
||||||
#define luai_numidiv(L,a,b) ((void)L, l_mathop(floor)(luai_numdiv(L,a,b)))
|
|
||||||
|
|
||||||
/*
|
|
||||||
** module: defined as 'a - floor(a/b)*b'; the previous definition gives
|
|
||||||
** NaN when 'b' is huge, but the result should be 'a'. 'fmod' gives the
|
|
||||||
** result of 'a - trunc(a/b)*b', and therefore must be corrected when
|
|
||||||
** 'trunc(a/b) ~= floor(a/b)'. That happens when the division has a
|
|
||||||
** non-integer negative result, which is equivalent to the test below
|
|
||||||
*/
|
|
||||||
#define luai_nummod(L,a,b,m) \
|
|
||||||
{ (m) = l_mathop(fmod)(a,b); if ((m)*(b) < 0) (m) += (b); }
|
|
||||||
|
|
||||||
/* exponentiation */
|
|
||||||
#define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b))
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* these are quite standard operations */
|
|
||||||
#if defined(LUA_CORE)
|
|
||||||
#define luai_numadd(L,a,b) ((a)+(b))
|
|
||||||
#define luai_numsub(L,a,b) ((a)-(b))
|
|
||||||
#define luai_nummul(L,a,b) ((a)*(b))
|
|
||||||
#define luai_numdiv(L,a,b) ((a)/(b))
|
|
||||||
#define luai_numunm(L,a) (-(a))
|
|
||||||
#define luai_numeq(a,b) ((a)==(b))
|
|
||||||
#define luai_numlt(a,b) ((a)<(b))
|
|
||||||
#define luai_numle(a,b) ((a)<=(b))
|
|
||||||
#define luai_numisnan(a) (!luai_numeq((a), (a)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ LUA_INTEGER is the integer type used by Lua.
|
@@ LUA_INTEGER is the integer type used by Lua.
|
||||||
@@ -538,7 +519,7 @@
|
|||||||
|
|
||||||
/* now the variable definitions */
|
/* now the variable definitions */
|
||||||
|
|
||||||
#if defined(LUA_INT_INT) /* { int */
|
#if LUA_INT_TYPE == LUA_INT_INT /* { int */
|
||||||
|
|
||||||
#define LUA_INTEGER int
|
#define LUA_INTEGER int
|
||||||
#define LUA_INTEGER_FRMLEN ""
|
#define LUA_INTEGER_FRMLEN ""
|
||||||
@@ -546,7 +527,7 @@
|
|||||||
#define LUA_MAXINTEGER INT_MAX
|
#define LUA_MAXINTEGER INT_MAX
|
||||||
#define LUA_MININTEGER INT_MIN
|
#define LUA_MININTEGER INT_MIN
|
||||||
|
|
||||||
#elif defined(LUA_INT_LONG) /* }{ long */
|
#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */
|
||||||
|
|
||||||
#define LUA_INTEGER long
|
#define LUA_INTEGER long
|
||||||
#define LUA_INTEGER_FRMLEN "l"
|
#define LUA_INTEGER_FRMLEN "l"
|
||||||
@@ -554,7 +535,7 @@
|
|||||||
#define LUA_MAXINTEGER LONG_MAX
|
#define LUA_MAXINTEGER LONG_MAX
|
||||||
#define LUA_MININTEGER LONG_MIN
|
#define LUA_MININTEGER LONG_MIN
|
||||||
|
|
||||||
#elif defined(LUA_INT_LONGLONG) /* }{ long long */
|
#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */
|
||||||
|
|
||||||
#if defined(LLONG_MAX) /* { */
|
#if defined(LLONG_MAX) /* { */
|
||||||
/* use ISO C99 stuff */
|
/* use ISO C99 stuff */
|
||||||
@@ -592,13 +573,13 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** {==================================================================
|
** {==================================================================
|
||||||
** Dependencies with C99
|
** Dependencies with C99 and other C details
|
||||||
** ===================================================================
|
** ===================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ lua_strx2number converts an hexadecimal numeric string to a number.
|
@@ lua_strx2number converts an hexadecimal numeric string to a number.
|
||||||
** In C99, 'strtod' does both conversions. Otherwise, you can
|
** In C99, 'strtod' does that conversion. Otherwise, you can
|
||||||
** leave 'lua_strx2number' undefined and Lua will provide its own
|
** leave 'lua_strx2number' undefined and Lua will provide its own
|
||||||
** implementation.
|
** implementation.
|
||||||
*/
|
*/
|
||||||
@@ -608,12 +589,13 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ LUA_USE_AFORMAT allows '%a'/'%A' specifiers in 'string.format'
|
@@ lua_number2strx converts a float to an hexadecimal numeric string.
|
||||||
** Enable it if the C function 'printf' supports these specifiers.
|
** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
|
||||||
** (C99 demands it and Windows also supports it.)
|
** Otherwise, you can leave 'lua_number2strx' undefined and Lua will
|
||||||
|
** provide its own implementation.
|
||||||
*/
|
*/
|
||||||
#if !defined(LUA_USE_C89) || defined(LUA_USE_WINDOWS)
|
#if !defined(LUA_USE_C89)
|
||||||
#define LUA_USE_AFORMAT
|
#define lua_number2strx(L,b,f,n) sprintf(b,f,n)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -642,12 +624,50 @@
|
|||||||
#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \
|
#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \
|
||||||
__STDC_VERSION__ >= 199901L
|
__STDC_VERSION__ >= 199901L
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#if defined (INTPTR_MAX) /* even in C99 this type is optional */
|
#if defined(INTPTR_MAX) /* even in C99 this type is optional */
|
||||||
#undef LUA_KCONTEXT
|
#undef LUA_KCONTEXT
|
||||||
#define LUA_KCONTEXT intptr_t
|
#define LUA_KCONTEXT intptr_t
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point).
|
||||||
|
** Change that if you do not want to use C locales. (Code using this
|
||||||
|
** macro must include header 'locale.h'.)
|
||||||
|
*/
|
||||||
|
#if !defined(lua_getlocaledecpoint)
|
||||||
|
#define lua_getlocaledecpoint() (localeconv()->decimal_point[0])
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* }================================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** {==================================================================
|
||||||
|
** Language Variations
|
||||||
|
** =====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some
|
||||||
|
** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from
|
||||||
|
** numbers to strings. Define LUA_NOCVTS2N to turn off automatic
|
||||||
|
** coercion from strings to numbers.
|
||||||
|
*/
|
||||||
|
/* #define LUA_NOCVTN2S */
|
||||||
|
/* #define LUA_NOCVTS2N */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ LUA_USE_APICHECK turns on several consistency checks on the C API.
|
||||||
|
** Define it as a help when debugging C code.
|
||||||
|
*/
|
||||||
|
#if defined(LUA_USE_APICHECK)
|
||||||
|
#include <assert.h>
|
||||||
|
#define luai_apicheck(l,e) assert(e)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* }================================================================== */
|
/* }================================================================== */
|
||||||
|
|
||||||
|
|
||||||
@@ -671,9 +691,6 @@
|
|||||||
#define LUAI_MAXSTACK 15000
|
#define LUAI_MAXSTACK 15000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* reserve some space for error handling */
|
|
||||||
#define LUAI_FIRSTPSEUDOIDX (-LUAI_MAXSTACK - 1000)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
|
@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
|
||||||
@@ -691,20 +708,18 @@
|
|||||||
#define LUA_IDSIZE 60
|
#define LUA_IDSIZE 60
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ LUAI_MAXSHORTLEN is the maximum length for short strings, that is,
|
|
||||||
** strings that are internalized. (Cannot be smaller than reserved words
|
|
||||||
** or tags for metamethods, as these strings must be internalized;
|
|
||||||
** #("function") = 8, #("__newindex") = 10.)
|
|
||||||
*/
|
|
||||||
#define LUAI_MAXSHORTLEN 40
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
|
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
|
||||||
** CHANGE it if it uses too much C-stack space.
|
** CHANGE it if it uses too much C-stack space. (For long double,
|
||||||
|
** 'string.format("%.99f", 1e4932)' needs ~5030 bytes, so a
|
||||||
|
** smaller buffer would force a memory allocation for each call to
|
||||||
|
** 'string.format'.)
|
||||||
*/
|
*/
|
||||||
#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
|
#if defined(LUA_FLOAT_LONGDOUBLE)
|
||||||
|
#define LUAL_BUFFERSIZE 8192
|
||||||
|
#else
|
||||||
|
#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
|
||||||
|
#endif
|
||||||
|
|
||||||
/* }================================================================== */
|
/* }================================================================== */
|
||||||
|
|
||||||
|
|||||||
@@ -44,8 +44,6 @@ LUAMOD_API int (luaopen_debug) (lua_State *L);
|
|||||||
#define LUA_LOADLIBNAME "package"
|
#define LUA_LOADLIBNAME "package"
|
||||||
LUAMOD_API int (luaopen_package) (lua_State *L);
|
LUAMOD_API int (luaopen_package) (lua_State *L);
|
||||||
|
|
||||||
#define LUA_CACHELIB
|
|
||||||
LUAMOD_API int (luaopen_cache) (lua_State *L);
|
|
||||||
|
|
||||||
/* open all previous libraries */
|
/* open all previous libraries */
|
||||||
LUALIB_API void (luaL_openlibs) (lua_State *L);
|
LUALIB_API void (luaL_openlibs) (lua_State *L);
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ static TString *LoadString (LoadState *S) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void LoadCode (LoadState *S, SharedProto *f) {
|
static void LoadCode (LoadState *S, Proto *f) {
|
||||||
int n = LoadInt(S);
|
int n = LoadInt(S);
|
||||||
f->code = luaM_newvector(S->L, n, Instruction);
|
f->code = luaM_newvector(S->L, n, Instruction);
|
||||||
f->sizecode = n;
|
f->sizecode = n;
|
||||||
@@ -115,7 +115,7 @@ static void LoadConstants (LoadState *S, Proto *f) {
|
|||||||
int i;
|
int i;
|
||||||
int n = LoadInt(S);
|
int n = LoadInt(S);
|
||||||
f->k = luaM_newvector(S->L, n, TValue);
|
f->k = luaM_newvector(S->L, n, TValue);
|
||||||
f->sp->sizek = n;
|
f->sizek = n;
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
setnilvalue(&f->k[i]);
|
setnilvalue(&f->k[i]);
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
@@ -149,17 +149,17 @@ static void LoadProtos (LoadState *S, Proto *f) {
|
|||||||
int i;
|
int i;
|
||||||
int n = LoadInt(S);
|
int n = LoadInt(S);
|
||||||
f->p = luaM_newvector(S->L, n, Proto *);
|
f->p = luaM_newvector(S->L, n, Proto *);
|
||||||
f->sp->sizep = n;
|
f->sizep = n;
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
f->p[i] = NULL;
|
f->p[i] = NULL;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
f->p[i] = luaF_newproto(S->L, NULL);
|
f->p[i] = luaF_newproto(S->L);
|
||||||
LoadFunction(S, f->p[i], f->sp->source);
|
LoadFunction(S, f->p[i], f->source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void LoadUpvalues (LoadState *S, SharedProto *f) {
|
static void LoadUpvalues (LoadState *S, Proto *f) {
|
||||||
int i, n;
|
int i, n;
|
||||||
n = LoadInt(S);
|
n = LoadInt(S);
|
||||||
f->upvalues = luaM_newvector(S->L, n, Upvaldesc);
|
f->upvalues = luaM_newvector(S->L, n, Upvaldesc);
|
||||||
@@ -173,7 +173,7 @@ static void LoadUpvalues (LoadState *S, SharedProto *f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void LoadDebug (LoadState *S, SharedProto *f) {
|
static void LoadDebug (LoadState *S, Proto *f) {
|
||||||
int i, n;
|
int i, n;
|
||||||
n = LoadInt(S);
|
n = LoadInt(S);
|
||||||
f->lineinfo = luaM_newvector(S->L, n, int);
|
f->lineinfo = luaM_newvector(S->L, n, int);
|
||||||
@@ -195,8 +195,7 @@ static void LoadDebug (LoadState *S, SharedProto *f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void LoadFunction (LoadState *S, Proto *fp, TString *psource) {
|
static void LoadFunction (LoadState *S, Proto *f, TString *psource) {
|
||||||
SharedProto *f = fp->sp;
|
|
||||||
f->source = LoadString(S);
|
f->source = LoadString(S);
|
||||||
if (f->source == NULL) /* no source in dump? */
|
if (f->source == NULL) /* no source in dump? */
|
||||||
f->source = psource; /* reuse parent's source */
|
f->source = psource; /* reuse parent's source */
|
||||||
@@ -206,9 +205,9 @@ static void LoadFunction (LoadState *S, Proto *fp, TString *psource) {
|
|||||||
f->is_vararg = LoadByte(S);
|
f->is_vararg = LoadByte(S);
|
||||||
f->maxstacksize = LoadByte(S);
|
f->maxstacksize = LoadByte(S);
|
||||||
LoadCode(S, f);
|
LoadCode(S, f);
|
||||||
LoadConstants(S, fp);
|
LoadConstants(S, f);
|
||||||
LoadUpvalues(S, f);
|
LoadUpvalues(S, f);
|
||||||
LoadProtos(S, fp);
|
LoadProtos(S, f);
|
||||||
LoadDebug(S, f);
|
LoadDebug(S, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,7 +268,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, Mbuffer *buff,
|
|||||||
cl = luaF_newLclosure(L, LoadByte(&S));
|
cl = luaF_newLclosure(L, LoadByte(&S));
|
||||||
setclLvalue(L, L->top, cl);
|
setclLvalue(L, L->top, cl);
|
||||||
incr_top(L);
|
incr_top(L);
|
||||||
cl->p = luaF_newproto(L, NULL);
|
cl->p = luaF_newproto(L);
|
||||||
LoadFunction(&S, cl->p, NULL);
|
LoadFunction(&S, cl->p, NULL);
|
||||||
lua_assert(cl->nupvalues == cl->p->sizeupvalues);
|
lua_assert(cl->nupvalues == cl->p->sizeupvalues);
|
||||||
luai_verifycode(L, buff, cl->p);
|
luai_verifycode(L, buff, cl->p);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lutf8lib.c,v 1.13 2014/11/02 19:19:04 roberto Exp $
|
** $Id: lutf8lib.c,v 1.15 2015/03/28 19:16:55 roberto Exp $
|
||||||
** Standard library for UTF-8 manipulation
|
** Standard library for UTF-8 manipulation
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ static lua_Integer u_posrelat (lua_Integer pos, size_t len) {
|
|||||||
** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid.
|
** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid.
|
||||||
*/
|
*/
|
||||||
static const char *utf8_decode (const char *o, int *val) {
|
static const char *utf8_decode (const char *o, int *val) {
|
||||||
static unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF};
|
static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF};
|
||||||
const unsigned char *s = (const unsigned char *)o;
|
const unsigned char *s = (const unsigned char *)o;
|
||||||
unsigned int c = s[0];
|
unsigned int c = s[0];
|
||||||
unsigned int res = 0; /* final result */
|
unsigned int res = 0; /* final result */
|
||||||
@@ -106,9 +107,9 @@ static int codepoint (lua_State *L) {
|
|||||||
luaL_argcheck(L, posi >= 1, 2, "out of range");
|
luaL_argcheck(L, posi >= 1, 2, "out of range");
|
||||||
luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range");
|
luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range");
|
||||||
if (posi > pose) return 0; /* empty interval; return no values */
|
if (posi > pose) return 0; /* empty interval; return no values */
|
||||||
n = (int)(pose - posi + 1);
|
if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */
|
||||||
if (posi + n <= pose) /* (lua_Integer -> int) overflow? */
|
|
||||||
return luaL_error(L, "string slice too long");
|
return luaL_error(L, "string slice too long");
|
||||||
|
n = (int)(pose - posi) + 1;
|
||||||
luaL_checkstack(L, n, "string slice too long");
|
luaL_checkstack(L, n, "string slice too long");
|
||||||
n = 0;
|
n = 0;
|
||||||
se = s + pose;
|
se = s + pose;
|
||||||
@@ -234,7 +235,7 @@ static int iter_codes (lua_State *L) {
|
|||||||
#define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*"
|
#define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*"
|
||||||
|
|
||||||
|
|
||||||
static struct luaL_Reg funcs[] = {
|
static const luaL_Reg funcs[] = {
|
||||||
{"offset", byteoffset},
|
{"offset", byteoffset},
|
||||||
{"codepoint", codepoint},
|
{"codepoint", codepoint},
|
||||||
{"char", utfchar},
|
{"char", utfchar},
|
||||||
@@ -248,7 +249,7 @@ static struct luaL_Reg funcs[] = {
|
|||||||
|
|
||||||
LUAMOD_API int luaopen_utf8 (lua_State *L) {
|
LUAMOD_API int luaopen_utf8 (lua_State *L) {
|
||||||
luaL_newlib(L, funcs);
|
luaL_newlib(L, funcs);
|
||||||
lua_pushliteral(L, UTF8PATT);
|
lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1);
|
||||||
lua_setfield(L, -2, "charpattern");
|
lua_setfield(L, -2, "charpattern");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
265
3rd/lua/lvm.c
265
3rd/lua/lvm.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lvm.c,v 2.232 2014/12/27 20:30:38 roberto Exp $
|
** $Id: lvm.c,v 2.245 2015/06/09 15:53:35 roberto Exp $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -9,8 +9,9 @@
|
|||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -30,47 +31,38 @@
|
|||||||
#include "lvm.h"
|
#include "lvm.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** You can define LUA_FLOORN2I if you want to convert floats to integers
|
|
||||||
** by flooring them (instead of raising an error if they are not
|
|
||||||
** integral values)
|
|
||||||
*/
|
|
||||||
#if !defined(LUA_FLOORN2I)
|
|
||||||
#define LUA_FLOORN2I 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* limit for table tag-method chains (to avoid loops) */
|
/* limit for table tag-method chains (to avoid loops) */
|
||||||
#define MAXTAGLOOP 2000
|
#define MAXTAGLOOP 2000
|
||||||
|
|
||||||
/* Add by skynet */
|
|
||||||
lua_State * skynet_sig_L = NULL;
|
|
||||||
|
|
||||||
LUA_API void
|
|
||||||
lua_checksig_(lua_State *L) {
|
|
||||||
if (skynet_sig_L == G(L)->mainthread) {
|
|
||||||
skynet_sig_L = NULL;
|
|
||||||
lua_pushnil(L);
|
|
||||||
lua_error(L);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Similar to 'tonumber', but does not attempt to convert strings and
|
** 'l_intfitsf' checks whether a given integer can be converted to a
|
||||||
** ensure correct precision (no extra bits). Used in comparisons.
|
** float without rounding. Used in comparisons. Left undefined if
|
||||||
|
** all integers fit in a float precisely.
|
||||||
*/
|
*/
|
||||||
static int tofloat (const TValue *obj, lua_Number *n) {
|
#if !defined(l_intfitsf)
|
||||||
if (ttisfloat(obj)) *n = fltvalue(obj);
|
|
||||||
else if (ttisinteger(obj)) {
|
/* number of bits in the mantissa of a float */
|
||||||
volatile lua_Number x = cast_num(ivalue(obj)); /* avoid extra precision */
|
#define NBM (l_mathlim(MANT_DIG))
|
||||||
*n = x;
|
|
||||||
}
|
/*
|
||||||
else {
|
** Check whether some integers may not fit in a float, that is, whether
|
||||||
*n = 0; /* to avoid warnings */
|
** (maxinteger >> NBM) > 0 (that implies (1 << NBM) <= maxinteger).
|
||||||
return 0;
|
** (The shifts are done in parts to avoid shifting by more than the size
|
||||||
}
|
** of an integer. In a worst case, NBM == 113 for long double and
|
||||||
return 1;
|
** sizeof(integer) == 32.)
|
||||||
}
|
*/
|
||||||
|
#if ((((LUA_MAXINTEGER >> (NBM / 4)) >> (NBM / 4)) >> (NBM / 4)) \
|
||||||
|
>> (NBM - (3 * (NBM / 4)))) > 0
|
||||||
|
|
||||||
|
#define l_intfitsf(i) \
|
||||||
|
(-((lua_Integer)1 << NBM) <= (i) && (i) <= ((lua_Integer)1 << NBM))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -84,7 +76,7 @@ int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (cvt2num(obj) && /* string convertible to number? */
|
else if (cvt2num(obj) && /* string convertible to number? */
|
||||||
luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) {
|
luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
|
||||||
*n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */
|
*n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -99,7 +91,7 @@ int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
|
|||||||
** mode == 1: takes the floor of the number
|
** mode == 1: takes the floor of the number
|
||||||
** mode == 2: takes the ceil of the number
|
** mode == 2: takes the ceil of the number
|
||||||
*/
|
*/
|
||||||
static int tointeger_aux (const TValue *obj, lua_Integer *p, int mode) {
|
int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) {
|
||||||
TValue v;
|
TValue v;
|
||||||
again:
|
again:
|
||||||
if (ttisfloat(obj)) {
|
if (ttisfloat(obj)) {
|
||||||
@@ -117,7 +109,7 @@ static int tointeger_aux (const TValue *obj, lua_Integer *p, int mode) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (cvt2num(obj) &&
|
else if (cvt2num(obj) &&
|
||||||
luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) {
|
luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
|
||||||
obj = &v;
|
obj = &v;
|
||||||
goto again; /* convert result from 'luaO_str2num' to an integer */
|
goto again; /* convert result from 'luaO_str2num' to an integer */
|
||||||
}
|
}
|
||||||
@@ -125,14 +117,6 @@ static int tointeger_aux (const TValue *obj, lua_Integer *p, int mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** try to convert a value to an integer
|
|
||||||
*/
|
|
||||||
int luaV_tointeger_ (const TValue *obj, lua_Integer *p) {
|
|
||||||
return tointeger_aux(obj, p, LUA_FLOORN2I);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Try to convert a 'for' limit to an integer, preserving the
|
** Try to convert a 'for' limit to an integer, preserving the
|
||||||
** semantics of the loop.
|
** semantics of the loop.
|
||||||
@@ -151,11 +135,11 @@ int luaV_tointeger_ (const TValue *obj, lua_Integer *p) {
|
|||||||
static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step,
|
static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step,
|
||||||
int *stopnow) {
|
int *stopnow) {
|
||||||
*stopnow = 0; /* usually, let loops run */
|
*stopnow = 0; /* usually, let loops run */
|
||||||
if (!tointeger_aux(obj, p, (step < 0 ? 2 : 1))) { /* not fit in integer? */
|
if (!luaV_tointeger(obj, p, (step < 0 ? 2 : 1))) { /* not fit in integer? */
|
||||||
lua_Number n; /* try to convert to float */
|
lua_Number n; /* try to convert to float */
|
||||||
if (!tonumber(obj, &n)) /* cannot convert to float? */
|
if (!tonumber(obj, &n)) /* cannot convert to float? */
|
||||||
return 0; /* not a number */
|
return 0; /* not a number */
|
||||||
if (n > 0) { /* if true, float is larger than max integer */
|
if (luai_numlt(0, n)) { /* if true, float is larger than max integer */
|
||||||
*p = LUA_MAXINTEGER;
|
*p = LUA_MAXINTEGER;
|
||||||
if (step < 0) *stopnow = 1;
|
if (step < 0) *stopnow = 1;
|
||||||
}
|
}
|
||||||
@@ -250,9 +234,9 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
|
|||||||
*/
|
*/
|
||||||
static int l_strcmp (const TString *ls, const TString *rs) {
|
static int l_strcmp (const TString *ls, const TString *rs) {
|
||||||
const char *l = getstr(ls);
|
const char *l = getstr(ls);
|
||||||
size_t ll = ls->len;
|
size_t ll = tsslen(ls);
|
||||||
const char *r = getstr(rs);
|
const char *r = getstr(rs);
|
||||||
size_t lr = rs->len;
|
size_t lr = tsslen(rs);
|
||||||
for (;;) { /* for each segment */
|
for (;;) { /* for each segment */
|
||||||
int temp = strcoll(l, r);
|
int temp = strcoll(l, r);
|
||||||
if (temp != 0) /* not equal? */
|
if (temp != 0) /* not equal? */
|
||||||
@@ -271,16 +255,103 @@ static int l_strcmp (const TString *ls, const TString *rs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Check whether integer 'i' is less than float 'f'. If 'i' has an
|
||||||
|
** exact representation as a float ('l_intfitsf'), compare numbers as
|
||||||
|
** floats. Otherwise, if 'f' is outside the range for integers, result
|
||||||
|
** is trivial. Otherwise, compare them as integers. (When 'i' has no
|
||||||
|
** float representation, either 'f' is "far away" from 'i' or 'f' has
|
||||||
|
** no precision left for a fractional part; either way, how 'f' is
|
||||||
|
** truncated is irrelevant.) When 'f' is NaN, comparisons must result
|
||||||
|
** in false.
|
||||||
|
*/
|
||||||
|
static int LTintfloat (lua_Integer i, lua_Number f) {
|
||||||
|
#if defined(l_intfitsf)
|
||||||
|
if (!l_intfitsf(i)) {
|
||||||
|
if (f >= -cast_num(LUA_MININTEGER)) /* -minint == maxint + 1 */
|
||||||
|
return 1; /* f >= maxint + 1 > i */
|
||||||
|
else if (f > cast_num(LUA_MININTEGER)) /* minint < f <= maxint ? */
|
||||||
|
return (i < cast(lua_Integer, f)); /* compare them as integers */
|
||||||
|
else /* f <= minint <= i (or 'f' is NaN) --> not(i < f) */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return luai_numlt(cast_num(i), f); /* compare them as floats */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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) {
|
||||||
|
#if defined(l_intfitsf)
|
||||||
|
if (!l_intfitsf(i)) {
|
||||||
|
if (f >= -cast_num(LUA_MININTEGER)) /* -minint == maxint + 1 */
|
||||||
|
return 1; /* f >= maxint + 1 > i */
|
||||||
|
else if (f >= cast_num(LUA_MININTEGER)) /* minint <= f <= maxint ? */
|
||||||
|
return (i <= cast(lua_Integer, f)); /* compare them as integers */
|
||||||
|
else /* f < minint <= i (or 'f' is NaN) --> not(i <= f) */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return luai_numle(cast_num(i), f); /* compare them as floats */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return 'l < r', for numbers.
|
||||||
|
*/
|
||||||
|
static int LTnum (const TValue *l, const TValue *r) {
|
||||||
|
if (ttisinteger(l)) {
|
||||||
|
lua_Integer li = ivalue(l);
|
||||||
|
if (ttisinteger(r))
|
||||||
|
return li < ivalue(r); /* both are integers */
|
||||||
|
else /* 'l' is int and 'r' is float */
|
||||||
|
return LTintfloat(li, fltvalue(r)); /* l < r ? */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lua_Number lf = fltvalue(l); /* 'l' must be float */
|
||||||
|
if (ttisfloat(r))
|
||||||
|
return luai_numlt(lf, fltvalue(r)); /* both are float */
|
||||||
|
else if (luai_numisnan(lf)) /* 'r' is int and 'l' is float */
|
||||||
|
return 0; /* NaN < i is always false */
|
||||||
|
else /* without NaN, (l < r) <--> not(r <= l) */
|
||||||
|
return !LEintfloat(ivalue(r), lf); /* not (r <= l) ? */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return 'l <= r', for numbers.
|
||||||
|
*/
|
||||||
|
static int LEnum (const TValue *l, const TValue *r) {
|
||||||
|
if (ttisinteger(l)) {
|
||||||
|
lua_Integer li = ivalue(l);
|
||||||
|
if (ttisinteger(r))
|
||||||
|
return li <= ivalue(r); /* both are integers */
|
||||||
|
else /* 'l' is int and 'r' is float */
|
||||||
|
return LEintfloat(li, fltvalue(r)); /* l <= r ? */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lua_Number lf = fltvalue(l); /* 'l' must be float */
|
||||||
|
if (ttisfloat(r))
|
||||||
|
return luai_numle(lf, fltvalue(r)); /* both are float */
|
||||||
|
else if (luai_numisnan(lf)) /* 'r' is int and 'l' is float */
|
||||||
|
return 0; /* NaN <= i is always false */
|
||||||
|
else /* without NaN, (l <= r) <--> not(r < l) */
|
||||||
|
return !LTintfloat(ivalue(r), lf); /* not (r < l) ? */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Main operation less than; return 'l < r'.
|
** Main operation less than; return 'l < r'.
|
||||||
*/
|
*/
|
||||||
int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
|
int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
|
||||||
int res;
|
int res;
|
||||||
lua_Number nl, nr;
|
if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */
|
||||||
if (ttisinteger(l) && ttisinteger(r)) /* both operands are integers? */
|
return LTnum(l, r);
|
||||||
return (ivalue(l) < ivalue(r));
|
|
||||||
else if (tofloat(l, &nl) && tofloat(r, &nr)) /* both are numbers? */
|
|
||||||
return luai_numlt(nl, nr);
|
|
||||||
else if (ttisstring(l) && ttisstring(r)) /* both are strings? */
|
else if (ttisstring(l) && ttisstring(r)) /* both are strings? */
|
||||||
return l_strcmp(tsvalue(l), tsvalue(r)) < 0;
|
return l_strcmp(tsvalue(l), tsvalue(r)) < 0;
|
||||||
else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0) /* no metamethod? */
|
else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0) /* no metamethod? */
|
||||||
@@ -290,18 +361,20 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Main operation less than or equal to; return 'l <= r'.
|
** Main operation less than or equal to; return 'l <= r'. If it needs
|
||||||
|
** a metamethod and there is no '__le', try '__lt', based on
|
||||||
|
** l <= r iff !(r < l) (assuming a total order). If the metamethod
|
||||||
|
** yields during this substitution, the continuation has to know
|
||||||
|
** about it (to negate the result of r<l); bit CIST_LEQ in the call
|
||||||
|
** status keeps that information.
|
||||||
*/
|
*/
|
||||||
int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
|
int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
|
||||||
int res;
|
int res;
|
||||||
lua_Number nl, nr;
|
if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */
|
||||||
if (ttisinteger(l) && ttisinteger(r)) /* both operands are integers? */
|
return LEnum(l, r);
|
||||||
return (ivalue(l) <= ivalue(r));
|
|
||||||
else if (tofloat(l, &nl) && tofloat(r, &nr)) /* both are numbers? */
|
|
||||||
return luai_numle(nl, nr);
|
|
||||||
else if (ttisstring(l) && ttisstring(r)) /* both are strings? */
|
else if (ttisstring(l) && ttisstring(r)) /* both are strings? */
|
||||||
return l_strcmp(tsvalue(l), tsvalue(r)) <= 0;
|
return l_strcmp(tsvalue(l), tsvalue(r)) <= 0;
|
||||||
else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try 'le' */
|
else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* try 'le' */
|
||||||
return res;
|
return res;
|
||||||
else { /* try 'lt': */
|
else { /* try 'lt': */
|
||||||
L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */
|
L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */
|
||||||
@@ -314,9 +387,8 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Main operation for equality of Lua values; return 't1 == t2'.
|
** Main operation for equality of Lua values; return 't1 == t2'.
|
||||||
** L == NULL means raw equality (no metamethods)
|
** L == NULL means raw equality (no metamethods)
|
||||||
*/
|
*/
|
||||||
int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
|
int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
|
||||||
@@ -325,10 +397,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
|
|||||||
if (ttnov(t1) != ttnov(t2) || ttnov(t1) != LUA_TNUMBER)
|
if (ttnov(t1) != ttnov(t2) || ttnov(t1) != LUA_TNUMBER)
|
||||||
return 0; /* only numbers can be equal with different variants */
|
return 0; /* only numbers can be equal with different variants */
|
||||||
else { /* two numbers with different variants */
|
else { /* two numbers with different variants */
|
||||||
lua_Number n1, n2; /* compare them as floats */
|
lua_Integer i1, i2; /* compare them as integers */
|
||||||
lua_assert(ttisnumber(t1) && ttisnumber(t2));
|
return (tointeger(t1, &i1) && tointeger(t2, &i2) && i1 == i2);
|
||||||
cast_void(tofloat(t1, &n1)); cast_void(tofloat(t2, &n2));
|
|
||||||
return luai_numeq(n1, n2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* values have same type and same variant */
|
/* values have same type and same variant */
|
||||||
@@ -371,6 +441,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
|
|||||||
#define tostring(L,o) \
|
#define tostring(L,o) \
|
||||||
(ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1)))
|
(ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1)))
|
||||||
|
|
||||||
|
#define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Main operation for concatenation: concat 'total' values in the stack,
|
** Main operation for concatenation: concat 'total' values in the stack,
|
||||||
** from 'L->top - total' up to 'L->top - 1'.
|
** from 'L->top - total' up to 'L->top - 1'.
|
||||||
@@ -382,19 +454,19 @@ void luaV_concat (lua_State *L, int total) {
|
|||||||
int n = 2; /* number of elements handled in this pass (at least 2) */
|
int n = 2; /* number of elements handled in this pass (at least 2) */
|
||||||
if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1))
|
if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1))
|
||||||
luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);
|
luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);
|
||||||
else if (tsvalue(top-1)->len == 0) /* second operand is empty? */
|
else if (isemptystr(top - 1)) /* second operand is empty? */
|
||||||
cast_void(tostring(L, top - 2)); /* result is first operand */
|
cast_void(tostring(L, top - 2)); /* result is first operand */
|
||||||
else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) {
|
else if (isemptystr(top - 2)) { /* first operand is an empty string? */
|
||||||
setobjs2s(L, top - 2, top - 1); /* result is second op. */
|
setobjs2s(L, top - 2, top - 1); /* result is second op. */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* at least two non-empty string values; get as many as possible */
|
/* at least two non-empty string values; get as many as possible */
|
||||||
size_t tl = tsvalue(top-1)->len;
|
size_t tl = vslen(top - 1);
|
||||||
char *buffer;
|
char *buffer;
|
||||||
int i;
|
int i;
|
||||||
/* collect total length */
|
/* collect total length */
|
||||||
for (i = 1; i < total && tostring(L, top-i-1); i++) {
|
for (i = 1; i < total && tostring(L, top-i-1); i++) {
|
||||||
size_t l = tsvalue(top-i-1)->len;
|
size_t l = vslen(top - i - 1);
|
||||||
if (l >= (MAX_SIZE/sizeof(char)) - tl)
|
if (l >= (MAX_SIZE/sizeof(char)) - tl)
|
||||||
luaG_runerror(L, "string length overflow");
|
luaG_runerror(L, "string length overflow");
|
||||||
tl += l;
|
tl += l;
|
||||||
@@ -403,7 +475,7 @@ void luaV_concat (lua_State *L, int total) {
|
|||||||
tl = 0;
|
tl = 0;
|
||||||
n = i;
|
n = i;
|
||||||
do { /* copy all strings to buffer */
|
do { /* copy all strings to buffer */
|
||||||
size_t l = tsvalue(top-i)->len;
|
size_t l = vslen(top - i);
|
||||||
memcpy(buffer+tl, svalue(top-i), l * sizeof(char));
|
memcpy(buffer+tl, svalue(top-i), l * sizeof(char));
|
||||||
tl += l;
|
tl += l;
|
||||||
} while (--i > 0);
|
} while (--i > 0);
|
||||||
@@ -420,7 +492,7 @@ void luaV_concat (lua_State *L, int total) {
|
|||||||
*/
|
*/
|
||||||
void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
|
void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
|
||||||
const TValue *tm;
|
const TValue *tm;
|
||||||
switch (ttnov(rb)) {
|
switch (ttype(rb)) {
|
||||||
case LUA_TTABLE: {
|
case LUA_TTABLE: {
|
||||||
Table *h = hvalue(rb);
|
Table *h = hvalue(rb);
|
||||||
tm = fasttm(L, h->metatable, TM_LEN);
|
tm = fasttm(L, h->metatable, TM_LEN);
|
||||||
@@ -428,8 +500,12 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
|
|||||||
setivalue(ra, luaH_getn(h)); /* else primitive len */
|
setivalue(ra, luaH_getn(h)); /* else primitive len */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case LUA_TSTRING: {
|
case LUA_TSHRSTR: {
|
||||||
setivalue(ra, tsvalue(rb)->len);
|
setivalue(ra, tsvalue(rb)->shrlen);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case LUA_TLNGSTR: {
|
||||||
|
setivalue(ra, tsvalue(rb)->u.lnglen);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default: { /* try metamethod */
|
default: { /* try metamethod */
|
||||||
@@ -465,7 +541,7 @@ lua_Integer luaV_div (lua_State *L, lua_Integer m, lua_Integer n) {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Integer modulus; return 'm % n'. (Assume that C '%' with
|
** Integer modulus; return 'm % n'. (Assume that C '%' with
|
||||||
** negative operands follows C99 behavior. See previous comment
|
** negative operands follows C99 behavior. See previous comment
|
||||||
** about luaV_div.)
|
** about luaV_div.)
|
||||||
*/
|
*/
|
||||||
@@ -510,8 +586,8 @@ lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) {
|
|||||||
static LClosure *getcached (Proto *p, UpVal **encup, StkId base) {
|
static LClosure *getcached (Proto *p, UpVal **encup, StkId base) {
|
||||||
LClosure *c = p->cache;
|
LClosure *c = p->cache;
|
||||||
if (c != NULL) { /* is there a cached closure? */
|
if (c != NULL) { /* is there a cached closure? */
|
||||||
int nup = p->sp->sizeupvalues;
|
int nup = p->sizeupvalues;
|
||||||
Upvaldesc *uv = p->sp->upvalues;
|
Upvaldesc *uv = p->upvalues;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < nup; i++) { /* check whether it has right upvalues */
|
for (i = 0; i < nup; i++) { /* check whether it has right upvalues */
|
||||||
TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v;
|
TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v;
|
||||||
@@ -531,8 +607,8 @@ static LClosure *getcached (Proto *p, UpVal **encup, StkId base) {
|
|||||||
*/
|
*/
|
||||||
static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
|
static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
|
||||||
StkId ra) {
|
StkId ra) {
|
||||||
int nup = p->sp->sizeupvalues;
|
int nup = p->sizeupvalues;
|
||||||
Upvaldesc *uv = p->sp->upvalues;
|
Upvaldesc *uv = p->upvalues;
|
||||||
int i;
|
int i;
|
||||||
LClosure *ncl = luaF_newLclosure(L, nup);
|
LClosure *ncl = luaF_newLclosure(L, nup);
|
||||||
ncl->p = p;
|
ncl->p = p;
|
||||||
@@ -624,7 +700,7 @@ void luaV_finishOp (lua_State *L) {
|
|||||||
** some macros for common tasks in 'luaV_execute'
|
** some macros for common tasks in 'luaV_execute'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined luai_runtimecheck
|
#if !defined(luai_runtimecheck)
|
||||||
#define luai_runtimecheck(L, c) /* void */
|
#define luai_runtimecheck(L, c) /* void */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -760,7 +836,7 @@ void luaV_execute (lua_State *L) {
|
|||||||
Protect(luaV_gettable(L, rb, RKC(i), ra));
|
Protect(luaV_gettable(L, rb, RKC(i), ra));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_ADD) {
|
vmcase(OP_ADD) {
|
||||||
TValue *rb = RKB(i);
|
TValue *rb = RKB(i);
|
||||||
TValue *rc = RKC(i);
|
TValue *rc = RKC(i);
|
||||||
lua_Number nb; lua_Number nc;
|
lua_Number nb; lua_Number nc;
|
||||||
@@ -945,14 +1021,13 @@ void luaV_execute (lua_State *L) {
|
|||||||
L->top = base + c + 1; /* mark the end of concat operands */
|
L->top = base + c + 1; /* mark the end of concat operands */
|
||||||
Protect(luaV_concat(L, c - b + 1));
|
Protect(luaV_concat(L, c - b + 1));
|
||||||
ra = RA(i); /* 'luav_concat' may invoke TMs and move the stack */
|
ra = RA(i); /* 'luav_concat' may invoke TMs and move the stack */
|
||||||
rb = b + base;
|
rb = base + b;
|
||||||
setobjs2s(L, ra, rb);
|
setobjs2s(L, ra, rb);
|
||||||
checkGC(L, (ra >= rb ? ra + 1 : rb));
|
checkGC(L, (ra >= rb ? ra + 1 : rb));
|
||||||
L->top = ci->top; /* restore top */
|
L->top = ci->top; /* restore top */
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_JMP) {
|
vmcase(OP_JMP) {
|
||||||
lua_checksig(L);
|
|
||||||
dojump(ci, i, 0);
|
dojump(ci, i, 0);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
@@ -1005,7 +1080,6 @@ void luaV_execute (lua_State *L) {
|
|||||||
vmcase(OP_CALL) {
|
vmcase(OP_CALL) {
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
int nresults = GETARG_C(i) - 1;
|
int nresults = GETARG_C(i) - 1;
|
||||||
lua_checksig(L);
|
|
||||||
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
||||||
if (luaD_precall(L, ra, nresults)) { /* C function? */
|
if (luaD_precall(L, ra, nresults)) { /* C function? */
|
||||||
if (nresults >= 0) L->top = ci->top; /* adjust results */
|
if (nresults >= 0) L->top = ci->top; /* adjust results */
|
||||||
@@ -1020,7 +1094,6 @@ void luaV_execute (lua_State *L) {
|
|||||||
}
|
}
|
||||||
vmcase(OP_TAILCALL) {
|
vmcase(OP_TAILCALL) {
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
lua_checksig(L);
|
|
||||||
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
||||||
lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
|
lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
|
||||||
if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */
|
if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */
|
||||||
@@ -1032,10 +1105,10 @@ void luaV_execute (lua_State *L) {
|
|||||||
StkId nfunc = nci->func; /* called function */
|
StkId nfunc = nci->func; /* called function */
|
||||||
StkId ofunc = oci->func; /* caller function */
|
StkId ofunc = oci->func; /* caller function */
|
||||||
/* last stack slot filled by 'precall' */
|
/* last stack slot filled by 'precall' */
|
||||||
StkId lim = nci->u.l.base + getproto(nfunc)->sp->numparams;
|
StkId lim = nci->u.l.base + getproto(nfunc)->numparams;
|
||||||
int aux;
|
int aux;
|
||||||
/* close all upvalues from previous call */
|
/* close all upvalues from previous call */
|
||||||
if (cl->p->sp->sizep > 0) luaF_close(L, oci->u.l.base);
|
if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base);
|
||||||
/* move new frame into old one */
|
/* move new frame into old one */
|
||||||
for (aux = 0; nfunc + aux < lim; aux++)
|
for (aux = 0; nfunc + aux < lim; aux++)
|
||||||
setobjs2s(L, ofunc + aux, nfunc + aux);
|
setobjs2s(L, ofunc + aux, nfunc + aux);
|
||||||
@@ -1051,9 +1124,8 @@ void luaV_execute (lua_State *L) {
|
|||||||
}
|
}
|
||||||
vmcase(OP_RETURN) {
|
vmcase(OP_RETURN) {
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
if (b != 0) L->top = ra+b-1;
|
if (cl->p->sizep > 0) luaF_close(L, base);
|
||||||
if (cl->p->sp->sizep > 0) luaF_close(L, base);
|
b = luaD_poscall(L, ra, (b != 0 ? b - 1 : L->top - ra));
|
||||||
b = luaD_poscall(L, ra);
|
|
||||||
if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */
|
if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */
|
||||||
return; /* external invocation: return */
|
return; /* external invocation: return */
|
||||||
else { /* invocation via reentry: continue execution */
|
else { /* invocation via reentry: continue execution */
|
||||||
@@ -1071,7 +1143,7 @@ void luaV_execute (lua_State *L) {
|
|||||||
lua_Integer limit = ivalue(ra + 1);
|
lua_Integer limit = ivalue(ra + 1);
|
||||||
if ((0 < step) ? (idx <= limit) : (limit <= idx)) {
|
if ((0 < step) ? (idx <= limit) : (limit <= idx)) {
|
||||||
ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
|
ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
|
||||||
setivalue(ra, idx); /* update internal index... */
|
chgivalue(ra, idx); /* update internal index... */
|
||||||
setivalue(ra + 3, idx); /* ...and external index */
|
setivalue(ra + 3, idx); /* ...and external index */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1082,7 +1154,7 @@ void luaV_execute (lua_State *L) {
|
|||||||
if (luai_numlt(0, step) ? luai_numle(idx, limit)
|
if (luai_numlt(0, step) ? luai_numle(idx, limit)
|
||||||
: luai_numle(limit, idx)) {
|
: luai_numle(limit, idx)) {
|
||||||
ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
|
ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
|
||||||
setfltvalue(ra, idx); /* update internal index... */
|
chgfltvalue(ra, idx); /* update internal index... */
|
||||||
setfltvalue(ra + 3, idx); /* ...and external index */
|
setfltvalue(ra + 3, idx); /* ...and external index */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1131,7 +1203,6 @@ void luaV_execute (lua_State *L) {
|
|||||||
}
|
}
|
||||||
vmcase(OP_TFORLOOP) {
|
vmcase(OP_TFORLOOP) {
|
||||||
l_tforloop:
|
l_tforloop:
|
||||||
lua_checksig(L);
|
|
||||||
if (!ttisnil(ra + 1)) { /* continue loop? */
|
if (!ttisnil(ra + 1)) { /* continue loop? */
|
||||||
setobjs2s(L, ra, ra + 1); /* save control variable */
|
setobjs2s(L, ra, ra + 1); /* save control variable */
|
||||||
ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
|
ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
|
||||||
@@ -1174,7 +1245,7 @@ void luaV_execute (lua_State *L) {
|
|||||||
vmcase(OP_VARARG) {
|
vmcase(OP_VARARG) {
|
||||||
int b = GETARG_B(i) - 1;
|
int b = GETARG_B(i) - 1;
|
||||||
int j;
|
int j;
|
||||||
int n = cast_int(base - ci->func) - cl->p->sp->numparams - 1;
|
int n = cast_int(base - ci->func) - cl->p->numparams - 1;
|
||||||
if (b < 0) { /* B == 0? */
|
if (b < 0) { /* B == 0? */
|
||||||
b = n; /* get all var. arguments */
|
b = n; /* get all var. arguments */
|
||||||
Protect(luaD_checkstack(L, n));
|
Protect(luaD_checkstack(L, n));
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lvm.h,v 2.34 2014/08/01 17:24:02 roberto Exp $
|
** $Id: lvm.h,v 2.35 2015/02/20 14:27:53 roberto Exp $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -27,11 +27,21 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** You can define LUA_FLOORN2I if you want to convert floats to integers
|
||||||
|
** by flooring them (instead of raising an error if they are not
|
||||||
|
** integral values)
|
||||||
|
*/
|
||||||
|
#if !defined(LUA_FLOORN2I)
|
||||||
|
#define LUA_FLOORN2I 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define tonumber(o,n) \
|
#define tonumber(o,n) \
|
||||||
(ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n))
|
(ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n))
|
||||||
|
|
||||||
#define tointeger(o,i) \
|
#define tointeger(o,i) \
|
||||||
(ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger_(o,i))
|
(ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I))
|
||||||
|
|
||||||
#define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2))
|
#define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2))
|
||||||
|
|
||||||
@@ -42,7 +52,7 @@ LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2);
|
|||||||
LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
|
LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
|
||||||
LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
|
LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
|
||||||
LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n);
|
LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n);
|
||||||
LUAI_FUNC int luaV_tointeger_ (const TValue *obj, lua_Integer *p);
|
LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode);
|
||||||
LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
|
LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
|
||||||
StkId val);
|
StkId val);
|
||||||
LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
|
LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
|
||||||
|
|||||||
Reference in New Issue
Block a user