Bläddra i källkod

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).
Roberto Ierusalimschy 5 år sedan
förälder
incheckning
bfcf06d91a
5 ändrade filer med 30 tillägg och 17 borttagningar
  1. 20 7
      ltests.c
  2. 1 1
      testes/coroutine.lua
  3. 4 4
      testes/gc.lua
  4. 2 2
      testes/locals.lua
  5. 3 3
      testes/main.lua

+ 20 - 7
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 */
   strcat(buff, msg);  /* add new message to current warning */
   if (!tocont) {  /* message finished? */
   if (!tocont) {  /* message finished? */
     lua_unlock(L);
     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 */
       lua_pop(L, 1);  /* ok, no previous unexpected warning */
     else {
     else {
       badexit("Unhandled warning in store mode: %s\naborting...\n",
       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);
       lua_pushnumber(L1, (lua_Number)getnum);
     }
     }
     else if EQ("pushstatus") {
     else if EQ("pushstatus") {
-      pushcode(L1, status);
+      lua_pushstring(L1, statcodes[status]);
     }
     }
     else if EQ("pushstring") {
     else if EQ("pushstring") {
       lua_pushstring(L1, getstring);
       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) {
 static int Cfunck (lua_State *L, int status, lua_KContext ctx) {
-  pushcode(L, status);
+  lua_pushstring(L, statcodes[status]);
   lua_setglobal(L, "status");
   lua_setglobal(L, "status");
   lua_pushinteger(L, ctx);
   lua_pushinteger(L, ctx);
   lua_setglobal(L, "ctx");
   lua_setglobal(L, "ctx");
@@ -1865,6 +1875,9 @@ int luaB_opentests (lua_State *L) {
   void *ud;
   void *ud;
   lua_atpanic(L, &tpanic);
   lua_atpanic(L, &tpanic);
   lua_setwarnf(L, &warnf, L);
   lua_setwarnf(L, &warnf, L);
+  lua_pushboolean(L, 0);
+  lua_setglobal(L, "_WARN");  /* _WARN = false */
+  regcodes(L);
   atexit(checkfinalmem);
   atexit(checkfinalmem);
   lua_assert(lua_getallocf(L, &ud) == debug_realloc);
   lua_assert(lua_getallocf(L, &ud) == debug_realloc);
   lua_assert(ud == cast_voidp(&l_memcontrol));
   lua_assert(ud == cast_voidp(&l_memcontrol));

+ 1 - 1
testes/coroutine.lua

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

+ 4 - 4
testes/gc.lua

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

+ 2 - 2
testes/locals.lua

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

+ 3 - 3
testes/main.lua

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