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() |
