@ -242,6 +242,7 @@ do
assert ( a == 1 and b == 2 and c == 3 and X == 20 and Y == 10 and d == nil )
assert ( a == 1 and b == 2 and c == 3 and X == 20 and Y == 10 and d == nil )
end
end
do -- errors in __close
do -- errors in __close
local log = { }
local log = { }
local function foo ( err )
local function foo ( err )
@ -264,7 +265,9 @@ do -- errors in __close
and # log == 4 )
and # log == 4 )
end
end
if rawget ( _G , " T " ) then
if rawget ( _G , " T " ) then
-- memory error inside closing function
-- memory error inside closing function
local function foo ( )
local function foo ( )
local * toclose y = function ( ) T.alloccount ( ) end
local * toclose y = function ( ) T.alloccount ( ) end
@ -296,7 +299,7 @@ if rawget(_G, "T") then
local function test ( )
local function test ( )
local * toclose x = enter ( 0 ) -- set a memory limit
local * toclose x = enter ( 0 ) -- set a memory limit
-- creation of previous upvalue will raise a memory error
-- creation of previous upvalue will raise a memory error
os.exi t( false ) -- should not run
asser t( false ) -- should not run
end
end
local _ , msg = pcall ( test )
local _ , msg = pcall ( test )
@ -326,33 +329,54 @@ if rawget(_G, "T") then
do -- testing 'toclose' in C string buffer
do -- testing 'toclose' in C string buffer
local s = string.rep ( " a " , 10000 )
collectgarbage ( )
local s = string.rep ( ' a ' , 10000 ) -- large string
local m = T.totalmem ( )
collectgarbage ( " stop " )
s = string.upper ( s ) -- allocate buffer + new string (10K each)
-- ensure buffer was deallocated
assert ( T.totalmem ( ) - m <= 11000 )
collectgarbage ( " restart " )
end
do -- now some tests for freeing buffer in case of errors
local lim = 10000 -- some size larger than the static buffer
local extra = 2000 -- some extra memory (for callinfo, etc.)
local s = string.rep ( " a " , lim )
-- concat this table needs two buffer resizes (one for each 's')
local a = { s , s }
local a = { s , s }
-- ensure proper initialization (stack space, metatable)
collectgarbage ( )
table.concat ( a )
collectgarbage ( ) ; collectgarbage ( )
local m = T.totalmem ( )
m = T.totalmem ( )
collectgarbage ( " stop " )
-- error in the first buffer allocation
T . totalmem ( m + extra )
assert ( not pcall ( table.concat , a ) )
-- first buffer was not even allocated
assert ( T.totalmem ( ) - m <= extra )
-- error in the second buffer allocation
-- error in the second buffer allocation
T.alloccount ( 3 )
T . totalmem ( m + lim + extra )
assert ( not pcall ( table.concat , a ) )
assert ( not pcall ( table.concat , a ) )
T.alloccount ( )
-- first buffer was released by 'toclose'
-- first buffer was released by 'toclose'
assert ( T.totalmem ( ) - m <= 5000 )
assert ( T.totalmem ( ) - m <= extra )
-- error in creation of final string
-- error in creation of final string
T.alloccount ( 4 )
T.totalmem ( m + 2 * lim + extra )
assert ( not pcall ( table.concat , a ) )
assert ( not pcall ( table.concat , a ) )
T.alloccount ( )
-- second buffer was released by 'toclose'
-- second buffer was released by 'toclose'
assert ( T.totalmem ( ) - m <= 5000 )
assert ( T.totalmem ( ) - m <= extra )
-- userdata, upvalue, buffer, buffer, string
-- userdata, upvalue, buffer, buffer, final string
T.alloccount ( 5 )
T.totalmem ( m + 4 * lim + extra )
assert ( # table.concat ( a ) == 20000 )
assert ( # table.concat ( a ) == 2 * lim )
T.alloccount ( )
T.totalmem ( 0 ) -- remove memory limit
collectgarbage ( " restart " )
print ' + '
print ' + '
end
end