mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 12:20:41 +00:00
Compare commits
45 Commits
v1.0.0-rc2
...
v1.0.0-rc3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed1a8313f4 | ||
|
|
c450b7b5d7 | ||
|
|
56846b7dda | ||
|
|
fb232cc43e | ||
|
|
a5c79cc4bd | ||
|
|
4b96ade660 | ||
|
|
76d1e6fa1f | ||
|
|
a6299a0748 | ||
|
|
6cc558bb82 | ||
|
|
84b08bf286 | ||
|
|
4ada09b93c | ||
|
|
2862568eca | ||
|
|
ed2e16a346 | ||
|
|
45d46b9072 | ||
|
|
4924c6d30b | ||
|
|
6b2eb80188 | ||
|
|
298e4baf0e | ||
|
|
c5fb93823a | ||
|
|
f238113677 | ||
|
|
f56d777cc2 | ||
|
|
b124d4c1b8 | ||
|
|
4fe098713f | ||
|
|
146f8ea09d | ||
|
|
69b5bd8c13 | ||
|
|
dd7e962c94 | ||
|
|
5332021086 | ||
|
|
8de3149485 | ||
|
|
e3fee604e1 | ||
|
|
dd152fc910 | ||
|
|
c4b45acae3 | ||
|
|
cf50a582f2 | ||
|
|
ca5e855c34 | ||
|
|
13d1d9fc9d | ||
|
|
242ff32bca | ||
|
|
ba451c1cd2 | ||
|
|
e5490522ce | ||
|
|
ae717c3e7d | ||
|
|
1a7df9108a | ||
|
|
7771e180ec | ||
|
|
82bbb1c944 | ||
|
|
bacaf10f1b | ||
|
|
6303886b8c | ||
|
|
30cbcfd013 | ||
|
|
a39e822184 | ||
|
|
716ecccaed |
Submodule 3rd/jemalloc updated: 91010a9e2e...e02b83cc5e
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lapi.c,v 2.257 2015/11/02 18:48:07 roberto Exp $
|
** $Id: lapi.c,v 2.259 2016/02/29 14:27:14 roberto Exp $
|
||||||
** Lua API
|
** Lua API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -379,9 +379,9 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
lua_lock(L); /* 'luaO_tostring' may create a new string */
|
lua_lock(L); /* 'luaO_tostring' may create a new string */
|
||||||
|
luaO_tostring(L, o);
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
o = index2addr(L, idx); /* previous call may reallocate the stack */
|
o = index2addr(L, idx); /* previous call may reallocate the stack */
|
||||||
luaO_tostring(L, o);
|
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
if (len != NULL)
|
if (len != NULL)
|
||||||
@@ -480,10 +480,10 @@ LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
|
|||||||
LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
|
LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
|
||||||
TString *ts;
|
TString *ts;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
luaC_checkGC(L);
|
|
||||||
ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
|
ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
|
||||||
setsvalue2s(L, L->top, ts);
|
setsvalue2s(L, L->top, ts);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
|
luaC_checkGC(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return getstr(ts);
|
return getstr(ts);
|
||||||
}
|
}
|
||||||
@@ -495,12 +495,12 @@ LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
|
|||||||
setnilvalue(L->top);
|
setnilvalue(L->top);
|
||||||
else {
|
else {
|
||||||
TString *ts;
|
TString *ts;
|
||||||
luaC_checkGC(L);
|
|
||||||
ts = luaS_new(L, s);
|
ts = luaS_new(L, s);
|
||||||
setsvalue2s(L, L->top, ts);
|
setsvalue2s(L, L->top, ts);
|
||||||
s = getstr(ts); /* internal copy's address */
|
s = getstr(ts); /* internal copy's address */
|
||||||
}
|
}
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
|
luaC_checkGC(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@@ -510,8 +510,8 @@ LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
|
|||||||
va_list argp) {
|
va_list argp) {
|
||||||
const char *ret;
|
const char *ret;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
luaC_checkGC(L);
|
|
||||||
ret = luaO_pushvfstring(L, fmt, argp);
|
ret = luaO_pushvfstring(L, fmt, argp);
|
||||||
|
luaC_checkGC(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -521,10 +521,10 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
|
|||||||
const char *ret;
|
const char *ret;
|
||||||
va_list argp;
|
va_list argp;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
luaC_checkGC(L);
|
|
||||||
va_start(argp, fmt);
|
va_start(argp, fmt);
|
||||||
ret = luaO_pushvfstring(L, fmt, argp);
|
ret = luaO_pushvfstring(L, fmt, argp);
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
|
luaC_checkGC(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -539,7 +539,6 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
|||||||
CClosure *cl;
|
CClosure *cl;
|
||||||
api_checknelems(L, n);
|
api_checknelems(L, n);
|
||||||
api_check(L, n <= MAXUPVAL, "upvalue index too large");
|
api_check(L, n <= MAXUPVAL, "upvalue index too large");
|
||||||
luaC_checkGC(L);
|
|
||||||
cl = luaF_newCclosure(L, n);
|
cl = luaF_newCclosure(L, n);
|
||||||
cl->f = fn;
|
cl->f = fn;
|
||||||
L->top -= n;
|
L->top -= n;
|
||||||
@@ -550,6 +549,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
|||||||
setclCvalue(L, L->top, cl);
|
setclCvalue(L, L->top, cl);
|
||||||
}
|
}
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
|
luaC_checkGC(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,16 +586,16 @@ LUA_API int lua_pushthread (lua_State *L) {
|
|||||||
|
|
||||||
|
|
||||||
static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
|
static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
|
||||||
const TValue *aux;
|
const TValue *slot;
|
||||||
TString *str = luaS_new(L, k);
|
TString *str = luaS_new(L, k);
|
||||||
if (luaV_fastget(L, t, str, aux, luaH_getstr)) {
|
if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
|
||||||
setobj2s(L, L->top, aux);
|
setobj2s(L, L->top, slot);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setsvalue2s(L, L->top, str);
|
setsvalue2s(L, L->top, str);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
luaV_finishget(L, t, L->top - 1, L->top - 1, aux);
|
luaV_finishget(L, t, L->top - 1, L->top - 1, slot);
|
||||||
}
|
}
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ttnov(L->top - 1);
|
return ttnov(L->top - 1);
|
||||||
@@ -627,17 +627,17 @@ LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
|
|||||||
|
|
||||||
LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
|
LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
|
||||||
StkId t;
|
StkId t;
|
||||||
const TValue *aux;
|
const TValue *slot;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = index2addr(L, idx);
|
t = index2addr(L, idx);
|
||||||
if (luaV_fastget(L, t, n, aux, luaH_getint)) {
|
if (luaV_fastget(L, t, n, slot, luaH_getint)) {
|
||||||
setobj2s(L, L->top, aux);
|
setobj2s(L, L->top, slot);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setivalue(L->top, n);
|
setivalue(L->top, n);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
luaV_finishget(L, t, L->top - 1, L->top - 1, aux);
|
luaV_finishget(L, t, L->top - 1, L->top - 1, slot);
|
||||||
}
|
}
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ttnov(L->top - 1);
|
return ttnov(L->top - 1);
|
||||||
@@ -684,12 +684,12 @@ LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
|
|||||||
LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
|
LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
|
||||||
Table *t;
|
Table *t;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
luaC_checkGC(L);
|
|
||||||
t = luaH_new(L);
|
t = luaH_new(L);
|
||||||
sethvalue(L, L->top, t);
|
sethvalue(L, L->top, t);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
if (narray > 0 || nrec > 0)
|
if (narray > 0 || nrec > 0)
|
||||||
luaH_resize(L, t, narray, nrec);
|
luaH_resize(L, t, narray, nrec);
|
||||||
|
luaC_checkGC(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -741,15 +741,15 @@ LUA_API int lua_getuservalue (lua_State *L, int idx) {
|
|||||||
** t[k] = value at the top of the stack (where 'k' is a string)
|
** t[k] = value at the top of the stack (where 'k' is a string)
|
||||||
*/
|
*/
|
||||||
static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
|
static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
|
||||||
const TValue *aux;
|
const TValue *slot;
|
||||||
TString *str = luaS_new(L, k);
|
TString *str = luaS_new(L, k);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
if (luaV_fastset(L, t, str, aux, luaH_getstr, L->top - 1))
|
if (luaV_fastset(L, t, str, slot, luaH_getstr, L->top - 1))
|
||||||
L->top--; /* pop value */
|
L->top--; /* pop value */
|
||||||
else {
|
else {
|
||||||
setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */
|
setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
luaV_finishset(L, t, L->top - 1, L->top - 2, aux);
|
luaV_finishset(L, t, L->top - 1, L->top - 2, slot);
|
||||||
L->top -= 2; /* pop value and key */
|
L->top -= 2; /* pop value and key */
|
||||||
}
|
}
|
||||||
lua_unlock(L); /* lock done by caller */
|
lua_unlock(L); /* lock done by caller */
|
||||||
@@ -782,16 +782,16 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
|
|||||||
|
|
||||||
LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
|
LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
|
||||||
StkId t;
|
StkId t;
|
||||||
const TValue *aux;
|
const TValue *slot;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
t = index2addr(L, idx);
|
t = index2addr(L, idx);
|
||||||
if (luaV_fastset(L, t, n, aux, luaH_getint, L->top - 1))
|
if (luaV_fastset(L, t, n, slot, luaH_getint, L->top - 1))
|
||||||
L->top--; /* pop value */
|
L->top--; /* pop value */
|
||||||
else {
|
else {
|
||||||
setivalue(L->top, n);
|
setivalue(L->top, n);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
luaV_finishset(L, t, L->top - 1, L->top - 2, aux);
|
luaV_finishset(L, t, L->top - 1, L->top - 2, slot);
|
||||||
L->top -= 2; /* pop value and key */
|
L->top -= 2; /* pop value and key */
|
||||||
}
|
}
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
@@ -1193,7 +1193,6 @@ LUA_API void lua_concat (lua_State *L, int n) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, n);
|
api_checknelems(L, n);
|
||||||
if (n >= 2) {
|
if (n >= 2) {
|
||||||
luaC_checkGC(L);
|
|
||||||
luaV_concat(L, n);
|
luaV_concat(L, n);
|
||||||
}
|
}
|
||||||
else if (n == 0) { /* push empty string */
|
else if (n == 0) { /* push empty string */
|
||||||
@@ -1201,6 +1200,7 @@ LUA_API void lua_concat (lua_State *L, int n) {
|
|||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
/* else n == 1; nothing to do */
|
/* else n == 1; nothing to do */
|
||||||
|
luaC_checkGC(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1236,10 +1236,10 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
|
|||||||
LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
|
LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
|
||||||
Udata *u;
|
Udata *u;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
luaC_checkGC(L);
|
|
||||||
u = luaS_newudata(L, size);
|
u = luaS_newudata(L, size);
|
||||||
setuvalue(L, L->top, u);
|
setuvalue(L, L->top, u);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
|
luaC_checkGC(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return getudatamem(u);
|
return getudatamem(u);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lauxlib.c,v 1.284 2015/11/19 19:16:22 roberto Exp $
|
** $Id: lauxlib.c,v 1.286 2016/01/08 15:33:09 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
|
||||||
*/
|
*/
|
||||||
@@ -17,7 +17,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
/* This file uses only the official API of Lua.
|
/*
|
||||||
|
** This file uses only the official API of Lua.
|
||||||
** Any function declared here could be written as an application function.
|
** Any function declared here could be written as an application function.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -198,6 +199,10 @@ static void tag_error (lua_State *L, int arg, int tag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The use of 'lua_pushfstring' ensures this function does not
|
||||||
|
** need reserved stack space when called.
|
||||||
|
*/
|
||||||
LUALIB_API void luaL_where (lua_State *L, int level) {
|
LUALIB_API void luaL_where (lua_State *L, int level) {
|
||||||
lua_Debug ar;
|
lua_Debug ar;
|
||||||
if (lua_getstack(L, level, &ar)) { /* check function at level */
|
if (lua_getstack(L, level, &ar)) { /* check function at level */
|
||||||
@@ -207,10 +212,15 @@ LUALIB_API void luaL_where (lua_State *L, int level) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lua_pushliteral(L, ""); /* else, no information available... */
|
lua_pushfstring(L, ""); /* else, no information available... */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Again, the use of 'lua_pushvfstring' ensures this function does
|
||||||
|
** not need reserved stack space when called. (At worst, it generates
|
||||||
|
** an error with "stack overflow" instead of the given message.)
|
||||||
|
*/
|
||||||
LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
|
LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
|
||||||
va_list argp;
|
va_list argp;
|
||||||
va_start(argp, fmt);
|
va_start(argp, fmt);
|
||||||
@@ -349,10 +359,15 @@ LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Ensures the stack has at least 'space' extra slots, raising an error
|
||||||
|
** if it cannot fulfill the request. (The error handling needs a few
|
||||||
|
** extra slots to format the error message. In case of an error without
|
||||||
|
** this extra space, Lua will generate the same 'stack overflow' error,
|
||||||
|
** but without 'msg'.)
|
||||||
|
*/
|
||||||
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
|
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
|
||||||
/* keep some extra space to run error routines, if needed */
|
if (!lua_checkstack(L, space)) {
|
||||||
const int extra = LUA_MINSTACK;
|
|
||||||
if (!lua_checkstack(L, space + extra)) {
|
|
||||||
if (msg)
|
if (msg)
|
||||||
luaL_error(L, "stack overflow (%s)", msg);
|
luaL_error(L, "stack overflow (%s)", msg);
|
||||||
else
|
else
|
||||||
@@ -678,7 +693,7 @@ static int skipcomment (LoadF *lf, int *cp) {
|
|||||||
if (c == '#') { /* first line is a comment (Unix exec. file)? */
|
if (c == '#') { /* first line is a comment (Unix exec. file)? */
|
||||||
do { /* skip first line */
|
do { /* skip first line */
|
||||||
c = getc(lf->f);
|
c = getc(lf->f);
|
||||||
} while (c != EOF && c != '\n') ;
|
} while (c != EOF && c != '\n');
|
||||||
*cp = getc(lf->f); /* skip end-of-line, if present */
|
*cp = getc(lf->f); /* skip end-of-line, if present */
|
||||||
return 1; /* there was a comment */
|
return 1; /* there was a comment */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lbaselib.c,v 1.312 2015/10/29 15:21:04 roberto Exp $
|
** $Id: lbaselib.c,v 1.313 2016/04/11 19:18:40 roberto Exp $
|
||||||
** Basic library
|
** Basic library
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -102,8 +102,8 @@ static int luaB_tonumber (lua_State *L) {
|
|||||||
static int luaB_error (lua_State *L) {
|
static int luaB_error (lua_State *L) {
|
||||||
int level = (int)luaL_optinteger(L, 2, 1);
|
int level = (int)luaL_optinteger(L, 2, 1);
|
||||||
lua_settop(L, 1);
|
lua_settop(L, 1);
|
||||||
if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
|
if (lua_type(L, 1) == LUA_TSTRING && level > 0) {
|
||||||
luaL_where(L, level);
|
luaL_where(L, level); /* add extra information */
|
||||||
lua_pushvalue(L, 1);
|
lua_pushvalue(L, 1);
|
||||||
lua_concat(L, 2);
|
lua_concat(L, 2);
|
||||||
}
|
}
|
||||||
@@ -251,9 +251,8 @@ static int ipairsaux (lua_State *L) {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This function will use either 'ipairsaux' or 'ipairsaux_raw' to
|
** 'ipairs' function. Returns 'ipairsaux', given "table", 0.
|
||||||
** traverse a table, depending on whether the table has metamethods
|
** (The given "table" may not be a table.)
|
||||||
** that can affect the traversal.
|
|
||||||
*/
|
*/
|
||||||
static int luaB_ipairs (lua_State *L) {
|
static int luaB_ipairs (lua_State *L) {
|
||||||
#if defined(LUA_COMPAT_IPAIRS)
|
#if defined(LUA_COMPAT_IPAIRS)
|
||||||
|
|||||||
693
3rd/lua/lcode.c
693
3rd/lua/lcode.c
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lcode.h,v 1.63 2013/12/30 20:47:58 roberto Exp $
|
** $Id: lcode.h,v 1.64 2016/01/05 16:22:37 roberto Exp $
|
||||||
** Code generator for Lua
|
** Code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -40,7 +40,8 @@ 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])
|
/* get (pointer to) instruction of given 'expdesc' */
|
||||||
|
#define getinstruction(fs,e) ((fs)->f->sp->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: lcorolib.c,v 1.9 2014/11/02 19:19:04 roberto Exp $
|
** $Id: lcorolib.c,v 1.10 2016/04/11 19:19:55 roberto Exp $
|
||||||
** Coroutine Library
|
** Coroutine Library
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -75,7 +75,7 @@ static int luaB_auxwrap (lua_State *L) {
|
|||||||
lua_State *co = lua_tothread(L, lua_upvalueindex(1));
|
lua_State *co = lua_tothread(L, lua_upvalueindex(1));
|
||||||
int r = auxresume(L, co, lua_gettop(L));
|
int r = auxresume(L, co, lua_gettop(L));
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (lua_isstring(L, -1)) { /* error object is a string? */
|
if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */
|
||||||
luaL_where(L, 1); /* add extra info */
|
luaL_where(L, 1); /* add extra info */
|
||||||
lua_insert(L, -2);
|
lua_insert(L, -2);
|
||||||
lua_concat(L, 2);
|
lua_concat(L, 2);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldebug.c,v 2.117 2015/11/02 18:48:07 roberto Exp $
|
** $Id: ldebug.c,v 2.120 2016/03/31 19:01:21 roberto Exp $
|
||||||
** Debug Interface
|
** Debug Interface
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -69,7 +69,13 @@ static void swapextra (lua_State *L) {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** this function can be called asynchronous (e.g. during a signal)
|
** This function can be called asynchronously (e.g. during a signal).
|
||||||
|
** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by
|
||||||
|
** 'resethookcount') are for debug only, and it is no problem if they
|
||||||
|
** get arbitrary values (causes at most one wrong hook call). 'hookmask'
|
||||||
|
** is an atomic value. We assume that pointers are atomic too (e.g., gcc
|
||||||
|
** ensures that for all platforms where it runs). Moreover, 'hook' is
|
||||||
|
** always checked before being called (see 'luaD_hook').
|
||||||
*/
|
*/
|
||||||
LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
|
LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
|
||||||
if (func == NULL || mask == 0) { /* turn off hooks? */
|
if (func == NULL || mask == 0) { /* turn off hooks? */
|
||||||
@@ -118,7 +124,7 @@ 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->sp->sizeupvalues, p->sp->upvalues[uv].name);
|
||||||
if (s == NULL) return "?";
|
if (s == NULL) return "?";
|
||||||
else return getstr(s);
|
else return getstr(s);
|
||||||
}
|
}
|
||||||
@@ -558,7 +564,7 @@ static const char *varinfo (lua_State *L, const TValue *o) {
|
|||||||
|
|
||||||
|
|
||||||
l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
|
l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
|
||||||
const char *t = objtypename(o);
|
const char *t = luaT_objtypename(L, o);
|
||||||
luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o));
|
luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,9 +596,9 @@ l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) {
|
|||||||
|
|
||||||
|
|
||||||
l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
|
l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
|
||||||
const char *t1 = objtypename(p1);
|
const char *t1 = luaT_objtypename(L, p1);
|
||||||
const char *t2 = objtypename(p2);
|
const char *t2 = luaT_objtypename(L, p2);
|
||||||
if (t1 == t2)
|
if (strcmp(t1, t2) == 0)
|
||||||
luaG_runerror(L, "attempt to compare two %s values", t1);
|
luaG_runerror(L, "attempt to compare two %s values", t1);
|
||||||
else
|
else
|
||||||
luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
|
luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldo.c,v 2.150 2015/11/19 19:16:22 roberto Exp $
|
** $Id: ldo.c,v 2.151 2015/12/16 16:40:07 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
|
||||||
*/
|
*/
|
||||||
@@ -242,9 +242,14 @@ void luaD_inctop (lua_State *L) {
|
|||||||
/* }================================================================== */
|
/* }================================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Call a hook for the given event. Make sure there is a hook to be
|
||||||
|
** called. (Both 'L->hook' and 'L->hookmask', which triggers this
|
||||||
|
** function, can be changed asynchronously by signals.)
|
||||||
|
*/
|
||||||
void luaD_hook (lua_State *L, int event, int line) {
|
void luaD_hook (lua_State *L, int event, int line) {
|
||||||
lua_Hook hook = L->hook;
|
lua_Hook hook = L->hook;
|
||||||
if (hook && L->allowhook) {
|
if (hook && L->allowhook) { /* make sure there is a hook */
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
ptrdiff_t top = savestack(L, L->top);
|
ptrdiff_t top = savestack(L, L->top);
|
||||||
ptrdiff_t ci_top = savestack(L, ci->top);
|
ptrdiff_t ci_top = savestack(L, ci->top);
|
||||||
@@ -768,7 +773,7 @@ static void f_parser (lua_State *L, void *ud) {
|
|||||||
checkmode(L, p->mode, "text");
|
checkmode(L, p->mode, "text");
|
||||||
cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
|
cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
|
||||||
}
|
}
|
||||||
lua_assert(cl->nupvalues == cl->p->sizeupvalues);
|
lua_assert(cl->nupvalues == cl->p->sp->sizeupvalues);
|
||||||
luaF_initupvals(L, cl);
|
luaF_initupvals(L, cl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldo.h,v 2.28 2015/11/23 11:29:43 roberto Exp $
|
** $Id: ldo.h,v 2.29 2015/12/21 13:02:14 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
|
||||||
*/
|
*/
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
{ pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); }
|
{ pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); }
|
||||||
|
|
||||||
/* In general, 'pre'/'pos' are empty (nothing to save) */
|
/* In general, 'pre'/'pos' are empty (nothing to save) */
|
||||||
#define luaD_checkstack(L,n) luaD_checkstackaux(L,n,,)
|
#define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lgc.c,v 2.210 2015/11/03 18:10:44 roberto Exp $
|
** $Id: lgc.c,v 2.212 2016/03/31 19:02:03 roberto Exp $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -761,14 +761,11 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
|
|||||||
/*
|
/*
|
||||||
** sweep a list until a live object (or end of list)
|
** sweep a list until a live object (or end of list)
|
||||||
*/
|
*/
|
||||||
static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) {
|
static GCObject **sweeptolive (lua_State *L, GCObject **p) {
|
||||||
GCObject **old = p;
|
GCObject **old = p;
|
||||||
int i = 0;
|
|
||||||
do {
|
do {
|
||||||
i++;
|
|
||||||
p = sweeplist(L, p, 1);
|
p = sweeplist(L, p, 1);
|
||||||
} while (p == old);
|
} while (p == old);
|
||||||
if (n) *n += i;
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -863,10 +860,10 @@ static int runafewfinalizers (lua_State *L) {
|
|||||||
/*
|
/*
|
||||||
** call all pending finalizers
|
** call all pending finalizers
|
||||||
*/
|
*/
|
||||||
static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
|
static void callallpendingfinalizers (lua_State *L) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
while (g->tobefnz)
|
while (g->tobefnz)
|
||||||
GCTM(L, propagateerrors);
|
GCTM(L, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -916,7 +913,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
|
|||||||
if (issweepphase(g)) {
|
if (issweepphase(g)) {
|
||||||
makewhite(g, o); /* "sweep" object 'o' */
|
makewhite(g, o); /* "sweep" object 'o' */
|
||||||
if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */
|
if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */
|
||||||
g->sweepgc = sweeptolive(L, g->sweepgc, NULL); /* change 'sweepgc' */
|
g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */
|
||||||
}
|
}
|
||||||
/* search for pointer pointing to 'o' */
|
/* search for pointer pointing to 'o' */
|
||||||
for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ }
|
for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ }
|
||||||
@@ -958,19 +955,16 @@ static void setpause (global_State *g) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Enter first sweep phase.
|
** Enter first sweep phase.
|
||||||
** The call to 'sweeptolive' makes pointer point to an object inside
|
** The call to 'sweeplist' tries to make pointer point to an object
|
||||||
** the list (instead of to the header), so that the real sweep do not
|
** inside the list (instead of to the header), so that the real sweep do
|
||||||
** need to skip objects created between "now" and the start of the real
|
** not need to skip objects created between "now" and the start of the
|
||||||
** sweep.
|
** real sweep.
|
||||||
** Returns how many objects it swept.
|
|
||||||
*/
|
*/
|
||||||
static int entersweep (lua_State *L) {
|
static void entersweep (lua_State *L) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
int n = 0;
|
|
||||||
g->gcstate = GCSswpallgc;
|
g->gcstate = GCSswpallgc;
|
||||||
lua_assert(g->sweepgc == NULL);
|
lua_assert(g->sweepgc == NULL);
|
||||||
g->sweepgc = sweeptolive(L, &g->allgc, &n);
|
g->sweepgc = sweeplist(L, &g->allgc, 1);
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -978,7 +972,7 @@ void luaC_freeallobjects (lua_State *L) {
|
|||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
separatetobefnz(g, 1); /* separate all objects with finalizers */
|
separatetobefnz(g, 1); /* separate all objects with finalizers */
|
||||||
lua_assert(g->finobj == NULL);
|
lua_assert(g->finobj == NULL);
|
||||||
callallpendingfinalizers(L, 0);
|
callallpendingfinalizers(L);
|
||||||
lua_assert(g->tobefnz == NULL);
|
lua_assert(g->tobefnz == NULL);
|
||||||
g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
|
g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
|
||||||
g->gckind = KGC_NORMAL;
|
g->gckind = KGC_NORMAL;
|
||||||
@@ -1071,12 +1065,11 @@ static lu_mem singlestep (lua_State *L) {
|
|||||||
}
|
}
|
||||||
case GCSatomic: {
|
case GCSatomic: {
|
||||||
lu_mem work;
|
lu_mem work;
|
||||||
int sw;
|
|
||||||
propagateall(g); /* make sure gray list is empty */
|
propagateall(g); /* make sure gray list is empty */
|
||||||
work = atomic(L); /* work is what was traversed by 'atomic' */
|
work = atomic(L); /* work is what was traversed by 'atomic' */
|
||||||
sw = entersweep(L);
|
entersweep(L);
|
||||||
g->GCestimate = gettotalbytes(g); /* first estimate */;
|
g->GCestimate = gettotalbytes(g); /* first estimate */;
|
||||||
return work + sw * GCSWEEPCOST;
|
return work;
|
||||||
}
|
}
|
||||||
case GCSswpallgc: { /* sweep "regular" objects */
|
case GCSswpallgc: { /* sweep "regular" objects */
|
||||||
return sweepstep(L, g, GCSswpfinobj, &g->finobj);
|
return sweepstep(L, g, GCSswpfinobj, &g->finobj);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lgc.h,v 2.90 2015/10/21 18:15:15 roberto Exp $
|
** $Id: lgc.h,v 2.91 2015/12/21 13:02:14 roberto Exp $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
condchangemem(L,pre,pos); }
|
condchangemem(L,pre,pos); }
|
||||||
|
|
||||||
/* more often than not, 'pre'/'pos' are empty */
|
/* more often than not, 'pre'/'pos' are empty */
|
||||||
#define luaC_checkGC(L) luaC_condGC(L,,)
|
#define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0)
|
||||||
|
|
||||||
|
|
||||||
#define luaC_barrier(L,p,v) ( \
|
#define luaC_barrier(L,p,v) ( \
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: liolib.c,v 2.148 2015/11/23 11:36:11 roberto Exp $
|
** $Id: liolib.c,v 2.149 2016/05/02 14:03:19 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
|
||||||
*/
|
*/
|
||||||
@@ -375,14 +375,17 @@ static int io_lines (lua_State *L) {
|
|||||||
|
|
||||||
|
|
||||||
/* maximum length of a numeral */
|
/* maximum length of a numeral */
|
||||||
#define MAXRN 200
|
#if !defined (L_MAXLENNUM)
|
||||||
|
#define L_MAXLENNUM 200
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* auxiliary structure used by 'read_number' */
|
/* auxiliary structure used by 'read_number' */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FILE *f; /* file being read */
|
FILE *f; /* file being read */
|
||||||
int c; /* current character (look ahead) */
|
int c; /* current character (look ahead) */
|
||||||
int n; /* number of elements in buffer 'buff' */
|
int n; /* number of elements in buffer 'buff' */
|
||||||
char buff[MAXRN + 1]; /* +1 for ending '\0' */
|
char buff[L_MAXLENNUM + 1]; /* +1 for ending '\0' */
|
||||||
} RN;
|
} RN;
|
||||||
|
|
||||||
|
|
||||||
@@ -390,7 +393,7 @@ typedef struct {
|
|||||||
** Add current char to buffer (if not out of space) and read next one
|
** Add current char to buffer (if not out of space) and read next one
|
||||||
*/
|
*/
|
||||||
static int nextc (RN *rn) {
|
static int nextc (RN *rn) {
|
||||||
if (rn->n >= MAXRN) { /* buffer overflow? */
|
if (rn->n >= L_MAXLENNUM) { /* buffer overflow? */
|
||||||
rn->buff[0] = '\0'; /* invalidate result */
|
rn->buff[0] = '\0'; /* invalidate result */
|
||||||
return 0; /* fail */
|
return 0; /* fail */
|
||||||
}
|
}
|
||||||
@@ -403,10 +406,10 @@ static int nextc (RN *rn) {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Accept current char if it is in 'set' (of size 1 or 2)
|
** Accept current char if it is in 'set' (of size 2)
|
||||||
*/
|
*/
|
||||||
static int test2 (RN *rn, const char *set) {
|
static int test2 (RN *rn, const char *set) {
|
||||||
if (rn->c == set[0] || (rn->c == set[1] && rn->c != '\0'))
|
if (rn->c == set[0] || rn->c == set[1])
|
||||||
return nextc(rn);
|
return nextc(rn);
|
||||||
else return 0;
|
else return 0;
|
||||||
}
|
}
|
||||||
@@ -435,11 +438,11 @@ static int read_number (lua_State *L, FILE *f) {
|
|||||||
char decp[2];
|
char decp[2];
|
||||||
rn.f = f; rn.n = 0;
|
rn.f = f; rn.n = 0;
|
||||||
decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */
|
decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */
|
||||||
decp[1] = '\0';
|
decp[1] = '.'; /* always accept a dot */
|
||||||
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 */
|
||||||
if (test2(&rn, "0")) {
|
if (test2(&rn, "00")) {
|
||||||
if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */
|
if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */
|
||||||
else count = 1; /* count initial '0' as a valid digit */
|
else count = 1; /* count initial '0' as a valid digit */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: llex.c,v 2.95 2015/11/19 19:16:22 roberto Exp $
|
** $Id: llex.c,v 2.96 2016/05/02 14:02:12 roberto Exp $
|
||||||
** Lexical Analyzer
|
** Lexical Analyzer
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -162,7 +162,6 @@ static void inclinenumber (LexState *ls) {
|
|||||||
void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
|
void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
|
||||||
int firstchar) {
|
int firstchar) {
|
||||||
ls->t.token = 0;
|
ls->t.token = 0;
|
||||||
ls->decpoint = '.';
|
|
||||||
ls->L = L;
|
ls->L = L;
|
||||||
ls->current = firstchar;
|
ls->current = firstchar;
|
||||||
ls->lookahead.token = TK_EOS; /* no look-ahead token */
|
ls->lookahead.token = TK_EOS; /* no look-ahead token */
|
||||||
@@ -207,35 +206,6 @@ static int check_next2 (LexState *ls, const char *set) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** change all characters 'from' in buffer to 'to'
|
|
||||||
*/
|
|
||||||
static void buffreplace (LexState *ls, char from, char to) {
|
|
||||||
if (from != to) {
|
|
||||||
size_t n = luaZ_bufflen(ls->buff);
|
|
||||||
char *p = luaZ_buffer(ls->buff);
|
|
||||||
while (n--)
|
|
||||||
if (p[n] == from) p[n] = to;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** in case of format error, try to change decimal point separator to
|
|
||||||
** the one defined in the current locale and check again
|
|
||||||
*/
|
|
||||||
static void trydecpoint (LexState *ls, TValue *o) {
|
|
||||||
char old = ls->decpoint;
|
|
||||||
ls->decpoint = lua_getlocaledecpoint();
|
|
||||||
buffreplace(ls, old, ls->decpoint); /* try new decimal separator */
|
|
||||||
if (luaO_str2num(luaZ_buffer(ls->buff), o) == 0) {
|
|
||||||
/* format error with correct decimal point: no more options */
|
|
||||||
buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
|
|
||||||
lexerror(ls, "malformed number", TK_FLT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* LUA_NUMBER */
|
/* LUA_NUMBER */
|
||||||
/*
|
/*
|
||||||
** this function is quite liberal in what it accepts, as 'luaO_str2num'
|
** this function is quite liberal in what it accepts, as 'luaO_str2num'
|
||||||
@@ -259,9 +229,8 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) {
|
|||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
save(ls, '\0');
|
save(ls, '\0');
|
||||||
buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
|
|
||||||
if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0) /* format error? */
|
if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0) /* format error? */
|
||||||
trydecpoint(ls, &obj); /* try to update decimal point separator */
|
lexerror(ls, "malformed number", TK_FLT);
|
||||||
if (ttisinteger(&obj)) {
|
if (ttisinteger(&obj)) {
|
||||||
seminfo->i = ivalue(&obj);
|
seminfo->i = ivalue(&obj);
|
||||||
return TK_INT;
|
return TK_INT;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: llex.h,v 1.78 2014/10/29 15:38:24 roberto Exp $
|
** $Id: llex.h,v 1.79 2016/05/02 14:02:12 roberto Exp $
|
||||||
** Lexical Analyzer
|
** Lexical Analyzer
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -69,7 +69,6 @@ typedef struct LexState {
|
|||||||
struct Dyndata *dyd; /* dynamic structures used by the parser */
|
struct Dyndata *dyd; /* dynamic structures used by the parser */
|
||||||
TString *source; /* current source name */
|
TString *source; /* current source name */
|
||||||
TString *envn; /* environment variable name */
|
TString *envn; /* environment variable name */
|
||||||
char decpoint; /* locale decimal point */
|
|
||||||
} LexState;
|
} LexState;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.c,v 2.108 2015/11/02 16:09:30 roberto Exp $
|
** $Id: lobject.c,v 2.110 2016/05/02 14:00:32 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
|
||||||
*/
|
*/
|
||||||
@@ -243,17 +243,53 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
|
|||||||
/* }====================================================== */
|
/* }====================================================== */
|
||||||
|
|
||||||
|
|
||||||
static const char *l_str2d (const char *s, lua_Number *result) {
|
/* maximum length of a numeral */
|
||||||
|
#if !defined (L_MAXLENNUM)
|
||||||
|
#define L_MAXLENNUM 200
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const char *l_str2dloc (const char *s, lua_Number *result, int mode) {
|
||||||
char *endptr;
|
char *endptr;
|
||||||
if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */
|
*result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */
|
||||||
|
: lua_str2number(s, &endptr);
|
||||||
|
if (endptr == s) return NULL; /* nothing recognized? */
|
||||||
|
while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */
|
||||||
|
return (*endptr == '\0') ? endptr : NULL; /* OK if no trailing characters */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Convert string 's' to a Lua number (put in 'result'). Return NULL
|
||||||
|
** on fail or the address of the ending '\0' on success.
|
||||||
|
** 'pmode' points to (and 'mode' contains) special things in the string:
|
||||||
|
** - 'x'/'X' means an hexadecimal numeral
|
||||||
|
** - 'n'/'N' means 'inf' or 'nan' (which should be rejected)
|
||||||
|
** - '.' just optimizes the search for the common case (nothing special)
|
||||||
|
** This function accepts both the current locale or a dot as the radix
|
||||||
|
** mark. If the convertion fails, it may mean number has a dot but
|
||||||
|
** locale accepts something else. In that case, the code copies 's'
|
||||||
|
** to a buffer (because 's' is read-only), changes the dot to the
|
||||||
|
** current locale radix mark, and tries to convert again.
|
||||||
|
*/
|
||||||
|
static const char *l_str2d (const char *s, lua_Number *result) {
|
||||||
|
const char *endptr;
|
||||||
|
const char *pmode = strpbrk(s, ".xXnN");
|
||||||
|
int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0;
|
||||||
|
if (mode == 'n') /* reject 'inf' and 'nan' */
|
||||||
return NULL;
|
return NULL;
|
||||||
else if (strpbrk(s, "xX")) /* hex? */
|
endptr = l_str2dloc(s, result, mode); /* try to convert */
|
||||||
*result = lua_strx2number(s, &endptr);
|
if (endptr == NULL) { /* failed? may be a different locale */
|
||||||
else
|
char buff[L_MAXLENNUM + 1];
|
||||||
*result = lua_str2number(s, &endptr);
|
char *pdot = strchr(s, '.');
|
||||||
if (endptr == s) return NULL; /* nothing recognized */
|
if (strlen(s) > L_MAXLENNUM || pdot == NULL)
|
||||||
while (lisspace(cast_uchar(*endptr))) endptr++;
|
return NULL; /* string too long or no dot; fail */
|
||||||
return (*endptr == '\0' ? endptr : NULL); /* OK if no trailing characters */
|
strcpy(buff, s); /* copy string to buffer */
|
||||||
|
buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */
|
||||||
|
endptr = l_str2dloc(buff, result, mode); /* try again */
|
||||||
|
if (endptr != NULL)
|
||||||
|
endptr = s + (endptr - buff); /* make relative to 's' */
|
||||||
|
}
|
||||||
|
return endptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -351,8 +387,10 @@ static void pushstr (lua_State *L, const char *str, size_t l) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* this function handles only '%d', '%c', '%f', '%p', and '%s'
|
/*
|
||||||
conventional formats, plus Lua-specific '%I' and '%U' */
|
** this function handles only '%d', '%c', '%f', '%p', and '%s'
|
||||||
|
conventional formats, plus Lua-specific '%I' and '%U'
|
||||||
|
*/
|
||||||
const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
|
const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -360,13 +398,13 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
|
|||||||
if (e == NULL) break;
|
if (e == NULL) break;
|
||||||
pushstr(L, fmt, e - fmt);
|
pushstr(L, fmt, e - fmt);
|
||||||
switch (*(e+1)) {
|
switch (*(e+1)) {
|
||||||
case 's': {
|
case 's': { /* zero-terminated string */
|
||||||
const char *s = va_arg(argp, char *);
|
const char *s = va_arg(argp, char *);
|
||||||
if (s == NULL) s = "(null)";
|
if (s == NULL) s = "(null)";
|
||||||
pushstr(L, s, strlen(s));
|
pushstr(L, s, strlen(s));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'c': {
|
case 'c': { /* an 'int' as a character */
|
||||||
char buff = cast(char, va_arg(argp, int));
|
char buff = cast(char, va_arg(argp, int));
|
||||||
if (lisprint(cast_uchar(buff)))
|
if (lisprint(cast_uchar(buff)))
|
||||||
pushstr(L, &buff, 1);
|
pushstr(L, &buff, 1);
|
||||||
@@ -374,28 +412,28 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
|
|||||||
luaO_pushfstring(L, "<\\%d>", cast_uchar(buff));
|
luaO_pushfstring(L, "<\\%d>", cast_uchar(buff));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'd': {
|
case 'd': { /* an 'int' */
|
||||||
setivalue(L->top, va_arg(argp, int));
|
setivalue(L->top, va_arg(argp, int));
|
||||||
goto top2str;
|
goto top2str;
|
||||||
}
|
}
|
||||||
case 'I': {
|
case 'I': { /* a 'lua_Integer' */
|
||||||
setivalue(L->top, cast(lua_Integer, va_arg(argp, l_uacInt)));
|
setivalue(L->top, cast(lua_Integer, va_arg(argp, l_uacInt)));
|
||||||
goto top2str;
|
goto top2str;
|
||||||
}
|
}
|
||||||
case 'f': {
|
case 'f': { /* a 'lua_Number' */
|
||||||
setfltvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
|
setfltvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
|
||||||
top2str:
|
top2str: /* convert the top element to a string */
|
||||||
luaD_inctop(L);
|
luaD_inctop(L);
|
||||||
luaO_tostring(L, L->top - 1);
|
luaO_tostring(L, L->top - 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'p': {
|
case 'p': { /* a pointer */
|
||||||
char buff[4*sizeof(void *) + 8]; /* should be enough space for a '%p' */
|
char buff[4*sizeof(void *) + 8]; /* should be enough space for a '%p' */
|
||||||
int l = l_sprintf(buff, sizeof(buff), "%p", va_arg(argp, void *));
|
int l = l_sprintf(buff, sizeof(buff), "%p", va_arg(argp, void *));
|
||||||
pushstr(L, buff, l);
|
pushstr(L, buff, l);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'U': {
|
case 'U': { /* an 'int' as a UTF-8 sequence */
|
||||||
char buff[UTF8BUFFSZ];
|
char buff[UTF8BUFFSZ];
|
||||||
int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long)));
|
int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long)));
|
||||||
pushstr(L, buff + UTF8BUFFSZ - l, l);
|
pushstr(L, buff + UTF8BUFFSZ - l, l);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: loslib.c,v 1.60 2015/11/19 19:16:22 roberto Exp $
|
** $Id: loslib.c,v 1.64 2016/04/18 13:06:55 roberto Exp $
|
||||||
** Standard Operating System library
|
** Standard Operating System library
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -24,18 +24,29 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** {==================================================================
|
** {==================================================================
|
||||||
** list of valid conversion specifiers for the 'strftime' function
|
** List of valid conversion specifiers for the 'strftime' function;
|
||||||
|
** options are grouped by length; group of length 2 start with '||'.
|
||||||
** ===================================================================
|
** ===================================================================
|
||||||
*/
|
*/
|
||||||
#if !defined(LUA_STRFTIMEOPTIONS) /* { */
|
#if !defined(LUA_STRFTIMEOPTIONS) /* { */
|
||||||
|
|
||||||
#if defined(LUA_USE_C89)
|
/* options for ANSI C 89 */
|
||||||
#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" }
|
#define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%"
|
||||||
|
|
||||||
|
/* options for ISO C 99 and POSIX */
|
||||||
|
#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
|
||||||
|
"||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy"
|
||||||
|
|
||||||
|
/* options for Windows */
|
||||||
|
#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \
|
||||||
|
"||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y"
|
||||||
|
|
||||||
|
#if defined(LUA_USE_WINDOWS)
|
||||||
|
#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN
|
||||||
|
#elif defined(LUA_USE_C89)
|
||||||
|
#define LUA_STRFTIMEOPTIONS L_STRFTIMEC89
|
||||||
#else /* C99 specification */
|
#else /* C99 specification */
|
||||||
#define LUA_STRFTIMEOPTIONS \
|
#define LUA_STRFTIMEOPTIONS L_STRFTIMEC99
|
||||||
{ "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", \
|
|
||||||
"E", "cCxXyY", \
|
|
||||||
"O", "deHImMSuUVwWy" }
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* } */
|
#endif /* } */
|
||||||
@@ -195,6 +206,23 @@ static void setboolfield (lua_State *L, const char *key, int value) {
|
|||||||
lua_setfield(L, -2, key);
|
lua_setfield(L, -2, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Set all fields from structure 'tm' in the table on top of the stack
|
||||||
|
*/
|
||||||
|
static void setallfields (lua_State *L, struct tm *stm) {
|
||||||
|
setfield(L, "sec", stm->tm_sec);
|
||||||
|
setfield(L, "min", stm->tm_min);
|
||||||
|
setfield(L, "hour", stm->tm_hour);
|
||||||
|
setfield(L, "day", stm->tm_mday);
|
||||||
|
setfield(L, "month", stm->tm_mon + 1);
|
||||||
|
setfield(L, "year", stm->tm_year + 1900);
|
||||||
|
setfield(L, "wday", stm->tm_wday + 1);
|
||||||
|
setfield(L, "yday", stm->tm_yday + 1);
|
||||||
|
setboolfield(L, "isdst", stm->tm_isdst);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int getboolfield (lua_State *L, const char *key) {
|
static int getboolfield (lua_State *L, const char *key) {
|
||||||
int res;
|
int res;
|
||||||
res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1);
|
res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1);
|
||||||
@@ -210,18 +238,18 @@ static int getboolfield (lua_State *L, const char *key) {
|
|||||||
|
|
||||||
static int getfield (lua_State *L, const char *key, int d, int delta) {
|
static int getfield (lua_State *L, const char *key, int d, int delta) {
|
||||||
int isnum;
|
int isnum;
|
||||||
int t = lua_getfield(L, -1, key);
|
int t = lua_getfield(L, -1, key); /* get field and its type */
|
||||||
lua_Integer res = lua_tointegerx(L, -1, &isnum);
|
lua_Integer res = lua_tointegerx(L, -1, &isnum);
|
||||||
if (!isnum) { /* field is not a number? */
|
if (!isnum) { /* field is not an integer? */
|
||||||
if (t != LUA_TNIL) /* some other value? */
|
if (t != LUA_TNIL) /* some other value? */
|
||||||
return luaL_error(L, "field '%s' not an integer", key);
|
return luaL_error(L, "field '%s' is not an integer", key);
|
||||||
else if (d < 0) /* absent field; no default? */
|
else if (d < 0) /* absent field; no default? */
|
||||||
return luaL_error(L, "field '%s' missing in date table", key);
|
return luaL_error(L, "field '%s' missing in date table", key);
|
||||||
res = d;
|
res = d;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD))
|
if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD))
|
||||||
return luaL_error(L, "field '%s' out-of-bounds", key);
|
return luaL_error(L, "field '%s' is out-of-bound", key);
|
||||||
res -= delta;
|
res -= delta;
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
@@ -230,21 +258,15 @@ static int getfield (lua_State *L, const char *key, int d, int delta) {
|
|||||||
|
|
||||||
|
|
||||||
static const char *checkoption (lua_State *L, const char *conv, char *buff) {
|
static const char *checkoption (lua_State *L, const char *conv, char *buff) {
|
||||||
static const char *const options[] = LUA_STRFTIMEOPTIONS;
|
const char *option;
|
||||||
unsigned int i;
|
int oplen = 1;
|
||||||
for (i = 0; i < sizeof(options)/sizeof(options[0]); i += 2) {
|
for (option = LUA_STRFTIMEOPTIONS; *option != '\0'; option += oplen) {
|
||||||
if (*conv != '\0' && strchr(options[i], *conv) != NULL) {
|
if (*option == '|') /* next block? */
|
||||||
buff[1] = *conv;
|
oplen++; /* next length */
|
||||||
if (*options[i + 1] == '\0') { /* one-char conversion specifier? */
|
else if (memcmp(conv, option, oplen) == 0) { /* match? */
|
||||||
buff[2] = '\0'; /* end buffer */
|
memcpy(buff, conv, oplen); /* copy valid option to buffer */
|
||||||
return conv + 1;
|
buff[oplen] = '\0';
|
||||||
}
|
return conv + oplen; /* return next item */
|
||||||
else if (*(conv + 1) != '\0' &&
|
|
||||||
strchr(options[i + 1], *(conv + 1)) != NULL) {
|
|
||||||
buff[2] = *(conv + 1); /* valid two-char conversion specifier */
|
|
||||||
buff[3] = '\0'; /* end buffer */
|
|
||||||
return conv + 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
luaL_argerror(L, 1,
|
luaL_argerror(L, 1,
|
||||||
@@ -271,18 +293,10 @@ static int os_date (lua_State *L) {
|
|||||||
luaL_error(L, "time result cannot be represented in this installation");
|
luaL_error(L, "time result cannot be represented in this installation");
|
||||||
if (strcmp(s, "*t") == 0) {
|
if (strcmp(s, "*t") == 0) {
|
||||||
lua_createtable(L, 0, 9); /* 9 = number of fields */
|
lua_createtable(L, 0, 9); /* 9 = number of fields */
|
||||||
setfield(L, "sec", stm->tm_sec);
|
setallfields(L, stm);
|
||||||
setfield(L, "min", stm->tm_min);
|
|
||||||
setfield(L, "hour", stm->tm_hour);
|
|
||||||
setfield(L, "day", stm->tm_mday);
|
|
||||||
setfield(L, "month", stm->tm_mon+1);
|
|
||||||
setfield(L, "year", stm->tm_year+1900);
|
|
||||||
setfield(L, "wday", stm->tm_wday+1);
|
|
||||||
setfield(L, "yday", stm->tm_yday+1);
|
|
||||||
setboolfield(L, "isdst", stm->tm_isdst);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char cc[4];
|
char cc[4]; /* buffer for individual conversion specifiers */
|
||||||
luaL_Buffer b;
|
luaL_Buffer b;
|
||||||
cc[0] = '%';
|
cc[0] = '%';
|
||||||
luaL_buffinit(L, &b);
|
luaL_buffinit(L, &b);
|
||||||
@@ -292,7 +306,7 @@ static int os_date (lua_State *L) {
|
|||||||
else {
|
else {
|
||||||
size_t reslen;
|
size_t reslen;
|
||||||
char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT);
|
char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT);
|
||||||
s = checkoption(L, s + 1, cc);
|
s = checkoption(L, s + 1, cc + 1); /* copy specifier to 'cc' */
|
||||||
reslen = strftime(buff, SIZETIMEFMT, cc, stm);
|
reslen = strftime(buff, SIZETIMEFMT, cc, stm);
|
||||||
luaL_addsize(&b, reslen);
|
luaL_addsize(&b, reslen);
|
||||||
}
|
}
|
||||||
@@ -319,6 +333,7 @@ static int os_time (lua_State *L) {
|
|||||||
ts.tm_year = getfield(L, "year", -1, 1900);
|
ts.tm_year = getfield(L, "year", -1, 1900);
|
||||||
ts.tm_isdst = getboolfield(L, "isdst");
|
ts.tm_isdst = getboolfield(L, "isdst");
|
||||||
t = mktime(&ts);
|
t = mktime(&ts);
|
||||||
|
setallfields(L, &ts); /* update fields with normalized values */
|
||||||
}
|
}
|
||||||
if (t != (time_t)(l_timet)t || t == (time_t)(-1))
|
if (t != (time_t)(l_timet)t || t == (time_t)(-1))
|
||||||
luaL_error(L, "time result cannot be represented in this installation");
|
luaL_error(L, "time result cannot be represented in this installation");
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lparser.c,v 2.149 2015/11/02 16:09:30 roberto Exp $
|
** $Id: lparser.c,v 2.152 2016/03/07 19:25:39 roberto Exp $
|
||||||
** Lua Parser
|
** Lua Parser
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -165,7 +165,8 @@ static int registerlocalvar (LexState *ls, TString *varname) {
|
|||||||
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, fp, varname);
|
||||||
return fs->nlocvars++;
|
return fs->nlocvars++;
|
||||||
@@ -232,7 +233,8 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
|
|||||||
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,
|
||||||
Upvaldesc, MAXUPVAL, "upvalues");
|
Upvaldesc, MAXUPVAL, "upvalues");
|
||||||
while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;
|
while (oldsize < f->sizeupvalues)
|
||||||
|
f->upvalues[oldsize++].name = NULL;
|
||||||
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;
|
||||||
@@ -257,7 +259,8 @@ static int searchvar (FuncState *fs, TString *n) {
|
|||||||
*/
|
*/
|
||||||
static void markupval (FuncState *fs, int level) {
|
static void markupval (FuncState *fs, int level) {
|
||||||
BlockCnt *bl = fs->bl;
|
BlockCnt *bl = fs->bl;
|
||||||
while (bl->nactvar > level) bl = bl->previous;
|
while (bl->nactvar > level)
|
||||||
|
bl = bl->previous;
|
||||||
bl->upval = 1;
|
bl->upval = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,7 +504,8 @@ static Proto *addprototype (LexState *ls) {
|
|||||||
if (fs->np >= f->sp->sizep) {
|
if (fs->np >= f->sp->sizep) {
|
||||||
int oldsize = f->sp->sizep;
|
int oldsize = f->sp->sizep;
|
||||||
luaM_growvector(L, f->p, fs->np, f->sp->sizep, Proto *, MAXARG_Bx, "functions");
|
luaM_growvector(L, f->p, fs->np, f->sp->sizep, Proto *, MAXARG_Bx, "functions");
|
||||||
while (oldsize < f->sp->sizep) f->p[oldsize++] = NULL;
|
while (oldsize < f->sp->sizep)
|
||||||
|
f->p[oldsize++] = NULL;
|
||||||
}
|
}
|
||||||
f->p[fs->np++] = clp = luaF_newproto(L, NULL);
|
f->p[fs->np++] = clp = luaF_newproto(L, NULL);
|
||||||
luaC_objbarrier(L, f, clp);
|
luaC_objbarrier(L, f, clp);
|
||||||
@@ -1229,7 +1233,7 @@ static void labelstat (LexState *ls, TString *label, int line) {
|
|||||||
checkrepeated(fs, ll, label); /* check for repeated labels */
|
checkrepeated(fs, ll, label); /* check for repeated labels */
|
||||||
checknext(ls, TK_DBCOLON); /* skip double colon */
|
checknext(ls, TK_DBCOLON); /* skip double colon */
|
||||||
/* create new entry for this label */
|
/* create new entry for this label */
|
||||||
l = newlabelentry(ls, ll, label, line, fs->pc);
|
l = newlabelentry(ls, ll, label, line, luaK_getlabel(fs));
|
||||||
skipnoopstat(ls); /* skip other no-op statements */
|
skipnoopstat(ls); /* skip other no-op statements */
|
||||||
if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */
|
if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */
|
||||||
/* assume that locals are already out of scope */
|
/* assume that locals are already out of scope */
|
||||||
@@ -1497,7 +1501,7 @@ static void exprstat (LexState *ls) {
|
|||||||
}
|
}
|
||||||
else { /* stat -> func */
|
else { /* stat -> func */
|
||||||
check_condition(ls, v.v.k == VCALL, "syntax error");
|
check_condition(ls, v.v.k == VCALL, "syntax error");
|
||||||
SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
|
SETARG_C(getinstruction(fs, &v.v), 1); /* call statement uses no results */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1514,8 +1518,8 @@ static void retstat (LexState *ls) {
|
|||||||
if (hasmultret(e.k)) {
|
if (hasmultret(e.k)) {
|
||||||
luaK_setmultret(fs, &e);
|
luaK_setmultret(fs, &e);
|
||||||
if (e.k == VCALL && nret == 1) { /* tail call? */
|
if (e.k == VCALL && nret == 1) { /* tail call? */
|
||||||
SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
|
SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL);
|
||||||
lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
|
lua_assert(GETARG_A(getinstruction(fs,&e)) == fs->nactvar);
|
||||||
}
|
}
|
||||||
first = fs->nactvar;
|
first = fs->nactvar;
|
||||||
nret = LUA_MULTRET; /* return all values */
|
nret = LUA_MULTRET; /* return all values */
|
||||||
@@ -1597,7 +1601,7 @@ static void statement (LexState *ls) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
|
lua_assert(ls->fs->f->sp->maxstacksize >= ls->fs->freereg &&
|
||||||
ls->fs->freereg >= ls->fs->nactvar);
|
ls->fs->freereg >= ls->fs->nactvar);
|
||||||
ls->fs->freereg = ls->fs->nactvar; /* free registers */
|
ls->fs->freereg = ls->fs->nactvar; /* free registers */
|
||||||
leavelevel(ls);
|
leavelevel(ls);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lparser.h,v 1.74 2014/10/25 11:50:46 roberto Exp $
|
** $Id: lparser.h,v 1.76 2015/12/30 18:16:13 roberto Exp $
|
||||||
** Lua Parser
|
** Lua Parser
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -13,25 +13,38 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Expression descriptor
|
** Expression and variable descriptor.
|
||||||
|
** Code generation for variables and expressions can be delayed to allow
|
||||||
|
** optimizations; An 'expdesc' structure describes a potentially-delayed
|
||||||
|
** variable/expression. It has a description of its "main" value plus a
|
||||||
|
** list of conditional jumps that can also produce its value (generated
|
||||||
|
** by short-circuit operators 'and'/'or').
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* kinds of variables/expressions */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VVOID, /* no value */
|
VVOID, /* when 'expdesc' describes the last expression a list,
|
||||||
VNIL,
|
this kind means an empty list (so, no expression) */
|
||||||
VTRUE,
|
VNIL, /* constant nil */
|
||||||
VFALSE,
|
VTRUE, /* constant true */
|
||||||
VK, /* info = index of constant in 'k' */
|
VFALSE, /* constant false */
|
||||||
VKFLT, /* nval = numerical float value */
|
VK, /* constant in 'k'; info = index of constant in 'k' */
|
||||||
VKINT, /* nval = numerical integer value */
|
VKFLT, /* floating constant; nval = numerical float value */
|
||||||
VNONRELOC, /* info = result register */
|
VKINT, /* integer constant; nval = numerical integer value */
|
||||||
VLOCAL, /* info = local register */
|
VNONRELOC, /* expression has its value in a fixed register;
|
||||||
VUPVAL, /* info = index of upvalue in 'upvalues' */
|
info = result register */
|
||||||
VINDEXED, /* t = table register/upvalue; idx = index R/K */
|
VLOCAL, /* local variable; info = local register */
|
||||||
VJMP, /* info = instruction pc */
|
VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */
|
||||||
VRELOCABLE, /* info = instruction pc */
|
VINDEXED, /* indexed variable;
|
||||||
VCALL, /* info = instruction pc */
|
ind.vt = whether 't' is register or upvalue;
|
||||||
VVARARG /* info = instruction pc */
|
ind.t = table register or upvalue;
|
||||||
|
ind.idx = key's R/K index */
|
||||||
|
VJMP, /* expression is a test/comparison;
|
||||||
|
info = pc of corresponding jump instruction */
|
||||||
|
VRELOCABLE, /* expression can put result in any register;
|
||||||
|
info = instruction pc */
|
||||||
|
VCALL, /* expression is a function call; info = instruction pc */
|
||||||
|
VVARARG /* vararg expression; info = instruction pc */
|
||||||
} expkind;
|
} expkind;
|
||||||
|
|
||||||
|
|
||||||
@@ -41,14 +54,14 @@ typedef enum {
|
|||||||
typedef struct expdesc {
|
typedef struct expdesc {
|
||||||
expkind k;
|
expkind k;
|
||||||
union {
|
union {
|
||||||
|
lua_Integer ival; /* for VKINT */
|
||||||
|
lua_Number nval; /* for VKFLT */
|
||||||
|
int info; /* for generic use */
|
||||||
struct { /* for indexed variables (VINDEXED) */
|
struct { /* for indexed variables (VINDEXED) */
|
||||||
short idx; /* index (R/K) */
|
short idx; /* index (R/K) */
|
||||||
lu_byte t; /* table (register or upvalue) */
|
lu_byte t; /* table (register or upvalue) */
|
||||||
lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
|
lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
|
||||||
} ind;
|
} ind;
|
||||||
int info; /* for generic use */
|
|
||||||
lua_Number nval; /* for VKFLT */
|
|
||||||
lua_Integer ival; /* for VKINT */
|
|
||||||
} u;
|
} u;
|
||||||
int t; /* patch list of 'exit when true' */
|
int t; /* patch list of 'exit when true' */
|
||||||
int f; /* patch list of 'exit when false' */
|
int f; /* patch list of 'exit when false' */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstate.h,v 2.128 2015/11/13 12:16:51 roberto Exp $
|
** $Id: lstate.h,v 2.130 2015/12/16 16:39:38 roberto Exp $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -33,6 +33,15 @@
|
|||||||
struct lua_longjmp; /* defined in ldo.c */
|
struct lua_longjmp; /* defined in ldo.c */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Atomic type (relative to signals) to better ensure that 'lua_sethook'
|
||||||
|
** is thread safe
|
||||||
|
*/
|
||||||
|
#if !defined(l_signalT)
|
||||||
|
#include <signal.h>
|
||||||
|
#define l_signalT sig_atomic_t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* extra stack space to handle TM calls and some other extras */
|
/* extra stack space to handle TM calls and some other extras */
|
||||||
#define EXTRA_STACK 5
|
#define EXTRA_STACK 5
|
||||||
@@ -162,14 +171,14 @@ struct lua_State {
|
|||||||
struct lua_State *twups; /* list of threads with open upvalues */
|
struct lua_State *twups; /* list of threads with open upvalues */
|
||||||
struct lua_longjmp *errorJmp; /* current error recover point */
|
struct lua_longjmp *errorJmp; /* current error recover point */
|
||||||
CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
|
CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
|
||||||
lua_Hook hook;
|
volatile lua_Hook hook;
|
||||||
ptrdiff_t errfunc; /* current error handling function (stack index) */
|
ptrdiff_t errfunc; /* current error handling function (stack index) */
|
||||||
int stacksize;
|
int stacksize;
|
||||||
int basehookcount;
|
int basehookcount;
|
||||||
int hookcount;
|
int hookcount;
|
||||||
unsigned short nny; /* number of non-yieldable calls in stack */
|
unsigned short nny; /* number of non-yieldable calls in stack */
|
||||||
unsigned short nCcalls; /* number of nested C calls */
|
unsigned short nCcalls; /* number of nested C calls */
|
||||||
lu_byte hookmask;
|
l_signalT hookmask;
|
||||||
lu_byte allowhook;
|
lu_byte allowhook;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstrlib.c,v 1.239 2015/11/25 16:28:17 roberto Exp $
|
** $Id: lstrlib.c,v 1.248 2016/05/02 13:58:01 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
|
||||||
*/
|
*/
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <locale.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -26,7 +27,8 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** maximum number of captures that a pattern can do during
|
** maximum number of captures that a pattern can do during
|
||||||
** pattern-matching. This limit is arbitrary.
|
** pattern-matching. This limit is arbitrary, but must fit in
|
||||||
|
** an unsigned char.
|
||||||
*/
|
*/
|
||||||
#if !defined(LUA_MAXCAPTURES)
|
#if !defined(LUA_MAXCAPTURES)
|
||||||
#define LUA_MAXCAPTURES 32
|
#define LUA_MAXCAPTURES 32
|
||||||
@@ -214,9 +216,8 @@ typedef struct MatchState {
|
|||||||
const char *src_end; /* end ('\0') of source string */
|
const char *src_end; /* end ('\0') of source string */
|
||||||
const char *p_end; /* end ('\0') of pattern */
|
const char *p_end; /* end ('\0') of pattern */
|
||||||
lua_State *L;
|
lua_State *L;
|
||||||
size_t nrep; /* limit to avoid non-linear complexity */
|
|
||||||
int matchdepth; /* control for recursive depth (to avoid C stack overflow) */
|
int matchdepth; /* control for recursive depth (to avoid C stack overflow) */
|
||||||
int level; /* total number of captures (finished or unfinished) */
|
unsigned char level; /* total number of captures (finished or unfinished) */
|
||||||
struct {
|
struct {
|
||||||
const char *init;
|
const char *init;
|
||||||
ptrdiff_t len;
|
ptrdiff_t len;
|
||||||
@@ -234,17 +235,6 @@ static const char *match (MatchState *ms, const char *s, const char *p);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** parameters to control the maximum number of operators handled in
|
|
||||||
** a match (to avoid non-linear complexity). The maximum will be:
|
|
||||||
** (subject length) * A_REPS + B_REPS
|
|
||||||
*/
|
|
||||||
#if !defined(A_REPS)
|
|
||||||
#define A_REPS 4
|
|
||||||
#define B_REPS 100000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define L_ESC '%'
|
#define L_ESC '%'
|
||||||
#define SPECIALS "^$*+?.([%-"
|
#define SPECIALS "^$*+?.([%-"
|
||||||
|
|
||||||
@@ -502,8 +492,6 @@ static const char *match (MatchState *ms, const char *s, const char *p) {
|
|||||||
s = NULL; /* fail */
|
s = NULL; /* fail */
|
||||||
}
|
}
|
||||||
else { /* matched once */
|
else { /* matched once */
|
||||||
if (ms->nrep-- == 0)
|
|
||||||
luaL_error(ms->L, "pattern too complex");
|
|
||||||
switch (*ep) { /* handle optional suffix */
|
switch (*ep) { /* handle optional suffix */
|
||||||
case '?': { /* optional */
|
case '?': { /* optional */
|
||||||
const char *res;
|
const char *res;
|
||||||
@@ -607,10 +595,6 @@ static void prepstate (MatchState *ms, lua_State *L,
|
|||||||
ms->src_init = s;
|
ms->src_init = s;
|
||||||
ms->src_end = s + ls;
|
ms->src_end = s + ls;
|
||||||
ms->p_end = p + lp;
|
ms->p_end = p + lp;
|
||||||
if (ls < (MAX_SIZET - B_REPS) / A_REPS)
|
|
||||||
ms->nrep = A_REPS * ls + B_REPS;
|
|
||||||
else /* overflow (very long subject) */
|
|
||||||
ms->nrep = MAX_SIZET; /* no limit */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -681,6 +665,7 @@ static int str_match (lua_State *L) {
|
|||||||
typedef struct GMatchState {
|
typedef struct GMatchState {
|
||||||
const char *src; /* current position */
|
const char *src; /* current position */
|
||||||
const char *p; /* pattern */
|
const char *p; /* pattern */
|
||||||
|
const char *lastmatch; /* end of last match */
|
||||||
MatchState ms; /* match state */
|
MatchState ms; /* match state */
|
||||||
} GMatchState;
|
} GMatchState;
|
||||||
|
|
||||||
@@ -688,14 +673,12 @@ typedef struct GMatchState {
|
|||||||
static int gmatch_aux (lua_State *L) {
|
static int gmatch_aux (lua_State *L) {
|
||||||
GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3));
|
GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3));
|
||||||
const char *src;
|
const char *src;
|
||||||
|
gm->ms.L = L;
|
||||||
for (src = gm->src; src <= gm->ms.src_end; src++) {
|
for (src = gm->src; src <= gm->ms.src_end; src++) {
|
||||||
const char *e;
|
const char *e;
|
||||||
reprepstate(&gm->ms);
|
reprepstate(&gm->ms);
|
||||||
if ((e = match(&gm->ms, src, gm->p)) != NULL) {
|
if ((e = match(&gm->ms, src, gm->p)) != NULL && e != gm->lastmatch) {
|
||||||
if (e == src) /* empty match? */
|
gm->src = gm->lastmatch = e;
|
||||||
gm->src =src + 1; /* go at least one position */
|
|
||||||
else
|
|
||||||
gm->src = e;
|
|
||||||
return push_captures(&gm->ms, src, e);
|
return push_captures(&gm->ms, src, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -711,7 +694,7 @@ static int gmatch (lua_State *L) {
|
|||||||
lua_settop(L, 2); /* keep them on closure to avoid being collected */
|
lua_settop(L, 2); /* keep them on closure to avoid being collected */
|
||||||
gm = (GMatchState *)lua_newuserdata(L, sizeof(GMatchState));
|
gm = (GMatchState *)lua_newuserdata(L, sizeof(GMatchState));
|
||||||
prepstate(&gm->ms, L, s, ls, p, lp);
|
prepstate(&gm->ms, L, s, ls, p, lp);
|
||||||
gm->src = s; gm->p = p;
|
gm->src = s; gm->p = p; gm->lastmatch = NULL;
|
||||||
lua_pushcclosure(L, gmatch_aux, 3);
|
lua_pushcclosure(L, gmatch_aux, 3);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -778,12 +761,13 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
|
|||||||
|
|
||||||
static int str_gsub (lua_State *L) {
|
static int str_gsub (lua_State *L) {
|
||||||
size_t srcl, lp;
|
size_t srcl, lp;
|
||||||
const char *src = luaL_checklstring(L, 1, &srcl);
|
const char *src = luaL_checklstring(L, 1, &srcl); /* subject */
|
||||||
const char *p = luaL_checklstring(L, 2, &lp);
|
const char *p = luaL_checklstring(L, 2, &lp); /* pattern */
|
||||||
int tr = lua_type(L, 3);
|
const char *lastmatch = NULL; /* end of last match */
|
||||||
lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1);
|
int tr = lua_type(L, 3); /* replacement type */
|
||||||
|
lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */
|
||||||
int anchor = (*p == '^');
|
int anchor = (*p == '^');
|
||||||
lua_Integer n = 0;
|
lua_Integer n = 0; /* replacement count */
|
||||||
MatchState ms;
|
MatchState ms;
|
||||||
luaL_Buffer b;
|
luaL_Buffer b;
|
||||||
luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
|
luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
|
||||||
@@ -796,16 +780,15 @@ static int str_gsub (lua_State *L) {
|
|||||||
prepstate(&ms, L, src, srcl, p, lp);
|
prepstate(&ms, L, src, srcl, p, lp);
|
||||||
while (n < max_s) {
|
while (n < max_s) {
|
||||||
const char *e;
|
const char *e;
|
||||||
reprepstate(&ms);
|
reprepstate(&ms); /* (re)prepare state for new match */
|
||||||
if ((e = match(&ms, src, p)) != NULL) {
|
if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */
|
||||||
n++;
|
n++;
|
||||||
add_value(&ms, &b, src, e, tr);
|
add_value(&ms, &b, src, e, tr); /* add replacement to buffer */
|
||||||
|
src = lastmatch = e;
|
||||||
}
|
}
|
||||||
if (e && e>src) /* non empty match? */
|
else if (src < ms.src_end) /* otherwise, skip one character */
|
||||||
src = e; /* skip it */
|
|
||||||
else if (src < ms.src_end)
|
|
||||||
luaL_addchar(&b, *src++);
|
luaL_addchar(&b, *src++);
|
||||||
else break;
|
else break; /* end of subject */
|
||||||
if (anchor) break;
|
if (anchor) break;
|
||||||
}
|
}
|
||||||
luaL_addlstring(&b, src, ms.src_end-src);
|
luaL_addlstring(&b, src, ms.src_end-src);
|
||||||
@@ -830,7 +813,6 @@ static int str_gsub (lua_State *L) {
|
|||||||
** Hexadecimal floating-point formatter
|
** Hexadecimal floating-point formatter
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <locale.h>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char))
|
#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char))
|
||||||
@@ -922,16 +904,14 @@ static int lua_number2strx (lua_State *L, char *buff, int sz,
|
|||||||
#define MAX_FORMAT 32
|
#define MAX_FORMAT 32
|
||||||
|
|
||||||
|
|
||||||
static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
|
static void addquoted (luaL_Buffer *b, const char *s, size_t len) {
|
||||||
size_t l;
|
|
||||||
const char *s = luaL_checklstring(L, arg, &l);
|
|
||||||
luaL_addchar(b, '"');
|
luaL_addchar(b, '"');
|
||||||
while (l--) {
|
while (len--) {
|
||||||
if (*s == '"' || *s == '\\' || *s == '\n') {
|
if (*s == '"' || *s == '\\' || *s == '\n') {
|
||||||
luaL_addchar(b, '\\');
|
luaL_addchar(b, '\\');
|
||||||
luaL_addchar(b, *s);
|
luaL_addchar(b, *s);
|
||||||
}
|
}
|
||||||
else if (*s == '\0' || iscntrl(uchar(*s))) {
|
else if (iscntrl(uchar(*s))) {
|
||||||
char buff[10];
|
char buff[10];
|
||||||
if (!isdigit(uchar(*(s+1))))
|
if (!isdigit(uchar(*(s+1))))
|
||||||
l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s));
|
l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s));
|
||||||
@@ -946,6 +926,52 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
|
|||||||
luaL_addchar(b, '"');
|
luaL_addchar(b, '"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Convert a Lua number to a string in floating-point hexadecimal
|
||||||
|
** format. Ensures the resulting string uses a dot as the radix
|
||||||
|
** character.
|
||||||
|
*/
|
||||||
|
static void addliteralnum (lua_State *L, luaL_Buffer *b, lua_Number n) {
|
||||||
|
char *buff = luaL_prepbuffsize(b, MAX_ITEM);
|
||||||
|
int nb = lua_number2strx(L, buff, MAX_ITEM,
|
||||||
|
"%" LUA_NUMBER_FRMLEN "a", n);
|
||||||
|
if (memchr(buff, '.', nb) == NULL) { /* no dot? */
|
||||||
|
char point = lua_getlocaledecpoint(); /* try locale point */
|
||||||
|
char *ppoint = memchr(buff, point, nb);
|
||||||
|
if (ppoint) *ppoint = '.'; /* change it to a dot */
|
||||||
|
}
|
||||||
|
luaL_addsize(b, nb);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void addliteral (lua_State *L, luaL_Buffer *b, int arg) {
|
||||||
|
switch (lua_type(L, arg)) {
|
||||||
|
case LUA_TSTRING: {
|
||||||
|
size_t len;
|
||||||
|
const char *s = lua_tolstring(L, arg, &len);
|
||||||
|
addquoted(b, s, len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LUA_TNUMBER: {
|
||||||
|
if (!lua_isinteger(L, arg)) { /* write floats as hexa ('%a') */
|
||||||
|
addliteralnum(L, b, lua_tonumber(L, arg));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* else integers; write in "native" format *//* FALLTHROUGH */
|
||||||
|
}
|
||||||
|
case LUA_TNIL: case LUA_TBOOLEAN: {
|
||||||
|
luaL_tolstring(L, arg, NULL);
|
||||||
|
luaL_addvalue(b);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
luaL_argerror(L, arg, "value has no literal form");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
|
static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
|
||||||
const char *p = strfrmt;
|
const char *p = strfrmt;
|
||||||
while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */
|
while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */
|
||||||
@@ -1025,7 +1051,7 @@ static int str_format (lua_State *L) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'q': {
|
case 'q': {
|
||||||
addquoted(L, &b, arg);
|
addliteral(L, &b, arg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 's': {
|
case 's': {
|
||||||
@@ -1070,8 +1096,8 @@ static int str_format (lua_State *L) {
|
|||||||
|
|
||||||
|
|
||||||
/* value used for padding */
|
/* value used for padding */
|
||||||
#if !defined(LUA_PACKPADBYTE)
|
#if !defined(LUAL_PACKPADBYTE)
|
||||||
#define LUA_PACKPADBYTE 0x00
|
#define LUAL_PACKPADBYTE 0x00
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* maximum size for the binary representation of an integer */
|
/* maximum size for the binary representation of an integer */
|
||||||
@@ -1308,7 +1334,7 @@ static int str_pack (lua_State *L) {
|
|||||||
KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
|
KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
|
||||||
totalsize += ntoalign + size;
|
totalsize += ntoalign + size;
|
||||||
while (ntoalign-- > 0)
|
while (ntoalign-- > 0)
|
||||||
luaL_addchar(&b, LUA_PACKPADBYTE); /* fill alignment */
|
luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */
|
||||||
arg++;
|
arg++;
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case Kint: { /* signed integers */
|
case Kint: { /* signed integers */
|
||||||
@@ -1348,7 +1374,7 @@ static int str_pack (lua_State *L) {
|
|||||||
else { /* string smaller than needed */
|
else { /* string smaller than needed */
|
||||||
luaL_addlstring(&b, s, len); /* add it all */
|
luaL_addlstring(&b, s, len); /* add it all */
|
||||||
while (len++ < (size_t)size) /* pad extra space */
|
while (len++ < (size_t)size) /* pad extra space */
|
||||||
luaL_addchar(&b, LUA_PACKPADBYTE);
|
luaL_addchar(&b, LUAL_PACKPADBYTE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1372,7 +1398,7 @@ static int str_pack (lua_State *L) {
|
|||||||
totalsize += len + 1;
|
totalsize += len + 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Kpadding: luaL_addchar(&b, LUA_PACKPADBYTE); /* FALLTHROUGH */
|
case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE); /* FALLTHROUGH */
|
||||||
case Kpaddalign: case Knop:
|
case Kpaddalign: case Knop:
|
||||||
arg--; /* undo increment */
|
arg--; /* undo increment */
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltablib.c,v 1.90 2015/11/25 12:48:57 roberto Exp $
|
** $Id: ltablib.c,v 1.93 2016/02/25 19:41:54 roberto Exp $
|
||||||
** Library for Table Manipulation
|
** Library for Table Manipulation
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -53,7 +53,7 @@ static void checktab (lua_State *L, int arg, int what) {
|
|||||||
lua_pop(L, n); /* pop metatable and tested metamethods */
|
lua_pop(L, n); /* pop metatable and tested metamethods */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
luaL_argerror(L, arg, "table expected"); /* force an error */
|
luaL_checktype(L, arg, LUA_TTABLE); /* force an error */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ static int tmove (lua_State *L) {
|
|||||||
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,
|
luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4,
|
||||||
"destination wrap around");
|
"destination wrap around");
|
||||||
if (t > e || t <= f || tt != 1) {
|
if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) {
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
lua_geti(L, 1, f + i);
|
lua_geti(L, 1, f + i);
|
||||||
lua_seti(L, tt, t + i);
|
lua_seti(L, tt, t + i);
|
||||||
@@ -152,7 +152,7 @@ static int tmove (lua_State *L) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lua_pushvalue(L, tt); /* return "to table" */
|
lua_pushvalue(L, tt); /* return destination table */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ static int tconcat (lua_State *L) {
|
|||||||
size_t lsep;
|
size_t lsep;
|
||||||
const char *sep = luaL_optlstring(L, 2, "", &lsep);
|
const char *sep = luaL_optlstring(L, 2, "", &lsep);
|
||||||
lua_Integer i = luaL_optinteger(L, 3, 1);
|
lua_Integer i = luaL_optinteger(L, 3, 1);
|
||||||
last = luaL_opt(L, luaL_checkinteger, 4, last);
|
last = luaL_optinteger(L, 4, last);
|
||||||
luaL_buffinit(L, &b);
|
luaL_buffinit(L, &b);
|
||||||
for (; i < last; i++) {
|
for (; i < last; i++) {
|
||||||
addfield(L, &b, i);
|
addfield(L, &b, i);
|
||||||
@@ -232,6 +232,10 @@ static int unpack (lua_State *L) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* type for array indices */
|
||||||
|
typedef unsigned int IdxT;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Produce a "random" 'unsigned int' to randomize pivot choice. This
|
** Produce a "random" 'unsigned int' to randomize pivot choice. This
|
||||||
** macro is used only when 'sort' detects a big imbalance in the result
|
** macro is used only when 'sort' detects a big imbalance in the result
|
||||||
@@ -270,7 +274,7 @@ static unsigned int l_randomizePivot (void) {
|
|||||||
#define RANLIMIT 100u
|
#define RANLIMIT 100u
|
||||||
|
|
||||||
|
|
||||||
static void set2 (lua_State *L, unsigned int i, unsigned int j) {
|
static void set2 (lua_State *L, IdxT i, IdxT j) {
|
||||||
lua_seti(L, 1, i);
|
lua_seti(L, 1, i);
|
||||||
lua_seti(L, 1, j);
|
lua_seti(L, 1, j);
|
||||||
}
|
}
|
||||||
@@ -303,10 +307,9 @@ static int sort_comp (lua_State *L, int a, int b) {
|
|||||||
** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up]
|
** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up]
|
||||||
** returns 'i'.
|
** returns 'i'.
|
||||||
*/
|
*/
|
||||||
static unsigned int partition (lua_State *L, unsigned int lo,
|
static IdxT partition (lua_State *L, IdxT lo, IdxT up) {
|
||||||
unsigned int up) {
|
IdxT i = lo; /* will be incremented before first use */
|
||||||
unsigned int i = lo; /* will be incremented before first use */
|
IdxT j = up - 1; /* will be decremented before first use */
|
||||||
unsigned int j = up - 1; /* will be decremented before first use */
|
|
||||||
/* loop invariant: a[lo .. i] <= P <= a[j .. up] */
|
/* loop invariant: a[lo .. i] <= P <= a[j .. up] */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* next loop: repeat ++i while a[i] < P */
|
/* next loop: repeat ++i while a[i] < P */
|
||||||
@@ -340,10 +343,9 @@ static unsigned int partition (lua_State *L, unsigned int lo,
|
|||||||
** Choose an element in the middle (2nd-3th quarters) of [lo,up]
|
** Choose an element in the middle (2nd-3th quarters) of [lo,up]
|
||||||
** "randomized" by 'rnd'
|
** "randomized" by 'rnd'
|
||||||
*/
|
*/
|
||||||
static unsigned int choosePivot (unsigned int lo, unsigned int up,
|
static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) {
|
||||||
unsigned int rnd) {
|
IdxT r4 = (up - lo) / 4; /* range/4 */
|
||||||
unsigned int r4 = (unsigned int)(up - lo) / 4u; /* range/4 */
|
IdxT p = rnd % (r4 * 2) + (lo + r4);
|
||||||
unsigned int p = rnd % (r4 * 2) + (lo + r4);
|
|
||||||
lua_assert(lo + r4 <= p && p <= up - r4);
|
lua_assert(lo + r4 <= p && p <= up - r4);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@@ -352,11 +354,11 @@ static unsigned int choosePivot (unsigned int lo, unsigned int up,
|
|||||||
/*
|
/*
|
||||||
** QuickSort algorithm (recursive function)
|
** QuickSort algorithm (recursive function)
|
||||||
*/
|
*/
|
||||||
static void auxsort (lua_State *L, unsigned int lo, unsigned int up,
|
static void auxsort (lua_State *L, IdxT lo, IdxT up,
|
||||||
unsigned int rnd) {
|
unsigned int rnd) {
|
||||||
while (lo < up) { /* loop for tail recursion */
|
while (lo < up) { /* loop for tail recursion */
|
||||||
unsigned int p; /* Pivot index */
|
IdxT p; /* Pivot index */
|
||||||
unsigned int n; /* to be used later */
|
IdxT n; /* to be used later */
|
||||||
/* sort elements 'lo', 'p', and 'up' */
|
/* sort elements 'lo', 'p', and 'up' */
|
||||||
lua_geti(L, 1, lo);
|
lua_geti(L, 1, lo);
|
||||||
lua_geti(L, 1, up);
|
lua_geti(L, 1, up);
|
||||||
@@ -400,7 +402,7 @@ static void auxsort (lua_State *L, unsigned int lo, unsigned int up,
|
|||||||
n = up - p; /* size of smaller interval */
|
n = up - p; /* size of smaller interval */
|
||||||
up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */
|
up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */
|
||||||
}
|
}
|
||||||
if ((up - lo) / 128u > n) /* partition too imbalanced? */
|
if ((up - lo) / 128 > n) /* partition too imbalanced? */
|
||||||
rnd = l_randomizePivot(); /* try a new randomization */
|
rnd = l_randomizePivot(); /* try a new randomization */
|
||||||
} /* tail call auxsort(L, lo, up, rnd) */
|
} /* tail call auxsort(L, lo, up, rnd) */
|
||||||
}
|
}
|
||||||
@@ -410,11 +412,10 @@ static int sort (lua_State *L) {
|
|||||||
lua_Integer n = aux_getn(L, 1, TAB_RW);
|
lua_Integer n = aux_getn(L, 1, TAB_RW);
|
||||||
if (n > 1) { /* non-trivial interval? */
|
if (n > 1) { /* non-trivial interval? */
|
||||||
luaL_argcheck(L, n < INT_MAX, 1, "array too big");
|
luaL_argcheck(L, n < INT_MAX, 1, "array too big");
|
||||||
luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
|
|
||||||
if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
|
if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
|
||||||
luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */
|
luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */
|
||||||
lua_settop(L, 2); /* make sure there are two arguments */
|
lua_settop(L, 2); /* make sure there are two arguments */
|
||||||
auxsort(L, 1, (unsigned int)n, 0u);
|
auxsort(L, 1, (IdxT)n, 0);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltm.c,v 2.36 2015/11/03 15:47:30 roberto Exp $
|
** $Id: ltm.c,v 2.37 2016/02/26 19:20:15 roberto Exp $
|
||||||
** Tag methods
|
** Tag methods
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -83,6 +83,22 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return the name of the type of an object. For tables and userdata
|
||||||
|
** with metatable, use their '__name' metafield, if present.
|
||||||
|
*/
|
||||||
|
const char *luaT_objtypename (lua_State *L, const TValue *o) {
|
||||||
|
Table *mt;
|
||||||
|
if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) ||
|
||||||
|
(ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) {
|
||||||
|
const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name"));
|
||||||
|
if (ttisstring(name)) /* is '__name' a string? */
|
||||||
|
return getstr(tsvalue(name)); /* use it as type name */
|
||||||
|
}
|
||||||
|
return ttypename(ttnov(o)); /* else use standard type name */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
|
void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
|
||||||
const TValue *p2, TValue *p3, int hasres) {
|
const TValue *p2, TValue *p3, int hasres) {
|
||||||
ptrdiff_t result = savestack(L, p3);
|
ptrdiff_t result = savestack(L, p3);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltm.h,v 2.21 2014/10/25 11:50:46 roberto Exp $
|
** $Id: ltm.h,v 2.22 2016/02/26 19:20:15 roberto Exp $
|
||||||
** Tag methods
|
** Tag methods
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -51,11 +51,12 @@ typedef enum {
|
|||||||
#define fasttm(l,et,e) gfasttm(G(l), et, e)
|
#define fasttm(l,et,e) gfasttm(G(l), et, e)
|
||||||
|
|
||||||
#define ttypename(x) luaT_typenames_[(x) + 1]
|
#define ttypename(x) luaT_typenames_[(x) + 1]
|
||||||
#define objtypename(x) ttypename(ttnov(x))
|
|
||||||
|
|
||||||
LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS];
|
LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS];
|
||||||
|
|
||||||
|
|
||||||
|
LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o);
|
||||||
|
|
||||||
LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
|
LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
|
||||||
LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
|
LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
|
||||||
TMS event);
|
TMS event);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lua.h,v 1.329 2015/11/13 17:18:42 roberto Exp $
|
** $Id: lua.h,v 1.330 2016/01/13 17:55:19 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,11 +19,11 @@
|
|||||||
#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 "2"
|
#define LUA_VERSION_RELEASE "3"
|
||||||
|
|
||||||
#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
|
||||||
#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2015 Lua.org, PUC-Rio"
|
#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2016 Lua.org, PUC-Rio"
|
||||||
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
|
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
|
||||||
|
|
||||||
|
|
||||||
@@ -467,7 +467,7 @@ LUA_API void (lua_checksig_)(lua_State *L);
|
|||||||
#define lua_checksig(L) if (skynet_sig_L) { lua_checksig_(L); }
|
#define lua_checksig(L) if (skynet_sig_L) { lua_checksig_(L); }
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Copyright (C) 1994-2015 Lua.org, PUC-Rio.
|
* Copyright (C) 1994-2016 Lua.org, PUC-Rio.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: luaconf.h,v 1.254 2015/10/21 18:17:40 roberto Exp $
|
** $Id: luaconf.h,v 1.255 2016/05/01 20:06:09 roberto Exp $
|
||||||
** Configuration file for Lua
|
** Configuration file for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -612,7 +612,7 @@
|
|||||||
** provide its own implementation.
|
** provide its own implementation.
|
||||||
*/
|
*/
|
||||||
#if !defined(LUA_USE_C89)
|
#if !defined(LUA_USE_C89)
|
||||||
#define lua_number2strx(L,b,sz,f,n) l_sprintf(b,sz,f,n)
|
#define lua_number2strx(L,b,sz,f,n) ((void)L, l_sprintf(b,sz,f,n))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
|
|||||||
luaD_inctop(L);
|
luaD_inctop(L);
|
||||||
cl->p = luaF_newproto(L, NULL);
|
cl->p = luaF_newproto(L, NULL);
|
||||||
LoadFunction(&S, cl->p, NULL);
|
LoadFunction(&S, cl->p, NULL);
|
||||||
lua_assert(cl->nupvalues == cl->p->sizeupvalues);
|
lua_assert(cl->nupvalues == cl->p->sp->sizeupvalues);
|
||||||
luai_verifycode(L, buff, cl->p);
|
luai_verifycode(L, buff, cl->p);
|
||||||
return cl;
|
return cl;
|
||||||
}
|
}
|
||||||
|
|||||||
104
3rd/lua/lvm.c
104
3rd/lua/lvm.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lvm.c,v 2.265 2015/11/23 11:30:45 roberto Exp $
|
** $Id: lvm.c,v 2.268 2016/02/05 19:59:14 roberto Exp $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -163,54 +163,67 @@ static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step,
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Complete a table access: if 't' is a table, 'tm' has its metamethod;
|
** Finish the table access 'val = t[key]'.
|
||||||
** otherwise, 'tm' is NULL.
|
** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to
|
||||||
|
** t[k] entry (which must be nil).
|
||||||
*/
|
*/
|
||||||
void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
|
void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
|
||||||
const TValue *tm) {
|
const TValue *slot) {
|
||||||
int loop; /* counter to avoid infinite loops */
|
int loop; /* counter to avoid infinite loops */
|
||||||
lua_assert(tm != NULL || !ttistable(t));
|
const TValue *tm; /* metamethod */
|
||||||
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
||||||
if (tm == NULL) { /* no metamethod (from a table)? */
|
if (slot == NULL) { /* 't' is not a table? */
|
||||||
if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
|
lua_assert(!ttistable(t));
|
||||||
|
tm = luaT_gettmbyobj(L, t, TM_INDEX);
|
||||||
|
if (ttisnil(tm))
|
||||||
luaG_typeerror(L, t, "index"); /* no metamethod */
|
luaG_typeerror(L, t, "index"); /* no metamethod */
|
||||||
|
/* else will try the metamethod */
|
||||||
}
|
}
|
||||||
if (ttisfunction(tm)) { /* metamethod is a function */
|
else { /* 't' is a table */
|
||||||
|
lua_assert(ttisnil(slot));
|
||||||
|
tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */
|
||||||
|
if (tm == NULL) { /* no metamethod? */
|
||||||
|
setnilvalue(val); /* result is nil */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* else will try the metamethod */
|
||||||
|
}
|
||||||
|
if (ttisfunction(tm)) { /* is metamethod a function? */
|
||||||
luaT_callTM(L, tm, t, key, val, 1); /* call it */
|
luaT_callTM(L, tm, t, key, val, 1); /* call it */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
t = tm; /* else repeat access over 'tm' */
|
t = tm; /* else try to access 'tm[key]' */
|
||||||
if (luaV_fastget(L,t,key,tm,luaH_get)) { /* try fast track */
|
if (luaV_fastget(L,t,key,slot,luaH_get)) { /* fast track? */
|
||||||
setobj2s(L, val, tm); /* done */
|
setobj2s(L, val, slot); /* done */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* else repeat */
|
/* else repeat (tail call 'luaV_finishget') */
|
||||||
}
|
}
|
||||||
luaG_runerror(L, "gettable chain too long; possible loop");
|
luaG_runerror(L, "'__index' chain too long; possible loop");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Main function for table assignment (invoking metamethods if needed).
|
** Finish a table assignment 't[key] = val'.
|
||||||
** Compute 't[key] = val'
|
** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points
|
||||||
|
** to the entry 't[key]', or to 'luaO_nilobject' if there is no such
|
||||||
|
** entry. (The value at 'slot' must be nil, otherwise 'luaV_fastset'
|
||||||
|
** would have done the job.)
|
||||||
*/
|
*/
|
||||||
void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
|
void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
|
||||||
StkId val, const TValue *oldval) {
|
StkId val, const TValue *slot) {
|
||||||
int loop; /* counter to avoid infinite loops */
|
int loop; /* counter to avoid infinite loops */
|
||||||
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
||||||
const TValue *tm;
|
const TValue *tm; /* '__newindex' metamethod */
|
||||||
if (oldval != NULL) {
|
if (slot != NULL) { /* is 't' a table? */
|
||||||
Table *h = hvalue(t);
|
Table *h = hvalue(t); /* save 't' table */
|
||||||
lua_assert(ttisnil(oldval));
|
lua_assert(ttisnil(slot)); /* old value must be nil */
|
||||||
/* must check the metamethod */
|
tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
|
||||||
if ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL &&
|
if (tm == NULL) { /* no metamethod? */
|
||||||
/* no metamethod; is there a previous entry in the table? */
|
if (slot == luaO_nilobject) /* no previous entry? */
|
||||||
(oldval != luaO_nilobject ||
|
slot = luaH_newkey(L, h, key); /* create one */
|
||||||
/* no previous entry; must create one. (The next test is
|
|
||||||
always true; we only need the assignment.) */
|
|
||||||
(oldval = luaH_newkey(L, h, key), 1))) {
|
|
||||||
/* no metamethod and (now) there is an entry with given key */
|
/* no metamethod and (now) there is an entry with given key */
|
||||||
setobj2t(L, cast(TValue *, oldval), val);
|
setobj2t(L, cast(TValue *, slot), val); /* set its new value */
|
||||||
invalidateTMcache(h);
|
invalidateTMcache(h);
|
||||||
luaC_barrierback(L, h, val);
|
luaC_barrierback(L, h, val);
|
||||||
return;
|
return;
|
||||||
@@ -227,11 +240,11 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
t = tm; /* else repeat assignment over 'tm' */
|
t = tm; /* else repeat assignment over 'tm' */
|
||||||
if (luaV_fastset(L, t, key, oldval, luaH_get, val))
|
if (luaV_fastset(L, t, key, slot, luaH_get, val))
|
||||||
return; /* done */
|
return; /* done */
|
||||||
/* else loop */
|
/* else loop */
|
||||||
}
|
}
|
||||||
luaG_runerror(L, "settable chain too long; possible loop");
|
luaG_runerror(L, "'__newindex' chain too long; possible loop");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -749,18 +762,28 @@ void luaV_finishOp (lua_State *L) {
|
|||||||
luai_threadyield(L); }
|
luai_threadyield(L); }
|
||||||
|
|
||||||
|
|
||||||
|
/* fetch an instruction and prepare its execution */
|
||||||
|
#define vmfetch() { \
|
||||||
|
i = *(ci->u.l.savedpc++); \
|
||||||
|
if (L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) \
|
||||||
|
Protect(luaG_traceexec(L)); \
|
||||||
|
ra = RA(i); /* WARNING: any stack reallocation invalidates 'ra' */ \
|
||||||
|
lua_assert(base == ci->u.l.base); \
|
||||||
|
lua_assert(base <= L->top && L->top < L->stack + L->stacksize); \
|
||||||
|
}
|
||||||
|
|
||||||
#define vmdispatch(o) switch(o)
|
#define vmdispatch(o) switch(o)
|
||||||
#define vmcase(l) case l:
|
#define vmcase(l) case l:
|
||||||
#define vmbreak break
|
#define vmbreak break
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** copy of 'luaV_gettable', but protecting call to potential metamethod
|
** copy of 'luaV_gettable', but protecting the call to potential
|
||||||
** (which can reallocate the stack)
|
** metamethod (which can reallocate the stack)
|
||||||
*/
|
*/
|
||||||
#define gettableProtected(L,t,k,v) { const TValue *aux; \
|
#define gettableProtected(L,t,k,v) { const TValue *slot; \
|
||||||
if (luaV_fastget(L,t,k,aux,luaH_get)) { setobj2s(L, v, aux); } \
|
if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
|
||||||
else Protect(luaV_finishget(L,t,k,v,aux)); }
|
else Protect(luaV_finishget(L,t,k,v,slot)); }
|
||||||
|
|
||||||
|
|
||||||
/* same for 'luaV_settable' */
|
/* same for 'luaV_settable' */
|
||||||
@@ -783,14 +806,9 @@ void luaV_execute (lua_State *L) {
|
|||||||
base = ci->u.l.base; /* local copy of function's base */
|
base = ci->u.l.base; /* local copy of function's base */
|
||||||
/* main loop of interpreter */
|
/* main loop of interpreter */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Instruction i = *(ci->u.l.savedpc++);
|
Instruction i;
|
||||||
StkId ra;
|
StkId ra;
|
||||||
if (L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT))
|
vmfetch();
|
||||||
Protect(luaG_traceexec(L));
|
|
||||||
/* WARNING: several calls may realloc the stack and invalidate 'ra' */
|
|
||||||
ra = RA(i);
|
|
||||||
lua_assert(base == ci->u.l.base);
|
|
||||||
lua_assert(base <= L->top && L->top < L->stack + L->stacksize);
|
|
||||||
vmdispatch (GET_OPCODE(i)) {
|
vmdispatch (GET_OPCODE(i)) {
|
||||||
vmcase(OP_MOVE) {
|
vmcase(OP_MOVE) {
|
||||||
setobjs2s(L, ra, RB(i));
|
setobjs2s(L, ra, RB(i));
|
||||||
@@ -1163,7 +1181,7 @@ void luaV_execute (lua_State *L) {
|
|||||||
oci->u.l.savedpc = nci->u.l.savedpc;
|
oci->u.l.savedpc = nci->u.l.savedpc;
|
||||||
oci->callstatus |= CIST_TAIL; /* function was tail called */
|
oci->callstatus |= CIST_TAIL; /* function was tail called */
|
||||||
ci = L->ci = oci; /* remove new frame */
|
ci = L->ci = oci; /* remove new frame */
|
||||||
lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize);
|
lua_assert(L->top == oci->u.l.base + getproto(ofunc)->sp->maxstacksize);
|
||||||
goto newframe; /* restart luaV_execute over new Lua function */
|
goto newframe; /* restart luaV_execute over new Lua function */
|
||||||
}
|
}
|
||||||
vmbreak;
|
vmbreak;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lvm.h,v 2.39 2015/09/09 13:44:07 roberto Exp $
|
** $Id: lvm.h,v 2.40 2016/01/05 16:07:21 roberto Exp $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -49,25 +49,24 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** fast track for 'gettable': 1 means 'aux' points to resulted value;
|
** fast track for 'gettable': if 't' is a table and 't[k]' is not nil,
|
||||||
** 0 means 'aux' is metamethod (if 't' is a table) or NULL. 'f' is
|
** return 1 with 'slot' pointing to 't[k]' (final result). Otherwise,
|
||||||
** the raw get function to use.
|
** return 0 (meaning it will have to check metamethod) with 'slot'
|
||||||
|
** pointing to a nil 't[k]' (if 't' is a table) or NULL (otherwise).
|
||||||
|
** 'f' is the raw get function to use.
|
||||||
*/
|
*/
|
||||||
#define luaV_fastget(L,t,k,aux,f) \
|
#define luaV_fastget(L,t,k,slot,f) \
|
||||||
(!ttistable(t) \
|
(!ttistable(t) \
|
||||||
? (aux = NULL, 0) /* not a table; 'aux' is NULL and result is 0 */ \
|
? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
|
||||||
: (aux = f(hvalue(t), k), /* else, do raw access */ \
|
: (slot = f(hvalue(t), k), /* else, do raw access */ \
|
||||||
!ttisnil(aux) ? 1 /* result not nil? 'aux' has it */ \
|
!ttisnil(slot))) /* result not nil? */
|
||||||
: (aux = fasttm(L, hvalue(t)->metatable, TM_INDEX), /* get metamethod */\
|
|
||||||
aux != NULL ? 0 /* has metamethod? must call it */ \
|
|
||||||
: (aux = luaO_nilobject, 1)))) /* else, final result is nil */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** standard implementation for 'gettable'
|
** standard implementation for 'gettable'
|
||||||
*/
|
*/
|
||||||
#define luaV_gettable(L,t,k,v) { const TValue *aux; \
|
#define luaV_gettable(L,t,k,v) { const TValue *slot; \
|
||||||
if (luaV_fastget(L,t,k,aux,luaH_get)) { setobj2s(L, v, aux); } \
|
if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
|
||||||
else luaV_finishget(L,t,k,v,aux); }
|
else luaV_finishget(L,t,k,v,slot); }
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -100,9 +99,9 @@ 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, int mode);
|
LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode);
|
||||||
LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
|
LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
|
||||||
StkId val, const TValue *tm);
|
StkId val, const TValue *slot);
|
||||||
LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
|
LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
|
||||||
StkId val, const TValue *oldval);
|
StkId val, const TValue *slot);
|
||||||
LUAI_FUNC void luaV_finishOp (lua_State *L);
|
LUAI_FUNC void luaV_finishOp (lua_State *L);
|
||||||
LUAI_FUNC void luaV_execute (lua_State *L);
|
LUAI_FUNC void luaV_execute (lua_State *L);
|
||||||
LUAI_FUNC void luaV_concat (lua_State *L, int total);
|
LUAI_FUNC void luaV_concat (lua_State *L, int total);
|
||||||
|
|||||||
15
HISTORY.md
15
HISTORY.md
@@ -1,4 +1,17 @@
|
|||||||
v1.0.0-rc2 (2015-3-7)
|
v1.0.0-rc3 (2016-5-9)
|
||||||
|
-----------
|
||||||
|
* Update jemalloc 4.1.1
|
||||||
|
* Update lua 5.3.3 rc1
|
||||||
|
* Update sproto to support encoding empty table
|
||||||
|
* Make skynet.init stable (keep order)
|
||||||
|
* skynet.getenv can return empty string
|
||||||
|
* Add lua VM memory warning
|
||||||
|
* lua VM support memory limit
|
||||||
|
* skynet.pcall suport varargs
|
||||||
|
* Bugfix : Global name query
|
||||||
|
* Bugfix : snax.queryglobal
|
||||||
|
|
||||||
|
v1.0.0-rc2 (2016-3-7)
|
||||||
-----------
|
-----------
|
||||||
* Fix a bug in lua 5.3.2
|
* Fix a bug in lua 5.3.2
|
||||||
* Update sproto (fix bugs and add ud for package)
|
* Update sproto (fix bugs and add ud for package)
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -1,6 +1,6 @@
|
|||||||
## Build
|
## Build
|
||||||
|
|
||||||
For linux, install autoconf first for jemalloc
|
For Linux, install autoconf first for jemalloc:
|
||||||
|
|
||||||
```
|
```
|
||||||
git clone https://github.com/cloudwu/skynet.git
|
git clone https://github.com/cloudwu/skynet.git
|
||||||
@@ -8,18 +8,18 @@ cd skynet
|
|||||||
make 'PLATFORM' # PLATFORM can be linux, macosx, freebsd now
|
make 'PLATFORM' # PLATFORM can be linux, macosx, freebsd now
|
||||||
```
|
```
|
||||||
|
|
||||||
Or you can :
|
Or you can:
|
||||||
|
|
||||||
```
|
```
|
||||||
export PLAT=linux
|
export PLAT=linux
|
||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
For freeBSD , use gmake instead of make .
|
For FreeBSD , use gmake instead of make.
|
||||||
|
|
||||||
## Test
|
## Test
|
||||||
|
|
||||||
Run these in different console
|
Run these in different consoles:
|
||||||
|
|
||||||
```
|
```
|
||||||
./skynet examples/config # Launch first skynet node (Gate server) and a skynet-master (see config for standalone option)
|
./skynet examples/config # Launch first skynet node (Gate server) and a skynet-master (see config for standalone option)
|
||||||
@@ -28,11 +28,11 @@ Run these in different console
|
|||||||
|
|
||||||
## About Lua
|
## About Lua
|
||||||
|
|
||||||
Skynet now use a modify version of lua 5.3.2 ( http://www.lua.org/ftp/lua-5.3.2.tar.gz ) .
|
Skynet now uses a modified version of lua 5.3.2 ( http://www.lua.org/ftp/lua-5.3.2.tar.gz ) .
|
||||||
|
|
||||||
For detail : http://lua-users.org/lists/lua-l/2014-03/msg00489.html
|
For details: http://lua-users.org/lists/lua-l/2014-03/msg00489.html
|
||||||
|
|
||||||
You can also use the other official Lua version , edit the makefile by yourself .
|
You can also use other official Lua versions, just edit the Makefile by yourself.
|
||||||
|
|
||||||
## How To Use (Sorry, Only in Chinese now)
|
## How To Use (Sorry, Only in Chinese now)
|
||||||
|
|
||||||
|
|||||||
30
examples/checkdeadloop.lua
Normal file
30
examples/checkdeadloop.lua
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
local skynet = require "skynet"
|
||||||
|
|
||||||
|
local list = {}
|
||||||
|
|
||||||
|
local function timeout_check(ti)
|
||||||
|
if not next(list) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
skynet.sleep(ti) -- sleep 10 sec
|
||||||
|
for k,v in pairs(list) do
|
||||||
|
skynet.error("timout",ti,k,v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
skynet.start(function()
|
||||||
|
skynet.error("ping all")
|
||||||
|
local list_ret = skynet.call(".launcher", "lua", "LIST")
|
||||||
|
for addr, desc in pairs(list_ret) do
|
||||||
|
list[addr] = desc
|
||||||
|
skynet.fork(function()
|
||||||
|
skynet.call(addr,"debug","INFO")
|
||||||
|
list[addr] = nil
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
skynet.sleep(0)
|
||||||
|
timeout_check(100)
|
||||||
|
timeout_check(400)
|
||||||
|
timeout_check(500)
|
||||||
|
skynet.exit()
|
||||||
|
end)
|
||||||
@@ -4,7 +4,7 @@ local sprotoloader = require "sprotoloader"
|
|||||||
local max_client = 64
|
local max_client = 64
|
||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
print("Server start")
|
skynet.error("Server start")
|
||||||
skynet.uniqueservice("protoloader")
|
skynet.uniqueservice("protoloader")
|
||||||
local console = skynet.newservice("console")
|
local console = skynet.newservice("console")
|
||||||
skynet.newservice("debug_console",8000)
|
skynet.newservice("debug_console",8000)
|
||||||
@@ -15,7 +15,6 @@ skynet.start(function()
|
|||||||
maxclient = max_client,
|
maxclient = max_client,
|
||||||
nodelay = true,
|
nodelay = true,
|
||||||
})
|
})
|
||||||
print("Watchdog listen on ", 8888)
|
skynet.error("Watchdog listen on", 8888)
|
||||||
|
|
||||||
skynet.exit()
|
skynet.exit()
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -551,7 +551,7 @@ seri(lua_State *L, struct block *b, int len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_luaseri_unpack(lua_State *L) {
|
luaseri_unpack(lua_State *L) {
|
||||||
if (lua_isnoneornil(L,1)) {
|
if (lua_isnoneornil(L,1)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -595,7 +595,7 @@ _luaseri_unpack(lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_luaseri_pack(lua_State *L) {
|
luaseri_pack(lua_State *L) {
|
||||||
struct block temp;
|
struct block temp;
|
||||||
temp.next = NULL;
|
temp.next = NULL;
|
||||||
struct write_block wb;
|
struct write_block wb;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
|
|
||||||
int _luaseri_pack(lua_State *L);
|
int luaseri_pack(lua_State *L);
|
||||||
int _luaseri_unpack(lua_State *L);
|
int luaseri_unpack(lua_State *L);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ forward_cb(struct skynet_context * context, void * ud, int type, int session, ui
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_callback(lua_State *L) {
|
lcallback(lua_State *L) {
|
||||||
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
||||||
int forward = lua_toboolean(L, 2);
|
int forward = lua_toboolean(L, 2);
|
||||||
luaL_checktype(L,1,LUA_TFUNCTION);
|
luaL_checktype(L,1,LUA_TFUNCTION);
|
||||||
@@ -101,7 +101,7 @@ _callback(lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_command(lua_State *L) {
|
lcommand(lua_State *L) {
|
||||||
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
||||||
const char * cmd = luaL_checkstring(L,1);
|
const char * cmd = luaL_checkstring(L,1);
|
||||||
const char * result;
|
const char * result;
|
||||||
@@ -119,7 +119,7 @@ _command(lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_intcommand(lua_State *L) {
|
lintcommand(lua_State *L) {
|
||||||
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
||||||
const char * cmd = luaL_checkstring(L,1);
|
const char * cmd = luaL_checkstring(L,1);
|
||||||
const char * result;
|
const char * result;
|
||||||
@@ -141,7 +141,7 @@ _intcommand(lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_genid(lua_State *L) {
|
lgenid(lua_State *L) {
|
||||||
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
||||||
int session = skynet_send(context, 0, 0, PTYPE_TAG_ALLOCSESSION , 0 , NULL, 0);
|
int session = skynet_send(context, 0, 0, PTYPE_TAG_ALLOCSESSION , 0 , NULL, 0);
|
||||||
lua_pushinteger(L, session);
|
lua_pushinteger(L, session);
|
||||||
@@ -167,7 +167,7 @@ get_dest_string(lua_State *L, int index) {
|
|||||||
integer len
|
integer len
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_send(lua_State *L) {
|
lsend(lua_State *L) {
|
||||||
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
||||||
uint32_t dest = (uint32_t)lua_tointeger(L, 1);
|
uint32_t dest = (uint32_t)lua_tointeger(L, 1);
|
||||||
const char * dest_string = NULL;
|
const char * dest_string = NULL;
|
||||||
@@ -224,7 +224,7 @@ _send(lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_redirect(lua_State *L) {
|
lredirect(lua_State *L) {
|
||||||
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
||||||
uint32_t dest = (uint32_t)lua_tointeger(L,1);
|
uint32_t dest = (uint32_t)lua_tointeger(L,1);
|
||||||
const char * dest_string = NULL;
|
const char * dest_string = NULL;
|
||||||
@@ -267,14 +267,32 @@ _redirect(lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_error(lua_State *L) {
|
lerror(lua_State *L) {
|
||||||
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
||||||
skynet_error(context, "%s", luaL_checkstring(L,1));
|
int n = lua_gettop(L);
|
||||||
|
if (n <= 1) {
|
||||||
|
lua_settop(L, 1);
|
||||||
|
const char * s = luaL_tolstring(L, 1, NULL);
|
||||||
|
skynet_error(context, "%s", s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
luaL_Buffer b;
|
||||||
|
luaL_buffinit(L, &b);
|
||||||
|
int i;
|
||||||
|
for (i=1; i<=n; i++) {
|
||||||
|
luaL_tolstring(L, i, NULL);
|
||||||
|
luaL_addvalue(&b);
|
||||||
|
if (i<n) {
|
||||||
|
luaL_addchar(&b, ' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
luaL_pushresult(&b);
|
||||||
|
skynet_error(context, "%s", lua_tostring(L, -1));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_tostring(lua_State *L) {
|
ltostring(lua_State *L) {
|
||||||
if (lua_isnoneornil(L,1)) {
|
if (lua_isnoneornil(L,1)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -285,7 +303,7 @@ _tostring(lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_harbor(lua_State *L) {
|
lharbor(lua_State *L) {
|
||||||
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
||||||
uint32_t handle = (uint32_t)luaL_checkinteger(L,1);
|
uint32_t handle = (uint32_t)luaL_checkinteger(L,1);
|
||||||
int harbor = 0;
|
int harbor = 0;
|
||||||
@@ -298,7 +316,7 @@ _harbor(lua_State *L) {
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
lpackstring(lua_State *L) {
|
lpackstring(lua_State *L) {
|
||||||
_luaseri_pack(L);
|
luaseri_pack(L);
|
||||||
char * str = (char *)lua_touserdata(L, -2);
|
char * str = (char *)lua_touserdata(L, -2);
|
||||||
int sz = lua_tointeger(L, -1);
|
int sz = lua_tointeger(L, -1);
|
||||||
lua_pushlstring(L, str, sz);
|
lua_pushlstring(L, str, sz);
|
||||||
@@ -338,19 +356,19 @@ luaopen_skynet_core(lua_State *L) {
|
|||||||
luaL_checkversion(L);
|
luaL_checkversion(L);
|
||||||
|
|
||||||
luaL_Reg l[] = {
|
luaL_Reg l[] = {
|
||||||
{ "send" , _send },
|
{ "send" , lsend },
|
||||||
{ "genid", _genid },
|
{ "genid", lgenid },
|
||||||
{ "redirect", _redirect },
|
{ "redirect", lredirect },
|
||||||
{ "command" , _command },
|
{ "command" , lcommand },
|
||||||
{ "intcommand", _intcommand },
|
{ "intcommand", lintcommand },
|
||||||
{ "error", _error },
|
{ "error", lerror },
|
||||||
{ "tostring", _tostring },
|
{ "tostring", ltostring },
|
||||||
{ "harbor", _harbor },
|
{ "harbor", lharbor },
|
||||||
{ "pack", _luaseri_pack },
|
{ "pack", luaseri_pack },
|
||||||
{ "unpack", _luaseri_unpack },
|
{ "unpack", luaseri_unpack },
|
||||||
{ "packstring", lpackstring },
|
{ "packstring", lpackstring },
|
||||||
{ "trash" , ltrash },
|
{ "trash" , ltrash },
|
||||||
{ "callback", _callback },
|
{ "callback", lcallback },
|
||||||
{ "now", lnow },
|
{ "now", lnow },
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -210,13 +210,13 @@ Each integer number must be serialized in little-endian format.
|
|||||||
The sproto message must be a user defined type struct, and a struct is encoded in three parts. The header, the field part, and the data part.
|
The sproto message must be a user defined type struct, and a struct is encoded in three parts. The header, the field part, and the data part.
|
||||||
The tag and small integer or boolean will be encoded in field part, and others are in data part.
|
The tag and small integer or boolean will be encoded in field part, and others are in data part.
|
||||||
|
|
||||||
All the fields must be encoded in ascending order (by tag). The tags of fields can be discontinuous, if a field is nil. (default value in lua), don't encode it in message.
|
All the fields must be encoded in ascending order (by tag, base 0). The tags of fields can be discontinuous, if a field is nil. (default value in lua), don't encode it in message.
|
||||||
|
|
||||||
The header is a 16bit integer. It is the number of fields.
|
The header is a 16bit integer. It is the number of fields.
|
||||||
|
|
||||||
Each field in field part is a 16bit integer (n). If n is zero, that means the field data is encoded in data part ;
|
Each field in field part is a 16bit integer (n). If n is zero, that means the field data is encoded in data part ;
|
||||||
|
|
||||||
If n is even (and not zero), the value of this field is n/2-1 ;
|
If n is even (and not zero), the value of this field is n/2-1 , and the tag increases 1;
|
||||||
|
|
||||||
If n is odd, that means the tags is not continuous, and we should add current tag by (n+1)/2 .
|
If n is odd, that means the tags is not continuous, and we should add current tag by (n+1)/2 .
|
||||||
|
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ encode(const struct sproto_arg *args) {
|
|||||||
lua_replace(L, self->array_index);
|
lua_replace(L, self->array_index);
|
||||||
}
|
}
|
||||||
self->array_index = 0;
|
self->array_index = 0;
|
||||||
return 0;
|
return SPROTO_CB_NOARRAY;
|
||||||
}
|
}
|
||||||
if (!lua_istable(L, -1)) {
|
if (!lua_istable(L, -1)) {
|
||||||
return luaL_error(L, ".*%s(%d) should be a table (Is a %s)",
|
return luaL_error(L, ".*%s(%d) should be a table (Is a %s)",
|
||||||
@@ -147,7 +147,7 @@ encode(const struct sproto_arg *args) {
|
|||||||
// iterate end
|
// iterate end
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
lua_replace(L, self->iter_index);
|
lua_replace(L, self->iter_index);
|
||||||
return 0;
|
return SPROTO_CB_NIL;
|
||||||
}
|
}
|
||||||
lua_insert(L, -2);
|
lua_insert(L, -2);
|
||||||
lua_replace(L, self->iter_index);
|
lua_replace(L, self->iter_index);
|
||||||
@@ -159,7 +159,7 @@ encode(const struct sproto_arg *args) {
|
|||||||
}
|
}
|
||||||
if (lua_isnil(L, -1)) {
|
if (lua_isnil(L, -1)) {
|
||||||
lua_pop(L,1);
|
lua_pop(L,1);
|
||||||
return 0;
|
return SPROTO_CB_NIL;
|
||||||
}
|
}
|
||||||
switch (args->type) {
|
switch (args->type) {
|
||||||
case SPROTO_TINTEGER: {
|
case SPROTO_TINTEGER: {
|
||||||
@@ -203,10 +203,10 @@ encode(const struct sproto_arg *args) {
|
|||||||
str = lua_tolstring(L, -1, &sz);
|
str = lua_tolstring(L, -1, &sz);
|
||||||
}
|
}
|
||||||
if (sz > args->length)
|
if (sz > args->length)
|
||||||
return -1;
|
return SPROTO_CB_ERROR;
|
||||||
memcpy(args->value, str, sz);
|
memcpy(args->value, str, sz);
|
||||||
lua_pop(L,1);
|
lua_pop(L,1);
|
||||||
return sz + 1; // The length of empty string is 1.
|
return sz;
|
||||||
}
|
}
|
||||||
case SPROTO_TSTRUCT: {
|
case SPROTO_TSTRUCT: {
|
||||||
struct encode_ud sub;
|
struct encode_ud sub;
|
||||||
@@ -226,6 +226,8 @@ encode(const struct sproto_arg *args) {
|
|||||||
sub.iter_index = sub.tbl_index + 1;
|
sub.iter_index = sub.tbl_index + 1;
|
||||||
r = sproto_encode(args->subtype, args->value, args->length, encode, &sub);
|
r = sproto_encode(args->subtype, args->value, args->length, encode, &sub);
|
||||||
lua_settop(L, top-1); // pop the value
|
lua_settop(L, top-1); // pop the value
|
||||||
|
if (r < 0)
|
||||||
|
return SPROTO_CB_ERROR;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -309,7 +311,7 @@ decode(const struct sproto_arg *args) {
|
|||||||
lua_State *L = self->L;
|
lua_State *L = self->L;
|
||||||
if (self->deep >= ENCODE_DEEPLEVEL)
|
if (self->deep >= ENCODE_DEEPLEVEL)
|
||||||
return luaL_error(L, "The table is too deep");
|
return luaL_error(L, "The table is too deep");
|
||||||
if (args->index > 0) {
|
if (args->index != 0) {
|
||||||
// It's array
|
// It's array
|
||||||
if (args->tagname != self->array_tag) {
|
if (args->tagname != self->array_tag) {
|
||||||
self->array_tag = args->tagname;
|
self->array_tag = args->tagname;
|
||||||
@@ -321,6 +323,10 @@ decode(const struct sproto_arg *args) {
|
|||||||
} else {
|
} else {
|
||||||
self->array_index = lua_gettop(L);
|
self->array_index = lua_gettop(L);
|
||||||
}
|
}
|
||||||
|
if (args->index < 0) {
|
||||||
|
// It's a empty array, return now.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (args->type) {
|
switch (args->type) {
|
||||||
@@ -355,9 +361,10 @@ decode(const struct sproto_arg *args) {
|
|||||||
sub.key_index = lua_gettop(L);
|
sub.key_index = lua_gettop(L);
|
||||||
|
|
||||||
r = sproto_decode(args->subtype, args->value, args->length, decode, &sub);
|
r = sproto_decode(args->subtype, args->value, args->length, decode, &sub);
|
||||||
if (r < 0 || r != args->length)
|
if (r < 0)
|
||||||
|
return SPROTO_CB_ERROR;
|
||||||
|
if (r != args->length)
|
||||||
return r;
|
return r;
|
||||||
// assert(args->index > 0);
|
|
||||||
lua_pushvalue(L, sub.key_index);
|
lua_pushvalue(L, sub.key_index);
|
||||||
if (lua_isnil(L, -1)) {
|
if (lua_isnil(L, -1)) {
|
||||||
luaL_error(L, "Can't find main index (tag=%d) in [%s]", args->mainindex, args->tagname);
|
luaL_error(L, "Can't find main index (tag=%d) in [%s]", args->mainindex, args->tagname);
|
||||||
@@ -370,7 +377,9 @@ decode(const struct sproto_arg *args) {
|
|||||||
sub.mainindex_tag = -1;
|
sub.mainindex_tag = -1;
|
||||||
sub.key_index = 0;
|
sub.key_index = 0;
|
||||||
r = sproto_decode(args->subtype, args->value, args->length, decode, &sub);
|
r = sproto_decode(args->subtype, args->value, args->length, decode, &sub);
|
||||||
if (r < 0 || r != args->length)
|
if (r < 0)
|
||||||
|
return SPROTO_CB_ERROR;
|
||||||
|
if (r != args->length)
|
||||||
return r;
|
return r;
|
||||||
lua_settop(L, sub.result_index);
|
lua_settop(L, sub.result_index);
|
||||||
break;
|
break;
|
||||||
@@ -532,6 +541,9 @@ lprotocol(lua_State *L) {
|
|||||||
lua_pushstring(L, name);
|
lua_pushstring(L, name);
|
||||||
} else {
|
} else {
|
||||||
const char * name = lua_tostring(L, 2);
|
const char * name = lua_tostring(L, 2);
|
||||||
|
if (name == NULL) {
|
||||||
|
return luaL_argerror(L, 2, "Should be number or string");
|
||||||
|
}
|
||||||
tag = sproto_prototag(sp, name);
|
tag = sproto_prototag(sp, name);
|
||||||
if (tag < 0)
|
if (tag < 0)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -592,6 +604,8 @@ encode_default(const struct sproto_arg *args) {
|
|||||||
lua_pushstring(L, args->tagname);
|
lua_pushstring(L, args->tagname);
|
||||||
if (args->index > 0) {
|
if (args->index > 0) {
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
|
lua_rawset(L, -3);
|
||||||
|
return SPROTO_CB_NOARRAY;
|
||||||
} else {
|
} else {
|
||||||
switch(args->type) {
|
switch(args->type) {
|
||||||
case SPROTO_TINTEGER:
|
case SPROTO_TINTEGER:
|
||||||
@@ -609,9 +623,9 @@ encode_default(const struct sproto_arg *args) {
|
|||||||
lua_setfield(L, -2, "__type");
|
lua_setfield(L, -2, "__type");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
lua_rawset(L, -3);
|
||||||
|
return SPROTO_CB_NIL;
|
||||||
}
|
}
|
||||||
lua_rawset(L, -3);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -677,10 +677,10 @@ encode_object(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int si
|
|||||||
args->value = data+SIZEOF_LENGTH;
|
args->value = data+SIZEOF_LENGTH;
|
||||||
args->length = size-SIZEOF_LENGTH;
|
args->length = size-SIZEOF_LENGTH;
|
||||||
sz = cb(args);
|
sz = cb(args);
|
||||||
if (sz <= 0)
|
if (sz < 0) {
|
||||||
return sz;
|
if (sz == SPROTO_CB_NIL)
|
||||||
if (args->type == SPROTO_TSTRING) {
|
return 0;
|
||||||
--sz; // the length of null string is 1
|
return -1; // sz == SPROTO_CB_ERROR
|
||||||
}
|
}
|
||||||
assert(sz <= size-SIZEOF_LENGTH); // verify buffer overflow
|
assert(sz <= size-SIZEOF_LENGTH); // verify buffer overflow
|
||||||
return fill_size(data, sz);
|
return fill_size(data, sz);
|
||||||
@@ -702,7 +702,7 @@ uint32_to_uint64(int negative, uint8_t *buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t *
|
static uint8_t *
|
||||||
encode_integer_array(sproto_callback cb, struct sproto_arg *args, uint8_t *buffer, int size) {
|
encode_integer_array(sproto_callback cb, struct sproto_arg *args, uint8_t *buffer, int size, int *noarray) {
|
||||||
uint8_t * header = buffer;
|
uint8_t * header = buffer;
|
||||||
int intlen;
|
int intlen;
|
||||||
int index;
|
int index;
|
||||||
@@ -712,6 +712,8 @@ encode_integer_array(sproto_callback cb, struct sproto_arg *args, uint8_t *buffe
|
|||||||
size--;
|
size--;
|
||||||
intlen = sizeof(uint32_t);
|
intlen = sizeof(uint32_t);
|
||||||
index = 1;
|
index = 1;
|
||||||
|
*noarray = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int sz;
|
int sz;
|
||||||
union {
|
union {
|
||||||
@@ -722,10 +724,15 @@ encode_integer_array(sproto_callback cb, struct sproto_arg *args, uint8_t *buffe
|
|||||||
args->length = sizeof(u);
|
args->length = sizeof(u);
|
||||||
args->index = index;
|
args->index = index;
|
||||||
sz = cb(args);
|
sz = cb(args);
|
||||||
if (sz < 0)
|
if (sz <= 0) {
|
||||||
return NULL;
|
if (sz == SPROTO_CB_NIL) // nil object, end of array
|
||||||
if (sz == 0) // nil object, end of array
|
break;
|
||||||
break;
|
if (sz == SPROTO_CB_NOARRAY) { // no array, don't encode it
|
||||||
|
*noarray = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return NULL; // sz == SPROTO_CB_ERROR
|
||||||
|
}
|
||||||
if (size < sizeof(uint64_t))
|
if (size < sizeof(uint64_t))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (sz == sizeof(uint32_t)) {
|
if (sz == sizeof(uint32_t)) {
|
||||||
@@ -790,11 +797,17 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
|
|||||||
size -= SIZEOF_LENGTH;
|
size -= SIZEOF_LENGTH;
|
||||||
buffer = data + SIZEOF_LENGTH;
|
buffer = data + SIZEOF_LENGTH;
|
||||||
switch (args->type) {
|
switch (args->type) {
|
||||||
case SPROTO_TINTEGER:
|
case SPROTO_TINTEGER: {
|
||||||
buffer = encode_integer_array(cb,args,buffer,size);
|
int noarray;
|
||||||
|
buffer = encode_integer_array(cb,args,buffer,size, &noarray);
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (noarray) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case SPROTO_TBOOLEAN:
|
case SPROTO_TBOOLEAN:
|
||||||
args->index = 1;
|
args->index = 1;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -802,10 +815,13 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
|
|||||||
args->value = &v;
|
args->value = &v;
|
||||||
args->length = sizeof(v);
|
args->length = sizeof(v);
|
||||||
sz = cb(args);
|
sz = cb(args);
|
||||||
if (sz < 0)
|
if (sz < 0) {
|
||||||
return -1;
|
if (sz == SPROTO_CB_NIL) // nil object , end of array
|
||||||
if (sz == 0) // nil object , end of array
|
break;
|
||||||
break;
|
if (sz == SPROTO_CB_NOARRAY) // no array, don't encode it
|
||||||
|
return 0;
|
||||||
|
return -1; // sz == SPROTO_CB_ERROR
|
||||||
|
}
|
||||||
if (size < 1)
|
if (size < 1)
|
||||||
return -1;
|
return -1;
|
||||||
buffer[0] = v ? 1: 0;
|
buffer[0] = v ? 1: 0;
|
||||||
@@ -823,12 +839,13 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
|
|||||||
args->value = buffer+SIZEOF_LENGTH;
|
args->value = buffer+SIZEOF_LENGTH;
|
||||||
args->length = size;
|
args->length = size;
|
||||||
sz = cb(args);
|
sz = cb(args);
|
||||||
if (sz == 0)
|
if (sz < 0) {
|
||||||
break;
|
if (sz == SPROTO_CB_NIL) {
|
||||||
if (sz < 0)
|
break;
|
||||||
return -1;
|
}
|
||||||
if (args->type == SPROTO_TSTRING) {
|
if (sz == SPROTO_CB_NOARRAY) // no array, don't encode it
|
||||||
--sz;
|
return 0;
|
||||||
|
return -1; // sz == SPROTO_CB_ERROR
|
||||||
}
|
}
|
||||||
fill_size(buffer, sz);
|
fill_size(buffer, sz);
|
||||||
buffer += SIZEOF_LENGTH+sz;
|
buffer += SIZEOF_LENGTH+sz;
|
||||||
@@ -838,8 +855,6 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sz = buffer - (data + SIZEOF_LENGTH);
|
sz = buffer - (data + SIZEOF_LENGTH);
|
||||||
if (sz == 0) // empty array
|
|
||||||
return 0;
|
|
||||||
return fill_size(data, sz);
|
return fill_size(data, sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -885,10 +900,13 @@ sproto_encode(const struct sproto_type *st, void * buffer, int size, sproto_call
|
|||||||
args.value = &u;
|
args.value = &u;
|
||||||
args.length = sizeof(u);
|
args.length = sizeof(u);
|
||||||
sz = cb(&args);
|
sz = cb(&args);
|
||||||
if (sz < 0)
|
if (sz < 0) {
|
||||||
return -1;
|
if (sz == SPROTO_CB_NIL)
|
||||||
if (sz == 0) // nil object
|
continue;
|
||||||
continue;
|
if (sz == SPROTO_CB_NOARRAY) // no array, don't encode it
|
||||||
|
return 0;
|
||||||
|
return -1; // sz == SPROTO_CB_ERROR
|
||||||
|
}
|
||||||
if (sz == sizeof(uint32_t)) {
|
if (sz == sizeof(uint32_t)) {
|
||||||
if (u.u32 < 0x7fff) {
|
if (u.u32 < 0x7fff) {
|
||||||
value = (u.u32+1) * 2;
|
value = (u.u32+1) * 2;
|
||||||
@@ -985,13 +1003,18 @@ decode_array(sproto_callback cb, struct sproto_arg *args, uint8_t * stream) {
|
|||||||
uint32_t sz = todword(stream);
|
uint32_t sz = todword(stream);
|
||||||
int type = args->type;
|
int type = args->type;
|
||||||
int i;
|
int i;
|
||||||
|
if (sz == 0) {
|
||||||
|
// It's empty array, call cb with index == -1 to create the empty array.
|
||||||
|
args->index = -1;
|
||||||
|
args->value = NULL;
|
||||||
|
args->length = 0;
|
||||||
|
cb(args);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
stream += SIZEOF_LENGTH;
|
stream += SIZEOF_LENGTH;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SPROTO_TINTEGER: {
|
case SPROTO_TINTEGER: {
|
||||||
int len;
|
int len = *stream;
|
||||||
if (sz < 1)
|
|
||||||
return -1;
|
|
||||||
len = *stream;
|
|
||||||
++stream;
|
++stream;
|
||||||
--sz;
|
--sz;
|
||||||
if (len == sizeof(uint32_t)) {
|
if (len == sizeof(uint32_t)) {
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ struct sproto_type;
|
|||||||
#define SPROTO_TSTRING 2
|
#define SPROTO_TSTRING 2
|
||||||
#define SPROTO_TSTRUCT 3
|
#define SPROTO_TSTRUCT 3
|
||||||
|
|
||||||
|
#define SPROTO_CB_ERROR -1
|
||||||
|
#define SPROTO_CB_NIL -2
|
||||||
|
#define SPROTO_CB_NOARRAY -3
|
||||||
|
|
||||||
struct sproto * sproto_create(const void * proto, size_t sz);
|
struct sproto * sproto_create(const void * proto, size_t sz);
|
||||||
void sproto_release(struct sproto *);
|
void sproto_release(struct sproto *);
|
||||||
|
|
||||||
|
|||||||
@@ -54,11 +54,10 @@ redcmd[42] = function(fd, data) -- '*'
|
|||||||
local noerr = true
|
local noerr = true
|
||||||
for i = 1,n do
|
for i = 1,n do
|
||||||
local ok, v = read_response(fd)
|
local ok, v = read_response(fd)
|
||||||
if ok then
|
if not ok then
|
||||||
bulk[i] = v
|
|
||||||
else
|
|
||||||
noerr = false
|
noerr = false
|
||||||
end
|
end
|
||||||
|
bulk[i] = v
|
||||||
end
|
end
|
||||||
return noerr, bulk
|
return noerr, bulk
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -28,12 +28,12 @@ function sharedata.query(name)
|
|||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
|
|
||||||
function sharedata.new(name, v)
|
function sharedata.new(name, v, ...)
|
||||||
skynet.call(service, "lua", "new", name, v)
|
skynet.call(service, "lua", "new", name, v, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
function sharedata.update(name, v)
|
function sharedata.update(name, v, ...)
|
||||||
skynet.call(service, "lua", "update", name, v)
|
skynet.call(service, "lua", "update", name, v, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
function sharedata.delete(name)
|
function sharedata.delete(name)
|
||||||
|
|||||||
@@ -343,12 +343,7 @@ function skynet.exit()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function skynet.getenv(key)
|
function skynet.getenv(key)
|
||||||
local ret = c.command("GETENV",key)
|
return (c.command("GETENV",key))
|
||||||
if ret == "" then
|
|
||||||
return
|
|
||||||
else
|
|
||||||
return ret
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function skynet.setenv(key, value)
|
function skynet.setenv(key, value)
|
||||||
@@ -553,13 +548,7 @@ function skynet.harbor(addr)
|
|||||||
return c.harbor(addr)
|
return c.harbor(addr)
|
||||||
end
|
end
|
||||||
|
|
||||||
function skynet.error(...)
|
skynet.error = c.error
|
||||||
local t = {...}
|
|
||||||
for i=1,#t do
|
|
||||||
t[i] = tostring(t[i])
|
|
||||||
end
|
|
||||||
return c.error(table.concat(t, " "))
|
|
||||||
end
|
|
||||||
|
|
||||||
----- register protocol
|
----- register protocol
|
||||||
do
|
do
|
||||||
@@ -592,9 +581,9 @@ function skynet.init(f, name)
|
|||||||
if init_func == nil then
|
if init_func == nil then
|
||||||
f()
|
f()
|
||||||
else
|
else
|
||||||
if name == nil then
|
table.insert(init_func, f)
|
||||||
table.insert(init_func, f)
|
if name then
|
||||||
else
|
assert(type(name) == "string")
|
||||||
assert(init_func[name] == nil)
|
assert(init_func[name] == nil)
|
||||||
init_func[name] = f
|
init_func[name] = f
|
||||||
end
|
end
|
||||||
@@ -605,8 +594,8 @@ local function init_all()
|
|||||||
local funcs = init_func
|
local funcs = init_func
|
||||||
init_func = nil
|
init_func = nil
|
||||||
if funcs then
|
if funcs then
|
||||||
for k,v in pairs(funcs) do
|
for _,f in ipairs(funcs) do
|
||||||
v()
|
f()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -616,14 +605,14 @@ local function ret(f, ...)
|
|||||||
return ...
|
return ...
|
||||||
end
|
end
|
||||||
|
|
||||||
local function init_template(start)
|
local function init_template(start, ...)
|
||||||
init_all()
|
init_all()
|
||||||
init_func = {}
|
init_func = {}
|
||||||
return ret(init_all, start())
|
return ret(init_all, start(...))
|
||||||
end
|
end
|
||||||
|
|
||||||
function skynet.pcall(start)
|
function skynet.pcall(start, ...)
|
||||||
return xpcall(init_template, debug.traceback, start)
|
return xpcall(init_template, debug.traceback, start, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
function skynet.init_service(start)
|
function skynet.init_service(start)
|
||||||
@@ -667,6 +656,11 @@ function skynet.term(service)
|
|||||||
return _error_dispatch(0, service)
|
return _error_dispatch(0, service)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function skynet.memlimit(bytes)
|
||||||
|
debug.getregistry().memlimit = bytes
|
||||||
|
skynet.memlimit = nil -- set only once
|
||||||
|
end
|
||||||
|
|
||||||
local function clear_pool()
|
local function clear_pool()
|
||||||
coroutine_pool = {}
|
coroutine_pool = {}
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ local coroutine_running = coroutine.running
|
|||||||
local select = select
|
local select = select
|
||||||
local skynetco = {}
|
local skynetco = {}
|
||||||
|
|
||||||
skynetco.create = coroutine.create
|
|
||||||
skynetco.isyieldable = coroutine.isyieldable
|
skynetco.isyieldable = coroutine.isyieldable
|
||||||
skynetco.running = coroutine.running
|
skynetco.running = coroutine.running
|
||||||
skynetco.status = coroutine.status
|
skynetco.status = coroutine.status
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
local table = table
|
local table = table
|
||||||
|
local extern_dbgcmd = {};
|
||||||
|
|
||||||
return function (skynet, export)
|
return function (skynet, export)
|
||||||
|
|
||||||
@@ -11,7 +12,7 @@ end
|
|||||||
local dbgcmd
|
local dbgcmd
|
||||||
|
|
||||||
local function init_dbgcmd()
|
local function init_dbgcmd()
|
||||||
dbgcmd = {}
|
dbgcmd = extern_dbgcmd
|
||||||
|
|
||||||
function dbgcmd.MEM()
|
function dbgcmd.MEM()
|
||||||
local kb, bytes = collectgarbage "count"
|
local kb, bytes = collectgarbage "count"
|
||||||
|
|||||||
@@ -407,8 +407,6 @@ end
|
|||||||
|
|
||||||
---------------------- UDP
|
---------------------- UDP
|
||||||
|
|
||||||
local udp_socket = {}
|
|
||||||
|
|
||||||
local function create_udp_object(id, cb)
|
local function create_udp_object(id, cb)
|
||||||
assert(not socket_pool[id], "socket is not closed")
|
assert(not socket_pool[id], "socket is not closed")
|
||||||
socket_pool[id] = {
|
socket_pool[id] = {
|
||||||
|
|||||||
@@ -9,9 +9,14 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define MEMORY_WARNING_REPORT (1024 * 1024 * 32)
|
||||||
|
|
||||||
struct snlua {
|
struct snlua {
|
||||||
lua_State * L;
|
lua_State * L;
|
||||||
struct skynet_context * ctx;
|
struct skynet_context * ctx;
|
||||||
|
size_t mem;
|
||||||
|
size_t mem_report;
|
||||||
|
size_t mem_limit;
|
||||||
};
|
};
|
||||||
|
|
||||||
// LUA_CACHELIB may defined in patched lua for shared proto
|
// LUA_CACHELIB may defined in patched lua for shared proto
|
||||||
@@ -53,7 +58,7 @@ traceback (lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_report_launcher_error(struct skynet_context *ctx) {
|
report_launcher_error(struct skynet_context *ctx) {
|
||||||
// sizeof "ERROR" == 5
|
// sizeof "ERROR" == 5
|
||||||
skynet_sendname(ctx, 0, ".launcher", PTYPE_TEXT, 0, "ERROR", 5);
|
skynet_sendname(ctx, 0, ".launcher", PTYPE_TEXT, 0, "ERROR", 5);
|
||||||
}
|
}
|
||||||
@@ -68,7 +73,7 @@ optstring(struct skynet_context *ctx, const char *key, const char * str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_init(struct snlua *l, struct skynet_context *ctx, const char * args, size_t sz) {
|
init_cb(struct snlua *l, struct skynet_context *ctx, const char * args, size_t sz) {
|
||||||
lua_State *L = l->L;
|
lua_State *L = l->L;
|
||||||
l->ctx = ctx;
|
l->ctx = ctx;
|
||||||
lua_gc(L, LUA_GCSTOP, 0);
|
lua_gc(L, LUA_GCSTOP, 0);
|
||||||
@@ -101,17 +106,25 @@ _init(struct snlua *l, struct skynet_context *ctx, const char * args, size_t sz)
|
|||||||
int r = luaL_loadfile(L,loader);
|
int r = luaL_loadfile(L,loader);
|
||||||
if (r != LUA_OK) {
|
if (r != LUA_OK) {
|
||||||
skynet_error(ctx, "Can't load %s : %s", loader, lua_tostring(L, -1));
|
skynet_error(ctx, "Can't load %s : %s", loader, lua_tostring(L, -1));
|
||||||
_report_launcher_error(ctx);
|
report_launcher_error(ctx);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
lua_pushlstring(L, args, sz);
|
lua_pushlstring(L, args, sz);
|
||||||
r = lua_pcall(L,1,0,1);
|
r = lua_pcall(L,1,0,1);
|
||||||
if (r != LUA_OK) {
|
if (r != LUA_OK) {
|
||||||
skynet_error(ctx, "lua loader error : %s", lua_tostring(L, -1));
|
skynet_error(ctx, "lua loader error : %s", lua_tostring(L, -1));
|
||||||
_report_launcher_error(ctx);
|
report_launcher_error(ctx);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
lua_settop(L,0);
|
lua_settop(L,0);
|
||||||
|
if (lua_getfield(L, LUA_REGISTRYINDEX, "memlimit") == LUA_TNUMBER) {
|
||||||
|
size_t limit = lua_tointeger(L, -1);
|
||||||
|
l->mem_limit = limit;
|
||||||
|
skynet_error(ctx, "Set memory limit to %.2f M", (float)limit / (1024 * 1024));
|
||||||
|
lua_pushnil(L);
|
||||||
|
lua_setfield(L, LUA_REGISTRYINDEX, "memlimit");
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
lua_gc(L, LUA_GCRESTART, 0);
|
lua_gc(L, LUA_GCRESTART, 0);
|
||||||
|
|
||||||
@@ -119,11 +132,11 @@ _init(struct snlua *l, struct skynet_context *ctx, const char * args, size_t sz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_launch(struct skynet_context * context, void *ud, int type, int session, uint32_t source , const void * msg, size_t sz) {
|
launch_cb(struct skynet_context * context, void *ud, int type, int session, uint32_t source , const void * msg, size_t sz) {
|
||||||
assert(type == 0 && session == 0);
|
assert(type == 0 && session == 0);
|
||||||
struct snlua *l = ud;
|
struct snlua *l = ud;
|
||||||
skynet_callback(context, NULL, NULL);
|
skynet_callback(context, NULL, NULL);
|
||||||
int err = _init(l, context, msg, sz);
|
int err = init_cb(l, context, msg, sz);
|
||||||
if (err) {
|
if (err) {
|
||||||
skynet_command(context, "EXIT", NULL);
|
skynet_command(context, "EXIT", NULL);
|
||||||
}
|
}
|
||||||
@@ -136,7 +149,7 @@ snlua_init(struct snlua *l, struct skynet_context *ctx, const char * args) {
|
|||||||
int sz = strlen(args);
|
int sz = strlen(args);
|
||||||
char * tmp = skynet_malloc(sz);
|
char * tmp = skynet_malloc(sz);
|
||||||
memcpy(tmp, args, sz);
|
memcpy(tmp, args, sz);
|
||||||
skynet_callback(ctx, l , _launch);
|
skynet_callback(ctx, l , launch_cb);
|
||||||
const char * self = skynet_command(ctx, "REG", NULL);
|
const char * self = skynet_command(ctx, "REG", NULL);
|
||||||
uint32_t handle_id = strtoul(self+1, NULL, 16);
|
uint32_t handle_id = strtoul(self+1, NULL, 16);
|
||||||
// it must be first message
|
// it must be first message
|
||||||
@@ -144,11 +157,33 @@ snlua_init(struct snlua *l, struct skynet_context *ctx, const char * args) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
lalloc(void * ud, void *ptr, size_t osize, size_t nsize) {
|
||||||
|
struct snlua *l = ud;
|
||||||
|
size_t mem = l->mem;
|
||||||
|
l->mem += nsize;
|
||||||
|
if (ptr)
|
||||||
|
l->mem -= osize;
|
||||||
|
if (l->mem_limit != 0 && l->mem > l->mem_limit) {
|
||||||
|
if (ptr == NULL || nsize > osize) {
|
||||||
|
l->mem = mem;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (l->mem > l->mem_report) {
|
||||||
|
l->mem_report *= 2;
|
||||||
|
skynet_error(l->ctx, "Memory warning %.2f M", (float)l->mem / (1024 * 1024));
|
||||||
|
}
|
||||||
|
return skynet_lalloc(ptr, osize, nsize);
|
||||||
|
}
|
||||||
|
|
||||||
struct snlua *
|
struct snlua *
|
||||||
snlua_create(void) {
|
snlua_create(void) {
|
||||||
struct snlua * l = skynet_malloc(sizeof(*l));
|
struct snlua * l = skynet_malloc(sizeof(*l));
|
||||||
memset(l,0,sizeof(*l));
|
memset(l,0,sizeof(*l));
|
||||||
l->L = lua_newstate(skynet_lalloc, NULL);
|
l->mem_report = MEMORY_WARNING_REPORT;
|
||||||
|
l->mem_limit = 0;
|
||||||
|
l->L = lua_newstate(lalloc, l);
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,8 +196,12 @@ snlua_release(struct snlua *l) {
|
|||||||
void
|
void
|
||||||
snlua_signal(struct snlua *l, int signal) {
|
snlua_signal(struct snlua *l, int signal) {
|
||||||
skynet_error(l->ctx, "recv a signal %d", signal);
|
skynet_error(l->ctx, "recv a signal %d", signal);
|
||||||
|
if (signal == 0) {
|
||||||
#ifdef lua_checksig
|
#ifdef lua_checksig
|
||||||
// If our lua support signal (modified lua version by skynet), trigger it.
|
// If our lua support signal (modified lua version by skynet), trigger it.
|
||||||
skynet_sig_L = l->L;
|
skynet_sig_L = l->L;
|
||||||
#endif
|
#endif
|
||||||
|
} else if (signal == 1) {
|
||||||
|
skynet_error(l->ctx, "Current Memory %.3fK", (float)l->mem / 1024);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ require "skynet.manager" -- import skynet.launch, ...
|
|||||||
local memory = require "memory"
|
local memory = require "memory"
|
||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
local sharestring = tonumber(skynet.getenv "sharestring")
|
local sharestring = tonumber(skynet.getenv "sharestring" or 4096)
|
||||||
memory.ssexpand(sharestring or 4096)
|
memory.ssexpand(sharestring)
|
||||||
|
|
||||||
local standalone = skynet.getenv "standalone"
|
local standalone = skynet.getenv "standalone"
|
||||||
|
|
||||||
local launcher = assert(skynet.launch("snlua","launcher"))
|
local launcher = assert(skynet.launch("snlua","launcher"))
|
||||||
skynet.name(".launcher", launcher)
|
skynet.name(".launcher", launcher)
|
||||||
|
|
||||||
local harbor_id = tonumber(skynet.getenv "harbor")
|
local harbor_id = tonumber(skynet.getenv "harbor" or 0)
|
||||||
if harbor_id == 0 then
|
if harbor_id == 0 then
|
||||||
assert(standalone == nil)
|
assert(standalone == nil)
|
||||||
standalone = true
|
standalone = true
|
||||||
|
|||||||
@@ -215,6 +215,7 @@ function harbor.QUERYNAME(fd, name)
|
|||||||
end
|
end
|
||||||
local queue = queryname[name]
|
local queue = queryname[name]
|
||||||
if queue == nil then
|
if queue == nil then
|
||||||
|
socket.write(fd, pack_package("Q", name))
|
||||||
queue = { skynet.response() }
|
queue = { skynet.response() }
|
||||||
queryname[name] = queue
|
queryname[name] = queue
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -52,13 +52,10 @@ end
|
|||||||
local function docmd(cmdline, print, fd)
|
local function docmd(cmdline, print, fd)
|
||||||
local split = split_cmdline(cmdline)
|
local split = split_cmdline(cmdline)
|
||||||
local command = split[1]
|
local command = split[1]
|
||||||
if command == "debug" then
|
|
||||||
table.insert(split, fd)
|
|
||||||
end
|
|
||||||
local cmd = COMMAND[command]
|
local cmd = COMMAND[command]
|
||||||
local ok, list
|
local ok, list
|
||||||
if cmd then
|
if cmd then
|
||||||
ok, list = pcall(cmd, select(2,table.unpack(split)))
|
ok, list = pcall(cmd, fd, select(2,table.unpack(split)))
|
||||||
else
|
else
|
||||||
print("Invalid command, type help for command list")
|
print("Invalid command, type help for command list")
|
||||||
end
|
end
|
||||||
@@ -79,18 +76,21 @@ local function docmd(cmdline, print, fd)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function console_main_loop(stdin, print)
|
local function console_main_loop(stdin, print)
|
||||||
socket.lock(stdin)
|
|
||||||
print("Welcome to skynet console")
|
print("Welcome to skynet console")
|
||||||
while true do
|
skynet.error(stdin, "connected")
|
||||||
local cmdline = socket.readline(stdin, "\n")
|
pcall(function()
|
||||||
if not cmdline then
|
while true do
|
||||||
break
|
local cmdline = socket.readline(stdin, "\n")
|
||||||
|
if not cmdline then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if cmdline ~= "" then
|
||||||
|
docmd(cmdline, print, stdin)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if cmdline ~= "" then
|
end)
|
||||||
docmd(cmdline, print, stdin)
|
skynet.error(stdin, "disconnected")
|
||||||
end
|
socket.close(stdin)
|
||||||
end
|
|
||||||
socket.unlock(stdin)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
@@ -140,25 +140,33 @@ function COMMAND.clearcache()
|
|||||||
codecache.clear()
|
codecache.clear()
|
||||||
end
|
end
|
||||||
|
|
||||||
function COMMAND.start(...)
|
function COMMAND.start(fd, ...)
|
||||||
local ok, addr = pcall(skynet.newservice, ...)
|
local ok, addr = pcall(skynet.newservice, ...)
|
||||||
if ok then
|
if ok then
|
||||||
return { [skynet.address(addr)] = ... }
|
if addr then
|
||||||
|
return { [skynet.address(addr)] = ... }
|
||||||
|
else
|
||||||
|
return "Exit"
|
||||||
|
end
|
||||||
else
|
else
|
||||||
return "Failed"
|
return "Failed"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function COMMAND.log(...)
|
function COMMAND.log(fd, ...)
|
||||||
local ok, addr = pcall(skynet.call, ".launcher", "lua", "LOGLAUNCH", "snlua", ...)
|
local ok, addr = pcall(skynet.call, ".launcher", "lua", "LOGLAUNCH", "snlua", ...)
|
||||||
if ok then
|
if ok then
|
||||||
return { [skynet.address(addr)] = ... }
|
if addr then
|
||||||
|
return { [skynet.address(addr)] = ... }
|
||||||
|
else
|
||||||
|
return "Failed"
|
||||||
|
end
|
||||||
else
|
else
|
||||||
return "Failed"
|
return "Failed"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function COMMAND.snax(...)
|
function COMMAND.snax(fd, ...)
|
||||||
local ok, s = pcall(snax.newservice, ...)
|
local ok, s = pcall(snax.newservice, ...)
|
||||||
if ok then
|
if ok then
|
||||||
local addr = s.handle
|
local addr = s.handle
|
||||||
@@ -191,7 +199,7 @@ function COMMAND.mem()
|
|||||||
return skynet.call(".launcher", "lua", "MEM")
|
return skynet.call(".launcher", "lua", "MEM")
|
||||||
end
|
end
|
||||||
|
|
||||||
function COMMAND.kill(address)
|
function COMMAND.kill(fd, address)
|
||||||
return skynet.call(".launcher", "lua", "KILL", address)
|
return skynet.call(".launcher", "lua", "KILL", address)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -199,11 +207,11 @@ function COMMAND.gc()
|
|||||||
return skynet.call(".launcher", "lua", "GC")
|
return skynet.call(".launcher", "lua", "GC")
|
||||||
end
|
end
|
||||||
|
|
||||||
function COMMAND.exit(address)
|
function COMMAND.exit(fd, address)
|
||||||
skynet.send(adjust_address(address), "debug", "EXIT")
|
skynet.send(adjust_address(address), "debug", "EXIT")
|
||||||
end
|
end
|
||||||
|
|
||||||
function COMMAND.inject(address, filename)
|
function COMMAND.inject(fd, address, filename)
|
||||||
address = adjust_address(address)
|
address = adjust_address(address)
|
||||||
local f = io.open(filename, "rb")
|
local f = io.open(filename, "rb")
|
||||||
if not f then
|
if not f then
|
||||||
@@ -214,17 +222,17 @@ function COMMAND.inject(address, filename)
|
|||||||
return skynet.call(address, "debug", "RUN", source, filename)
|
return skynet.call(address, "debug", "RUN", source, filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
function COMMAND.task(address)
|
function COMMAND.task(fd, address)
|
||||||
address = adjust_address(address)
|
address = adjust_address(address)
|
||||||
return skynet.call(address,"debug","TASK")
|
return skynet.call(address,"debug","TASK")
|
||||||
end
|
end
|
||||||
|
|
||||||
function COMMAND.info(address)
|
function COMMAND.info(fd, address)
|
||||||
address = adjust_address(address)
|
address = adjust_address(address)
|
||||||
return skynet.call(address,"debug","INFO")
|
return skynet.call(address,"debug","INFO")
|
||||||
end
|
end
|
||||||
|
|
||||||
function COMMAND.debug(address, fd)
|
function COMMAND.debug(fd, address)
|
||||||
address = adjust_address(address)
|
address = adjust_address(address)
|
||||||
local agent = skynet.newservice "debug_agent"
|
local agent = skynet.newservice "debug_agent"
|
||||||
local stop
|
local stop
|
||||||
@@ -243,17 +251,17 @@ function COMMAND.debug(address, fd)
|
|||||||
stop = true
|
stop = true
|
||||||
end
|
end
|
||||||
|
|
||||||
function COMMAND.logon(address)
|
function COMMAND.logon(fd, address)
|
||||||
address = adjust_address(address)
|
address = adjust_address(address)
|
||||||
core.command("LOGON", skynet.address(address))
|
core.command("LOGON", skynet.address(address))
|
||||||
end
|
end
|
||||||
|
|
||||||
function COMMAND.logoff(address)
|
function COMMAND.logoff(fd, address)
|
||||||
address = adjust_address(address)
|
address = adjust_address(address)
|
||||||
core.command("LOGOFF", skynet.address(address))
|
core.command("LOGOFF", skynet.address(address))
|
||||||
end
|
end
|
||||||
|
|
||||||
function COMMAND.signal(address, sig)
|
function COMMAND.signal(fd, address, sig)
|
||||||
address = skynet.address(adjust_address(address))
|
address = skynet.address(adjust_address(address))
|
||||||
if sig then
|
if sig then
|
||||||
core.command("SIGNAL", string.format("%s %d",address,sig))
|
core.command("SIGNAL", string.format("%s %d",address,sig))
|
||||||
|
|||||||
@@ -24,7 +24,10 @@ end
|
|||||||
function command.STAT()
|
function command.STAT()
|
||||||
local list = {}
|
local list = {}
|
||||||
for k,v in pairs(services) do
|
for k,v in pairs(services) do
|
||||||
local stat = skynet.call(k,"debug","STAT")
|
local ok, stat = pcall(skynet.call,k,"debug","STAT")
|
||||||
|
if not ok then
|
||||||
|
stat = string.format("ERROR (%s)",v)
|
||||||
|
end
|
||||||
list[skynet.address(k)] = stat
|
list[skynet.address(k)] = stat
|
||||||
end
|
end
|
||||||
return list
|
return list
|
||||||
@@ -41,8 +44,12 @@ end
|
|||||||
function command.MEM()
|
function command.MEM()
|
||||||
local list = {}
|
local list = {}
|
||||||
for k,v in pairs(services) do
|
for k,v in pairs(services) do
|
||||||
local kb, bytes = skynet.call(k,"debug","MEM")
|
local ok, kb, bytes = pcall(skynet.call,k,"debug","MEM")
|
||||||
list[skynet.address(k)] = string.format("%.2f Kb (%s)",kb,v)
|
if not ok then
|
||||||
|
list[skynet.address(k)] = string.format("ERROR (%s)",v)
|
||||||
|
else
|
||||||
|
list[skynet.address(k)] = string.format("%.2f Kb (%s)",kb,v)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return list
|
return list
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -142,14 +142,23 @@ local function register_global()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function register_local()
|
local function register_local()
|
||||||
function cmd.GLAUNCH(name, ...)
|
local function waitfor_remote(cmd, name, ...)
|
||||||
local global_name = "@" .. name
|
local global_name = "@" .. name
|
||||||
return waitfor(global_name, skynet.call, "SERVICE", "lua", "LAUNCH", global_name, ...)
|
local local_name
|
||||||
|
if name == "snaxd" then
|
||||||
|
local_name = global_name .. "." .. (...)
|
||||||
|
else
|
||||||
|
local_name = global_name
|
||||||
|
end
|
||||||
|
return waitfor(local_name, skynet.call, "SERVICE", "lua", cmd, global_name, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
function cmd.GQUERY(name, ...)
|
function cmd.GLAUNCH(...)
|
||||||
local global_name = "@" .. name
|
return waitfor_remote("LAUNCH", ...)
|
||||||
return waitfor(global_name, skynet.call, "SERVICE", "lua", "QUERY", global_name, ...)
|
end
|
||||||
|
|
||||||
|
function cmd.GQUERY(...)
|
||||||
|
return waitfor_remote("QUERY", ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
function cmd.LIST()
|
function cmd.LIST()
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ local CMD = {}
|
|||||||
|
|
||||||
local env_mt = { __index = _ENV }
|
local env_mt = { __index = _ENV }
|
||||||
|
|
||||||
function CMD.new(name, t)
|
function CMD.new(name, t, ...)
|
||||||
local dt = type(t)
|
local dt = type(t)
|
||||||
local value
|
local value
|
||||||
if dt == "table" then
|
if dt == "table" then
|
||||||
@@ -51,7 +51,7 @@ function CMD.new(name, t)
|
|||||||
else
|
else
|
||||||
f = assert(load(t, "=" .. name, "bt", value))
|
f = assert(load(t, "=" .. name, "bt", value))
|
||||||
end
|
end
|
||||||
local _, ret = assert(skynet.pcall(f))
|
local _, ret = assert(skynet.pcall(f, ...))
|
||||||
setmetatable(value, nil)
|
setmetatable(value, nil)
|
||||||
if type(ret) == "table" then
|
if type(ret) == "table" then
|
||||||
value = ret
|
value = ret
|
||||||
@@ -90,7 +90,7 @@ function CMD.confirm(cobj)
|
|||||||
return NORET
|
return NORET
|
||||||
end
|
end
|
||||||
|
|
||||||
function CMD.update(name, t)
|
function CMD.update(name, t, ...)
|
||||||
local v = pool[name]
|
local v = pool[name]
|
||||||
local watch, oldcobj
|
local watch, oldcobj
|
||||||
if v then
|
if v then
|
||||||
@@ -101,7 +101,7 @@ function CMD.update(name, t)
|
|||||||
pool[name] = nil
|
pool[name] = nil
|
||||||
pool_count[name] = nil
|
pool_count[name] = nil
|
||||||
end
|
end
|
||||||
CMD.new(name, t)
|
CMD.new(name, t, ...)
|
||||||
local newobj = pool[name].obj
|
local newobj = pool[name].obj
|
||||||
if watch then
|
if watch then
|
||||||
sharedata.host.markdirty(oldcobj)
|
sharedata.host.markdirty(oldcobj)
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ skynet_strdup(const char *str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
skynet_lalloc(void *ud, void *ptr, size_t osize, size_t nsize) {
|
skynet_lalloc(void *ptr, size_t osize, size_t nsize) {
|
||||||
if (nsize == 0) {
|
if (nsize == 0) {
|
||||||
raw_free(ptr);
|
raw_free(ptr);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
struct skynet_config config;
|
struct skynet_config config;
|
||||||
|
|
||||||
struct lua_State *L = lua_newstate(skynet_lalloc, NULL);
|
struct lua_State *L = luaL_newstate();
|
||||||
luaL_openlibs(L); // link lua lib
|
luaL_openlibs(L); // link lua lib
|
||||||
|
|
||||||
int err = luaL_loadstring(L, load_config);
|
int err = luaL_loadstring(L, load_config);
|
||||||
|
|||||||
@@ -13,6 +13,6 @@ void * skynet_calloc(size_t nmemb,size_t size);
|
|||||||
void * skynet_realloc(void *ptr, size_t size);
|
void * skynet_realloc(void *ptr, size_t size);
|
||||||
void skynet_free(void *ptr);
|
void skynet_free(void *ptr);
|
||||||
char * skynet_strdup(const char *str);
|
char * skynet_strdup(const char *str);
|
||||||
void * skynet_lalloc(void *ud, void *ptr, size_t osize, size_t nsize); // use for lua
|
void * skynet_lalloc(void *ptr, size_t osize, size_t nsize); // use for lua
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
17
test/testmemlimit.lua
Normal file
17
test/testmemlimit.lua
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
local skynet = require "skynet"
|
||||||
|
|
||||||
|
-- set sandbox memory limit to 1M, must set here (at start, out of skynet.start)
|
||||||
|
skynet.memlimit(1 * 1024 * 1024)
|
||||||
|
|
||||||
|
skynet.start(function()
|
||||||
|
local a = {}
|
||||||
|
local limit
|
||||||
|
local ok, err = pcall(function()
|
||||||
|
for i=1, 1000000 do
|
||||||
|
limit = i
|
||||||
|
table.insert(a, {})
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
skynet.error(limit, err)
|
||||||
|
skynet.exit()
|
||||||
|
end)
|
||||||
Reference in New Issue
Block a user