Avoid memory allocation in some functions from 'ltests.c'

To allow their use in memory tests, some functions in 'ltests.c'
should never allocate memory. To avoid this allocation, the
library registers the strings used for status codes, and keeps
the variable '_WARN' always defined (with false instead of nil).
This commit is contained in:
Roberto Ierusalimschy 2020-07-04 16:40:18 -03:00
parent 0280407fc5
commit bfcf06d91a
5 changed files with 30 additions and 17 deletions

View File

@ -121,7 +121,8 @@ static void warnf (void *ud, const char *msg, int tocont) {
strcat(buff, msg); /* add new message to current warning */
if (!tocont) { /* message finished? */
lua_unlock(L);
if (lua_getglobal(L, "_WARN") == LUA_TNIL)
lua_getglobal(L, "_WARN");
if (!lua_toboolean(L, -1))
lua_pop(L, 1); /* ok, no previous unexpected warning */
else {
badexit("Unhandled warning in store mode: %s\naborting...\n",
@ -1282,10 +1283,19 @@ static int getindex_aux (lua_State *L, lua_State *L1, const char **pc) {
}
static void pushcode (lua_State *L, int code) {
static const char *const codes[] = {"OK", "YIELD", "ERRRUN",
"ERRSYNTAX", MEMERRMSG, "ERRGCMM", "ERRERR"};
lua_pushstring(L, codes[code]);
static const char *const statcodes[] = {"OK", "YIELD", "ERRRUN",
"ERRSYNTAX", MEMERRMSG, "ERRGCMM", "ERRERR"};
/*
** Avoid these stat codes from being collected, to avoid possible
** memory error when pushing them.
*/
static void regcodes (lua_State *L) {
unsigned int i;
for (i = 0; i < sizeof(statcodes) / sizeof(statcodes[0]); i++) {
lua_pushboolean(L, 1);
lua_setfield(L, LUA_REGISTRYINDEX, statcodes[i]);
}
}
@ -1508,7 +1518,7 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
lua_pushnumber(L1, (lua_Number)getnum);
}
else if EQ("pushstatus") {
pushcode(L1, status);
lua_pushstring(L1, statcodes[status]);
}
else if EQ("pushstring") {
lua_pushstring(L1, getstring);
@ -1710,7 +1720,7 @@ static int Cfunc (lua_State *L) {
static int Cfunck (lua_State *L, int status, lua_KContext ctx) {
pushcode(L, status);
lua_pushstring(L, statcodes[status]);
lua_setglobal(L, "status");
lua_pushinteger(L, ctx);
lua_setglobal(L, "ctx");
@ -1865,6 +1875,9 @@ int luaB_opentests (lua_State *L) {
void *ud;
lua_atpanic(L, &tpanic);
lua_setwarnf(L, &warnf, L);
lua_pushboolean(L, 0);
lua_setglobal(L, "_WARN"); /* _WARN = false */
regcodes(L);
atexit(checkfinalmem);
lua_assert(lua_getallocf(L, &ud) == debug_realloc);
lua_assert(ud == cast_voidp(&l_memcontrol));

View File

@ -184,7 +184,7 @@ do
if not T then
warn("@on")
else -- test library
assert(string.find(_WARN, "200")); _WARN = nil
assert(string.find(_WARN, "200")); _WARN = false
warn("@normal")
end
assert(st == false and coroutine.status(co) == "dead" and msg == 111)

View File

@ -372,7 +372,7 @@ if T then
warn("@on"); warn("@store")
collectgarbage()
assert(string.find(_WARN, "error in __gc metamethod"))
assert(string.match(_WARN, "@(.-)@") == "expected"); _WARN = nil
assert(string.match(_WARN, "@(.-)@") == "expected"); _WARN = false
for i = 8, 10 do assert(s[i]) end
for i = 1, 5 do
@ -481,7 +481,7 @@ if T then
u = setmetatable({}, {__gc = function () error "@expected error" end})
u = nil
collectgarbage()
assert(string.find(_WARN, "@expected error")); _WARN = nil
assert(string.find(_WARN, "@expected error")); _WARN = false
warn("@normal")
end
@ -657,14 +657,14 @@ if T then
n = n + 1
assert(n == o[1])
if n == 1 then
_WARN = nil
_WARN = false
elseif n == 2 then
assert(find(_WARN, "@expected warning"))
lastmsg = _WARN -- get message from previous error (first 'o')
else
assert(lastmsg == _WARN) -- subsequent error messages are equal
end
warn("@store"); _WARN = nil
warn("@store"); _WARN = false
error"@expected warning"
end}
for i = 10, 1, -1 do

View File

@ -337,7 +337,7 @@ local function endwarn ()
if not T then
warn("@on") -- back to normal
else
assert(_WARN == nil)
assert(_WARN == false)
warn("@normal")
end
end
@ -346,7 +346,7 @@ end
local function checkwarn (msg)
if T then
assert(string.find(_WARN, msg))
_WARN = nil -- reset variable to check next warning
_WARN = false -- reset variable to check next warning
end
end

View File

@ -393,12 +393,12 @@ if T then -- test library?
-- testing 'warn'
warn("@store")
warn("@123", "456", "789")
assert(_WARN == "@123456789"); _WARN = nil
assert(_WARN == "@123456789"); _WARN = false
warn("zip", "", " ", "zap")
assert(_WARN == "zip zap"); _WARN = nil
assert(_WARN == "zip zap"); _WARN = false
warn("ZIP", "", " ", "ZAP")
assert(_WARN == "ZIP ZAP"); _WARN = nil
assert(_WARN == "ZIP ZAP"); _WARN = false
warn("@normal")
end