commit bfcf06d91a87b7ffb8c83e290db0cb6176a167f8
parent 0280407fc54f9b6225139c5ac27326f98f0cf043
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Sat, 4 Jul 2020 16:39:51 -0300
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).
Diffstat:
5 files changed, 30 insertions(+), 17 deletions(-)
diff --git a/ltests.c b/ltests.c
@@ -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));
diff --git a/testes/coroutine.lua b/testes/coroutine.lua
@@ -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)
diff --git a/testes/gc.lua b/testes/gc.lua
@@ -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
diff --git a/testes/locals.lua b/testes/locals.lua
@@ -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
diff --git a/testes/main.lua b/testes/main.lua
@@ -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