diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-07-04 16:40:18 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-07-04 16:40:18 -0300 |
commit | bfcf06d91a87b7ffb8c83e290db0cb6176a167f8 (patch) | |
tree | 0bcba905a2772e536c845e39e9eeed0c7330312c | |
parent | 0280407fc54f9b6225139c5ac27326f98f0cf043 (diff) | |
download | lua-bfcf06d91a87b7ffb8c83e290db0cb6176a167f8.tar.gz lua-bfcf06d91a87b7ffb8c83e290db0cb6176a167f8.tar.bz2 lua-bfcf06d91a87b7ffb8c83e290db0cb6176a167f8.zip |
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).
-rw-r--r-- | ltests.c | 27 | ||||
-rw-r--r-- | testes/coroutine.lua | 2 | ||||
-rw-r--r-- | testes/gc.lua | 8 | ||||
-rw-r--r-- | testes/locals.lua | 4 | ||||
-rw-r--r-- | testes/main.lua | 6 |
5 files changed, 30 insertions, 17 deletions
@@ -121,7 +121,8 @@ static void warnf (void *ud, const char *msg, int tocont) { | |||
121 | strcat(buff, msg); /* add new message to current warning */ | 121 | strcat(buff, msg); /* add new message to current warning */ |
122 | if (!tocont) { /* message finished? */ | 122 | if (!tocont) { /* message finished? */ |
123 | lua_unlock(L); | 123 | lua_unlock(L); |
124 | if (lua_getglobal(L, "_WARN") == LUA_TNIL) | 124 | lua_getglobal(L, "_WARN"); |
125 | if (!lua_toboolean(L, -1)) | ||
125 | lua_pop(L, 1); /* ok, no previous unexpected warning */ | 126 | lua_pop(L, 1); /* ok, no previous unexpected warning */ |
126 | else { | 127 | else { |
127 | badexit("Unhandled warning in store mode: %s\naborting...\n", | 128 | 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) { | |||
1282 | } | 1283 | } |
1283 | 1284 | ||
1284 | 1285 | ||
1285 | static void pushcode (lua_State *L, int code) { | 1286 | static const char *const statcodes[] = {"OK", "YIELD", "ERRRUN", |
1286 | static const char *const codes[] = {"OK", "YIELD", "ERRRUN", | 1287 | "ERRSYNTAX", MEMERRMSG, "ERRGCMM", "ERRERR"}; |
1287 | "ERRSYNTAX", MEMERRMSG, "ERRGCMM", "ERRERR"}; | 1288 | |
1288 | lua_pushstring(L, codes[code]); | 1289 | /* |
1290 | ** Avoid these stat codes from being collected, to avoid possible | ||
1291 | ** memory error when pushing them. | ||
1292 | */ | ||
1293 | static void regcodes (lua_State *L) { | ||
1294 | unsigned int i; | ||
1295 | for (i = 0; i < sizeof(statcodes) / sizeof(statcodes[0]); i++) { | ||
1296 | lua_pushboolean(L, 1); | ||
1297 | lua_setfield(L, LUA_REGISTRYINDEX, statcodes[i]); | ||
1298 | } | ||
1289 | } | 1299 | } |
1290 | 1300 | ||
1291 | 1301 | ||
@@ -1508,7 +1518,7 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) { | |||
1508 | lua_pushnumber(L1, (lua_Number)getnum); | 1518 | lua_pushnumber(L1, (lua_Number)getnum); |
1509 | } | 1519 | } |
1510 | else if EQ("pushstatus") { | 1520 | else if EQ("pushstatus") { |
1511 | pushcode(L1, status); | 1521 | lua_pushstring(L1, statcodes[status]); |
1512 | } | 1522 | } |
1513 | else if EQ("pushstring") { | 1523 | else if EQ("pushstring") { |
1514 | lua_pushstring(L1, getstring); | 1524 | lua_pushstring(L1, getstring); |
@@ -1710,7 +1720,7 @@ static int Cfunc (lua_State *L) { | |||
1710 | 1720 | ||
1711 | 1721 | ||
1712 | static int Cfunck (lua_State *L, int status, lua_KContext ctx) { | 1722 | static int Cfunck (lua_State *L, int status, lua_KContext ctx) { |
1713 | pushcode(L, status); | 1723 | lua_pushstring(L, statcodes[status]); |
1714 | lua_setglobal(L, "status"); | 1724 | lua_setglobal(L, "status"); |
1715 | lua_pushinteger(L, ctx); | 1725 | lua_pushinteger(L, ctx); |
1716 | lua_setglobal(L, "ctx"); | 1726 | lua_setglobal(L, "ctx"); |
@@ -1865,6 +1875,9 @@ int luaB_opentests (lua_State *L) { | |||
1865 | void *ud; | 1875 | void *ud; |
1866 | lua_atpanic(L, &tpanic); | 1876 | lua_atpanic(L, &tpanic); |
1867 | lua_setwarnf(L, &warnf, L); | 1877 | lua_setwarnf(L, &warnf, L); |
1878 | lua_pushboolean(L, 0); | ||
1879 | lua_setglobal(L, "_WARN"); /* _WARN = false */ | ||
1880 | regcodes(L); | ||
1868 | atexit(checkfinalmem); | 1881 | atexit(checkfinalmem); |
1869 | lua_assert(lua_getallocf(L, &ud) == debug_realloc); | 1882 | lua_assert(lua_getallocf(L, &ud) == debug_realloc); |
1870 | lua_assert(ud == cast_voidp(&l_memcontrol)); | 1883 | lua_assert(ud == cast_voidp(&l_memcontrol)); |
diff --git a/testes/coroutine.lua b/testes/coroutine.lua index 73333c14..0a4c2ef3 100644 --- a/testes/coroutine.lua +++ b/testes/coroutine.lua | |||
@@ -184,7 +184,7 @@ do | |||
184 | if not T then | 184 | if not T then |
185 | warn("@on") | 185 | warn("@on") |
186 | else -- test library | 186 | else -- test library |
187 | assert(string.find(_WARN, "200")); _WARN = nil | 187 | assert(string.find(_WARN, "200")); _WARN = false |
188 | warn("@normal") | 188 | warn("@normal") |
189 | end | 189 | end |
190 | assert(st == false and coroutine.status(co) == "dead" and msg == 111) | 190 | assert(st == false and coroutine.status(co) == "dead" and msg == 111) |
diff --git a/testes/gc.lua b/testes/gc.lua index 91915c0b..80850f92 100644 --- a/testes/gc.lua +++ b/testes/gc.lua | |||
@@ -372,7 +372,7 @@ if T then | |||
372 | warn("@on"); warn("@store") | 372 | warn("@on"); warn("@store") |
373 | collectgarbage() | 373 | collectgarbage() |
374 | assert(string.find(_WARN, "error in __gc metamethod")) | 374 | assert(string.find(_WARN, "error in __gc metamethod")) |
375 | assert(string.match(_WARN, "@(.-)@") == "expected"); _WARN = nil | 375 | assert(string.match(_WARN, "@(.-)@") == "expected"); _WARN = false |
376 | for i = 8, 10 do assert(s[i]) end | 376 | for i = 8, 10 do assert(s[i]) end |
377 | 377 | ||
378 | for i = 1, 5 do | 378 | for i = 1, 5 do |
@@ -481,7 +481,7 @@ if T then | |||
481 | u = setmetatable({}, {__gc = function () error "@expected error" end}) | 481 | u = setmetatable({}, {__gc = function () error "@expected error" end}) |
482 | u = nil | 482 | u = nil |
483 | collectgarbage() | 483 | collectgarbage() |
484 | assert(string.find(_WARN, "@expected error")); _WARN = nil | 484 | assert(string.find(_WARN, "@expected error")); _WARN = false |
485 | warn("@normal") | 485 | warn("@normal") |
486 | end | 486 | end |
487 | 487 | ||
@@ -657,14 +657,14 @@ if T then | |||
657 | n = n + 1 | 657 | n = n + 1 |
658 | assert(n == o[1]) | 658 | assert(n == o[1]) |
659 | if n == 1 then | 659 | if n == 1 then |
660 | _WARN = nil | 660 | _WARN = false |
661 | elseif n == 2 then | 661 | elseif n == 2 then |
662 | assert(find(_WARN, "@expected warning")) | 662 | assert(find(_WARN, "@expected warning")) |
663 | lastmsg = _WARN -- get message from previous error (first 'o') | 663 | lastmsg = _WARN -- get message from previous error (first 'o') |
664 | else | 664 | else |
665 | assert(lastmsg == _WARN) -- subsequent error messages are equal | 665 | assert(lastmsg == _WARN) -- subsequent error messages are equal |
666 | end | 666 | end |
667 | warn("@store"); _WARN = nil | 667 | warn("@store"); _WARN = false |
668 | error"@expected warning" | 668 | error"@expected warning" |
669 | end} | 669 | end} |
670 | for i = 10, 1, -1 do | 670 | for i = 10, 1, -1 do |
diff --git a/testes/locals.lua b/testes/locals.lua index 0e5e0c74..f5e96244 100644 --- a/testes/locals.lua +++ b/testes/locals.lua | |||
@@ -337,7 +337,7 @@ local function endwarn () | |||
337 | if not T then | 337 | if not T then |
338 | warn("@on") -- back to normal | 338 | warn("@on") -- back to normal |
339 | else | 339 | else |
340 | assert(_WARN == nil) | 340 | assert(_WARN == false) |
341 | warn("@normal") | 341 | warn("@normal") |
342 | end | 342 | end |
343 | end | 343 | end |
@@ -346,7 +346,7 @@ end | |||
346 | local function checkwarn (msg) | 346 | local function checkwarn (msg) |
347 | if T then | 347 | if T then |
348 | assert(string.find(_WARN, msg)) | 348 | assert(string.find(_WARN, msg)) |
349 | _WARN = nil -- reset variable to check next warning | 349 | _WARN = false -- reset variable to check next warning |
350 | end | 350 | end |
351 | end | 351 | end |
352 | 352 | ||
diff --git a/testes/main.lua b/testes/main.lua index de14a088..d2d602de 100644 --- a/testes/main.lua +++ b/testes/main.lua | |||
@@ -393,12 +393,12 @@ if T then -- test library? | |||
393 | -- testing 'warn' | 393 | -- testing 'warn' |
394 | warn("@store") | 394 | warn("@store") |
395 | warn("@123", "456", "789") | 395 | warn("@123", "456", "789") |
396 | assert(_WARN == "@123456789"); _WARN = nil | 396 | assert(_WARN == "@123456789"); _WARN = false |
397 | 397 | ||
398 | warn("zip", "", " ", "zap") | 398 | warn("zip", "", " ", "zap") |
399 | assert(_WARN == "zip zap"); _WARN = nil | 399 | assert(_WARN == "zip zap"); _WARN = false |
400 | warn("ZIP", "", " ", "ZAP") | 400 | warn("ZIP", "", " ", "ZAP") |
401 | assert(_WARN == "ZIP ZAP"); _WARN = nil | 401 | assert(_WARN == "ZIP ZAP"); _WARN = false |
402 | warn("@normal") | 402 | warn("@normal") |
403 | end | 403 | end |
404 | 404 | ||