@@ -11,6 +11,9 @@ local debug = require "debug"
1111local pack = table.pack
1212
1313
14+ -- standard error message for memory errors
15+ local MEMERRMSG = " not enough memory"
16+
1417function tcheck (t1 , t2 )
1518 assert (t1 .n == (t2 .n or # t2 ) + 1 )
1619 for i = 2 , t1 .n do assert (t1 [i ] == t2 [i - 1 ]) end
408411
409412 -- memory error
410413 T .totalmem (T .totalmem ()+ 10000 ) -- set low memory limit (+10k)
411- assert (T .checkpanic (" newuserdata 20000" ) == " not enough memory " )
414+ assert (T .checkpanic (" newuserdata 20000" ) == MEMERRMSG )
412415 T .totalmem (0 ) -- restore high limit
413416
414417 -- stack error
@@ -1153,40 +1156,74 @@ do
11531156end
11541157
11551158
1156- ---- ---------------------------------------------------------------------
1157- -- testing memory limits
1158- ---- ---------------------------------------------------------------------
1159+ --[[
1160+ ** {==================================================================
1161+ ** Testing memory limits
1162+ ** ===================================================================
1163+ --]]
1164+
11591165print (" memory-allocation errors" )
11601166
11611167checkerr (" block too big" , T .newuserdata , math.maxinteger )
11621168collectgarbage ()
11631169local f = load " local a={}; for i=1,100000 do a[i]=i end"
11641170T .alloccount (10 )
1165- checkerr (" not enough memory " , f )
1171+ checkerr (MEMERRMSG , f )
11661172T .alloccount () -- remove limit
11671173
1174+
1175+ -- test memory errors; increase limit for maximum memory by steps,
1176+ -- o that we get memory errors in all allocations of a given
1177+ -- task, until there is enough memory to complete the task without
1178+ -- errors.
1179+ function testbytes (s , f )
1180+ collectgarbage ()
1181+ local M = T .totalmem ()
1182+ local oldM = M
1183+ local a ,b = nil
1184+ while true do
1185+ collectgarbage (); collectgarbage ()
1186+ T .totalmem (M )
1187+ a , b = T .testC (" pcall 0 1 0; pushstatus; return 2" , f )
1188+ T .totalmem (0 ) -- remove limit
1189+ if a and b == " OK" then break end -- stop when no more errors
1190+ if b ~= " OK" and b ~= MEMERRMSG then -- not a memory error?
1191+ error (a , 0 ) -- propagate it
1192+ end
1193+ M = M + 7 -- increase memory limit
1194+ end
1195+ print (string.format (" minimum memory for %s: %d bytes" , s , M - oldM ))
1196+ return a
1197+ end
1198+
11681199-- test memory errors; increase limit for number of allocations one
11691200-- by one, so that we get memory errors in all allocations of a given
11701201-- task, until there is enough allocations to complete the task without
11711202-- errors.
11721203
1173- function testamem (s , f )
1174- collectgarbage (); collectgarbage ()
1204+ function testalloc (s , f )
1205+ collectgarbage ()
11751206 local M = 0
11761207 local a ,b = nil
11771208 while true do
1209+ collectgarbage (); collectgarbage ()
11781210 T .alloccount (M )
1179- a , b = pcall ( f )
1211+ a , b = T . testC ( " pcall 0 1 0; pushstatus; return 2 " , f )
11801212 T .alloccount () -- remove limit
1181- if a and b then break end -- stop when no more errors
1182- if not a and not -- `real' error?
1183- (string.find (b , " memory" ) or string.find (b , " overflow" )) then
1184- error (b , 0 ) -- propagate it
1213+ if a and b == " OK" then break end -- stop when no more errors
1214+ if b ~= " OK" and b ~= MEMERRMSG then -- not a memory error?
1215+ error (a , 0 ) -- propagate it
11851216 end
11861217 M = M + 1 -- increase allocation limit
11871218 end
1188- print (string.format (" limit for %s: %d allocations" , s , M ))
1189- return b
1219+ print (string.format (" minimum allocations for %s: %d allocations" , s , M ))
1220+ return a
1221+ end
1222+
1223+
1224+ local function testamem (s , f )
1225+ testalloc (s , f )
1226+ return testbytes (s , f )
11901227end
11911228
11921229
@@ -1196,8 +1233,11 @@ assert(b == 10)
11961233
11971234-- testing memory errors when creating a new state
11981235
1199- b = testamem (" state creation" , T .newstate )
1200- T .closestate (b ); -- close new state
1236+ testamem (" state creation" , function ()
1237+ local st = T .newstate ()
1238+ if st then T .closestate (st ) end -- close new state
1239+ return st
1240+ end )
12011241
12021242testamem (" empty-table creation" , function ()
12031243 return {}
@@ -1345,6 +1385,9 @@ testamem("growing stack", function ()
13451385 return foo (100 )
13461386end )
13471387
1388+ -- }==================================================================
1389+
1390+
13481391do -- testing failing in 'lua_checkstack'
13491392 local res = T .testC ([[ rawcheckstack 500000; return 1]] )
13501393 assert (res == false )
0 commit comments