diff options
Diffstat (limited to 'testes')
-rw-r--r-- | testes/locals.lua | 58 |
1 files changed, 52 insertions, 6 deletions
diff --git a/testes/locals.lua b/testes/locals.lua index 8d55e9f5..d12c70a0 100644 --- a/testes/locals.lua +++ b/testes/locals.lua | |||
@@ -180,7 +180,7 @@ do | |||
180 | do | 180 | do |
181 | local scoped x = setmetatable({"x"}, {__close = function (self) | 181 | local scoped x = setmetatable({"x"}, {__close = function (self) |
182 | a[#a + 1] = self[1] end}) | 182 | a[#a + 1] = self[1] end}) |
183 | local scoped y = function () a[#a + 1] = "y" end | 183 | local scoped y = function (x) assert(x == nil); a[#a + 1] = "y" end |
184 | a[#a + 1] = "in" | 184 | a[#a + 1] = "in" |
185 | end | 185 | end |
186 | a[#a + 1] = "out" | 186 | a[#a + 1] = "out" |
@@ -210,27 +210,73 @@ do -- errors in __close | |||
210 | and #log == 4) | 210 | and #log == 4) |
211 | end | 211 | end |
212 | 212 | ||
213 | do | 213 | if rawget(_G, "T") then |
214 | local function stack(n) n = (n == 0) or stack(n - 1); end; | ||
214 | -- memory error inside closing function | 215 | -- memory error inside closing function |
215 | local function foo () | 216 | local function foo () |
216 | local scoped y = function () io.write(2); T.alloccount() end | 217 | local scoped y = function () T.alloccount() end |
217 | local scoped x = setmetatable({}, {__close = function () | 218 | local scoped x = setmetatable({}, {__close = function () |
218 | T.alloccount(0); local x = {} -- force a memory error | 219 | T.alloccount(0); local x = {} -- force a memory error |
219 | end}) | 220 | end}) |
220 | io.write("1\n") | ||
221 | error("a") -- common error inside the function's body | 221 | error("a") -- common error inside the function's body |
222 | end | 222 | end |
223 | 223 | ||
224 | stack(5) -- ensure a minimal number of CI structures | ||
225 | |||
226 | -- despite memory error, 'y' will be executed and | ||
227 | -- memory limit will be lifted | ||
224 | local _, msg = pcall(foo) | 228 | local _, msg = pcall(foo) |
225 | T.alloccount() | ||
226 | assert(msg == "not enough memory") | 229 | assert(msg == "not enough memory") |
227 | 230 | ||
231 | local function close (msg) | ||
232 | T.alloccount() | ||
233 | assert(msg == "not enough memory") | ||
234 | end | ||
235 | |||
236 | -- set a memory limit and return a closing function to remove the limit | ||
237 | local function enter (count) | ||
238 | stack(10) -- reserve some stack space | ||
239 | T.alloccount(count) | ||
240 | return close | ||
241 | end | ||
242 | |||
243 | local function test () | ||
244 | local scoped x = enter(0) -- set a memory limit | ||
245 | -- creation of previous upvalue will raise a memory error | ||
246 | os.exit(false) -- should not run | ||
247 | end | ||
248 | |||
249 | local _, msg = pcall(test) | ||
250 | assert(msg == "not enough memory") | ||
251 | |||
252 | -- now use metamethod for closing | ||
253 | close = setmetatable({}, {__close = function () | ||
254 | T.alloccount() | ||
255 | end}) | ||
256 | |||
257 | -- repeat test with extra closing upvalues | ||
258 | local function test () | ||
259 | local scoped xxx = function (msg) | ||
260 | assert(msg == "not enough memory"); | ||
261 | error(1000) -- raise another error | ||
262 | end | ||
263 | local scoped xx = function (msg) | ||
264 | assert(msg == "not enough memory"); | ||
265 | end | ||
266 | local scoped x = enter(0) -- set a memory limit | ||
267 | -- creation of previous upvalue will raise a memory error | ||
268 | os.exit(false) -- should not run | ||
269 | end | ||
270 | |||
271 | local _, msg = pcall(test) | ||
272 | assert(msg == 1000) | ||
273 | |||
228 | end | 274 | end |
229 | 275 | ||
230 | 276 | ||
231 | -- a suspended coroutine should not close its variables when collected | 277 | -- a suspended coroutine should not close its variables when collected |
232 | local co = coroutine.wrap(function() | 278 | local co = coroutine.wrap(function() |
233 | local scoped x = function () os.exit(1) end -- should not run | 279 | local scoped x = function () os.exit(false) end -- should not run |
234 | coroutine.yield() | 280 | coroutine.yield() |
235 | end) | 281 | end) |
236 | co() | 282 | co() |