|
@@ -185,9 +185,9 @@ end
|
|
|
do
|
|
|
local a = {}
|
|
|
do
|
|
|
- local *toclose x = setmetatable({"x"}, {__close = function (self)
|
|
|
+ local <toclose> x = setmetatable({"x"}, {__close = function (self)
|
|
|
a[#a + 1] = self[1] end})
|
|
|
- local *toclose y = func2close(function (self, err)
|
|
|
+ local <toclose> y = func2close(function (self, err)
|
|
|
assert(err == nil); a[#a + 1] = "y"
|
|
|
end)
|
|
|
a[#a + 1] = "in"
|
|
@@ -203,7 +203,7 @@ do
|
|
|
|
|
|
-- closing functions do not corrupt returning values
|
|
|
local function foo (x)
|
|
|
- local *toclose _ = closescope
|
|
|
+ local <toclose> _ = closescope
|
|
|
return x, X, 23
|
|
|
end
|
|
|
|
|
@@ -212,7 +212,7 @@ do
|
|
|
|
|
|
X = false
|
|
|
foo = function (x)
|
|
|
- local *toclose _ = closescope
|
|
|
+ local <toclose> _ = closescope
|
|
|
local y = 15
|
|
|
return y
|
|
|
end
|
|
@@ -221,7 +221,7 @@ do
|
|
|
|
|
|
X = false
|
|
|
foo = function ()
|
|
|
- local *toclose x = closescope
|
|
|
+ local <toclose> x = closescope
|
|
|
return x
|
|
|
end
|
|
|
|
|
@@ -234,13 +234,13 @@ do
|
|
|
-- calls cannot be tail in the scope of to-be-closed variables
|
|
|
local X, Y
|
|
|
local function foo ()
|
|
|
- local *toclose _ = func2close(function () Y = 10 end)
|
|
|
+ local <toclose> _ = func2close(function () Y = 10 end)
|
|
|
assert(X == true and Y == nil) -- 'X' not closed yet
|
|
|
return 1,2,3
|
|
|
end
|
|
|
|
|
|
local function bar ()
|
|
|
- local *toclose _ = func2close(function () X = false end)
|
|
|
+ local <toclose> _ = func2close(function () X = false end)
|
|
|
X = true
|
|
|
do
|
|
|
return foo() -- not a tail call!
|
|
@@ -255,14 +255,14 @@ end
|
|
|
do -- errors in __close
|
|
|
local log = {}
|
|
|
local function foo (err)
|
|
|
- local *toclose x =
|
|
|
+ local <toclose> x =
|
|
|
func2close(function (self, msg) log[#log + 1] = msg; error(1) end)
|
|
|
- local *toclose x1 =
|
|
|
+ local <toclose> x1 =
|
|
|
func2close(function (self, msg) log[#log + 1] = msg; end)
|
|
|
- local *toclose gc = func2close(function () collectgarbage() end)
|
|
|
- local *toclose y =
|
|
|
+ local <toclose> gc = func2close(function () collectgarbage() end)
|
|
|
+ local <toclose> y =
|
|
|
func2close(function (self, msg) log[#log + 1] = msg; error(2) end)
|
|
|
- local *toclose z =
|
|
|
+ local <toclose> z =
|
|
|
func2close(function (self, msg) log[#log + 1] = msg or 10; error(3) end)
|
|
|
if err then error(4) end
|
|
|
end
|
|
@@ -283,7 +283,7 @@ do
|
|
|
|
|
|
-- errors due to non-closable values
|
|
|
local function foo ()
|
|
|
- local *toclose x = 34
|
|
|
+ local <toclose> x = 34
|
|
|
end
|
|
|
local stat, msg = pcall(foo)
|
|
|
assert(not stat and string.find(msg, "variable 'x'"))
|
|
@@ -291,8 +291,8 @@ do
|
|
|
|
|
|
-- with other errors, non-closable values are ignored
|
|
|
local function foo ()
|
|
|
- local *toclose x = 34
|
|
|
- local *toclose y = func2close(function () error(32) end)
|
|
|
+ local <toclose> x = 34
|
|
|
+ local <toclose> y = func2close(function () error(32) end)
|
|
|
end
|
|
|
local stat, msg = pcall(foo)
|
|
|
assert(not stat and msg == 32)
|
|
@@ -304,8 +304,8 @@ if rawget(_G, "T") then
|
|
|
|
|
|
-- memory error inside closing function
|
|
|
local function foo ()
|
|
|
- local *toclose y = func2close(function () T.alloccount() end)
|
|
|
- local *toclose x = setmetatable({}, {__close = function ()
|
|
|
+ local <toclose> y = func2close(function () T.alloccount() end)
|
|
|
+ local <toclose> x = setmetatable({}, {__close = function ()
|
|
|
T.alloccount(0); local x = {} -- force a memory error
|
|
|
end})
|
|
|
error("a") -- common error inside the function's body
|
|
@@ -331,7 +331,7 @@ if rawget(_G, "T") then
|
|
|
end
|
|
|
|
|
|
local function test ()
|
|
|
- local *toclose x = enter(0) -- set a memory limit
|
|
|
+ local <toclose> x = enter(0) -- set a memory limit
|
|
|
-- creation of previous upvalue will raise a memory error
|
|
|
assert(false) -- should not run
|
|
|
end
|
|
@@ -346,14 +346,14 @@ if rawget(_G, "T") then
|
|
|
|
|
|
-- repeat test with extra closing upvalues
|
|
|
local function test ()
|
|
|
- local *toclose xxx = func2close(function (self, msg)
|
|
|
+ local <toclose> xxx = func2close(function (self, msg)
|
|
|
assert(msg == "not enough memory");
|
|
|
error(1000) -- raise another error
|
|
|
end)
|
|
|
- local *toclose xx = func2close(function (self, msg)
|
|
|
+ local <toclose> xx = func2close(function (self, msg)
|
|
|
assert(msg == "not enough memory");
|
|
|
end)
|
|
|
- local *toclose x = enter(0) -- set a memory limit
|
|
|
+ local <toclose> x = enter(0) -- set a memory limit
|
|
|
-- creation of previous upvalue will raise a memory error
|
|
|
os.exit(false) -- should not run
|
|
|
end
|
|
@@ -424,9 +424,9 @@ do
|
|
|
local x = false
|
|
|
local y = false
|
|
|
local co = coroutine.wrap(function ()
|
|
|
- local *toclose xv = func2close(function () x = true end)
|
|
|
+ local <toclose> xv = func2close(function () x = true end)
|
|
|
do
|
|
|
- local *toclose yv = func2close(function () y = true end)
|
|
|
+ local <toclose> yv = func2close(function () y = true end)
|
|
|
coroutine.yield(100) -- yield doesn't close variable
|
|
|
end
|
|
|
coroutine.yield(200) -- yield doesn't close variable
|
|
@@ -446,7 +446,7 @@ do
|
|
|
-- error in a wrapped coroutine raising errors when closing a variable
|
|
|
local x = false
|
|
|
local co = coroutine.wrap(function ()
|
|
|
- local *toclose xv = func2close(function () error("XXX") end)
|
|
|
+ local <toclose> xv = func2close(function () error("XXX") end)
|
|
|
coroutine.yield(100)
|
|
|
error(200)
|
|
|
end)
|
|
@@ -461,7 +461,7 @@ end
|
|
|
-- a suspended coroutine should not close its variables when collected
|
|
|
local co
|
|
|
co = coroutine.wrap(function()
|
|
|
- local *toclose x = function () os.exit(false) end -- should not run
|
|
|
+ local <toclose> x = function () os.exit(false) end -- should not run
|
|
|
co = nil
|
|
|
coroutine.yield()
|
|
|
end)
|