aboutsummaryrefslogtreecommitdiff
path: root/testes
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-10-17 10:44:42 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-10-17 10:44:42 -0300
commitbd96330d037660d9a1769c6c0d989f017e5f0278 (patch)
treec3f4580c628a71f512b057b7f52987153cb88d74 /testes
parent4cd1f4aac01184765818e0cebf02da454ccf6590 (diff)
downloadlua-bd96330d037660d9a1769c6c0d989f017e5f0278.tar.gz
lua-bd96330d037660d9a1769c6c0d989f017e5f0278.tar.bz2
lua-bd96330d037660d9a1769c6c0d989f017e5f0278.zip
First "complete" implementation of to-be-closed variables
Still missing: - handling of memory errors when creating upvalue (must run closing method all the same) - interaction with coroutines
Diffstat (limited to 'testes')
-rw-r--r--testes/api.lua14
-rw-r--r--testes/locals.lua64
2 files changed, 72 insertions, 6 deletions
diff --git a/testes/api.lua b/testes/api.lua
index bebb6d2d..925a80c1 100644
--- a/testes/api.lua
+++ b/testes/api.lua
@@ -1,4 +1,4 @@
1-- $Id: testes/api.lua $ 1-- $Id: testes/api.lua 2018-07-25 15:31:04 -0300 $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file all.lua
3 3
4if T==nil then 4if T==nil then
@@ -1027,6 +1027,18 @@ testamem("coroutine creation", function()
1027end) 1027end)
1028 1028
1029 1029
1030-- testing to-be-closed variables
1031testamem("to-be-closed variables", function()
1032 local flag
1033 do
1034 local scoped x = function () flag = true end
1035 flag = false
1036 local x = {}
1037 end
1038 return flag
1039end)
1040
1041
1030-- testing threads 1042-- testing threads
1031 1043
1032-- get main thread from registry (at index LUA_RIDX_MAINTHREAD == 1) 1044-- get main thread from registry (at index LUA_RIDX_MAINTHREAD == 1)
diff --git a/testes/locals.lua b/testes/locals.lua
index 20ecae4b..8d55e9f5 100644
--- a/testes/locals.lua
+++ b/testes/locals.lua
@@ -173,15 +173,69 @@ end
173assert(x==20) 173assert(x==20)
174 174
175 175
176-- tests for to-be-closed variables 176print"testing to-be-closed variables"
177
178do
179 local a = {}
180 do
181 local scoped x = setmetatable({"x"}, {__close = function (self)
182 a[#a + 1] = self[1] end})
183 local scoped y = function () a[#a + 1] = "y" end
184 a[#a + 1] = "in"
185 end
186 a[#a + 1] = "out"
187 assert(a[1] == "in" and a[2] == "y" and a[3] == "x" and a[4] == "out")
188end
189
190
191do -- errors in __close
192 local log = {}
193 local function foo (err)
194 local scoped x = function (msg) log[#log + 1] = msg; error(1) end
195 local scoped x1 = function (msg) log[#log + 1] = msg; end
196 local scoped gc = function () collectgarbage() end
197 local scoped y = function (msg) log[#log + 1] = msg; error(2) end
198 local scoped z = function (msg) log[#log + 1] = msg or 10; error(3) end
199 if err then error(4) end
200 end
201 local stat, msg = pcall(foo, false)
202 assert(msg == 1)
203 assert(log[1] == 10 and log[2] == 3 and log[3] == 2 and log[4] == 2
204 and #log == 4)
205
206 log = {}
207 local stat, msg = pcall(foo, true)
208 assert(msg == 1)
209 assert(log[1] == 4 and log[2] == 3 and log[3] == 2 and log[4] == 2
210 and #log == 4)
211end
212
177do 213do
178 local scoped x = 3 214 -- memory error inside closing function
179 local a 215 local function foo ()
180 local scoped y = 5 216 local scoped y = function () io.write(2); T.alloccount() end
181 assert(x == 3 and y == 5) 217 local scoped x = setmetatable({}, {__close = function ()
218 T.alloccount(0); local x = {} -- force a memory error
219 end})
220 io.write("1\n")
221 error("a") -- common error inside the function's body
222 end
223
224 local _, msg = pcall(foo)
225T.alloccount()
226 assert(msg == "not enough memory")
227
182end 228end
183 229
184 230
231-- a suspended coroutine should not close its variables when collected
232local co = coroutine.wrap(function()
233 local scoped x = function () os.exit(1) end -- should not run
234 coroutine.yield()
235end)
236co()
237co = nil
238
185print('OK') 239print('OK')
186 240
187return 5,f 241return 5,f