diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-10-17 10:44:42 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-10-17 10:44:42 -0300 |
commit | bd96330d037660d9a1769c6c0d989f017e5f0278 (patch) | |
tree | c3f4580c628a71f512b057b7f52987153cb88d74 /testes | |
parent | 4cd1f4aac01184765818e0cebf02da454ccf6590 (diff) | |
download | lua-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.lua | 14 | ||||
-rw-r--r-- | testes/locals.lua | 64 |
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 | ||
4 | if T==nil then | 4 | if T==nil then |
@@ -1027,6 +1027,18 @@ testamem("coroutine creation", function() | |||
1027 | end) | 1027 | end) |
1028 | 1028 | ||
1029 | 1029 | ||
1030 | -- testing to-be-closed variables | ||
1031 | testamem("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 | ||
1039 | end) | ||
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 | |||
173 | assert(x==20) | 173 | assert(x==20) |
174 | 174 | ||
175 | 175 | ||
176 | -- tests for to-be-closed variables | 176 | print"testing to-be-closed variables" |
177 | |||
178 | do | ||
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") | ||
188 | end | ||
189 | |||
190 | |||
191 | do -- 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) | ||
211 | end | ||
212 | |||
177 | do | 213 | do |
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) | ||
225 | T.alloccount() | ||
226 | assert(msg == "not enough memory") | ||
227 | |||
182 | end | 228 | end |
183 | 229 | ||
184 | 230 | ||
231 | -- a suspended coroutine should not close its variables when collected | ||
232 | local co = coroutine.wrap(function() | ||
233 | local scoped x = function () os.exit(1) end -- should not run | ||
234 | coroutine.yield() | ||
235 | end) | ||
236 | co() | ||
237 | co = nil | ||
238 | |||
185 | print('OK') | 239 | print('OK') |
186 | 240 | ||
187 | return 5,f | 241 | return 5,f |