Change in the syntax of attributes

Attributes changed to posfixed ('x <const>', instead of '<const> x'),
and "toclose" renamed to "close". Posfixed attributes seem to make it
clearer that it applies to only one variable when there are multiple
variables.
This commit is contained in:
Roberto Ierusalimschy 2019-07-30 12:18:19 -03:00
parent b80077b8f3
commit 0d52913804
11 changed files with 103 additions and 102 deletions

View File

@ -190,7 +190,7 @@ static int registerlocalvar (LexState *ls, FuncState *fs, TString *varname) {
** Create a new local variable with the given 'name'. Return its index ** Create a new local variable with the given 'name'. Return its index
** in the function. ** in the function.
*/ */
static int new_localvar (LexState *ls, TString *name, int kind) { static int new_localvar (LexState *ls, TString *name) {
lua_State *L = ls->L; lua_State *L = ls->L;
FuncState *fs = ls->fs; FuncState *fs = ls->fs;
Dyndata *dyd = ls->dyd; Dyndata *dyd = ls->dyd;
@ -200,14 +200,14 @@ static int new_localvar (LexState *ls, TString *name, int kind) {
luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1, luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
dyd->actvar.size, Vardesc, USHRT_MAX, "local variables"); dyd->actvar.size, Vardesc, USHRT_MAX, "local variables");
var = &dyd->actvar.arr[dyd->actvar.n++]; var = &dyd->actvar.arr[dyd->actvar.n++];
var->vd.kind = kind; var->vd.kind = VDKREG; /* default */
var->vd.name = name; var->vd.name = name;
return dyd->actvar.n - 1 - fs->firstlocal; return dyd->actvar.n - 1 - fs->firstlocal;
} }
#define new_localvarliteral(ls,v) \ #define new_localvarliteral(ls,v) \
new_localvar(ls, \ new_localvar(ls, \
luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1), VDKREG); luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1));
@ -947,7 +947,7 @@ static void parlist (LexState *ls) {
do { do {
switch (ls->t.token) { switch (ls->t.token) {
case TK_NAME: { /* param -> NAME */ case TK_NAME: { /* param -> NAME */
new_localvar(ls, str_checkname(ls), VDKREG); new_localvar(ls, str_checkname(ls));
nparams++; nparams++;
break; break;
} }
@ -1553,7 +1553,7 @@ static void fornum (LexState *ls, TString *varname, int line) {
new_localvarliteral(ls, "(for state)"); new_localvarliteral(ls, "(for state)");
new_localvarliteral(ls, "(for state)"); new_localvarliteral(ls, "(for state)");
new_localvarliteral(ls, "(for state)"); new_localvarliteral(ls, "(for state)");
new_localvar(ls, varname, VDKREG); new_localvar(ls, varname);
checknext(ls, '='); checknext(ls, '=');
exp1(ls); /* initial value */ exp1(ls); /* initial value */
checknext(ls, ','); checknext(ls, ',');
@ -1582,9 +1582,9 @@ static void forlist (LexState *ls, TString *indexname) {
new_localvarliteral(ls, "(for state)"); new_localvarliteral(ls, "(for state)");
new_localvarliteral(ls, "(for state)"); new_localvarliteral(ls, "(for state)");
/* create declared variables */ /* create declared variables */
new_localvar(ls, indexname, VDKREG); new_localvar(ls, indexname);
while (testnext(ls, ',')) { while (testnext(ls, ',')) {
new_localvar(ls, str_checkname(ls), VDKREG); new_localvar(ls, str_checkname(ls));
nvars++; nvars++;
} }
checknext(ls, TK_IN); checknext(ls, TK_IN);
@ -1708,7 +1708,7 @@ static void localfunc (LexState *ls) {
expdesc b; expdesc b;
FuncState *fs = ls->fs; FuncState *fs = ls->fs;
int fvar = fs->nactvar; /* function's variable index */ int fvar = fs->nactvar; /* function's variable index */
new_localvar(ls, str_checkname(ls), VDKREG); /* new local variable */ new_localvar(ls, str_checkname(ls)); /* new local variable */
adjustlocalvars(ls, 1); /* enter its scope */ adjustlocalvars(ls, 1); /* enter its scope */
body(ls, &b, 0, ls->linenumber); /* function created in next register */ body(ls, &b, 0, ls->linenumber); /* function created in next register */
/* debug information will only see the variable after this point! */ /* debug information will only see the variable after this point! */
@ -1723,7 +1723,7 @@ static int getlocalattribute (LexState *ls) {
checknext(ls, '>'); checknext(ls, '>');
if (strcmp(attr, "const") == 0) if (strcmp(attr, "const") == 0)
return RDKCONST; /* read-only variable */ return RDKCONST; /* read-only variable */
else if (strcmp(attr, "toclose") == 0) else if (strcmp(attr, "close") == 0)
return RDKTOCLOSE; /* to-be-closed variable */ return RDKTOCLOSE; /* to-be-closed variable */
else else
luaK_semerror(ls, luaK_semerror(ls,
@ -1748,13 +1748,14 @@ static void localstat (LexState *ls) {
FuncState *fs = ls->fs; FuncState *fs = ls->fs;
int toclose = -1; /* index of to-be-closed variable (if any) */ int toclose = -1; /* index of to-be-closed variable (if any) */
Vardesc *var; /* last variable */ Vardesc *var; /* last variable */
int ivar; /* index of last variable */ int ivar, kind; /* index and kind of last variable */
int nvars = 0; int nvars = 0;
int nexps; int nexps;
expdesc e; expdesc e;
do { do {
int kind = getlocalattribute(ls); ivar = new_localvar(ls, str_checkname(ls));
ivar = new_localvar(ls, str_checkname(ls), kind); kind = getlocalattribute(ls);
getlocalvardesc(fs, ivar)->vd.kind = kind;
if (kind == RDKTOCLOSE) { /* to-be-closed? */ if (kind == RDKTOCLOSE) { /* to-be-closed? */
if (toclose != -1) /* one already present? */ if (toclose != -1) /* one already present? */
luaK_semerror(ls, "multiple to-be-closed variables in local list"); luaK_semerror(ls, "multiple to-be-closed variables in local list");

View File

@ -1203,7 +1203,7 @@ end)
testamem("to-be-closed variables", function() testamem("to-be-closed variables", function()
local flag local flag
do do
local <toclose> x = local x <close> =
setmetatable({}, {__close = function () flag = true end}) setmetatable({}, {__close = function () flag = true end})
flag = false flag = false
local x = {} local x = {}

View File

@ -8,22 +8,22 @@ end
print "testing code generation and optimizations" print "testing code generation and optimizations"
-- to test constant propagation -- to test constant propagation
local <const> k0aux = 0 local k0aux <const> = 0
local <const> k0 = k0aux local k0 <const> = k0aux
local <const> k1 = 1 local k1 <const> = 1
local <const> k3 = 3 local k3 <const> = 3
local <const> k6 = k3 + (k3 << k0) local k6 <const> = k3 + (k3 << k0)
local <const> kFF0 = 0xFF0 local kFF0 <const> = 0xFF0
local <const> k3_78 = 3.78 local k3_78 <const> = 3.78
local <const> x, <const> k3_78_4 = 10, k3_78 / 4 local x, k3_78_4 <const> = 10, k3_78 / 4
assert(x == 10) assert(x == 10)
local <const> kx = "x" local kx <const> = "x"
local <const> kTrue = true local kTrue <const> = true
local <const> kFalse = false local kFalse <const> = false
local <const> kNil = nil local kNil <const> = nil
-- this code gave an error for the code checker -- this code gave an error for the code checker
do do
@ -105,7 +105,7 @@ end, 'CLOSURE', 'NEWTABLE', 'EXTRAARG', 'GETTABUP', 'CALL',
-- sequence of LOADNILs -- sequence of LOADNILs
check(function () check(function ()
local <const> kNil = nil local kNil <const> = nil
local a,b,c local a,b,c
local d; local e; local d; local e;
local f,g,h; local f,g,h;
@ -173,7 +173,7 @@ end,
-- "get/set table" with numeric indices -- "get/set table" with numeric indices
check(function (a) check(function (a)
local <const> k255 = 255 local k255 <const> = 255
a[1] = a[100] a[1] = a[100]
a[k255] = a[256] a[k255] = a[256]
a[256] = 5 a[256] = 5
@ -276,14 +276,14 @@ checkI(function () return ((100 << k6) << -4) >> 2 end, 100)
-- borders around MAXARG_sBx ((((1 << 17) - 1) >> 1) == 65535) -- borders around MAXARG_sBx ((((1 << 17) - 1) >> 1) == 65535)
local a = 17; local sbx = ((1 << a) - 1) >> 1 -- avoid folding local a = 17; local sbx = ((1 << a) - 1) >> 1 -- avoid folding
local <const> border = 65535 local border <const> = 65535
checkI(function () return border end, sbx) checkI(function () return border end, sbx)
checkI(function () return -border end, -sbx) checkI(function () return -border end, -sbx)
checkI(function () return border + 1 end, sbx + 1) checkI(function () return border + 1 end, sbx + 1)
checkK(function () return border + 2 end, sbx + 2) checkK(function () return border + 2 end, sbx + 2)
checkK(function () return -(border + 1) end, -(sbx + 1)) checkK(function () return -(border + 1) end, -(sbx + 1))
local <const> border = 65535.0 local border <const> = 65535.0
checkF(function () return border end, sbx + 0.0) checkF(function () return border end, sbx + 0.0)
checkF(function () return -border end, -sbx + 0.0) checkF(function () return -border end, -sbx + 0.0)
checkF(function () return border + 1 end, (sbx + 1.0)) checkF(function () return border + 1 end, (sbx + 1.0))
@ -411,9 +411,9 @@ checkequal(function () return 6 and true or nil end,
do -- string constants do -- string constants
local <const> k0 = "00000000000000000000000000000000000000000000000000" local k0 <const> = "00000000000000000000000000000000000000000000000000"
local function f1 () local function f1 ()
local <const> k = k0 local k <const> = k0
return function () return function ()
return function () return k end return function () return k end
end end

View File

@ -211,15 +211,15 @@ assert(a==1 and b==nil)
print'+'; print'+';
do -- testing constants do -- testing constants
local <const> prog = [[local <XXX> x = 10]] local prog <const> = [[local x <XXX> = 10]]
checkload(prog, "unknown attribute 'XXX'") checkload(prog, "unknown attribute 'XXX'")
checkload([[local <const> xxx = 20; xxx = 10]], checkload([[local xxx <const> = 20; xxx = 10]],
":1: attempt to assign to const variable 'xxx'") ":1: attempt to assign to const variable 'xxx'")
checkload([[ checkload([[
local xx; local xx;
local <const> xxx = 20; local xxx <const> = 20;
local yyy; local yyy;
local function foo () local function foo ()
local abc = xx + yyy + xxx; local abc = xx + yyy + xxx;
@ -228,7 +228,7 @@ do -- testing constants
]], ":6: attempt to assign to const variable 'xxx'") ]], ":6: attempt to assign to const variable 'xxx'")
checkload([[ checkload([[
local <toclose> x = nil local x <close> = nil
x = io.open() x = io.open()
]], ":2: attempt to assign to const variable 'x'") ]], ":2: attempt to assign to const variable 'x'")
end end
@ -304,7 +304,7 @@ if _ENV.GLOB1 == 0 then
basiccases[2][1] = "F" -- constant false basiccases[2][1] = "F" -- constant false
prog = [[ prog = [[
local <const> F = false local F <const> = false
if %s then IX = true end if %s then IX = true end
return %s return %s
]] ]]
@ -312,7 +312,7 @@ else
basiccases[4][1] = "k10" -- constant 10 basiccases[4][1] = "k10" -- constant 10
prog = [[ prog = [[
local <const> k10 = 10 local k10 <const> = 10
if %s then IX = true end if %s then IX = true end
return %s return %s
]] ]]
@ -322,12 +322,12 @@ print('testing short-circuit optimizations (' .. _ENV.GLOB1 .. ')')
-- operators with their respective values -- operators with their respective values
local <const> binops = { local binops <const> = {
{" and ", function (a,b) if not a then return a else return b end end}, {" and ", function (a,b) if not a then return a else return b end end},
{" or ", function (a,b) if a then return a else return b end end}, {" or ", function (a,b) if a then return a else return b end end},
} }
local <const> cases = {} local cases <const> = {}
-- creates all combinations of '(cases[i] op cases[n-i])' plus -- creates all combinations of '(cases[i] op cases[n-i])' plus
-- 'not(cases[i] op cases[n-i])' (syntax + value) -- 'not(cases[i] op cases[n-i])' (syntax + value)

View File

@ -151,7 +151,7 @@ do
end end
co = coroutine.create(function () co = coroutine.create(function ()
local <toclose> x = func2close(function (self, err) local x <close> = func2close(function (self, err)
assert(err == nil); X = false assert(err == nil); X = false
end) end)
X = true X = true
@ -165,12 +165,12 @@ do
-- error closing a coroutine -- error closing a coroutine
local x = 0 local x = 0
co = coroutine.create(function() co = coroutine.create(function()
local <toclose> y = func2close(function (self,err) local y <close> = func2close(function (self,err)
if (err ~= 111) then os.exit(false) end -- should not happen if (err ~= 111) then os.exit(false) end -- should not happen
x = 200 x = 200
error(200) error(200)
end) end)
local <toclose> x = func2close(function (self, err) local x <close> = func2close(function (self, err)
assert(err == nil); error(111) assert(err == nil); error(111)
end) end)
coroutine.yield() coroutine.yield()
@ -356,7 +356,7 @@ do
local X = false local X = false
A = coroutine.wrap(function() A = coroutine.wrap(function()
local <toclose> _ = setmetatable({}, {__close = function () X = true end}) local _ <close> = setmetatable({}, {__close = function () X = true end})
return pcall(A, 1) return pcall(A, 1)
end) end)
st, res = A() st, res = A()

View File

@ -125,7 +125,7 @@ do
-- closing file by scope -- closing file by scope
local F = nil local F = nil
do do
local <toclose> f = assert(io.open(file, "w")) local f <close> = assert(io.open(file, "w"))
F = f F = f
end end
assert(tostring(F) == "file (closed)") assert(tostring(F) == "file (closed)")
@ -135,7 +135,7 @@ assert(os.remove(file))
do do
-- test writing/reading numbers -- test writing/reading numbers
local <toclose> f = assert(io.open(file, "w")) local f <close> = assert(io.open(file, "w"))
f:write(maxint, '\n') f:write(maxint, '\n')
f:write(string.format("0X%x\n", maxint)) f:write(string.format("0X%x\n", maxint))
f:write("0xABCp-3", '\n') f:write("0xABCp-3", '\n')
@ -144,7 +144,7 @@ do
f:write(string.format("0x%X\n", -maxint)) f:write(string.format("0x%X\n", -maxint))
f:write("-0xABCp-3", '\n') f:write("-0xABCp-3", '\n')
assert(f:close()) assert(f:close())
local <toclose> f = assert(io.open(file, "r")) local f <close> = assert(io.open(file, "r"))
assert(f:read("n") == maxint) assert(f:read("n") == maxint)
assert(f:read("n") == maxint) assert(f:read("n") == maxint)
assert(f:read("n") == 0xABCp-3) assert(f:read("n") == 0xABCp-3)
@ -158,7 +158,7 @@ assert(os.remove(file))
-- testing multiple arguments to io.read -- testing multiple arguments to io.read
do do
local <toclose> f = assert(io.open(file, "w")) local f <close> = assert(io.open(file, "w"))
f:write[[ f:write[[
a line a line
another line another line
@ -170,18 +170,18 @@ three
]] ]]
local l1, l2, l3, l4, n1, n2, c, dummy local l1, l2, l3, l4, n1, n2, c, dummy
assert(f:close()) assert(f:close())
local <toclose> f = assert(io.open(file, "r")) local f <close> = assert(io.open(file, "r"))
l1, l2, n1, n2, dummy = f:read("l", "L", "n", "n") l1, l2, n1, n2, dummy = f:read("l", "L", "n", "n")
assert(l1 == "a line" and l2 == "another line\n" and assert(l1 == "a line" and l2 == "another line\n" and
n1 == 1234 and n2 == 3.45 and dummy == nil) n1 == 1234 and n2 == 3.45 and dummy == nil)
assert(f:close()) assert(f:close())
local <toclose> f = assert(io.open(file, "r")) local f <close> = assert(io.open(file, "r"))
l1, l2, n1, n2, c, l3, l4, dummy = f:read(7, "l", "n", "n", 1, "l", "l") l1, l2, n1, n2, c, l3, l4, dummy = f:read(7, "l", "n", "n", 1, "l", "l")
assert(l1 == "a line\n" and l2 == "another line" and c == '\n' and assert(l1 == "a line\n" and l2 == "another line" and c == '\n' and
n1 == 1234 and n2 == 3.45 and l3 == "one" and l4 == "two" n1 == 1234 and n2 == 3.45 and l3 == "one" and l4 == "two"
and dummy == nil) and dummy == nil)
assert(f:close()) assert(f:close())
local <toclose> f = assert(io.open(file, "r")) local f <close> = assert(io.open(file, "r"))
-- second item failing -- second item failing
l1, n1, n2, dummy = f:read("l", "n", "n", "l") l1, n1, n2, dummy = f:read("l", "n", "n", "l")
assert(l1 == "a line" and n1 == nil) assert(l1 == "a line" and n1 == nil)

View File

@ -258,7 +258,7 @@ do
::L2:: goto L3 ::L2:: goto L3
::L1:: do ::L1:: do
local <toclose> a = setmetatable({}, {__close = function () X = true end}) local a <close> = setmetatable({}, {__close = function () X = true end})
assert(X == nil) assert(X == nil)
if a then goto L2 end -- jumping back out of scope of 'a' if a then goto L2 end -- jumping back out of scope of 'a'
end end

View File

@ -174,7 +174,7 @@ assert(x==20)
do -- constants do -- constants
local <const> a, b, <const> c = 10, 20, 30 local a<const>, b, c<const> = 10, 20, 30
b = a + c + b -- 'b' is not constant b = a + c + b -- 'b' is not constant
assert(a == 10 and b == 60 and c == 30) assert(a == 10 and b == 60 and c == 30)
local function checkro (name, code) local function checkro (name, code)
@ -182,17 +182,17 @@ do -- constants
local gab = string.format("attempt to assign to const variable '%s'", name) local gab = string.format("attempt to assign to const variable '%s'", name)
assert(not st and string.find(msg, gab)) assert(not st and string.find(msg, gab))
end end
checkro("y", "local x, <const> y, z = 10, 20, 30; x = 11; y = 12") checkro("y", "local x, y <const>, z = 10, 20, 30; x = 11; y = 12")
checkro("x", "local <const> x, y, <const> z = 10, 20, 30; x = 11") checkro("x", "local x <const>, y, z <const> = 10, 20, 30; x = 11")
checkro("z", "local <const> x, y, <const> z = 10, 20, 30; y = 10; z = 11") checkro("z", "local x <const>, y, z <const> = 10, 20, 30; y = 10; z = 11")
checkro("z", [[ checkro("z", [[
local a, <const> z, b = 10; local a, z <const>, b = 10;
function foo() a = 20; z = 32; end function foo() a = 20; z = 32; end
]]) ]])
checkro("var1", [[ checkro("var1", [[
local a, <const> var1 = 10; local a, var1 <const> = 10;
function foo() a = 20; z = function () var1 = 12; end end function foo() a = 20; z = function () var1 = 12; end end
]]) ]])
end end
@ -215,9 +215,9 @@ end
do do
local a = {} local a = {}
do do
local <toclose> x = setmetatable({"x"}, {__close = function (self) local x <close> = setmetatable({"x"}, {__close = function (self)
a[#a + 1] = self[1] end}) a[#a + 1] = self[1] end})
local w, <toclose> y, z = func2close(function (self, err) local w, y <close>, z = func2close(function (self, err)
assert(err == nil); a[#a + 1] = "y" assert(err == nil); a[#a + 1] = "y"
end, 10, 20) end, 10, 20)
a[#a + 1] = "in" a[#a + 1] = "in"
@ -235,7 +235,7 @@ do
-- closing functions do not corrupt returning values -- closing functions do not corrupt returning values
local function foo (x) local function foo (x)
local <toclose> _ = closescope local _ <close> = closescope
return x, X, 23 return x, X, 23
end end
@ -244,7 +244,7 @@ do
X = false X = false
foo = function (x) foo = function (x)
local <toclose> _ = closescope local _<close> = closescope
local y = 15 local y = 15
return y return y
end end
@ -253,7 +253,7 @@ do
X = false X = false
foo = function () foo = function ()
local <toclose> x = closescope local x <close> = closescope
return x return x
end end
@ -266,13 +266,13 @@ do
-- calls cannot be tail in the scope of to-be-closed variables -- calls cannot be tail in the scope of to-be-closed variables
local X, Y local X, Y
local function foo () local function foo ()
local <toclose> _ = func2close(function () Y = 10 end) local _ <close> = func2close(function () Y = 10 end)
assert(X == true and Y == nil) -- 'X' not closed yet assert(X == true and Y == nil) -- 'X' not closed yet
return 1,2,3 return 1,2,3
end end
local function bar () local function bar ()
local <toclose> _ = func2close(function () X = false end) local _ <close> = func2close(function () X = false end)
X = true X = true
do do
return foo() -- not a tail call! return foo() -- not a tail call!
@ -287,14 +287,14 @@ end
do -- errors in __close do -- errors in __close
local log = {} local log = {}
local function foo (err) local function foo (err)
local <toclose> x = local x <close> =
func2close(function (self, msg) log[#log + 1] = msg; error(1) end) func2close(function (self, msg) log[#log + 1] = msg; error(1) end)
local <toclose> x1 = local x1 <close> =
func2close(function (self, msg) log[#log + 1] = msg; end) func2close(function (self, msg) log[#log + 1] = msg; end)
local <toclose> gc = func2close(function () collectgarbage() end) local gc <close> = func2close(function () collectgarbage() end)
local <toclose> y = local y <close> =
func2close(function (self, msg) log[#log + 1] = msg; error(2) end) func2close(function (self, msg) log[#log + 1] = msg; error(2) end)
local <toclose> z = local z <close> =
func2close(function (self, msg) func2close(function (self, msg)
log[#log + 1] = (msg or 10) + 1; log[#log + 1] = (msg or 10) + 1;
error(3) error(3)
@ -316,7 +316,7 @@ do -- errors in __close
-- error in toclose in vararg function -- error in toclose in vararg function
function foo (...) function foo (...)
local <toclose> x123 = 10 local x123 <close> = 10
end end
local st, msg = pcall(foo) local st, msg = pcall(foo)
@ -329,7 +329,7 @@ do
-- errors due to non-closable values -- errors due to non-closable values
local function foo () local function foo ()
local <toclose> x = {} local x <close> = {}
end end
local stat, msg = pcall(foo) local stat, msg = pcall(foo)
assert(not stat and string.find(msg, "variable 'x'")) assert(not stat and string.find(msg, "variable 'x'"))
@ -337,8 +337,8 @@ do
-- with other errors, non-closable values are ignored -- with other errors, non-closable values are ignored
local function foo () local function foo ()
local <toclose> x = 34 local x <close> = 34
local <toclose> y = func2close(function () error(32) end) local y <close> = func2close(function () error(32) end)
end end
local stat, msg = pcall(foo) local stat, msg = pcall(foo)
assert(not stat and msg == 32) assert(not stat and msg == 32)
@ -350,8 +350,8 @@ if rawget(_G, "T") then
-- memory error inside closing function -- memory error inside closing function
local function foo () local function foo ()
local <toclose> y = func2close(function () T.alloccount() end) local y <close> = func2close(function () T.alloccount() end)
local <toclose> x = setmetatable({}, {__close = function () local x <close> = setmetatable({}, {__close = function ()
T.alloccount(0); local x = {} -- force a memory error T.alloccount(0); local x = {} -- force a memory error
end}) end})
error(1000) -- common error inside the function's body error(1000) -- common error inside the function's body
@ -377,7 +377,7 @@ if rawget(_G, "T") then
end end
local function test () local function test ()
local <toclose> x = enter(0) -- set a memory limit local x <close> = enter(0) -- set a memory limit
-- creation of previous upvalue will raise a memory error -- creation of previous upvalue will raise a memory error
assert(false) -- should not run assert(false) -- should not run
end end
@ -392,14 +392,14 @@ if rawget(_G, "T") then
-- repeat test with extra closing upvalues -- repeat test with extra closing upvalues
local function test () local function test ()
local <toclose> xxx = func2close(function (self, msg) local xxx <close> = func2close(function (self, msg)
assert(msg == "not enough memory"); assert(msg == "not enough memory");
error(1000) -- raise another error error(1000) -- raise another error
end) end)
local <toclose> xx = func2close(function (self, msg) local xx <close> = func2close(function (self, msg)
assert(msg == "not enough memory"); assert(msg == "not enough memory");
end) end)
local <toclose> x = enter(0) -- set a memory limit local x <close> = enter(0) -- set a memory limit
-- creation of previous upvalue will raise a memory error -- creation of previous upvalue will raise a memory error
os.exit(false) -- should not run os.exit(false) -- should not run
end end
@ -469,9 +469,9 @@ do
local x = false local x = false
local y = false local y = false
local co = coroutine.wrap(function () local co = coroutine.wrap(function ()
local <toclose> xv = func2close(function () x = true end) local xv <close> = func2close(function () x = true end)
do do
local <toclose> yv = func2close(function () y = true end) local yv <close> = func2close(function () y = true end)
coroutine.yield(100) -- yield doesn't close variable coroutine.yield(100) -- yield doesn't close variable
end end
coroutine.yield(200) -- yield doesn't close variable coroutine.yield(200) -- yield doesn't close variable
@ -491,8 +491,8 @@ do
-- error in a wrapped coroutine raising errors when closing a variable -- error in a wrapped coroutine raising errors when closing a variable
local x = 0 local x = 0
local co = coroutine.wrap(function () local co = coroutine.wrap(function ()
local <toclose> xx = func2close(function () x = x + 1; error("YYY") end) local xx <close> = func2close(function () x = x + 1; error("YYY") end)
local <toclose> xv = func2close(function () x = x + 1; error("XXX") end) local xv <close> = func2close(function () x = x + 1; error("XXX") end)
coroutine.yield(100) coroutine.yield(100)
error(200) error(200)
end) end)
@ -503,8 +503,8 @@ do
local x = 0 local x = 0
local y = 0 local y = 0
co = coroutine.wrap(function () co = coroutine.wrap(function ()
local <toclose> xx = func2close(function () y = y + 1; error("YYY") end) local xx <close> = func2close(function () y = y + 1; error("YYY") end)
local <toclose> xv = func2close(function () x = x + 1; error("XXX") end) local xv <close> = func2close(function () x = x + 1; error("XXX") end)
coroutine.yield(100) coroutine.yield(100)
return 200 return 200
end) end)
@ -519,7 +519,7 @@ end
-- a suspended coroutine should not close its variables when collected -- a suspended coroutine should not close its variables when collected
local co local co
co = coroutine.wrap(function() co = coroutine.wrap(function()
local <toclose> x = function () os.exit(false) end -- should not run local x <close> = function () os.exit(false) end -- should not run
co = nil co = nil
coroutine.yield() coroutine.yield()
end) end)

View File

@ -320,11 +320,11 @@ NoRun("", "lua %s", prog) -- no message
-- to-be-closed variables in main chunk -- to-be-closed variables in main chunk
prepfile[[ prepfile[[
local <toclose> x = function (err) local x <close> = function (err)
assert(err == 120) assert(err == 120)
print("Ok") print("Ok")
end end
local <toclose> e1 = function () error(120) end local e1 <close> = function () error(120) end
os.exit(true, true) os.exit(true, true)
]] ]]
RUN('lua %s > %s', prog, out) RUN('lua %s > %s', prog, out)

View File

@ -3,10 +3,10 @@
print("testing numbers and math lib") print("testing numbers and math lib")
local <const> minint = math.mininteger local minint <const> = math.mininteger
local <const> maxint = math.maxinteger local maxint <const> = math.maxinteger
local <const> intbits = math.floor(math.log(maxint, 2) + 0.5) + 1 local intbits <const> = math.floor(math.log(maxint, 2) + 0.5) + 1
assert((1 << intbits) == 0) assert((1 << intbits) == 0)
assert(minint == 1 << (intbits - 1)) assert(minint == 1 << (intbits - 1))
@ -270,7 +270,7 @@ else
end end
do do
local <const> NaN = 0/0 local NaN <const> = 0/0
assert(not (NaN < 0)) assert(not (NaN < 0))
assert(not (NaN > minint)) assert(not (NaN > minint))
assert(not (NaN <= -9)) assert(not (NaN <= -9))
@ -767,8 +767,8 @@ assert(a == '10' and b == '20')
do do
print("testing -0 and NaN") print("testing -0 and NaN")
local <const> mz = -0.0 local mz <const> = -0.0
local <const> z = 0.0 local z <const> = 0.0
assert(mz == z) assert(mz == z)
assert(1/mz < 0 and 0 < 1/z) assert(1/mz < 0 and 0 < 1/z)
local a = {[mz] = 1} local a = {[mz] = 1}
@ -776,18 +776,18 @@ do
a[z] = 2 a[z] = 2
assert(a[z] == 2 and a[mz] == 2) assert(a[z] == 2 and a[mz] == 2)
local inf = math.huge * 2 + 1 local inf = math.huge * 2 + 1
local <const> mz = -1/inf local mz <const> = -1/inf
local <const> z = 1/inf local z <const> = 1/inf
assert(mz == z) assert(mz == z)
assert(1/mz < 0 and 0 < 1/z) assert(1/mz < 0 and 0 < 1/z)
local <const> NaN = inf - inf local NaN <const> = inf - inf
assert(NaN ~= NaN) assert(NaN ~= NaN)
assert(not (NaN < NaN)) assert(not (NaN < NaN))
assert(not (NaN <= NaN)) assert(not (NaN <= NaN))
assert(not (NaN > NaN)) assert(not (NaN > NaN))
assert(not (NaN >= NaN)) assert(not (NaN >= NaN))
assert(not (0 < NaN) and not (NaN < 0)) assert(not (0 < NaN) and not (NaN < 0))
local <const> NaN1 = 0/0 local NaN1 <const> = 0/0
assert(NaN ~= NaN1 and not (NaN <= NaN1) and not (NaN1 <= NaN)) assert(NaN ~= NaN1 and not (NaN <= NaN1) and not (NaN1 <= NaN))
local a = {} local a = {}
assert(not pcall(rawset, a, NaN, 1)) assert(not pcall(rawset, a, NaN, 1))
@ -816,8 +816,8 @@ end
-- the first call after seed 1007 should return 0x7a7040a5a323c9d6 -- the first call after seed 1007 should return 0x7a7040a5a323c9d6
do do
-- all computations should work with 32-bit integers -- all computations should work with 32-bit integers
local <const> h = 0x7a7040a5 -- higher half local h <const> = 0x7a7040a5 -- higher half
local <const> l = 0xa323c9d6 -- lower half local l <const> = 0xa323c9d6 -- lower half
math.randomseed(1007) math.randomseed(1007)
-- get the low 'intbits' of the 64-bit expected result -- get the low 'intbits' of the 64-bit expected result

View File

@ -3,8 +3,8 @@
print('testing strings and string library') print('testing strings and string library')
local <const> maxi = math.maxinteger local maxi <const> = math.maxinteger
local <const> mini = math.mininteger local mini <const> = math.mininteger
local function checkerror (msg, f, ...) local function checkerror (msg, f, ...)