From 6d04537ea660fd12fc16c328366b701fabaf4919 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 29 Nov 2018 16:02:44 -0200 Subject: A to-be-closed variable must have a closable value (or be nil) It is an error for a to-be-closed variable to have a non-closable non-nil value when it is being closed. This situation does not seem to be useful and often hints to an error. (Particularly in the C API, it is easy to change a to-be-closed index by mistake.) --- testes/api.lua | 21 ++++++++++++++------- testes/db.lua | 20 ++++++++++---------- testes/locals.lua | 21 +++++++++++++++++++++ 3 files changed, 45 insertions(+), 17 deletions(-) (limited to 'testes') diff --git a/testes/api.lua b/testes/api.lua index ed857fd0..6f35e132 100644 --- a/testes/api.lua +++ b/testes/api.lua @@ -366,7 +366,7 @@ do -- "argerror" without frames assert(T.checkpanic("loadstring 4") == "bad argument #4 (string expected, got no value)") - + -- memory error T.totalmem(T.totalmem()+10000) -- set low memory limit (+10k) @@ -987,12 +987,12 @@ do local a, b = T.testC([[ call 0 1 # create resource - pushint 34 + pushnil toclose -2 # mark call result to be closed - toclose -1 # mark number to be closed (will be ignored) + toclose -1 # mark nil to be closed (will be ignored) return 2 ]], newresource) - assert(a[1] == 11 and b == 34) + assert(a[1] == 11 and b == nil) assert(#openresource == 0) -- was closed -- repeat the test, but calling function in a 'multret' context @@ -1005,7 +1005,7 @@ do assert(#openresource == 0) -- was closed -- error - local a, b = pcall(T.testC, [[ + local a, b = pcall(T.makeCfunc[[ call 0 1 # create resource toclose -1 # mark it to be closed error # resource is the error object @@ -1038,6 +1038,13 @@ do ]], newresource, check) assert(a == 3) -- no extra items left in the stack + -- non-closable value + local a, b = pcall(T.makeCfunc[[ + pushint 32 + toclose -1 + ]]) + assert(not a and string.find(b, "(C temporary)")) + end @@ -1249,9 +1256,9 @@ do -- closing state with no extra memory T.closestate(L) T.alloccount() end - + do -- garbage collection with no extra memory - local L = T.newstate() + local L = T.newstate() T.loadlib(L) local res = (T.doremote(L, [[ _ENV = require"_G" diff --git a/testes/db.lua b/testes/db.lua index 5b243c39..976962b0 100644 --- a/testes/db.lua +++ b/testes/db.lua @@ -214,14 +214,14 @@ local function foo (a, ...) local t = table.pack(...) for i = 1, t.n do local n, v = debug.getlocal(1, -i) - assert(n == "(*vararg)" and v == t[i]) + assert(n == "(vararg)" and v == t[i]) end assert(not debug.getlocal(1, -(t.n + 1))) assert(not debug.setlocal(1, -(t.n + 1), 30)) if t.n > 0 then (function (x) - assert(debug.setlocal(2, -1, x) == "(*vararg)") - assert(debug.setlocal(2, -t.n, x) == "(*vararg)") + assert(debug.setlocal(2, -1, x) == "(vararg)") + assert(debug.setlocal(2, -t.n, x) == "(vararg)") end)(430) assert(... == 430) end @@ -328,9 +328,9 @@ assert(a[f] and a[g] and a[assert] and a[debug.getlocal] and not a[print]) -- tests for manipulating non-registered locals (C and Lua temporaries) local n, v = debug.getlocal(0, 1) -assert(v == 0 and n == "(*temporary)") +assert(v == 0 and n == "(C temporary)") local n, v = debug.getlocal(0, 2) -assert(v == 2 and n == "(*temporary)") +assert(v == 2 and n == "(C temporary)") assert(not debug.getlocal(0, 3)) assert(not debug.getlocal(0, 0)) @@ -607,7 +607,7 @@ co = load[[ local a = 0 -- 'A' should be visible to debugger only after its complete definition debug.sethook(function (e, l) - if l == 3 then a = a + 1; assert(debug.getlocal(2, 1) == "(*temporary)") + if l == 3 then a = a + 1; assert(debug.getlocal(2, 1) == "(temporary)") elseif l == 4 then a = a + 1; assert(debug.getlocal(2, 1) == "A") end end, "l") @@ -875,15 +875,15 @@ local debug = require'debug' local a = 12 -- a local variable local n, v = debug.getlocal(1, 1) -assert(n == "(*temporary)" and v == debug) -- unkown name but known value +assert(n == "(temporary)" and v == debug) -- unkown name but known value n, v = debug.getlocal(1, 2) -assert(n == "(*temporary)" and v == 12) -- unkown name but known value +assert(n == "(temporary)" and v == 12) -- unkown name but known value -- a function with an upvalue local f = function () local x; return a end n, v = debug.getupvalue(f, 1) -assert(n == "(*no name)" and v == 12) -assert(debug.setupvalue(f, 1, 13) == "(*no name)") +assert(n == "(no name)" and v == 12) +assert(debug.setupvalue(f, 1, 13) == "(no name)") assert(a == 13) local t = debug.getinfo(f) diff --git a/testes/locals.lua b/testes/locals.lua index 90a8b845..24681dd9 100644 --- a/testes/locals.lua +++ b/testes/locals.lua @@ -266,6 +266,27 @@ do -- errors in __close end +do + + -- errors due to non-closable values + local function foo () + local *toclose x = 34 + end + local stat, msg = pcall(foo) + assert(not stat and string.find(msg, "variable 'x'")) + + + -- with other errors, non-closable values are ignored + local function foo () + local *toclose x = 34 + local *toclose y = function () error(32) end + end + local stat, msg = pcall(foo) + assert(not stat and msg == 32) + +end + + if rawget(_G, "T") then -- memory error inside closing function -- cgit v1.2.3-55-g6feb