aboutsummaryrefslogtreecommitdiff
path: root/testes
diff options
context:
space:
mode:
Diffstat (limited to 'testes')
-rw-r--r--testes/locals.lua58
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)
211end 211end
212 212
213do 213if 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)
225T.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
228end 274end
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
232local co = coroutine.wrap(function() 278local 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()
235end) 281end)
236co() 282co()