mirror of https://github.com/rusefi/lua.git
More checks and documentation for uses of EXTRA_STACK
This commit is contained in:
parent
196bb94d66
commit
d61b0c6028
7
ldo.c
7
ldo.c
|
@ -602,12 +602,17 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||||
** Call a function (C or Lua) through C. 'inc' can be 1 (increment
|
** Call a function (C or Lua) through C. 'inc' can be 1 (increment
|
||||||
** number of recursive invocations in the C stack) or nyci (the same
|
** number of recursive invocations in the C stack) or nyci (the same
|
||||||
** plus increment number of non-yieldable calls).
|
** plus increment number of non-yieldable calls).
|
||||||
|
** This function can be called with some use of EXTRA_STACK, so it should
|
||||||
|
** check the stack before doing anything else. 'luaD_precall' already
|
||||||
|
** does that.
|
||||||
*/
|
*/
|
||||||
l_sinline void ccall (lua_State *L, StkId func, int nResults, int inc) {
|
l_sinline void ccall (lua_State *L, StkId func, int nResults, int inc) {
|
||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
L->nCcalls += inc;
|
L->nCcalls += inc;
|
||||||
if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
|
if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) {
|
||||||
|
checkstackp(L, 0, func); /* free any use of EXTRA_STACK */
|
||||||
luaE_checkcstack(L);
|
luaE_checkcstack(L);
|
||||||
|
}
|
||||||
if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */
|
if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */
|
||||||
ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */
|
ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */
|
||||||
luaV_execute(L, ci); /* call it */
|
luaV_execute(L, ci); /* call it */
|
||||||
|
|
7
ldo.h
7
ldo.h
|
@ -37,6 +37,13 @@
|
||||||
|
|
||||||
|
|
||||||
/* macro to check stack size, preserving 'p' */
|
/* macro to check stack size, preserving 'p' */
|
||||||
|
#define checkstackp(L,n,p) \
|
||||||
|
luaD_checkstackaux(L, n, \
|
||||||
|
ptrdiff_t t__ = savestack(L, p), /* save 'p' */ \
|
||||||
|
p = restorestack(L, t__)) /* 'pos' part: restore 'p' */
|
||||||
|
|
||||||
|
|
||||||
|
/* macro to check stack size and GC, preserving 'p' */
|
||||||
#define checkstackGCp(L,n,p) \
|
#define checkstackGCp(L,n,p) \
|
||||||
luaD_checkstackaux(L, n, \
|
luaD_checkstackaux(L, n, \
|
||||||
ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \
|
ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \
|
||||||
|
|
34
lobject.c
34
lobject.c
|
@ -386,29 +386,39 @@ void luaO_tostring (lua_State *L, TValue *obj) {
|
||||||
** ===================================================================
|
** ===================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* size for buffer space used by 'luaO_pushvfstring' */
|
/*
|
||||||
#define BUFVFS 200
|
** Size for buffer space used by 'luaO_pushvfstring'. It should be
|
||||||
|
** (LUA_IDSIZE + MAXNUMBER2STR) + a minimal space for basic messages,
|
||||||
|
** so that 'luaG_addinfo' can work directly on the buffer.
|
||||||
|
*/
|
||||||
|
#define BUFVFS (LUA_IDSIZE + MAXNUMBER2STR + 95)
|
||||||
|
|
||||||
/* buffer used by 'luaO_pushvfstring' */
|
/* buffer used by 'luaO_pushvfstring' */
|
||||||
typedef struct BuffFS {
|
typedef struct BuffFS {
|
||||||
lua_State *L;
|
lua_State *L;
|
||||||
int pushed; /* number of string pieces already on the stack */
|
int pushed; /* true if there is a part of the result on the stack */
|
||||||
int blen; /* length of partial string in 'space' */
|
int blen; /* length of partial string in 'space' */
|
||||||
char space[BUFVFS]; /* holds last part of the result */
|
char space[BUFVFS]; /* holds last part of the result */
|
||||||
} BuffFS;
|
} BuffFS;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Push given string to the stack, as part of the buffer, and
|
** Push given string to the stack, as part of the result, and
|
||||||
** join the partial strings in the stack into one.
|
** join it to previous partial result if there is one.
|
||||||
|
** It may call 'luaV_concat' while using one slot from EXTRA_STACK.
|
||||||
|
** This call cannot invoke metamethods, as both operands must be
|
||||||
|
** strings. It can, however, raise an error if the result is too
|
||||||
|
** long. In that case, 'luaV_concat' frees the extra slot before
|
||||||
|
** raising the error.
|
||||||
*/
|
*/
|
||||||
static void pushstr (BuffFS *buff, const char *str, size_t l) {
|
static void pushstr (BuffFS *buff, const char *str, size_t lstr) {
|
||||||
lua_State *L = buff->L;
|
lua_State *L = buff->L;
|
||||||
setsvalue2s(L, L->top, luaS_newlstr(L, str, l));
|
setsvalue2s(L, L->top, luaS_newlstr(L, str, lstr));
|
||||||
L->top++; /* may use one extra slot */
|
L->top++; /* may use one slot from EXTRA_STACK */
|
||||||
buff->pushed++;
|
if (!buff->pushed) /* no previous string on the stack? */
|
||||||
luaV_concat(L, buff->pushed); /* join partial results into one */
|
buff->pushed = 1; /* now there is one */
|
||||||
buff->pushed = 1;
|
else /* join previous string with new one */
|
||||||
|
luaV_concat(L, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -454,7 +464,7 @@ static void addstr2buff (BuffFS *buff, const char *str, size_t slen) {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Add a number to the buffer.
|
** Add a numeral to the buffer.
|
||||||
*/
|
*/
|
||||||
static void addnum2buff (BuffFS *buff, TValue *num) {
|
static void addnum2buff (BuffFS *buff, TValue *num) {
|
||||||
char *numbuff = getbuff(buff, MAXNUMBER2STR);
|
char *numbuff = getbuff(buff, MAXNUMBER2STR);
|
||||||
|
|
|
@ -52,6 +52,8 @@ typedef union Value {
|
||||||
lua_CFunction f; /* light C functions */
|
lua_CFunction f; /* light C functions */
|
||||||
lua_Integer i; /* integer numbers */
|
lua_Integer i; /* integer numbers */
|
||||||
lua_Number n; /* float numbers */
|
lua_Number n; /* float numbers */
|
||||||
|
/* not used, but may avoid warnings for uninitialized value */
|
||||||
|
lu_byte ub;
|
||||||
} Value;
|
} Value;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -151,6 +151,16 @@ do -- tail calls x varargs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
do -- C-stack overflow while handling C-stack overflow
|
||||||
|
local function loop ()
|
||||||
|
assert(pcall(loop))
|
||||||
|
end
|
||||||
|
|
||||||
|
local err, msg = xpcall(loop, loop)
|
||||||
|
assert(not err and string.find(msg, "error"))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
do -- tail calls x chain of __call
|
do -- tail calls x chain of __call
|
||||||
local n = 10000 -- depth
|
local n = 10000 -- depth
|
||||||
|
|
Loading…
Reference in New Issue