aboutsummaryrefslogtreecommitdiff
path: root/testes
diff options
context:
space:
mode:
Diffstat (limited to 'testes')
-rwxr-xr-x[-rw-r--r--]testes/all.lua38
-rw-r--r--testes/api.lua251
-rw-r--r--testes/attrib.lua26
-rw-r--r--testes/big.lua2
-rw-r--r--testes/bitwise.lua2
-rw-r--r--testes/bwcoercion.lua2
-rw-r--r--testes/calls.lua64
-rw-r--r--testes/closure.lua4
-rw-r--r--testes/code.lua26
-rw-r--r--testes/constructs.lua4
-rw-r--r--testes/coroutine.lua86
-rw-r--r--testes/cstack.lua2
-rw-r--r--testes/db.lua23
-rw-r--r--testes/errors.lua25
-rw-r--r--testes/events.lua15
-rw-r--r--testes/files.lua60
-rw-r--r--testes/gc.lua42
-rw-r--r--testes/gengc.lua2
-rw-r--r--testes/goto.lua172
-rw-r--r--testes/heavy.lua4
-rw-r--r--testes/libs/lib22.c51
-rw-r--r--testes/literals.lua4
-rw-r--r--testes/locals.lua44
-rw-r--r--testes/main.lua15
-rw-r--r--testes/math.lua23
-rw-r--r--testes/memerr.lua266
-rw-r--r--testes/nextvar.lua25
-rwxr-xr-xtestes/packtests1
-rw-r--r--testes/pm.lua8
-rw-r--r--testes/sort.lua2
-rw-r--r--testes/strings.lua3
-rw-r--r--testes/tpack.lua2
-rw-r--r--testes/tracegc.lua2
-rw-r--r--testes/utf8.lua15
-rw-r--r--testes/vararg.lua2
-rw-r--r--testes/verybig.lua2
36 files changed, 907 insertions, 408 deletions
diff --git a/testes/all.lua b/testes/all.lua
index 4ffa9efe..d3e2f123 100644..100755
--- a/testes/all.lua
+++ b/testes/all.lua
@@ -1,7 +1,11 @@
1#!../lua 1#!../lua
2-- $Id: testes/all.lua $ 2-- $Id: testes/all.lua $
3-- See Copyright Notice at the end of this file 3-- See Copyright Notice in file lua.h
4 4
5global <const> *
6
7global _soft, _port, _nomsg
8global T
5 9
6local version = "Lua 5.5" 10local version = "Lua 5.5"
7if _VERSION ~= version then 11if _VERSION ~= version then
@@ -34,7 +38,7 @@ if usertests then
34end 38end
35 39
36-- tests should require debug when needed 40-- tests should require debug when needed
37debug = nil 41global debug; debug = nil
38 42
39 43
40if usertests then 44if usertests then
@@ -71,7 +75,7 @@ do -- (
71 75
72-- track messages for tests not performed 76-- track messages for tests not performed
73local msgs = {} 77local msgs = {}
74function Message (m) 78global function Message (m)
75 if not _nomsg then 79 if not _nomsg then
76 print(m) 80 print(m)
77 msgs[#msgs+1] = string.sub(m, 3, -3) 81 msgs[#msgs+1] = string.sub(m, 3, -3)
@@ -182,6 +186,7 @@ dofile('nextvar.lua')
182dofile('pm.lua') 186dofile('pm.lua')
183dofile('utf8.lua') 187dofile('utf8.lua')
184dofile('api.lua') 188dofile('api.lua')
189dofile('memerr.lua')
185assert(dofile('events.lua') == 12) 190assert(dofile('events.lua') == 12)
186dofile('vararg.lua') 191dofile('vararg.lua')
187dofile('closure.lua') 192dofile('closure.lua')
@@ -282,30 +287,3 @@ end
282 287
283print("final OK !!!") 288print("final OK !!!")
284 289
285
286
287--[[
288*****************************************************************************
289* Copyright (C) 1994-2016 Lua.org, PUC-Rio.
290*
291* Permission is hereby granted, free of charge, to any person obtaining
292* a copy of this software and associated documentation files (the
293* "Software"), to deal in the Software without restriction, including
294* without limitation the rights to use, copy, modify, merge, publish,
295* distribute, sublicense, and/or sell copies of the Software, and to
296* permit persons to whom the Software is furnished to do so, subject to
297* the following conditions:
298*
299* The above copyright notice and this permission notice shall be
300* included in all copies or substantial portions of the Software.
301*
302* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
303* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
304* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
305* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
306* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
307* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
308* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
309*****************************************************************************
310]]
311
diff --git a/testes/api.lua b/testes/api.lua
index 21f703fd..b3791654 100644
--- a/testes/api.lua
+++ b/testes/api.lua
@@ -1,5 +1,5 @@
1-- $Id: testes/api.lua $ 1-- $Id: testes/api.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4if T==nil then 4if T==nil then
5 (Message or print)('\n >>> testC not active: skipping API tests <<<\n') 5 (Message or print)('\n >>> testC not active: skipping API tests <<<\n')
@@ -11,9 +11,6 @@ local debug = require "debug"
11local pack = table.pack 11local pack = table.pack
12 12
13 13
14-- standard error message for memory errors
15local MEMERRMSG = "not enough memory"
16
17local function tcheck (t1, t2) 14local function tcheck (t1, t2)
18 assert(t1.n == (t2.n or #t2) + 1) 15 assert(t1.n == (t2.n or #t2) + 1)
19 for i = 2, t1.n do assert(t1[i] == t2[i - 1]) end 16 for i = 2, t1.n do assert(t1[i] == t2[i - 1]) end
@@ -117,7 +114,7 @@ end
117 114
118-- testing warnings 115-- testing warnings
119T.testC([[ 116T.testC([[
120 warningC "#This shold be a" 117 warningC "#This should be a"
121 warningC " single " 118 warningC " single "
122 warning "warning" 119 warning "warning"
123 warningC "#This should be " 120 warningC "#This should be "
@@ -165,7 +162,7 @@ do -- test returning more results than fit in the caller stack
165end 162end
166 163
167 164
168do -- testing multipe returns 165do -- testing multiple returns
169 local function foo (n) 166 local function foo (n)
170 if n > 0 then return n, foo(n - 1) end 167 if n > 0 then return n, foo(n - 1) end
171 end 168 end
@@ -432,11 +429,6 @@ do
432 "bad argument #4 (string expected, got no value)") 429 "bad argument #4 (string expected, got no value)")
433 430
434 431
435 -- memory error
436 T.totalmem(T.totalmem()+10000) -- set low memory limit (+10k)
437 assert(T.checkpanic("newuserdata 20000") == MEMERRMSG)
438 T.totalmem(0) -- restore high limit
439
440 -- memory error + thread status 432 -- memory error + thread status
441 local x = T.checkpanic( 433 local x = T.checkpanic(
442 [[ alloccount 0 # force a memory error in next line 434 [[ alloccount 0 # force a memory error in next line
@@ -910,7 +902,7 @@ F = function (x)
910 assert(T.udataval(A) == B) 902 assert(T.udataval(A) == B)
911 debug.getmetatable(A) -- just access it 903 debug.getmetatable(A) -- just access it
912 end 904 end
913 A = x -- ressurect userdata 905 A = x -- resurrect userdata
914 B = udval 906 B = udval
915 return 1,2,3 907 return 1,2,3
916end 908end
@@ -1306,241 +1298,6 @@ do
1306end 1298end
1307 1299
1308 1300
1309--[[
1310** {==================================================================
1311** Testing memory limits
1312** ===================================================================
1313--]]
1314
1315print("memory-allocation errors")
1316
1317checkerr("block too big", T.newuserdata, math.maxinteger)
1318collectgarbage()
1319local f = load"local a={}; for i=1,100000 do a[i]=i end"
1320T.alloccount(10)
1321checkerr(MEMERRMSG, f)
1322T.alloccount() -- remove limit
1323
1324
1325-- test memory errors; increase limit for maximum memory by steps,
1326-- o that we get memory errors in all allocations of a given
1327-- task, until there is enough memory to complete the task without
1328-- errors.
1329local function testbytes (s, f)
1330 collectgarbage()
1331 local M = T.totalmem()
1332 local oldM = M
1333 local a,b = nil
1334 while true do
1335 collectgarbage(); collectgarbage()
1336 T.totalmem(M)
1337 a, b = T.testC("pcall 0 1 0; pushstatus; return 2", f)
1338 T.totalmem(0) -- remove limit
1339 if a and b == "OK" then break end -- stop when no more errors
1340 if b ~= "OK" and b ~= MEMERRMSG then -- not a memory error?
1341 error(a, 0) -- propagate it
1342 end
1343 M = M + 7 -- increase memory limit
1344 end
1345 print(string.format("minimum memory for %s: %d bytes", s, M - oldM))
1346 return a
1347end
1348
1349-- test memory errors; increase limit for number of allocations one
1350-- by one, so that we get memory errors in all allocations of a given
1351-- task, until there is enough allocations to complete the task without
1352-- errors.
1353
1354local function testalloc (s, f)
1355 collectgarbage()
1356 local M = 0
1357 local a,b = nil
1358 while true do
1359 collectgarbage(); collectgarbage()
1360 T.alloccount(M)
1361 a, b = T.testC("pcall 0 1 0; pushstatus; return 2", f)
1362 T.alloccount() -- remove limit
1363 if a and b == "OK" then break end -- stop when no more errors
1364 if b ~= "OK" and b ~= MEMERRMSG then -- not a memory error?
1365 error(a, 0) -- propagate it
1366 end
1367 M = M + 1 -- increase allocation limit
1368 end
1369 print(string.format("minimum allocations for %s: %d allocations", s, M))
1370 return a
1371end
1372
1373
1374local function testamem (s, f)
1375 testalloc(s, f)
1376 return testbytes(s, f)
1377end
1378
1379
1380-- doing nothing
1381b = testamem("doing nothing", function () return 10 end)
1382assert(b == 10)
1383
1384-- testing memory errors when creating a new state
1385
1386testamem("state creation", function ()
1387 local st = T.newstate()
1388 if st then T.closestate(st) end -- close new state
1389 return st
1390end)
1391
1392testamem("empty-table creation", function ()
1393 return {}
1394end)
1395
1396testamem("string creation", function ()
1397 return "XXX" .. "YYY"
1398end)
1399
1400testamem("coroutine creation", function()
1401 return coroutine.create(print)
1402end)
1403
1404
1405-- testing to-be-closed variables
1406testamem("to-be-closed variables", function()
1407 local flag
1408 do
1409 local x <close> =
1410 setmetatable({}, {__close = function () flag = true end})
1411 flag = false
1412 local x = {}
1413 end
1414 return flag
1415end)
1416
1417
1418-- testing threads
1419
1420-- get main thread from registry
1421local mt = T.testC("rawgeti R !M; return 1")
1422assert(type(mt) == "thread" and coroutine.running() == mt)
1423
1424
1425
1426local function expand (n,s)
1427 if n==0 then return "" end
1428 local e = string.rep("=", n)
1429 return string.format("T.doonnewstack([%s[ %s;\n collectgarbage(); %s]%s])\n",
1430 e, s, expand(n-1,s), e)
1431end
1432
1433G=0; collectgarbage(); a =collectgarbage("count")
1434load(expand(20,"G=G+1"))()
1435assert(G==20); collectgarbage(); -- assert(gcinfo() <= a+1)
1436G = nil
1437
1438testamem("running code on new thread", function ()
1439 return T.doonnewstack("local x=1") == 0 -- try to create thread
1440end)
1441
1442
1443-- testing memory x compiler
1444
1445testamem("loadstring", function ()
1446 return load("x=1") -- try to do load a string
1447end)
1448
1449
1450local testprog = [[
1451local function foo () return end
1452local t = {"x"}
1453AA = "aaa"
1454for i = 1, #t do AA = AA .. t[i] end
1455return true
1456]]
1457
1458-- testing memory x dofile
1459_G.AA = nil
1460local t =os.tmpname()
1461local f = assert(io.open(t, "w"))
1462f:write(testprog)
1463f:close()
1464testamem("dofile", function ()
1465 local a = loadfile(t)
1466 return a and a()
1467end)
1468assert(os.remove(t))
1469assert(_G.AA == "aaax")
1470
1471
1472-- other generic tests
1473
1474testamem("gsub", function ()
1475 local a, b = string.gsub("alo alo", "(a)", function (x) return x..'b' end)
1476 return (a == 'ablo ablo')
1477end)
1478
1479testamem("dump/undump", function ()
1480 local a = load(testprog)
1481 local b = a and string.dump(a)
1482 a = b and load(b)
1483 return a and a()
1484end)
1485
1486_G.AA = nil
1487
1488local t = os.tmpname()
1489testamem("file creation", function ()
1490 local f = assert(io.open(t, 'w'))
1491 assert (not io.open"nomenaoexistente")
1492 io.close(f);
1493 return not loadfile'nomenaoexistente'
1494end)
1495assert(os.remove(t))
1496
1497testamem("table creation", function ()
1498 local a, lim = {}, 10
1499 for i=1,lim do a[i] = i; a[i..'a'] = {} end
1500 return (type(a[lim..'a']) == 'table' and a[lim] == lim)
1501end)
1502
1503testamem("constructors", function ()
1504 local a = {10, 20, 30, 40, 50; a=1, b=2, c=3, d=4, e=5}
1505 return (type(a) == 'table' and a.e == 5)
1506end)
1507
1508local a = 1
1509local close = nil
1510testamem("closure creation", function ()
1511 function close (b)
1512 return function (x) return b + x end
1513 end
1514 return (close(2)(4) == 6)
1515end)
1516
1517testamem("using coroutines", function ()
1518 local a = coroutine.wrap(function ()
1519 coroutine.yield(string.rep("a", 10))
1520 return {}
1521 end)
1522 assert(string.len(a()) == 10)
1523 return a()
1524end)
1525
1526do -- auxiliary buffer
1527 local lim = 100
1528 local a = {}; for i = 1, lim do a[i] = "01234567890123456789" end
1529 testamem("auxiliary buffer", function ()
1530 return (#table.concat(a, ",") == 20*lim + lim - 1)
1531 end)
1532end
1533
1534testamem("growing stack", function ()
1535 local function foo (n)
1536 if n == 0 then return 1 else return 1 + foo(n - 1) end
1537 end
1538 return foo(100)
1539end)
1540
1541-- }==================================================================
1542
1543
1544do -- testing failing in 'lua_checkstack' 1301do -- testing failing in 'lua_checkstack'
1545 local res = T.testC([[rawcheckstack 500000; return 1]]) 1302 local res = T.testC([[rawcheckstack 500000; return 1]])
1546 assert(res == false) 1303 assert(res == false)
diff --git a/testes/attrib.lua b/testes/attrib.lua
index 9054e0b6..f4156086 100644
--- a/testes/attrib.lua
+++ b/testes/attrib.lua
@@ -1,5 +1,5 @@
1-- $Id: testes/attrib.lua $ 1-- $Id: testes/attrib.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4print "testing require" 4print "testing require"
5 5
@@ -308,11 +308,11 @@ else
308 _ENV.x, _ENV.y = nil 308 _ENV.x, _ENV.y = nil
309end 309end
310 310
311
311_ENV = _G 312_ENV = _G
312 313
313 314
314-- testing preload 315-- testing preload
315
316do 316do
317 local p = package 317 local p = package
318 package = {} 318 package = {}
@@ -331,6 +331,26 @@ do
331 assert(type(package.path) == "string") 331 assert(type(package.path) == "string")
332end 332end
333 333
334
335do print("testing external strings")
336 package.cpath = DC"?"
337 local lib2 = require"lib2-v2"
338 local t = {}
339 for _, len in ipairs{0, 10, 39, 40, 41, 1000} do
340 local str = string.rep("a", len)
341 local str1 = lib2.newstr(str)
342 assert(str == str1)
343 assert(not T or T.hash(str) == T.hash(str1))
344 t[str1] = 20; assert(t[str] == 20 and t[str1] == 20)
345 t[str] = 10; assert(t[str1] == 10)
346 local tt = {[str1] = str1}
347 assert(next(tt) == str1 and next(tt, str1) == nil)
348 assert(tt[str] == str)
349 local str2 = lib2.newstr(str1)
350 assert(str == str2 and t[str2] == 10 and tt[str2] == str)
351 end
352end
353
334print('+') 354print('+')
335 355
336end --] 356end --]
@@ -447,7 +467,7 @@ do
447end 467end
448 468
449 469
450-- test of large float/integer indices 470-- test of large float/integer indices
451 471
452-- compute maximum integer where all bits fit in a float 472-- compute maximum integer where all bits fit in a float
453local maxint = math.maxinteger 473local maxint = math.maxinteger
diff --git a/testes/big.lua b/testes/big.lua
index 46fd8466..119caa6c 100644
--- a/testes/big.lua
+++ b/testes/big.lua
@@ -1,5 +1,5 @@
1-- $Id: testes/big.lua $ 1-- $Id: testes/big.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4if _soft then 4if _soft then
5 return 'a' 5 return 'a'
diff --git a/testes/bitwise.lua b/testes/bitwise.lua
index dd0a1a9a..10afff43 100644
--- a/testes/bitwise.lua
+++ b/testes/bitwise.lua
@@ -1,5 +1,5 @@
1-- $Id: testes/bitwise.lua $ 1-- $Id: testes/bitwise.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4print("testing bitwise operations") 4print("testing bitwise operations")
5 5
diff --git a/testes/bwcoercion.lua b/testes/bwcoercion.lua
index cd735ab0..0544944d 100644
--- a/testes/bwcoercion.lua
+++ b/testes/bwcoercion.lua
@@ -4,7 +4,7 @@ local strsub = string.sub
4 4
5local print = print 5local print = print
6 6
7_ENV = nil 7global none
8 8
9-- Try to convert a value to an integer, without assuming any coercion. 9-- Try to convert a value to an integer, without assuming any coercion.
10local function toint (x) 10local function toint (x)
diff --git a/testes/calls.lua b/testes/calls.lua
index 31028215..0dacb85a 100644
--- a/testes/calls.lua
+++ b/testes/calls.lua
@@ -1,5 +1,7 @@
1-- $Id: testes/calls.lua $ 1-- $Id: testes/calls.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3
4global <const> *
3 5
4print("testing functions and calls") 6print("testing functions and calls")
5 7
@@ -22,7 +24,7 @@ assert(not pcall(type))
22 24
23 25
24-- testing local-function recursion 26-- testing local-function recursion
25fact = false 27global fact = false
26do 28do
27 local res = 1 29 local res = 1
28 local function fact (n) 30 local function fact (n)
@@ -63,7 +65,7 @@ a.b.c:f2('k', 12); assert(a.b.c.k == 12)
63 65
64print('+') 66print('+')
65 67
66t = nil -- 'declare' t 68global t = nil -- 'declare' t
67function f(a,b,c) local d = 'a'; t={a,b,c,d} end 69function f(a,b,c) local d = 'a'; t={a,b,c,d} end
68 70
69f( -- this line change must be valid 71f( -- this line change must be valid
@@ -75,7 +77,7 @@ assert(t[1] == 1 and t[2] == 2 and t[3] == 3 and t[4] == 'a')
75 77
76t = nil -- delete 't' 78t = nil -- delete 't'
77 79
78function fat(x) 80global function fat(x)
79 if x <= 1 then return 1 81 if x <= 1 then return 1
80 else return x*load("return fat(" .. x-1 .. ")", "")() 82 else return x*load("return fat(" .. x-1 .. ")", "")()
81 end 83 end
@@ -107,7 +109,7 @@ end
107 109
108_G.deep = nil -- "declaration" (used by 'all.lua') 110_G.deep = nil -- "declaration" (used by 'all.lua')
109 111
110function deep (n) 112global function deep (n)
111 if n>0 then deep(n-1) end 113 if n>0 then deep(n-1) end
112end 114end
113deep(10) 115deep(10)
@@ -352,7 +354,7 @@ assert(not load(function () return true end))
352 354
353-- small bug 355-- small bug
354local t = {nil, "return ", "3"} 356local t = {nil, "return ", "3"}
355f, msg = load(function () return table.remove(t, 1) end) 357local f, msg = load(function () return table.remove(t, 1) end)
356assert(f() == nil) -- should read the empty chunk 358assert(f() == nil) -- should read the empty chunk
357 359
358-- another small bug (in 5.2.1) 360-- another small bug (in 5.2.1)
@@ -388,7 +390,8 @@ assert(load("return _ENV", nil, nil, 123)() == 123)
388 390
389 391
390-- load when _ENV is not first upvalue 392-- load when _ENV is not first upvalue
391local x; XX = 123 393global XX; local x
394XX = 123
392local function h () 395local function h ()
393 local y=x -- use 'x', so that it becomes 1st upvalue 396 local y=x -- use 'x', so that it becomes 1st upvalue
394 return XX -- global name 397 return XX -- global name
@@ -480,15 +483,22 @@ assert((function (a) return a end)() == nil)
480 483
481print("testing binary chunks") 484print("testing binary chunks")
482do 485do
483 local header = string.pack("c4BBc6BBB", 486 local headformat = "c4BBc6BiBI4BjBn"
484 "\27Lua", -- signature 487 local header = { -- header components
485 0x55, -- version 5.5 (0x55) 488 "\27Lua", -- signature
486 0, -- format 489 0x55, -- version 5.5 (0x55)
487 "\x19\x93\r\n\x1a\n", -- data 490 0, -- format
488 4, -- size of instruction 491 "\x19\x93\r\n\x1a\n", -- a binary string
489 string.packsize("j"), -- sizeof(lua integer) 492 string.packsize("i"), -- size of an int
490 string.packsize("n") -- sizeof(lua number) 493 -0x5678, -- an int
491 ) 494 4, -- size of an instruction
495 0x12345678, -- an instruction (4 bytes)
496 string.packsize("j"), -- size of a Lua integer
497 -0x5678, -- a Lua integer
498 string.packsize("n"), -- size of a Lua float
499 -370.5, -- a Lua float
500 }
501
492 local c = string.dump(function () 502 local c = string.dump(function ()
493 local a = 1; local b = 3; 503 local a = 1; local b = 3;
494 local f = function () return a + b + _ENV.c; end -- upvalues 504 local f = function () return a + b + _ENV.c; end -- upvalues
@@ -500,17 +510,23 @@ do
500 assert(assert(load(c))() == 10) 510 assert(assert(load(c))() == 10)
501 511
502 -- check header 512 -- check header
503 assert(string.sub(c, 1, #header) == header) 513 local t = {string.unpack(headformat, c)}
504 -- check LUAC_INT and LUAC_NUM
505 local ci, cn = string.unpack("jn", c, #header + 1)
506 assert(ci == 0x5678 and cn == 370.5)
507
508 -- corrupted header
509 for i = 1, #header do 514 for i = 1, #header do
515 assert(t[i] == header[i])
516 end
517
518 -- Testing corrupted header.
519 -- A single wrong byte in the head invalidates the chunk,
520 -- except for the Lua float check. (If numbers are long double,
521 -- the representation may need padding, and changing that padding
522 -- will not invalidate the chunk.)
523 local headlen = string.packsize(headformat)
524 headlen = headlen - string.packsize("n") -- remove float check
525 for i = 1, headlen do
510 local s = string.sub(c, 1, i - 1) .. 526 local s = string.sub(c, 1, i - 1) ..
511 string.char(string.byte(string.sub(c, i, i)) + 1) .. 527 string.char((string.byte(string.sub(c, i, i)) + 1) & 0xFF) ..
512 string.sub(c, i + 1, -1) 528 string.sub(c, i + 1, -1)
513 assert(#s == #c) 529 assert(#s == #c and s ~= c)
514 assert(not load(s)) 530 assert(not load(s))
515 end 531 end
516 532
diff --git a/testes/closure.lua b/testes/closure.lua
index 07149ef3..0c2e96c0 100644
--- a/testes/closure.lua
+++ b/testes/closure.lua
@@ -1,5 +1,7 @@
1-- $Id: testes/closure.lua $ 1-- $Id: testes/closure.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3
4global <const> *
3 5
4print "testing closures" 6print "testing closures"
5 7
diff --git a/testes/code.lua b/testes/code.lua
index 50ce7392..380ff70c 100644
--- a/testes/code.lua
+++ b/testes/code.lua
@@ -1,5 +1,7 @@
1-- $Id: testes/code.lua $ 1-- $Id: testes/code.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3
4global <const> *
3 5
4if T==nil then 6if T==nil then
5 (Message or print)('\n >>> testC not active: skipping opcode tests <<<\n') 7 (Message or print)('\n >>> testC not active: skipping opcode tests <<<\n')
@@ -405,8 +407,8 @@ do -- tests for table access in upvalues
405end 407end
406 408
407-- de morgan 409-- de morgan
408checkequal(function () local a; if not (a or b) then b=a end end, 410checkequal(function () local a, b; if not (a or b) then b=a end end,
409 function () local a; if (not a and not b) then b=a end end) 411 function () local a, b; if (not a and not b) then b=a end end)
410 412
411checkequal(function (l) local a; return 0 <= a and a <= l end, 413checkequal(function (l) local a; return 0 <= a and a <= l end,
412 function (l) local a; return not (not(a >= 0) or not(a <= l)) end) 414 function (l) local a; return not (not(a >= 0) or not(a <= l)) end)
@@ -480,5 +482,23 @@ do -- basic check for SETLIST
480 assert(count == 1) 482 assert(count == 1)
481end 483end
482 484
485
486do print("testing code for integer limits")
487 local function checkints (n)
488 local source = string.format(
489 "local a = {[true] = 0X%x}; return a[true]", n)
490 local f = assert(load(source))
491 checkKlist(f, {n})
492 assert(f() == n)
493 f = load(string.dump(f))
494 assert(f() == n)
495 end
496
497 checkints(math.maxinteger)
498 checkints(math.mininteger)
499 checkints(-1)
500
501end
502
483print 'OK' 503print 'OK'
484 504
diff --git a/testes/constructs.lua b/testes/constructs.lua
index 6ac68166..94f670c7 100644
--- a/testes/constructs.lua
+++ b/testes/constructs.lua
@@ -1,5 +1,5 @@
1-- $Id: testes/constructs.lua $ 1-- $Id: testes/constructs.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4;;print "testing syntax";; 4;;print "testing syntax";;
5 5
@@ -60,7 +60,7 @@ assert((x>y) and x or y == 2);
60 60
61assert(1234567890 == tonumber('1234567890') and 1234567890+1 == 1234567891) 61assert(1234567890 == tonumber('1234567890') and 1234567890+1 == 1234567891)
62 62
63do -- testing operators with diffent kinds of constants 63do -- testing operators with different kinds of constants
64 -- operands to consider: 64 -- operands to consider:
65 -- * fit in register 65 -- * fit in register
66 -- * constant doesn't fit in register 66 -- * constant doesn't fit in register
diff --git a/testes/coroutine.lua b/testes/coroutine.lua
index abc08039..4881d964 100644
--- a/testes/coroutine.lua
+++ b/testes/coroutine.lua
@@ -1,5 +1,5 @@
1-- $Id: testes/coroutine.lua $ 1-- $Id: testes/coroutine.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4print "testing coroutines" 4print "testing coroutines"
5 5
@@ -156,12 +156,12 @@ do
156 st, msg = coroutine.close(co) 156 st, msg = coroutine.close(co)
157 assert(st and msg == nil) 157 assert(st and msg == nil)
158 158
159 local main = coroutine.running()
159 160
160 -- cannot close the running coroutine 161 -- cannot close 'main'
161 local st, msg = pcall(coroutine.close, coroutine.running()) 162 local st, msg = pcall(coroutine.close, main);
162 assert(not st and string.find(msg, "running")) 163 assert(not st and string.find(msg, "main"))
163 164
164 local main = coroutine.running()
165 165
166 -- cannot close a "normal" coroutine 166 -- cannot close a "normal" coroutine
167 ;(coroutine.wrap(function () 167 ;(coroutine.wrap(function ()
@@ -169,20 +169,19 @@ do
169 assert(not st and string.find(msg, "normal")) 169 assert(not st and string.find(msg, "normal"))
170 end))() 170 end))()
171 171
172 -- cannot close a coroutine while closing it 172 do -- close a coroutine while closing it
173 do
174 local co 173 local co
175 co = coroutine.create( 174 co = coroutine.create(
176 function() 175 function()
177 local x <close> = func2close(function() 176 local x <close> = func2close(function()
178 coroutine.close(co) -- try to close it again 177 coroutine.close(co) -- close it again
179 end) 178 end)
180 coroutine.yield(20) 179 coroutine.yield(20)
181 end) 180 end)
182 local st, msg = coroutine.resume(co) 181 local st, msg = coroutine.resume(co)
183 assert(st and msg == 20) 182 assert(st and msg == 20)
184 st, msg = coroutine.close(co) 183 st, msg = coroutine.close(co)
185 assert(not st and string.find(msg, "running coroutine")) 184 assert(st and msg == nil)
186 end 185 end
187 186
188 -- to-be-closed variables in coroutines 187 -- to-be-closed variables in coroutines
@@ -289,6 +288,56 @@ do
289end 288end
290 289
291 290
291do print("coroutines closing itself")
292 global <const> coroutine, string, os
293 global <const> assert, error, pcall
294
295 local X = nil
296
297 local function new ()
298 return coroutine.create(function (what)
299
300 local <close>var = func2close(function (t, err)
301 if what == "yield" then
302 coroutine.yield()
303 elseif what == "error" then
304 error(200)
305 else
306 X = "Ok"
307 return X
308 end
309 end)
310
311 -- do an unprotected call so that coroutine becomes non-yieldable
312 string.gsub("a", "a", function ()
313 assert(not coroutine.isyieldable())
314 -- do protected calls while non-yieldable, to add recovery
315 -- entries (setjmp) to the stack
316 assert(pcall(pcall, function ()
317 -- 'close' works even while non-yieldable
318 coroutine.close() -- close itself
319 os.exit(false) -- not reacheable
320 end))
321 end)
322 end)
323 end
324
325 local co = new()
326 local st, msg = coroutine.resume(co, "ret")
327 assert(st and msg == nil)
328 assert(X == "Ok")
329
330 local co = new()
331 local st, msg = coroutine.resume(co, "error")
332 assert(not st and msg == 200)
333
334 local co = new()
335 local st, msg = coroutine.resume(co, "yield")
336 assert(not st and string.find(msg, "attempt to yield"))
337
338end
339
340
292-- yielding across C boundaries 341-- yielding across C boundaries
293 342
294local co = coroutine.wrap(function() 343local co = coroutine.wrap(function()
@@ -505,6 +554,25 @@ assert(not pcall(a, a))
505a = nil 554a = nil
506 555
507 556
557do
558 -- bug in 5.4: thread can use message handler higher in the stack
559 -- than the variable being closed
560 local c = coroutine.create(function()
561 local clo <close> = setmetatable({}, {__close=function()
562 local x = 134 -- will overwrite message handler
563 error(x)
564 end})
565 -- yields coroutine but leaves a new message handler for it,
566 -- that would be used when closing the coroutine (except that it
567 -- will be overwritten)
568 xpcall(coroutine.yield, function() return "XXX" end)
569 end)
570
571 assert(coroutine.resume(c)) -- start coroutine
572 local st, msg = coroutine.close(c)
573 assert(not st and msg == 134)
574end
575
508-- access to locals of erroneous coroutines 576-- access to locals of erroneous coroutines
509local x = coroutine.create (function () 577local x = coroutine.create (function ()
510 local a = 10 578 local a = 10
diff --git a/testes/cstack.lua b/testes/cstack.lua
index 97afe9fd..0a68a30a 100644
--- a/testes/cstack.lua
+++ b/testes/cstack.lua
@@ -1,5 +1,5 @@
1-- $Id: testes/cstack.lua $ 1-- $Id: testes/cstack.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4 4
5local tracegc = require"tracegc" 5local tracegc = require"tracegc"
diff --git a/testes/db.lua b/testes/db.lua
index 75730d27..0f174f17 100644
--- a/testes/db.lua
+++ b/testes/db.lua
@@ -1,5 +1,5 @@
1-- $Id: testes/db.lua $ 1-- $Id: testes/db.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4-- testing debug library 4-- testing debug library
5 5
@@ -349,8 +349,11 @@ end, "crl")
349 349
350 350
351function f(a,b) 351function f(a,b)
352 -- declare some globals to check that they don't interfere with 'getlocal'
353 global collectgarbage
352 collectgarbage() 354 collectgarbage()
353 local _, x = debug.getlocal(1, 1) 355 local _, x = debug.getlocal(1, 1)
356 global assert, g, string
354 local _, y = debug.getlocal(1, 2) 357 local _, y = debug.getlocal(1, 2)
355 assert(x == a and y == b) 358 assert(x == a and y == b)
356 assert(debug.setlocal(2, 3, "pera") == "AA".."AA") 359 assert(debug.setlocal(2, 3, "pera") == "AA".."AA")
@@ -386,7 +389,9 @@ function g (...)
386 f(AAAA,B) 389 f(AAAA,B)
387 assert(AAAA == "pera" and B == "manga") 390 assert(AAAA == "pera" and B == "manga")
388 do 391 do
392 global *
389 local B = 13 393 local B = 13
394 global<const> assert
390 local x,y = debug.getlocal(1,5) 395 local x,y = debug.getlocal(1,5)
391 assert(x == 'B' and y == 13) 396 assert(x == 'B' and y == 13)
392 end 397 end
@@ -431,7 +436,7 @@ do
431 assert(a == nil and not b) 436 assert(a == nil and not b)
432end 437end
433 438
434-- testing iteraction between multiple values x hooks 439-- testing interaction between multiple values x hooks
435do 440do
436 local function f(...) return 3, ... end 441 local function f(...) return 3, ... end
437 local count = 0 442 local count = 0
@@ -587,7 +592,7 @@ t = getupvalues(foo2)
587assert(t.a == 1 and t.b == 2 and t.c == 3) 592assert(t.a == 1 and t.b == 2 and t.c == 3)
588assert(debug.setupvalue(foo1, 1, "xuxu") == "b") 593assert(debug.setupvalue(foo1, 1, "xuxu") == "b")
589assert(({debug.getupvalue(foo2, 3)})[2] == "xuxu") 594assert(({debug.getupvalue(foo2, 3)})[2] == "xuxu")
590-- upvalues of C functions are allways "called" "" (the empty string) 595-- upvalues of C functions are always named "" (the empty string)
591assert(debug.getupvalue(string.gmatch("x", "x"), 1) == "") 596assert(debug.getupvalue(string.gmatch("x", "x"), 1) == "")
592 597
593 598
@@ -701,7 +706,7 @@ assert(debug.traceback(print, 4) == print)
701assert(string.find(debug.traceback("hi", 4), "^hi\n")) 706assert(string.find(debug.traceback("hi", 4), "^hi\n"))
702assert(string.find(debug.traceback("hi"), "^hi\n")) 707assert(string.find(debug.traceback("hi"), "^hi\n"))
703assert(not string.find(debug.traceback("hi"), "'debug.traceback'")) 708assert(not string.find(debug.traceback("hi"), "'debug.traceback'"))
704assert(string.find(debug.traceback("hi", 0), "'debug.traceback'")) 709assert(string.find(debug.traceback("hi", 0), "'traceback'"))
705assert(string.find(debug.traceback(), "^stack traceback:\n")) 710assert(string.find(debug.traceback(), "^stack traceback:\n"))
706 711
707do -- C-function names in traceback 712do -- C-function names in traceback
@@ -829,7 +834,7 @@ end
829 834
830co = coroutine.create(function (x) f(x) end) 835co = coroutine.create(function (x) f(x) end)
831a, b = coroutine.resume(co, 3) 836a, b = coroutine.resume(co, 3)
832t = {"'coroutine.yield'", "'f'", "in function <"} 837t = {"'yield'", "'f'", "in function <"}
833while coroutine.status(co) == "suspended" do 838while coroutine.status(co) == "suspended" do
834 checktraceback(co, t) 839 checktraceback(co, t)
835 a, b = coroutine.resume(co) 840 a, b = coroutine.resume(co)
@@ -839,7 +844,7 @@ t[1] = "'error'"
839checktraceback(co, t) 844checktraceback(co, t)
840 845
841 846
842-- test acessing line numbers of a coroutine from a resume inside 847-- test accessing line numbers of a coroutine from a resume inside
843-- a C function (this is a known bug in Lua 5.0) 848-- a C function (this is a known bug in Lua 5.0)
844 849
845local function g(x) 850local function g(x)
@@ -966,9 +971,9 @@ local debug = require'debug'
966local a = 12 -- a local variable 971local a = 12 -- a local variable
967 972
968local n, v = debug.getlocal(1, 1) 973local n, v = debug.getlocal(1, 1)
969assert(n == "(temporary)" and v == debug) -- unkown name but known value 974assert(n == "(temporary)" and v == debug) -- unknown name but known value
970n, v = debug.getlocal(1, 2) 975n, v = debug.getlocal(1, 2)
971assert(n == "(temporary)" and v == 12) -- unkown name but known value 976assert(n == "(temporary)" and v == 12) -- unknown name but known value
972 977
973-- a function with an upvalue 978-- a function with an upvalue
974local f = function () local x; return a end 979local f = function () local x; return a end
@@ -1018,7 +1023,7 @@ do -- bug in 5.4.0: line hooks in stripped code
1018 line = l 1023 line = l
1019 end, "l") 1024 end, "l")
1020 assert(s() == 2); debug.sethook(nil) 1025 assert(s() == 2); debug.sethook(nil)
1021 assert(line == nil) -- hook called withoug debug info for 1st instruction 1026 assert(line == nil) -- hook called without debug info for 1st instruction
1022end 1027end
1023 1028
1024do -- tests for 'source' in binary dumps 1029do -- tests for 'source' in binary dumps
diff --git a/testes/errors.lua b/testes/errors.lua
index 5fdb7722..4230a352 100644
--- a/testes/errors.lua
+++ b/testes/errors.lua
@@ -1,5 +1,5 @@
1-- $Id: testes/errors.lua $ 1-- $Id: testes/errors.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4print("testing errors") 4print("testing errors")
5 5
@@ -46,7 +46,7 @@ end
46assert(doit("error('hi', 0)") == 'hi') 46assert(doit("error('hi', 0)") == 'hi')
47 47
48-- test nil error message 48-- test nil error message
49assert(doit("error()") == "<error object is nil>") 49assert(doit("error()") == "<no error object>")
50 50
51 51
52-- test common errors/errors that crashed in the past 52-- test common errors/errors that crashed in the past
@@ -162,6 +162,9 @@ checkmessage("aaa=(1)..{}", "a table value")
162-- bug in 5.4.6 162-- bug in 5.4.6
163checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'") 163checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'")
164 164
165-- a similar bug, since 5.4.0
166checkmessage("print(('_ENV').x + 1)", "field 'x'")
167
165_G.aaa, _G.bbbb = nil 168_G.aaa, _G.bbbb = nil
166 169
167-- calls 170-- calls
@@ -300,14 +303,14 @@ do
300 local f = function (a) return a + 1 end 303 local f = function (a) return a + 1 end
301 f = assert(load(string.dump(f, true))) 304 f = assert(load(string.dump(f, true)))
302 assert(f(3) == 4) 305 assert(f(3) == 4)
303 checkerr("^%?:%-1:", f, {}) 306 checkerr("^%?:%?:", f, {})
304 307
305 -- code with a move to a local var ('OP_MOV A B' with A<B) 308 -- code with a move to a local var ('OP_MOV A B' with A<B)
306 f = function () local a; a = {}; return a + 2 end 309 f = function () local a; a = {}; return a + 2 end
307 -- no debug info (so that 'a' is unknown) 310 -- no debug info (so that 'a' is unknown)
308 f = assert(load(string.dump(f, true))) 311 f = assert(load(string.dump(f, true)))
309 -- symbolic execution should not get lost 312 -- symbolic execution should not get lost
310 checkerr("^%?:%-1:.*table value", f) 313 checkerr("^%?:%?:.*table value", f)
311end 314end
312 315
313 316
@@ -486,6 +489,14 @@ if not b then
486 end 489 end
487end]], 5) 490end]], 5)
488 491
492lineerror([[
493_ENV = 1
494global function foo ()
495 local a = 10
496 return a
497end
498]], 2)
499
489 500
490-- bug in 5.4.0 501-- bug in 5.4.0
491lineerror([[ 502lineerror([[
@@ -504,7 +515,7 @@ end
504 515
505 516
506if not _soft then 517if not _soft then
507 -- several tests that exaust the Lua stack 518 -- several tests that exhaust the Lua stack
508 collectgarbage() 519 collectgarbage()
509 print"testing stack overflow" 520 print"testing stack overflow"
510 local C = 0 521 local C = 0
@@ -614,7 +625,7 @@ do
614 assert(not res and msg == t) 625 assert(not res and msg == t)
615 626
616 res, msg = pcall(function () error(nil) end) 627 res, msg = pcall(function () error(nil) end)
617 assert(not res and msg == "<error object is nil>") 628 assert(not res and msg == "<no error object>")
618 629
619 local function f() error{msg='x'} end 630 local function f() error{msg='x'} end
620 res, msg = xpcall(f, function (r) return {msg=r.msg..'y'} end) 631 res, msg = xpcall(f, function (r) return {msg=r.msg..'y'} end)
@@ -731,7 +742,7 @@ assert(c > 255 and string.find(b, "too many upvalues") and
731 742
732-- local variables 743-- local variables
733s = "\nfunction foo ()\n local " 744s = "\nfunction foo ()\n local "
734for j = 1,300 do 745for j = 1,200 do
735 s = s.."a"..j..", " 746 s = s.."a"..j..", "
736end 747end
737s = s.."b\n" 748s = s.."b\n"
diff --git a/testes/events.lua b/testes/events.lua
index 5360ac30..7e434b1f 100644
--- a/testes/events.lua
+++ b/testes/events.lua
@@ -1,5 +1,5 @@
1-- $Id: testes/events.lua $ 1-- $Id: testes/events.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4print('testing metatables') 4print('testing metatables')
5 5
@@ -379,6 +379,17 @@ x = 0 .."a".."b"..c..d.."e".."f".."g"
379assert(x.val == "0abcdefg") 379assert(x.val == "0abcdefg")
380 380
381 381
382do
383 -- bug since 5.4.1 (test needs T)
384 local mt = setmetatable({__newindex={}}, {__mode='v'})
385 local t = setmetatable({}, mt)
386
387 if T then T.allocfailnext() end
388
389 -- seg. fault
390 for i=1, 10 do t[i] = 1 end
391end
392
382-- concat metamethod x numbers (bug in 5.1.1) 393-- concat metamethod x numbers (bug in 5.1.1)
383c = {} 394c = {}
384local x 395local x
@@ -481,7 +492,7 @@ assert(not pcall(function (a,b) return a[b] end, a, 10))
481assert(not pcall(function (a,b,c) a[b] = c end, a, 10, true)) 492assert(not pcall(function (a,b,c) a[b] = c end, a, 10, true))
482 493
483-- bug in 5.1 494-- bug in 5.1
484T, K, V = nil 495local T, K, V = nil
485grandparent = {} 496grandparent = {}
486grandparent.__newindex = function(t,k,v) T=t; K=k; V=v end 497grandparent.__newindex = function(t,k,v) T=t; K=k; V=v end
487 498
diff --git a/testes/files.lua b/testes/files.lua
index 9bdf04d0..7146ac7c 100644
--- a/testes/files.lua
+++ b/testes/files.lua
@@ -1,5 +1,7 @@
1-- $Id: testes/files.lua $ 1-- $Id: testes/files.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3
4global <const> *
3 5
4local debug = require "debug" 6local debug = require "debug"
5 7
@@ -347,7 +349,7 @@ collectgarbage()
347 349
348assert(io.write(' ' .. t .. ' ')) 350assert(io.write(' ' .. t .. ' '))
349assert(io.write(';', 'end of file\n')) 351assert(io.write(';', 'end of file\n'))
350f:flush(); io.flush() 352assert(f:flush()); assert(io.flush())
351f:close() 353f:close()
352print('+') 354print('+')
353 355
@@ -461,7 +463,24 @@ do -- testing closing file in line iteration
461end 463end
462 464
463 465
464-- test for multipe arguments in 'lines' 466do print("testing flush")
467 local f = io.output("/dev/null")
468 assert(f:write("abcd")) -- write to buffer
469 assert(f:flush()) -- write to device
470 assert(f:write("abcd")) -- write to buffer
471 assert(io.flush()) -- write to device
472 assert(f:close())
473
474 local f = io.output("/dev/full")
475 assert(f:write("abcd")) -- write to buffer
476 assert(not f:flush()) -- cannot write to device
477 assert(f:write("abcd")) -- write to buffer
478 assert(not io.flush()) -- cannot write to device
479 assert(f:close())
480end
481
482
483-- test for multiple arguments in 'lines'
465io.output(file); io.write"0123456789\n":close() 484io.output(file); io.write"0123456789\n":close()
466for a,b in io.lines(file, 1, 1) do 485for a,b in io.lines(file, 1, 1) do
467 if a == "\n" then assert(not b) 486 if a == "\n" then assert(not b)
@@ -696,6 +715,37 @@ do
696end 715end
697 716
698 717
718if T and T.nonblock and not _port then
719 print("testing failed write")
720
721 -- unable to write anything to /dev/full
722 local f = io.open("/dev/full", "w")
723 assert(f:setvbuf("no"))
724 local _, _, err, count = f:write("abcd")
725 assert(err > 0 and count == 0)
726 assert(f:close())
727
728 -- receiver will read a "few" bytes (enough to empty a large buffer)
729 local receiver = [[
730 lua -e 'assert(io.stdin:setvbuf("no")); assert(#io.read(1e4) == 1e4)' ]]
731
732 local f = io.popen(receiver, "w")
733 assert(f:setvbuf("no"))
734 T.nonblock(f)
735
736 -- able to write a few bytes
737 assert(f:write(string.rep("a", 1e2)))
738
739 -- Unable to write more bytes than the pipe buffer supports.
740 -- (In Linux, the pipe buffer size is 64K (2^16). Posix requires at
741 -- least 512 bytes.)
742 local _, _, err, count = f:write("abcd", string.rep("a", 2^17))
743 assert(err > 0 and count >= 512 and count < 2^17)
744
745 assert(f:close())
746end
747
748
699if not _soft then 749if not _soft then
700 print("testing large files (> BUFSIZ)") 750 print("testing large files (> BUFSIZ)")
701 io.output(file) 751 io.output(file)
@@ -790,13 +840,13 @@ assert(os.date("!\0\0") == "\0\0")
790local x = string.rep("a", 10000) 840local x = string.rep("a", 10000)
791assert(os.date(x) == x) 841assert(os.date(x) == x)
792local t = os.time() 842local t = os.time()
793D = os.date("*t", t) 843global D = os.date("*t", t)
794assert(os.date(string.rep("%d", 1000), t) == 844assert(os.date(string.rep("%d", 1000), t) ==
795 string.rep(os.date("%d", t), 1000)) 845 string.rep(os.date("%d", t), 1000))
796assert(os.date(string.rep("%", 200)) == string.rep("%", 100)) 846assert(os.date(string.rep("%", 200)) == string.rep("%", 100))
797 847
798local function checkDateTable (t) 848local function checkDateTable (t)
799 _G.D = os.date("*t", t) 849 D = os.date("*t", t)
800 assert(os.time(D) == t) 850 assert(os.time(D) == t)
801 load(os.date([[assert(D.year==%Y and D.month==%m and D.day==%d and 851 load(os.date([[assert(D.year==%Y and D.month==%m and D.day==%d and
802 D.hour==%H and D.min==%M and D.sec==%S and 852 D.hour==%H and D.min==%M and D.sec==%S and
diff --git a/testes/gc.lua b/testes/gc.lua
index 09bfe09a..62713dac 100644
--- a/testes/gc.lua
+++ b/testes/gc.lua
@@ -1,5 +1,5 @@
1-- $Id: testes/gc.lua $ 1-- $Id: testes/gc.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4print('testing incremental garbage collection') 4print('testing incremental garbage collection')
5 5
@@ -288,6 +288,21 @@ x,y,z=nil
288collectgarbage() 288collectgarbage()
289assert(next(a) == string.rep('$', 11)) 289assert(next(a) == string.rep('$', 11))
290 290
291do -- invalid mode
292 local a = setmetatable({}, {__mode = 34})
293 collectgarbage()
294end
295
296
297if T then -- bug since 5.3: all-weak tables are not being revisited
298 T.gcstate("propagate")
299 local t = setmetatable({}, {__mode = "kv"})
300 T.gcstate("enteratomic") -- 't' was visited
301 setmetatable(t, {__mode = "kv"})
302 T.gcstate("pause") -- its new metatable is not being visited
303 assert(getmetatable(t).__mode == "kv")
304end
305
291 306
292-- 'bug' in 5.1 307-- 'bug' in 5.1
293a = {} 308a = {}
@@ -446,8 +461,8 @@ do -- tests for string keys in weak tables
446 local m = collectgarbage("count") -- current memory 461 local m = collectgarbage("count") -- current memory
447 local a = setmetatable({}, {__mode = "kv"}) 462 local a = setmetatable({}, {__mode = "kv"})
448 a[string.rep("a", 2^22)] = 25 -- long string key -> number value 463 a[string.rep("a", 2^22)] = 25 -- long string key -> number value
449 a[string.rep("b", 2^22)] = {} -- long string key -> colectable value 464 a[string.rep("b", 2^22)] = {} -- long string key -> collectable value
450 a[{}] = 14 -- colectable key 465 a[{}] = 14 -- collectable key
451 collectgarbage() 466 collectgarbage()
452 local k, v = next(a) -- string key with number value preserved 467 local k, v = next(a) -- string key with number value preserved
453 assert(k == string.rep("a", 2^22) and v == 25) 468 assert(k == string.rep("a", 2^22) and v == 25)
@@ -459,7 +474,7 @@ do -- tests for string keys in weak tables
459 assert(next(a) == nil) 474 assert(next(a) == nil)
460 -- make sure will not try to compare with dead key 475 -- make sure will not try to compare with dead key
461 assert(a[string.rep("b", 100)] == undef) 476 assert(a[string.rep("b", 100)] == undef)
462 assert(collectgarbage("count") <= m + 1) -- eveything collected 477 assert(collectgarbage("count") <= m + 1) -- everything collected
463end 478end
464 479
465 480
@@ -524,7 +539,7 @@ do
524 local co = coroutine.create(f) 539 local co = coroutine.create(f)
525 assert(coroutine.resume(co, co)) 540 assert(coroutine.resume(co, co))
526 end 541 end
527 -- Now, thread and closure are not reacheable any more. 542 -- Now, thread and closure are not reachable any more.
528 collectgarbage() 543 collectgarbage()
529 assert(collected) 544 assert(collected)
530 collectgarbage("restart") 545 collectgarbage("restart")
@@ -601,6 +616,21 @@ end
601 616
602 617
603if T then 618if T then
619 collectgarbage("stop")
620 T.gcstate("pause")
621 local sup = {x = 0}
622 local a = setmetatable({}, {__newindex = sup})
623 T.gcstate("enteratomic")
624 assert(T.gccolor(sup) == "black")
625 a.x = {} -- should not break the invariant
626 assert(not (T.gccolor(sup) == "black" and T.gccolor(sup.x) == "white"))
627 T.gcstate("pause") -- complete the GC cycle
628 sup.x.y = 10
629 collectgarbage("restart")
630end
631
632
633if T then
604 print("emergency collections") 634 print("emergency collections")
605 collectgarbage() 635 collectgarbage()
606 collectgarbage() 636 collectgarbage()
@@ -629,7 +659,7 @@ do
629 assert(getmetatable(o) == tt) 659 assert(getmetatable(o) == tt)
630 -- create new objects during GC 660 -- create new objects during GC
631 local a = 'xuxu'..(10+3)..'joao', {} 661 local a = 'xuxu'..(10+3)..'joao', {}
632 ___Glob = o -- ressurrect object! 662 ___Glob = o -- resurrect object!
633 setmetatable({}, tt) -- creates a new one with same metatable 663 setmetatable({}, tt) -- creates a new one with same metatable
634 print(">>> closing state " .. "<<<\n") 664 print(">>> closing state " .. "<<<\n")
635 end 665 end
diff --git a/testes/gengc.lua b/testes/gengc.lua
index c4f6ca1b..ea99bdc4 100644
--- a/testes/gengc.lua
+++ b/testes/gengc.lua
@@ -1,5 +1,5 @@
1-- $Id: testes/gengc.lua $ 1-- $Id: testes/gengc.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4print('testing generational garbage collection') 4print('testing generational garbage collection')
5 5
diff --git a/testes/goto.lua b/testes/goto.lua
index 103cccef..3310314d 100644
--- a/testes/goto.lua
+++ b/testes/goto.lua
@@ -1,5 +1,11 @@
1-- $Id: testes/goto.lua $ 1-- $Id: testes/goto.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3
4global<const> require
5global<const> print, load, assert, string, setmetatable
6global<const> collectgarbage, error
7
8print("testing goto and global declarations")
3 9
4collectgarbage() 10collectgarbage()
5 11
@@ -17,15 +23,18 @@ errmsg([[ ::l1:: ::l1:: ]], "label 'l1'")
17errmsg([[ ::l1:: do ::l1:: end]], "label 'l1'") 23errmsg([[ ::l1:: do ::l1:: end]], "label 'l1'")
18 24
19 25
20-- undefined label
21errmsg([[ goto l1; local aa ::l1:: ::l2:: print(3) ]], "local 'aa'")
22 26
23-- jumping over variable definition 27-- jumping over variable declaration
28errmsg([[ goto l1; local aa ::l1:: ::l2:: print(3) ]], "scope of 'aa'")
29
30errmsg([[ goto l2; global *; ::l1:: ::l2:: print(3) ]], "scope of '*'")
31
24errmsg([[ 32errmsg([[
25do local bb, cc; goto l1; end 33do local bb, cc; goto l1; end
26local aa 34local aa
27::l1:: print(3) 35::l1:: print(3)
28]], "local 'aa'") 36]], "scope of 'aa'")
37
29 38
30-- jumping into a block 39-- jumping into a block
31errmsg([[ do ::l1:: end goto l1 ]], "label 'l1'") 40errmsg([[ do ::l1:: end goto l1 ]], "label 'l1'")
@@ -38,7 +47,7 @@ errmsg([[
38 local xuxu = 10 47 local xuxu = 10
39 ::cont:: 48 ::cont::
40 until xuxu < x 49 until xuxu < x
41]], "local 'xuxu'") 50]], "scope of 'xuxu'")
42 51
43-- simple gotos 52-- simple gotos
44local x 53local x
@@ -252,6 +261,8 @@ assert(testG(5) == 10)
252 261
253do -- test goto's around to-be-closed variable 262do -- test goto's around to-be-closed variable
254 263
264 global *
265
255 -- set 'var' and return an object that will reset 'var' when 266 -- set 'var' and return an object that will reset 'var' when
256 -- it goes out of scope 267 -- it goes out of scope
257 local function newobj (var) 268 local function newobj (var)
@@ -263,16 +274,16 @@ do -- test goto's around to-be-closed variable
263 274
264 goto L1 275 goto L1
265 276
266 ::L4:: assert(not X); goto L5 -- varX dead here 277 ::L4:: assert(not varX); goto L5 -- varX dead here
267 278
268 ::L1:: 279 ::L1::
269 local varX <close> = newobj("X") 280 local varX <close> = newobj("X")
270 assert(X); goto L2 -- varX alive here 281 assert(varX); goto L2 -- varX alive here
271 282
272 ::L3:: 283 ::L3::
273 assert(X); goto L4 -- varX alive here 284 assert(varX); goto L4 -- varX alive here
274 285
275 ::L2:: assert(X); goto L3 -- varX alive here 286 ::L2:: assert(varX); goto L3 -- varX alive here
276 287
277 ::L5:: -- return 288 ::L5:: -- return
278end 289end
@@ -280,7 +291,146 @@ end
280 291
281 292
282foo() 293foo()
283-------------------------------------------------------------------------------- 294--------------------------------------------------------------------------
295
296local function checkerr (code, err)
297 local st, msg = load(code)
298 assert(not st and string.find(msg, err))
299end
300
301do
302 global T<const>
303
304 -- globals must be declared, after a global declaration
305 checkerr("global none; X = 1", "variable 'X'")
306 checkerr("global none; function XX() end", "variable 'XX'")
284 307
308 -- global variables cannot be to-be-closed
309 checkerr("global X<close>", "cannot be")
310 checkerr("global <close> *", "cannot be")
311
312 do
313 local X = 10
314 do global X; X = 20 end
315 assert(X == 10) -- local X
316 end
317 assert(_ENV.X == 20) -- global X
318
319 -- '_ENV' cannot be global
320 checkerr("global _ENV, a; a = 10", "variable 'a'")
321
322 -- global declarations inside functions
323 checkerr([[
324 global none
325 local function foo () XXX = 1 end --< ERROR]], "variable 'XXX'")
326
327 if not T then -- when not in "test mode", "global" isn't reserved
328 assert(load("global = 1; return global")() == 1)
329 print " ('global' is not a reserved word)"
330 else
331 -- "global" reserved, cannot be used as a variable
332 assert(not load("global = 1; return global"))
333 end
334
335 local foo = 20
336 do
337 global function foo (x)
338 if x == 0 then return 1 else return 2 * foo(x - 1) end
339 end
340 assert(foo == _ENV.foo and foo(4) == 16)
341 end
342 assert(_ENV.foo(4) == 16)
343 assert(foo == 20) -- local one is in context here
344
345 do
346 global foo;
347 function foo (x) return end -- Ok after declaration
348 end
349
350 checkerr([[
351 global<const> foo;
352 function foo (x) return end -- ERROR: foo is read-only
353 ]], "assign to const variable 'foo'")
354
355 checkerr([[
356 global foo <const>;
357 function foo (x) -- ERROR: foo is read-only
358 return
359 end
360 ]], "%:2%:") -- correct line in error message
361
362 checkerr([[
363 global<const> *;
364 print(X) -- Ok to use
365 Y = 1 -- ERROR
366 ]], "assign to const variable 'Y'")
367
368 checkerr([[
369 global *;
370 Y = X -- Ok to use
371 global<const> *;
372 Y = 1 -- ERROR
373 ]], "assign to const variable 'Y'")
374
375 global *
376 Y = 10
377 assert(_ENV.Y == 10)
378 global<const> *
379 local x = Y
380 global *
381 Y = x + Y
382 assert(_ENV.Y == 20)
383 Y = nil
384end
385
386
387do -- Ok to declare hundreds of globals
388 global table
389 local code = {}
390 for i = 1, 1000 do
391 code[#code + 1] = ";global x" .. i
392 end
393 code[#code + 1] = "; return x990"
394 code = table.concat(code)
395 _ENV.x990 = 11
396 assert(load(code)() == 11)
397 _ENV.x990 = nil
398end
399
400do -- mixing lots of global/local declarations
401 global table
402 local code = {}
403 for i = 1, 200 do
404 code[#code + 1] = ";global x" .. i
405 code[#code + 1] = ";local y" .. i .. "=" .. (2*i)
406 end
407 code[#code + 1] = "; return x200 + y200"
408 code = table.concat(code)
409 _ENV.x200 = 11
410 assert(assert(load(code))() == 2*200 + 11)
411 _ENV.x200 = nil
412end
413
414do print "testing initialization in global declarations"
415 global<const> a, b, c = 10, 20, 30
416 assert(_ENV.a == 10 and b == 20 and c == 30)
417
418 global<const> a, b, c = 10
419 assert(_ENV.a == 10 and b == nil and c == nil)
420
421 global table
422 global a, b, c, d = table.unpack{1, 2, 3, 6, 5}
423 assert(_ENV.a == 1 and b == 2 and c == 3 and d == 6)
424
425 local a, b = 100, 200
426 do
427 global a, b = a, b
428 end
429 assert(_ENV.a == 100 and _ENV.b == 200)
430
431
432 _ENV.a, _ENV.b, _ENV.c, _ENV.d = nil -- erase these globals
433end
285 434
286print'OK' 435print'OK'
436
diff --git a/testes/heavy.lua b/testes/heavy.lua
index 4731c747..3b4e4ce3 100644
--- a/testes/heavy.lua
+++ b/testes/heavy.lua
@@ -1,5 +1,5 @@
1-- $Id: heavy.lua,v 1.7 2017/12/29 15:42:15 roberto Exp $ 1-- $Id: testes/heavy.lua,v $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4local function teststring () 4local function teststring ()
5 print("creating a string too long") 5 print("creating a string too long")
diff --git a/testes/libs/lib22.c b/testes/libs/lib22.c
index 8e656502..b377cce5 100644
--- a/testes/libs/lib22.c
+++ b/testes/libs/lib22.c
@@ -1,3 +1,7 @@
1/* implementation for lib2-v2 */
2
3#include <string.h>
4
1#include "lua.h" 5#include "lua.h"
2#include "lauxlib.h" 6#include "lauxlib.h"
3 7
@@ -8,8 +12,54 @@ static int id (lua_State *L) {
8} 12}
9 13
10 14
15struct STR {
16 void *ud;
17 lua_Alloc allocf;
18};
19
20
21static void *t_freestr (void *ud, void *ptr, size_t osize, size_t nsize) {
22 struct STR *blk = (struct STR*)ptr - 1;
23 blk->allocf(blk->ud, blk, sizeof(struct STR) + osize, 0);
24 return NULL;
25}
26
27
28static int newstr (lua_State *L) {
29 size_t len;
30 const char *str = luaL_checklstring(L, 1, &len);
31 void *ud;
32 lua_Alloc allocf = lua_getallocf(L, &ud);
33 struct STR *blk = (struct STR*)allocf(ud, NULL, 0,
34 len + 1 + sizeof(struct STR));
35 if (blk == NULL) { /* allocation error? */
36 lua_pushliteral(L, "not enough memory");
37 lua_error(L); /* raise a memory error */
38 }
39 blk->ud = ud; blk->allocf = allocf;
40 memcpy(blk + 1, str, len + 1);
41 lua_pushexternalstring(L, (char *)(blk + 1), len, t_freestr, L);
42 return 1;
43}
44
45
46/*
47** Create an external string and keep it in the registry, so that it
48** will test that the library code is still available (to deallocate
49** this string) when closing the state.
50*/
51static void initstr (lua_State *L) {
52 lua_pushcfunction(L, newstr);
53 lua_pushstring(L,
54 "012345678901234567890123456789012345678901234567890123456789");
55 lua_call(L, 1, 1); /* call newstr("0123...") */
56 luaL_ref(L, LUA_REGISTRYINDEX); /* keep string in the registry */
57}
58
59
11static const struct luaL_Reg funcs[] = { 60static const struct luaL_Reg funcs[] = {
12 {"id", id}, 61 {"id", id},
62 {"newstr", newstr},
13 {NULL, NULL} 63 {NULL, NULL}
14}; 64};
15 65
@@ -18,6 +68,7 @@ LUAMOD_API int luaopen_lib2 (lua_State *L) {
18 lua_settop(L, 2); 68 lua_settop(L, 2);
19 lua_setglobal(L, "y"); /* y gets 2nd parameter */ 69 lua_setglobal(L, "y"); /* y gets 2nd parameter */
20 lua_setglobal(L, "x"); /* x gets 1st parameter */ 70 lua_setglobal(L, "x"); /* x gets 1st parameter */
71 initstr(L);
21 luaL_newlib(L, funcs); 72 luaL_newlib(L, funcs);
22 return 1; 73 return 1;
23} 74}
diff --git a/testes/literals.lua b/testes/literals.lua
index 30ab9ab1..336ef585 100644
--- a/testes/literals.lua
+++ b/testes/literals.lua
@@ -1,8 +1,10 @@
1-- $Id: testes/literals.lua $ 1-- $Id: testes/literals.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4print('testing scanner') 4print('testing scanner')
5 5
6global <const> *
7
6local debug = require "debug" 8local debug = require "debug"
7 9
8 10
diff --git a/testes/locals.lua b/testes/locals.lua
index 910deb8a..02f41980 100644
--- a/testes/locals.lua
+++ b/testes/locals.lua
@@ -1,5 +1,7 @@
1-- $Id: testes/locals.lua $ 1-- $Id: testes/locals.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3
4global <const> *
3 5
4print('testing local variables and environments') 6print('testing local variables and environments')
5 7
@@ -39,9 +41,11 @@ f = nil
39local f 41local f
40local x = 1 42local x = 1
41 43
42a = nil 44do
43load('local a = {}')() 45 global a; a = nil
44assert(a == nil) 46 load('local a = {}')()
47 assert(a == nil)
48end
45 49
46function f (a) 50function f (a)
47 local _1, _2, _3, _4, _5 51 local _1, _2, _3, _4, _5
@@ -154,7 +158,7 @@ local _ENV = (function (...) return ... end)(_G, dummy) -- {
154do local _ENV = {assert=assert}; assert(true) end 158do local _ENV = {assert=assert}; assert(true) end
155local mt = {_G = _G} 159local mt = {_G = _G}
156local foo,x 160local foo,x
157A = false -- "declare" A 161global A; A = false -- "declare" A
158do local _ENV = mt 162do local _ENV = mt
159 function foo (x) 163 function foo (x)
160 A = x 164 A = x
@@ -177,20 +181,27 @@ assert(x==20)
177A = nil 181A = nil
178 182
179 183
180do -- constants 184do print("testing local constants")
185 global assert<const>, load, string, X
186 X = 1 -- not a constant
181 local a<const>, b, c<const> = 10, 20, 30 187 local a<const>, b, c<const> = 10, 20, 30
182 b = a + c + b -- 'b' is not constant 188 b = a + c + b -- 'b' is not constant
183 assert(a == 10 and b == 60 and c == 30) 189 assert(a == 10 and b == 60 and c == 30)
190
184 local function checkro (name, code) 191 local function checkro (name, code)
185 local st, msg = load(code) 192 local st, msg = load(code)
186 local gab = string.format("attempt to assign to const variable '%s'", name) 193 local gab = string.format("attempt to assign to const variable '%s'", name)
187 assert(not st and string.find(msg, gab)) 194 assert(not st and string.find(msg, gab))
188 end 195 end
196
189 checkro("y", "local x, y <const>, z = 10, 20, 30; x = 11; y = 12") 197 checkro("y", "local x, y <const>, z = 10, 20, 30; x = 11; y = 12")
190 checkro("x", "local x <const>, y, z <const> = 10, 20, 30; x = 11") 198 checkro("x", "local x <const>, y, z <const> = 10, 20, 30; x = 11")
191 checkro("z", "local x <const>, y, z <const> = 10, 20, 30; y = 10; z = 11") 199 checkro("z", "local x <const>, y, z <const> = 10, 20, 30; y = 10; z = 11")
192 checkro("foo", "local foo <const> = 10; function foo() end") 200 checkro("foo", "local<const> foo = 10; function foo() end")
193 checkro("foo", "local foo <const> = {}; function foo() end") 201 checkro("foo", "local<const> foo <const> = {}; function foo() end")
202 checkro("foo", "global<const> foo <const>; function foo() end")
203 checkro("XX", "global XX <const>; XX = 10")
204 checkro("XX", "local _ENV; global XX <const>; XX = 10")
194 205
195 checkro("z", [[ 206 checkro("z", [[
196 local a, z <const>, b = 10; 207 local a, z <const>, b = 10;
@@ -201,11 +212,26 @@ do -- constants
201 local a, var1 <const> = 10; 212 local a, var1 <const> = 10;
202 function foo() a = 20; z = function () var1 = 12; end end 213 function foo() a = 20; z = function () var1 = 12; end end
203 ]]) 214 ]])
215
216 checkro("var1", [[
217 global a, var1 <const>, z;
218 local function foo() a = 20; z = function () var1 = 12; end end
219 ]])
204end 220end
205 221
206 222
223
207print"testing to-be-closed variables" 224print"testing to-be-closed variables"
208 225
226
227do
228 local st, msg = load("local <close> a, b")
229 assert(not st and string.find(msg, "multiple"))
230
231 local st, msg = load("local a<close>, b<close>")
232 assert(not st and string.find(msg, "multiple"))
233end
234
209local function stack(n) n = ((n == 0) or stack(n - 1)) end 235local function stack(n) n = ((n == 0) or stack(n - 1)) end
210 236
211local function func2close (f, x, y) 237local function func2close (f, x, y)
@@ -1162,7 +1188,7 @@ do
1162 local function open (x) 1188 local function open (x)
1163 numopen = numopen + 1 1189 numopen = numopen + 1
1164 return 1190 return
1165 function () -- iteraction function 1191 function () -- iteration function
1166 x = x - 1 1192 x = x - 1
1167 if x > 0 then return x end 1193 if x > 0 then return x end
1168 end, 1194 end,
diff --git a/testes/main.lua b/testes/main.lua
index e0e9cbe8..dc48dc48 100644
--- a/testes/main.lua
+++ b/testes/main.lua
@@ -1,6 +1,6 @@
1# testing special comment on first line 1# testing special comment on first line
2-- $Id: testes/main.lua $ 2-- $Id: testes/main.lua $
3-- See Copyright Notice in file all.lua 3-- See Copyright Notice in file lua.h
4 4
5-- most (all?) tests here assume a reasonable "Unix-like" shell 5-- most (all?) tests here assume a reasonable "Unix-like" shell
6if _port then return end 6if _port then return end
@@ -90,7 +90,7 @@ prepfile[[
901, a 901, a
91) 91)
92]] 92]]
93RUN('lua - < %s > %s', prog, out) 93RUN('lua - -- < %s > %s', prog, out)
94checkout("1\tnil\n") 94checkout("1\tnil\n")
95 95
96RUN('echo "print(10)\nprint(2)\n" | lua > %s', out) 96RUN('echo "print(10)\nprint(2)\n" | lua > %s', out)
@@ -133,7 +133,7 @@ checkout("-h\n")
133prepfile("print(package.path)") 133prepfile("print(package.path)")
134 134
135-- test LUA_PATH 135-- test LUA_PATH
136RUN('env LUA_INIT= LUA_PATH=x lua %s > %s', prog, out) 136RUN('env LUA_INIT= LUA_PATH=x lua -- %s > %s', prog, out)
137checkout("x\n") 137checkout("x\n")
138 138
139-- test LUA_PATH_version 139-- test LUA_PATH_version
@@ -226,7 +226,7 @@ RUN("lua -l 'str=string' '-lm=math' -e 'print(m.sin(0))' %s > %s", prog, out)
226checkout("0.0\nALO ALO\t20\n") 226checkout("0.0\nALO ALO\t20\n")
227 227
228 228
229-- test module names with version sufix ("libs/lib2-v2") 229-- test module names with version suffix ("libs/lib2-v2")
230RUN("env LUA_CPATH='./libs/?.so' lua -l lib2-v2 -e 'print(lib2.id())' > %s", 230RUN("env LUA_CPATH='./libs/?.so' lua -l lib2-v2 -e 'print(lib2.id())' > %s",
231 out) 231 out)
232checkout("true\n") 232checkout("true\n")
@@ -347,7 +347,7 @@ checkout("a\n")
347RUN([[lua "-eprint(1)" -ea=3 -e "print(a)" > %s]], out) 347RUN([[lua "-eprint(1)" -ea=3 -e "print(a)" > %s]], out)
348checkout("1\n3\n") 348checkout("1\n3\n")
349 349
350-- test iteractive mode 350-- test interactive mode
351prepfile[[ 351prepfile[[
352(6*2-6) -- === 352(6*2-6) -- ===
353a = 353a =
@@ -358,7 +358,7 @@ RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
358checkprogout("6\n10\n10\n\n") 358checkprogout("6\n10\n10\n\n")
359 359
360prepfile("a = [[b\nc\nd\ne]]\na") 360prepfile("a = [[b\nc\nd\ne]]\na")
361RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) 361RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i -- < %s > %s]], prog, out)
362checkprogout("b\nc\nd\ne\n\n") 362checkprogout("b\nc\nd\ne\n\n")
363 363
364-- input interrupted in continuation line 364-- input interrupted in continuation line
@@ -488,12 +488,13 @@ assert(not os.remove(out))
488-- invalid options 488-- invalid options
489NoRun("unrecognized option '-h'", "lua -h") 489NoRun("unrecognized option '-h'", "lua -h")
490NoRun("unrecognized option '---'", "lua ---") 490NoRun("unrecognized option '---'", "lua ---")
491NoRun("unrecognized option '-Ex'", "lua -Ex") 491NoRun("unrecognized option '-Ex'", "lua -Ex --")
492NoRun("unrecognized option '-vv'", "lua -vv") 492NoRun("unrecognized option '-vv'", "lua -vv")
493NoRun("unrecognized option '-iv'", "lua -iv") 493NoRun("unrecognized option '-iv'", "lua -iv")
494NoRun("'-e' needs argument", "lua -e") 494NoRun("'-e' needs argument", "lua -e")
495NoRun("syntax error", "lua -e a") 495NoRun("syntax error", "lua -e a")
496NoRun("'-l' needs argument", "lua -l") 496NoRun("'-l' needs argument", "lua -l")
497NoRun("-i", "lua -- -i") -- handles -i as a script name
497 498
498 499
499if T then -- test library? 500if T then -- test library?
diff --git a/testes/math.lua b/testes/math.lua
index 3937b9ce..0d228d09 100644
--- a/testes/math.lua
+++ b/testes/math.lua
@@ -1,10 +1,17 @@
1-- $Id: testes/math.lua $ 1-- $Id: testes/math.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4print("testing numbers and math lib") 4print("testing numbers and math lib")
5 5
6local minint <const> = math.mininteger 6local math = require "math"
7local maxint <const> = math.maxinteger 7local string = require "string"
8
9global none
10
11global<const> print, assert, pcall, type, pairs, load
12global<const> tonumber, tostring, select
13
14local<const> minint, maxint = math.mininteger, math.maxinteger
8 15
9local intbits <const> = math.floor(math.log(maxint, 2) + 0.5) + 1 16local intbits <const> = math.floor(math.log(maxint, 2) + 0.5) + 1
10assert((1 << intbits) == 0) 17assert((1 << intbits) == 0)
@@ -184,7 +191,7 @@ do
184 for i = -3, 3 do -- variables avoid constant folding 191 for i = -3, 3 do -- variables avoid constant folding
185 for j = -3, 3 do 192 for j = -3, 3 do
186 -- domain errors (0^(-n)) are not portable 193 -- domain errors (0^(-n)) are not portable
187 if not _port or i ~= 0 or j > 0 then 194 if not _ENV._port or i ~= 0 or j > 0 then
188 assert(eq(i^j, 1 / i^(-j))) 195 assert(eq(i^j, 1 / i^(-j)))
189 end 196 end
190 end 197 end
@@ -430,7 +437,7 @@ for i = 2,36 do
430 assert(tonumber('\t10000000000\t', i) == i10) 437 assert(tonumber('\t10000000000\t', i) == i10)
431end 438end
432 439
433if not _soft then 440if not _ENV._soft then
434 -- tests with very long numerals 441 -- tests with very long numerals
435 assert(tonumber("0x"..string.rep("f", 13)..".0") == 2.0^(4*13) - 1) 442 assert(tonumber("0x"..string.rep("f", 13)..".0") == 2.0^(4*13) - 1)
436 assert(tonumber("0x"..string.rep("f", 150)..".0") == 2.0^(4*150) - 1) 443 assert(tonumber("0x"..string.rep("f", 150)..".0") == 2.0^(4*150) - 1)
@@ -632,7 +639,7 @@ assert(maxint % -2 == -1)
632 639
633-- non-portable tests because Windows C library cannot compute 640-- non-portable tests because Windows C library cannot compute
634-- fmod(1, huge) correctly 641-- fmod(1, huge) correctly
635if not _port then 642if not _ENV._port then
636 local function anan (x) assert(isNaN(x)) end -- assert Not a Number 643 local function anan (x) assert(isNaN(x)) end -- assert Not a Number
637 anan(0.0 % 0) 644 anan(0.0 % 0)
638 anan(1.3 % 0) 645 anan(1.3 % 0)
@@ -779,6 +786,7 @@ assert(a == '10' and b == '20')
779 786
780do 787do
781 print("testing -0 and NaN") 788 print("testing -0 and NaN")
789 global rawset, undef
782 local mz <const> = -0.0 790 local mz <const> = -0.0
783 local z <const> = 0.0 791 local z <const> = 0.0
784 assert(mz == z) 792 assert(mz == z)
@@ -1071,9 +1079,10 @@ do
1071 assert(x == tonumber(tostring(x))) 1079 assert(x == tonumber(tostring(x)))
1072 end 1080 end
1073 1081
1074 -- different numbers shold print differently. 1082 -- different numbers should print differently.
1075 -- check pairs of floats with minimum detectable difference 1083 -- check pairs of floats with minimum detectable difference
1076 local p = floatbits - 1 1084 local p = floatbits - 1
1085 global ipairs
1077 for i = 1, maxexp - 1 do 1086 for i = 1, maxexp - 1 do
1078 for _, i in ipairs{-i, i} do 1087 for _, i in ipairs{-i, i} do
1079 local x = 2^i 1088 local x = 2^i
diff --git a/testes/memerr.lua b/testes/memerr.lua
new file mode 100644
index 00000000..77cb47cb
--- /dev/null
+++ b/testes/memerr.lua
@@ -0,0 +1,266 @@
1-- $Id: testes/memerr.lua $
2-- See Copyright Notice in file lua.h
3
4
5local function checkerr (msg, f, ...)
6 local stat, err = pcall(f, ...)
7 assert(not stat and string.find(err, msg))
8end
9
10if T==nil then
11 (Message or print)
12 ('\n >>> testC not active: skipping memory error tests <<<\n')
13 return
14end
15
16print("testing memory-allocation errors")
17
18local debug = require "debug"
19
20local pack = table.pack
21
22-- standard error message for memory errors
23local MEMERRMSG = "not enough memory"
24
25
26-- memory error in panic function
27T.totalmem(T.totalmem()+10000) -- set low memory limit (+10k)
28assert(T.checkpanic("newuserdata 20000") == MEMERRMSG)
29T.totalmem(0) -- restore high limit
30
31
32
33-- {==================================================================
34-- Testing memory limits
35-- ===================================================================
36
37checkerr("block too big", T.newuserdata, math.maxinteger)
38collectgarbage()
39local f = load"local a={}; for i=1,100000 do a[i]=i end"
40T.alloccount(10)
41checkerr(MEMERRMSG, f)
42T.alloccount() -- remove limit
43
44
45-- test memory errors; increase limit for maximum memory by steps,
46-- o that we get memory errors in all allocations of a given
47-- task, until there is enough memory to complete the task without
48-- errors.
49local function testbytes (s, f)
50 collectgarbage()
51 local M = T.totalmem()
52 local oldM = M
53 local a,b = nil
54 while true do
55 collectgarbage(); collectgarbage()
56 T.totalmem(M)
57 a, b = T.testC("pcall 0 1 0; pushstatus; return 2", f)
58 T.totalmem(0) -- remove limit
59 if a and b == "OK" then break end -- stop when no more errors
60 if b ~= "OK" and b ~= MEMERRMSG then -- not a memory error?
61 error(a, 0) -- propagate it
62 end
63 M = M + 7 -- increase memory limit
64 end
65 print(string.format("minimum memory for %s: %d bytes", s, M - oldM))
66 return a
67end
68
69-- test memory errors; increase limit for number of allocations one
70-- by one, so that we get memory errors in all allocations of a given
71-- task, until there is enough allocations to complete the task without
72-- errors.
73
74local function testalloc (s, f)
75 collectgarbage()
76 local M = 0
77 local a,b = nil
78 while true do
79 collectgarbage(); collectgarbage()
80 T.alloccount(M)
81 a, b = T.testC("pcall 0 1 0; pushstatus; return 2", f)
82 T.alloccount() -- remove limit
83 if a and b == "OK" then break end -- stop when no more errors
84 if b ~= "OK" and b ~= MEMERRMSG then -- not a memory error?
85 error(a, 0) -- propagate it
86 end
87 M = M + 1 -- increase allocation limit
88 end
89 print(string.format("minimum allocations for %s: %d allocations", s, M))
90 return a
91end
92
93
94local function testamem (s, f)
95 testalloc(s, f)
96 return testbytes(s, f)
97end
98
99
100-- doing nothing
101b = testamem("doing nothing", function () return 10 end)
102assert(b == 10)
103
104-- testing memory errors when creating a new state
105
106testamem("state creation", function ()
107 local st = T.newstate()
108 if st then T.closestate(st) end -- close new state
109 return st
110end)
111
112testamem("empty-table creation", function ()
113 return {}
114end)
115
116testamem("string creation", function ()
117 return "XXX" .. "YYY"
118end)
119
120testamem("coroutine creation", function()
121 return coroutine.create(print)
122end)
123
124
125-- testing to-be-closed variables
126testamem("to-be-closed variables", function()
127 local flag
128 do
129 local x <close> =
130 setmetatable({}, {__close = function () flag = true end})
131 flag = false
132 local x = {}
133 end
134 return flag
135end)
136
137
138-- testing threads
139
140-- get main thread from registry
141local mt = T.testC("rawgeti R !M; return 1")
142assert(type(mt) == "thread" and coroutine.running() == mt)
143
144
145
146local function expand (n,s)
147 if n==0 then return "" end
148 local e = string.rep("=", n)
149 return string.format("T.doonnewstack([%s[ %s;\n collectgarbage(); %s]%s])\n",
150 e, s, expand(n-1,s), e)
151end
152
153G=0; collectgarbage(); a =collectgarbage("count")
154load(expand(20,"G=G+1"))()
155assert(G==20); collectgarbage(); -- assert(gcinfo() <= a+1)
156G = nil
157
158testamem("running code on new thread", function ()
159 return T.doonnewstack("local x=1") == 0 -- try to create thread
160end)
161
162
163-- testing memory x compiler
164
165testamem("loadstring", function ()
166 return load("x=1") -- try to do load a string
167end)
168
169
170local testprog = [[
171local function foo () return end
172local t = {"x"}
173AA = "aaa"
174for i = 1, #t do AA = AA .. t[i] end
175return true
176]]
177
178-- testing memory x dofile
179_G.AA = nil
180local t =os.tmpname()
181local f = assert(io.open(t, "w"))
182f:write(testprog)
183f:close()
184testamem("dofile", function ()
185 local a = loadfile(t)
186 return a and a()
187end)
188assert(os.remove(t))
189assert(_G.AA == "aaax")
190
191
192-- other generic tests
193
194testamem("gsub", function ()
195 local a, b = string.gsub("alo alo", "(a)", function (x) return x..'b' end)
196 return (a == 'ablo ablo')
197end)
198
199testamem("dump/undump", function ()
200 local a = load(testprog)
201 local b = a and string.dump(a)
202 a = b and load(b)
203 return a and a()
204end)
205
206_G.AA = nil
207
208local t = os.tmpname()
209testamem("file creation", function ()
210 local f = assert(io.open(t, 'w'))
211 assert (not io.open"nomenaoexistente")
212 io.close(f);
213 return not loadfile'nomenaoexistente'
214end)
215assert(os.remove(t))
216
217testamem("table creation", function ()
218 local a, lim = {}, 10
219 for i=1,lim do a[i] = i; a[i..'a'] = {} end
220 return (type(a[lim..'a']) == 'table' and a[lim] == lim)
221end)
222
223testamem("constructors", function ()
224 local a = {10, 20, 30, 40, 50; a=1, b=2, c=3, d=4, e=5}
225 return (type(a) == 'table' and a.e == 5)
226end)
227
228local a = 1
229local close = nil
230testamem("closure creation", function ()
231 function close (b)
232 return function (x) return b + x end
233 end
234 return (close(2)(4) == 6)
235end)
236
237testamem("using coroutines", function ()
238 local a = coroutine.wrap(function ()
239 coroutine.yield(string.rep("a", 10))
240 return {}
241 end)
242 assert(string.len(a()) == 10)
243 return a()
244end)
245
246do -- auxiliary buffer
247 local lim = 100
248 local a = {}; for i = 1, lim do a[i] = "01234567890123456789" end
249 testamem("auxiliary buffer", function ()
250 return (#table.concat(a, ",") == 20*lim + lim - 1)
251 end)
252end
253
254testamem("growing stack", function ()
255 local function foo (n)
256 if n == 0 then return 1 else return 1 + foo(n - 1) end
257 end
258 return foo(100)
259end)
260
261-- }==================================================================
262
263
264print "Ok"
265
266
diff --git a/testes/nextvar.lua b/testes/nextvar.lua
index d1da3cee..7e5bed56 100644
--- a/testes/nextvar.lua
+++ b/testes/nextvar.lua
@@ -1,5 +1,7 @@
1-- $Id: testes/nextvar.lua $ 1-- $Id: testes/nextvar.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3
4global <const> *
3 5
4print('testing tables, next, and for') 6print('testing tables, next, and for')
5 7
@@ -227,7 +229,7 @@ for i = 1,lim do
227end 229end
228 230
229 231
230-- insert and delete elements until a rehash occurr. Caller must ensure 232-- insert and delete elements until a rehash occur. Caller must ensure
231-- that a rehash will change the shape of the table. Must repeat because 233-- that a rehash will change the shape of the table. Must repeat because
232-- the insertion may collide with the deleted element, and then there is 234-- the insertion may collide with the deleted element, and then there is
233-- no rehash. 235-- no rehash.
@@ -343,13 +345,22 @@ do
343 end 345 end
344end 346end
345 347
346local nofind = {}
347 348
348a,b,c = 1,2,3 349do print("testing attack on table length")
349a,b,c = nil 350 local t = {}
351 local lim = math.floor(math.log(math.maxinteger, 2)) - 1
352 for i = lim, 0, -1 do
353 t[2^i] = true
354 end
355 assert(t[1 << lim])
356 -- next loop should not take forever
357 for i = 1, #t do end
358end
359
360local nofind = {}
350 361
351 362
352-- next uses always the same iteraction function 363-- next uses always the same iteration function
353assert(next{} == next{}) 364assert(next{} == next{})
354 365
355local function find (name) 366local function find (name)
@@ -396,7 +407,7 @@ for i=0,10000 do
396 end 407 end
397end 408end
398 409
399n = {n=0} 410local n = {n=0}
400for i,v in pairs(a) do 411for i,v in pairs(a) do
401 n.n = n.n+1 412 n.n = n.n+1
402 assert(i and v and a[i] == v) 413 assert(i and v and a[i] == v)
diff --git a/testes/packtests b/testes/packtests
index 0dbb92fe..855c054a 100755
--- a/testes/packtests
+++ b/testes/packtests
@@ -28,6 +28,7 @@ $NAME/literals.lua \
28$NAME/locals.lua \ 28$NAME/locals.lua \
29$NAME/main.lua \ 29$NAME/main.lua \
30$NAME/math.lua \ 30$NAME/math.lua \
31$NAME/memerr.lua \
31$NAME/nextvar.lua \ 32$NAME/nextvar.lua \
32$NAME/pm.lua \ 33$NAME/pm.lua \
33$NAME/sort.lua \ 34$NAME/sort.lua \
diff --git a/testes/pm.lua b/testes/pm.lua
index f5889fcd..720d2a35 100644
--- a/testes/pm.lua
+++ b/testes/pm.lua
@@ -1,11 +1,13 @@
1-- $Id: testes/pm.lua $ 1-- $Id: testes/pm.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4-- UTF-8 file 4-- UTF-8 file
5 5
6 6
7print('testing pattern matching') 7print('testing pattern matching')
8 8
9global <const> *
10
9local function checkerror (msg, f, ...) 11local function checkerror (msg, f, ...)
10 local s, err = pcall(f, ...) 12 local s, err = pcall(f, ...)
11 assert(not s and string.find(err, msg)) 13 assert(not s and string.find(err, msg))
@@ -23,9 +25,9 @@ a,b = string.find('alo', '')
23assert(a == 1 and b == 0) 25assert(a == 1 and b == 0)
24a,b = string.find('a\0o a\0o a\0o', 'a', 1) -- first position 26a,b = string.find('a\0o a\0o a\0o', 'a', 1) -- first position
25assert(a == 1 and b == 1) 27assert(a == 1 and b == 1)
26a,b = string.find('a\0o a\0o a\0o', 'a\0o', 2) -- starts in the midle 28a,b = string.find('a\0o a\0o a\0o', 'a\0o', 2) -- starts in the middle
27assert(a == 5 and b == 7) 29assert(a == 5 and b == 7)
28a,b = string.find('a\0o a\0o a\0o', 'a\0o', 9) -- starts in the midle 30a,b = string.find('a\0o a\0o a\0o', 'a\0o', 9) -- starts in the middle
29assert(a == 9 and b == 11) 31assert(a == 9 and b == 11)
30a,b = string.find('a\0a\0a\0a\0\0ab', '\0ab', 2); -- finds at the end 32a,b = string.find('a\0a\0a\0a\0\0ab', '\0ab', 2); -- finds at the end
31assert(a == 9 and b == 11); 33assert(a == 9 and b == 11);
diff --git a/testes/sort.lua b/testes/sort.lua
index 290b199e..b0127660 100644
--- a/testes/sort.lua
+++ b/testes/sort.lua
@@ -1,5 +1,5 @@
1-- $Id: testes/sort.lua $ 1-- $Id: testes/sort.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4print "testing (parts of) table library" 4print "testing (parts of) table library"
5 5
diff --git a/testes/strings.lua b/testes/strings.lua
index 9bb52b35..46912d43 100644
--- a/testes/strings.lua
+++ b/testes/strings.lua
@@ -1,8 +1,9 @@
1-- $Id: testes/strings.lua $ 1-- $Id: testes/strings.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4-- ISO Latin encoding 4-- ISO Latin encoding
5 5
6global <const> *
6 7
7print('testing strings and string library') 8print('testing strings and string library')
8 9
diff --git a/testes/tpack.lua b/testes/tpack.lua
index 4b32efb5..70386178 100644
--- a/testes/tpack.lua
+++ b/testes/tpack.lua
@@ -1,5 +1,5 @@
1-- $Id: testes/tpack.lua $ 1-- $Id: testes/tpack.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4local pack = string.pack 4local pack = string.pack
5local packsize = string.packsize 5local packsize = string.packsize
diff --git a/testes/tracegc.lua b/testes/tracegc.lua
index 9c5c1b3f..a8c929df 100644
--- a/testes/tracegc.lua
+++ b/testes/tracegc.lua
@@ -6,7 +6,7 @@ local M = {}
6local setmetatable, stderr, collectgarbage = 6local setmetatable, stderr, collectgarbage =
7 setmetatable, io.stderr, collectgarbage 7 setmetatable, io.stderr, collectgarbage
8 8
9_ENV = nil 9global none
10 10
11local active = false 11local active = false
12 12
diff --git a/testes/utf8.lua b/testes/utf8.lua
index dc0f2f09..028995a4 100644
--- a/testes/utf8.lua
+++ b/testes/utf8.lua
@@ -1,8 +1,10 @@
1-- $Id: testes/utf8.lua $ 1-- $Id: testes/utf8.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4-- UTF-8 file 4-- UTF-8 file
5 5
6global <const> *
7
6print "testing UTF-8 library" 8print "testing UTF-8 library"
7 9
8local utf8 = require'utf8' 10local utf8 = require'utf8'
@@ -134,7 +136,7 @@ do
134 errorcodes("\xbfinvalid") 136 errorcodes("\xbfinvalid")
135 errorcodes("αλφ\xBFα") 137 errorcodes("αλφ\xBFα")
136 138
137 -- calling interation function with invalid arguments 139 -- calling iteration function with invalid arguments
138 local f = utf8.codes("") 140 local f = utf8.codes("")
139 assert(f("", 2) == nil) 141 assert(f("", 2) == nil)
140 assert(f("", -1) == nil) 142 assert(f("", -1) == nil)
@@ -150,11 +152,20 @@ checkerror("position out of bounds", utf8.offset, "", 1, -1)
150checkerror("continuation byte", utf8.offset, "𦧺", 1, 2) 152checkerror("continuation byte", utf8.offset, "𦧺", 1, 2)
151checkerror("continuation byte", utf8.offset, "𦧺", 1, 2) 153checkerror("continuation byte", utf8.offset, "𦧺", 1, 2)
152checkerror("continuation byte", utf8.offset, "\x80", 1) 154checkerror("continuation byte", utf8.offset, "\x80", 1)
155checkerror("continuation byte", utf8.offset, "\x9c", -1)
153 156
154-- error in indices for len 157-- error in indices for len
155checkerror("out of bounds", utf8.len, "abc", 0, 2) 158checkerror("out of bounds", utf8.len, "abc", 0, 2)
156checkerror("out of bounds", utf8.len, "abc", 1, 4) 159checkerror("out of bounds", utf8.len, "abc", 1, 4)
157 160
161do -- missing continuation bytes
162 -- get what is available
163 local p, e = utf8.offset("\xE0", 1)
164 assert(p == 1 and e == 1)
165 local p, e = utf8.offset("\xE0\x9e", -1)
166 assert(p == 1 and e == 2)
167end
168
158 169
159local s = "hello World" 170local s = "hello World"
160local t = {string.byte(s, 1, -1)} 171local t = {string.byte(s, 1, -1)}
diff --git a/testes/vararg.lua b/testes/vararg.lua
index 1b025102..10553de2 100644
--- a/testes/vararg.lua
+++ b/testes/vararg.lua
@@ -1,5 +1,5 @@
1-- $Id: testes/vararg.lua $ 1-- $Id: testes/vararg.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4print('testing vararg') 4print('testing vararg')
5 5
diff --git a/testes/verybig.lua b/testes/verybig.lua
index 250ea795..8163802c 100644
--- a/testes/verybig.lua
+++ b/testes/verybig.lua
@@ -1,5 +1,5 @@
1-- $Id: testes/verybig.lua $ 1-- $Id: testes/verybig.lua $
2-- See Copyright Notice in file all.lua 2-- See Copyright Notice in file lua.h
3 3
4print "testing RK" 4print "testing RK"
5 5