diff --git a/test/README.md b/test/README.md index f72290f225..ff16ac8ef8 100644 --- a/test/README.md +++ b/test/README.md @@ -1,110 +1,110 @@ -This directory contains the LuaJIT test suite, or at least something which -will evolve into the LuaJIT test suite. Large chunks of the suite can also -be run with any other Lua 5.1 or 5.2 interpreter. - -## Running the test suite ## - -To run the default test suite, run `test.lua` using the Lua interpreter you -wish to test, for example: - - $ ~/luajit-2.0/src/luajit test.lua - -If the test suite passes, the final line printed to stdout will be -`NNN passed`, and the exit code of the process will be zero. If any tests -fail, the exit code will be non-zero. If the failures caused catastrophic -termination of the entire process (such as a segmentation fault or assertion -failure), the last line of output will be number and name of the test which -caused the catastrophe. If the failures weren't catastrophic, the penultimate -line of output will be `NNN passed, MMM failed`, and the last line will say -how to re-run just the failing tests. - -Various flags and options can be passed to `test.lua` to control which tests -are run, and in which order. Run `lua test.lua --help` for details. - -## Structure of the test suite ## - -The test suite consists of a directory tree. Within said tree there are various -`.lua` files, and within every `.lua` file there are one or more tests. Every -directory in the tree contains a file called `index`, which enumerates the -members of the directory which contribute to the test suite (this is done to -avoid an external dependency for directory iteration, and to allow metadata to -be specified at the file/directory level). Every `.lua` file is structured as: - - << local definitions >> - << test 1 >> - ... - << test N >> - -Where `<< local definitions >>` consists of Lua code to act as a common prefix -for every test in the file, and each `<< test >>` looks like: - - do --- <> <> - << code >> - end - -Where `<>` is (almost) free-form, and `<< code >>` is Lua code which -performs some actions and probably calls `assert` alot. The `<>` -fragment can be used to specify the conditions under which the test should -or should not run, to adjust the environment in which the test is run, and to -allow key/value pairs to be specified in a standard place/format. - -Some common pieces of metadata are: - * `+luajit>=2.1` - The test requires LuaJIT 2.1 or later to run. - * `+lua<5.2` - The test requires Lua 5.1 or earlier to run (all versions of - LuaJIT report themselves as 5.1). - * `+ffi` - The test requires the `ffi` library to be present. - * `+bit` - The test requires the `bit` library to be present. - * `+jit` - The test requires JIT compilation be available and turned on. - * `+slow` - The test is too slow to run as part of the default suite, and - thus requires `+slow` to be specified on the command line. - * `!private_G` - The test modifies globals, and thus needs to be run with a - private (shallow) copy of `_G`. - -Lua code which is common across all (or some) tests in a single file can be -written at the top of the file as part of `<< local definitions >>`. Code -which is common across multiple files lives in the `common` directory, and -is pulled into applicable tests by means of `local x = require"common.x"`. - -It is intended that most `.lua` files in the test suite can be exercised -without the test runner by just passing them to a Lua interpreter. In such -cases, metadata is ignored, the tests are executed from top to bottom, and -any failure results in later tests not running. Also note that the test -runner converts every test into a separate function, which causes references -to local definitions to become upvalue accesses rather than local variable -accesses - in some cases this can cause differences in behaviour. - -## Extending the test suite ## - -First of all, decide where your new test(s) should live. This might be within -an existing `.lua` file, or might involve creating new files and/or directories. -If new files are created, remember to add them to the `index` file of the -enclosing directory. If new directories are created, remember to create an -`index` file in said directory, and add the new directory to the `index` file -in the parent directory. - -Once you've decided in which file the test(s) should live, you're ready to add -your test(s) to said file. Each test should be wrapped in a `do`/`end` block, -and given some kind of name (after the `do` keyword, as in `do --- <>`). -The test should call `assert` to confirm whether the thing under test is -behaving, or otherwise raise an error if the thing under test is misbehaving. -Your test(s) should not write to stdout or stderr, nor should they mutate -global state. After your test(s) are written, you should be able to determine -which features they require, and put on metadata appropriately. - -## Completing the tidy-up of the test suite ## - -Some files/directories in this directory need some thought: - - * `common/ffi_util.inc` - Needs renaming and being made `require`-able. - * `lib/ffi` - Tests need converting to structure described in this document. - * `lib/table/misc.lua` - Tests need organising and converting to structure - described in this document. - * `misc` - Tests need organising and converting to structure described in - this document. - * `src` - C/C++ source which needs to be compiled into a dynamic library and - loaded for certain tests. Need to figure out a good way of handling - C/C++ source. - * `sysdep` - Need to figure out a good way of handling these. - * `unportable` - Need to figure out a good way of handling these. - -After that, consult the README file by Mike in the directory above this one. +This directory contains the LuaJIT test suite, or at least something which +will evolve into the LuaJIT test suite. Large chunks of the suite can also +be run with any other Lua 5.1 or 5.2 interpreter. + +## Running the test suite ## + +To run the default test suite, run `test.lua` using the Lua interpreter you +wish to test, for example: + + $ ~/luajit-2.0/src/luajit test.lua + +If the test suite passes, the final line printed to stdout will be +`NNN passed`, and the exit code of the process will be zero. If any tests +fail, the exit code will be non-zero. If the failures caused catastrophic +termination of the entire process (such as a segmentation fault or assertion +failure), the last line of output will be number and name of the test which +caused the catastrophe. If the failures weren't catastrophic, the penultimate +line of output will be `NNN passed, MMM failed`, and the last line will say +how to re-run just the failing tests. + +Various flags and options can be passed to `test.lua` to control which tests +are run, and in which order. Run `lua test.lua --help` for details. + +## Structure of the test suite ## + +The test suite consists of a directory tree. Within said tree there are various +`.lua` files, and within every `.lua` file there are one or more tests. Every +directory in the tree contains a file called `index`, which enumerates the +members of the directory which contribute to the test suite (this is done to +avoid an external dependency for directory iteration, and to allow metadata to +be specified at the file/directory level). Every `.lua` file is structured as: + + << local definitions >> + << test 1 >> + ... + << test N >> + +Where `<< local definitions >>` consists of Lua code to act as a common prefix +for every test in the file, and each `<< test >>` looks like: + + do --- <> <> + << code >> + end + +Where `<>` is (almost) free-form, and `<< code >>` is Lua code which +performs some actions and probably calls `assert` alot. The `<>` +fragment can be used to specify the conditions under which the test should +or should not run, to adjust the environment in which the test is run, and to +allow key/value pairs to be specified in a standard place/format. + +Some common pieces of metadata are: + * `+luajit>=2.1` - The test requires LuaJIT 2.1 or later to run. + * `+lua<5.2` - The test requires Lua 5.1 or earlier to run (all versions of + LuaJIT report themselves as 5.1). + * `+ffi` - The test requires the `ffi` library to be present. + * `+bit` - The test requires the `bit` library to be present. + * `+jit` - The test requires JIT compilation be available and turned on. + * `+slow` - The test is too slow to run as part of the default suite, and + thus requires `+slow` to be specified on the command line. + * `!private_G` - The test modifies globals, and thus needs to be run with a + private (shallow) copy of `_G`. + +Lua code which is common across all (or some) tests in a single file can be +written at the top of the file as part of `<< local definitions >>`. Code +which is common across multiple files lives in the `common` directory, and +is pulled into applicable tests by means of `local x = require"common.x"`. + +It is intended that most `.lua` files in the test suite can be exercised +without the test runner by just passing them to a Lua interpreter. In such +cases, metadata is ignored, the tests are executed from top to bottom, and +any failure results in later tests not running. Also note that the test +runner converts every test into a separate function, which causes references +to local definitions to become upvalue accesses rather than local variable +accesses - in some cases this can cause differences in behaviour. + +## Extending the test suite ## + +First of all, decide where your new test(s) should live. This might be within +an existing `.lua` file, or might involve creating new files and/or directories. +If new files are created, remember to add them to the `index` file of the +enclosing directory. If new directories are created, remember to create an +`index` file in said directory, and add the new directory to the `index` file +in the parent directory. + +Once you've decided in which file the test(s) should live, you're ready to add +your test(s) to said file. Each test should be wrapped in a `do`/`end` block, +and given some kind of name (after the `do` keyword, as in `do --- <>`). +The test should call `assert` to confirm whether the thing under test is +behaving, or otherwise raise an error if the thing under test is misbehaving. +Your test(s) should not write to stdout or stderr, nor should they mutate +global state. After your test(s) are written, you should be able to determine +which features they require, and put on metadata appropriately. + +## Completing the tidy-up of the test suite ## + +Some files/directories in this directory need some thought: + + * `common/ffi_util.inc` - Needs renaming and being made `require`-able. + * `lib/ffi` - Tests need converting to structure described in this document. + * `lib/table/misc.lua` - Tests need organising and converting to structure + described in this document. + * `misc` - Tests need organising and converting to structure described in + this document. + * `src` - C/C++ source which needs to be compiled into a dynamic library and + loaded for certain tests. Need to figure out a good way of handling + C/C++ source. + * `sysdep` - Need to figure out a good way of handling these. + * `unportable` - Need to figure out a good way of handling these. + +After that, consult the README file by Mike in the directory above this one. diff --git a/test/bc/constov.lua b/test/bc/constov.lua index de1e2a6d5d..5827840b46 100644 --- a/test/bc/constov.lua +++ b/test/bc/constov.lua @@ -1,16 +1,16 @@ - -do --- float - local t = { "local x\n" } - for i=2,65537 do t[i] = "x="..i..".5\n" end - assert(loadstring(table.concat(t)) ~= nil) - t[65538] = "x=65538.5" - assert(loadstring(table.concat(t)) == nil) -end - -do --- int - local t = { "local x\n" } - for i=2,65537 do t[i] = "x='"..i.."'\n" end - assert(loadstring(table.concat(t)) ~= nil) - t[65538] = "x='65538'" - assert(loadstring(table.concat(t)) == nil) -end + +do --- float + local t = { "local x\n" } + for i=2,65537 do t[i] = "x="..i..".5\n" end + assert(loadstring(table.concat(t)) ~= nil) + t[65538] = "x=65538.5" + assert(loadstring(table.concat(t)) == nil) +end + +do --- int + local t = { "local x\n" } + for i=2,65537 do t[i] = "x='"..i.."'\n" end + assert(loadstring(table.concat(t)) ~= nil) + t[65538] = "x='65538'" + assert(loadstring(table.concat(t)) == nil) +end diff --git a/test/bc/index b/test/bc/index index 3954d57600..dead10f555 100644 --- a/test/bc/index +++ b/test/bc/index @@ -1 +1 @@ -constov.lua +slow +constov.lua +slow diff --git a/test/common/expect_error.lua b/test/common/expect_error.lua index 7643416720..e155090eda 100644 --- a/test/common/expect_error.lua +++ b/test/common/expect_error.lua @@ -1,16 +1,16 @@ -return function(f, msg) - local ok, err = pcall(f) - if ok then error("error check unexpectedly succeeded", 2) end - if msg then - if type(err) ~= "string" then - error("error check failed with "..tostring(err), 2) - end - local line, err2 = string.match(err, ":(%d*): (.*)") - if err2 ~= msg then - if err2:gsub(" got no value", " got nil") == msg then - return - end - error("error check failed with "..err, 2) - end - end -end +return function(f, msg) + local ok, err = pcall(f) + if ok then error("error check unexpectedly succeeded", 2) end + if msg then + if type(err) ~= "string" then + error("error check failed with "..tostring(err), 2) + end + local line, err2 = string.match(err, ":(%d*): (.*)") + if err2 ~= msg then + if err2:gsub(" got no value", " got nil") == msg then + return + end + error("error check failed with "..err, 2) + end + end +end diff --git a/test/common/test_runner_canary.lua b/test/common/test_runner_canary.lua index 138ad84c9e..fc9cadc637 100644 --- a/test/common/test_runner_canary.lua +++ b/test/common/test_runner_canary.lua @@ -1 +1 @@ -return "canary is alive" +return "canary is alive" diff --git a/test/computations.lua b/test/computations.lua index 439febee7e..4fce7fcd4a 100644 --- a/test/computations.lua +++ b/test/computations.lua @@ -1,113 +1,113 @@ -do --- ack - local function Ack(m, n) - if m == 0 then return n+1 end - if n == 0 then return Ack(m-1, 1) end - return Ack(m-1, (Ack(m, n-1))) -- The parentheses are deliberate. - end - - assert(Ack(3,5) == 253) -end - -do --- ack notail - local function Ack(m, n) - if m == 0 then return n+1 end - if n == 0 then return Ack(m-1, 1) end - return (Ack(m-1, (Ack(m, n-1)))) -- The parentheses are deliberate. - end - - assert(Ack(3,5) == 253) -end - -do --- fac - local function fac(n) - local x = 1 - for i=2,n do - x = x * i - end - return x - end - - assert(fac(10) == 3628800) -end - -do --- ffib - local function ffib(n) - if n <= 2 then return n,1 end - if n % 2 == 1 then - local a,b = ffib((n-1)/2) - local aa = a*a - return aa+a*(b+b), aa+b*b - else - local a,b = ffib(n/2-1) - local ab = a+b - return ab*ab+a*a, (ab+b)*a - end - end - - local function fib(n) - return (ffib(n)) - end - - assert(fib(40) == 165580141) - assert(fib(39) == 102334155) - assert(fib(77) == 8944394323791464) -end - -do --- fib - local function fib(n) - if n < 2 then return 1 end - return fib(n-2) + fib(n-1) - end - - assert(fib(27) == 317811) -end - -do --- nsieve - local function nsieve(m) - local isPrime = {} - for i=2,m do isPrime[i] = true end - local count = 0 - for i=2,m do - if isPrime[i] then - for k=i+i,m,i do isPrime[k] = false end - count = count + 1 - end - end - return count - end - - assert(nsieve(100) == 25) - assert(nsieve(12345) == 1474) -end - -do --- recsum - local function sum(n) - if n == 1 then return 1 end - return n + sum(n-1) - end - - for i=1, 100 do - assert(sum(i) == i*(i+1)/2) - end -end - -do --- recsump - local abs = math.abs - local function sum(n) - if n == 1 then return 1 end - return abs(n + sum(n-1)) - end - - for i=1, 100 do - assert(sum(i) == i*(i+1)/2) - end -end - -do --- tak - local function tak(x, y, z) - if y >= x then return z end - return tak(tak(x-1, y, z), tak(y-1, z, x), (tak(z-1, x, y))) - end - - assert(tak(21, 14, 7) == 14) -end +do --- ack + local function Ack(m, n) + if m == 0 then return n+1 end + if n == 0 then return Ack(m-1, 1) end + return Ack(m-1, (Ack(m, n-1))) -- The parentheses are deliberate. + end + + assert(Ack(3,5) == 253) +end + +do --- ack notail + local function Ack(m, n) + if m == 0 then return n+1 end + if n == 0 then return Ack(m-1, 1) end + return (Ack(m-1, (Ack(m, n-1)))) -- The parentheses are deliberate. + end + + assert(Ack(3,5) == 253) +end + +do --- fac + local function fac(n) + local x = 1 + for i=2,n do + x = x * i + end + return x + end + + assert(fac(10) == 3628800) +end + +do --- ffib + local function ffib(n) + if n <= 2 then return n,1 end + if n % 2 == 1 then + local a,b = ffib((n-1)/2) + local aa = a*a + return aa+a*(b+b), aa+b*b + else + local a,b = ffib(n/2-1) + local ab = a+b + return ab*ab+a*a, (ab+b)*a + end + end + + local function fib(n) + return (ffib(n)) + end + + assert(fib(40) == 165580141) + assert(fib(39) == 102334155) + assert(fib(77) == 8944394323791464) +end + +do --- fib + local function fib(n) + if n < 2 then return 1 end + return fib(n-2) + fib(n-1) + end + + assert(fib(27) == 317811) +end + +do --- nsieve + local function nsieve(m) + local isPrime = {} + for i=2,m do isPrime[i] = true end + local count = 0 + for i=2,m do + if isPrime[i] then + for k=i+i,m,i do isPrime[k] = false end + count = count + 1 + end + end + return count + end + + assert(nsieve(100) == 25) + assert(nsieve(12345) == 1474) +end + +do --- recsum + local function sum(n) + if n == 1 then return 1 end + return n + sum(n-1) + end + + for i=1, 100 do + assert(sum(i) == i*(i+1)/2) + end +end + +do --- recsump + local abs = math.abs + local function sum(n) + if n == 1 then return 1 end + return abs(n + sum(n-1)) + end + + for i=1, 100 do + assert(sum(i) == i*(i+1)/2) + end +end + +do --- tak + local function tak(x, y, z) + if y >= x then return z end + return tak(tak(x-1, y, z), tak(y-1, z, x), (tak(z-1, x, y))) + end + + assert(tak(21, 14, 7) == 14) +end diff --git a/test/index b/test/index index 256118eb9b..bd4081e39e 100644 --- a/test/index +++ b/test/index @@ -1,6 +1,6 @@ -lang -lib -bc +luajit>=2 -computations.lua -trace +jit -opt +jit +lang +lib +bc +luajit>=2 +computations.lua +trace +jit +opt +jit diff --git a/test/lang/andor.lua b/test/lang/andor.lua index dc4296faa3..55b2c756e5 100644 --- a/test/lang/andor.lua +++ b/test/lang/andor.lua @@ -1,61 +1,61 @@ -do --- smoke - local x = ((1 or false) and true) or false - assert(x == true) -end - -do --- allcases - local basiccases = { - {"nil", nil}, - {"false", false}, - {"true", true}, - {"10", 10}, - } - - local mem = {basiccases} -- for memoization - - local function allcases (n) - if mem[n] then return mem[n] end - local res = {} - -- include all smaller cases - for _, v in ipairs(allcases(n - 1)) do - res[#res + 1] = v - end - for i = 1, n - 1 do - for _, v1 in ipairs(allcases(i)) do - for _, v2 in ipairs(allcases(n - i)) do - res[#res + 1] = { - "(" .. v1[1] .. " and " .. v2[1] .. ")", - v1[2] and v2[2] - } - res[#res + 1] = { - "(" .. v1[1] .. " or " .. v2[1] .. ")", - v1[2] or v2[2] - } - end - end - end - mem[n] = res -- memoize - return res - end - - for _, v in pairs(allcases(4)) do - local res = (loadstring or load)("return " .. v[1])() - if res ~= v[2] then - error(string.format("bad conditional eval\n%s\nexpected: %s\ngot: %s", - v[1], tostring(v[2]), tostring(res))) - end - end -end - -do --- tracefib - -- 0001 KSHORT 1 2 - -- 0002 ISGE 0 1 - -- 0003 JMP 1 => 0006 - -- 0004 KSHORT 1 1 - -- 0005 JMP 1 => 0013 - -- ^^^ must be 2 - -- fix in jmp_patchtestreg - local function fib(n) return (n < 2) and 1 or fib(n-1)+fib(n-2) end - assert(fib(5) == 8) - assert(fib(10) == 89) -end +do --- smoke + local x = ((1 or false) and true) or false + assert(x == true) +end + +do --- allcases + local basiccases = { + {"nil", nil}, + {"false", false}, + {"true", true}, + {"10", 10}, + } + + local mem = {basiccases} -- for memoization + + local function allcases (n) + if mem[n] then return mem[n] end + local res = {} + -- include all smaller cases + for _, v in ipairs(allcases(n - 1)) do + res[#res + 1] = v + end + for i = 1, n - 1 do + for _, v1 in ipairs(allcases(i)) do + for _, v2 in ipairs(allcases(n - i)) do + res[#res + 1] = { + "(" .. v1[1] .. " and " .. v2[1] .. ")", + v1[2] and v2[2] + } + res[#res + 1] = { + "(" .. v1[1] .. " or " .. v2[1] .. ")", + v1[2] or v2[2] + } + end + end + end + mem[n] = res -- memoize + return res + end + + for _, v in pairs(allcases(4)) do + local res = (loadstring or load)("return " .. v[1])() + if res ~= v[2] then + error(string.format("bad conditional eval\n%s\nexpected: %s\ngot: %s", + v[1], tostring(v[2]), tostring(res))) + end + end +end + +do --- tracefib + -- 0001 KSHORT 1 2 + -- 0002 ISGE 0 1 + -- 0003 JMP 1 => 0006 + -- 0004 KSHORT 1 1 + -- 0005 JMP 1 => 0013 + -- ^^^ must be 2 + -- fix in jmp_patchtestreg + local function fib(n) return (n < 2) and 1 or fib(n-1)+fib(n-2) end + assert(fib(5) == 8) + assert(fib(10) == 89) +end diff --git a/test/lang/assignment.lua b/test/lang/assignment.lua index 34c7b52df7..e9745ef667 100644 --- a/test/lang/assignment.lua +++ b/test/lang/assignment.lua @@ -1,46 +1,46 @@ -local assert = assert - -do --- local - local a, b, c - a, b, c = 0, 1 - assert(a == 0) - assert(b == 1) - assert(c == nil) - a, b = a+1, b+1, a+b - assert(a == 1) - assert(b == 2) - a, b, c = 0 - assert(a == 0) - assert(b == nil) - assert(c == nil) -end - -do --- global !private_G - a, b, c = 0, 1 - assert(a == 0) - assert(b == 1) - assert(c == nil) - a, b = a+1, b+1, a+b - assert(a == 1) - assert(b == 2) - a, b, c = 0 - assert(a == 0) - assert(b == nil) - assert(c == nil) -end - -do --- local lhs in key on lhs - local a = {} - local i = 3 - i, a[i] = i+1, 20 - assert(i == 4) - assert(a[3] == 20) -end - -do --- global lhs in key on lhs !private_G - a = {} - i = 3 - i, a[i] = i+1, 20 - assert(i == 4) - assert(a[3] == 20) -end +local assert = assert + +do --- local + local a, b, c + a, b, c = 0, 1 + assert(a == 0) + assert(b == 1) + assert(c == nil) + a, b = a+1, b+1, a+b + assert(a == 1) + assert(b == 2) + a, b, c = 0 + assert(a == 0) + assert(b == nil) + assert(c == nil) +end + +do --- global !private_G + a, b, c = 0, 1 + assert(a == 0) + assert(b == 1) + assert(c == nil) + a, b = a+1, b+1, a+b + assert(a == 1) + assert(b == 2) + a, b, c = 0 + assert(a == 0) + assert(b == nil) + assert(c == nil) +end + +do --- local lhs in key on lhs + local a = {} + local i = 3 + i, a[i] = i+1, 20 + assert(i == 4) + assert(a[3] == 20) +end + +do --- global lhs in key on lhs !private_G + a = {} + i = 3 + i, a[i] = i+1, 20 + assert(i == 4) + assert(a[3] == 20) +end diff --git a/test/lang/compare.lua b/test/lang/compare.lua index 9b38ff5e2f..09c5488d15 100644 --- a/test/lang/compare.lua +++ b/test/lang/compare.lua @@ -1,323 +1,323 @@ -local function lt(x, y) - if x < y then return true else return false end -end - -local function le(x, y) - if x <= y then return true else return false end -end - -local function gt(x, y) - if x > y then return true else return false end -end - -local function ge(x, y) - if x >= y then return true else return false end -end - -local function eq(x, y) - if x == y then return true else return false end -end - -local function ne(x, y) - if x ~= y then return true else return false end -end - - -local function ltx1(x) - if x < 1 then return true else return false end -end - -local function lex1(x) - if x <= 1 then return true else return false end -end - -local function gtx1(x) - if x > 1 then return true else return false end -end - -local function gex1(x) - if x >= 1 then return true else return false end -end - -local function eqx1(x) - if x == 1 then return true else return false end -end - -local function nex1(x) - if x ~= 1 then return true else return false end -end - - -local function lt1x(x) - if 1 < x then return true else return false end -end - -local function le1x(x) - if 1 <= x then return true else return false end -end - -local function gt1x(x) - if 1 > x then return true else return false end -end - -local function ge1x(x) - if 1 >= x then return true else return false end -end - -local function eq1x(x) - if 1 == x then return true else return false end -end - -local function ne1x(x) - if 1 ~= x then return true else return false end -end - -local function check(a, b) - if a ~= b then - error("check failed with "..tostring(a).." ~= "..tostring(b), 2) - end -end - -do --- 1,2 - local x,y = 1,2 - - check(xy, false) - check(x>=y, false) - check(x==y, false) - check(x~=y, true) - - check(1y, false) - check(1>=y, false) - check(1==y, false) - check(1~=y, true) - - check(x<2, true) - check(x<=2, true) - check(x>2, false) - check(x>=2, false) - check(x==2, false) - check(x~=2, true) - - check(lt(x,y), true) - check(le(x,y), true) - check(gt(x,y), false) - check(ge(x,y), false) - check(eq(y,x), false) - check(ne(y,x), true) -end - -do --- 2,1 - local x,y = 2,1 - - check(xy, true) - check(x>=y, true) - check(x==y, false) - check(x~=y, true) - - check(2y, true) - check(2>=y, true) - check(2==y, false) - check(2~=y, true) - - check(x<1, false) - check(x<=1, false) - check(x>1, true) - check(x>=1, true) - check(x==1, false) - check(x~=1, true) - - check(lt(x,y), false) - check(le(x,y), false) - check(gt(x,y), true) - check(ge(x,y), true) - check(eq(y,x), false) - check(ne(y,x), true) -end - -do --- 1,1 - local x,y = 1,1 - - check(xy, false) - check(x>=y, true) - check(x==y, true) - check(x~=y, false) - - check(1y, false) - check(1>=y, true) - check(1==y, true) - check(1~=y, false) - - check(x<1, false) - check(x<=1, true) - check(x>1, false) - check(x>=1, true) - check(x==1, true) - check(x~=1, false) - - check(lt(x,y), false) - check(le(x,y), true) - check(gt(x,y), false) - check(ge(x,y), true) - check(eq(y,x), true) - check(ne(y,x), false) -end - -do --- 2 - check(lt1x(2), true) - check(le1x(2), true) - check(gt1x(2), false) - check(ge1x(2), false) - check(eq1x(2), false) - check(ne1x(2), true) - - check(ltx1(2), false) - check(lex1(2), false) - check(gtx1(2), true) - check(gex1(2), true) - check(eqx1(2), false) - check(nex1(2), true) -end - -do --- 1 - check(lt1x(1), false) - check(le1x(1), true) - check(gt1x(1), false) - check(ge1x(1), true) - check(eq1x(1), true) - check(ne1x(1), false) - - check(ltx1(1), false) - check(lex1(1), true) - check(gtx1(1), false) - check(gex1(1), true) - check(eqx1(1), true) - check(nex1(1), false) -end - -do --- 0 - check(lt1x(0), false) - check(le1x(0), false) - check(gt1x(0), true) - check(ge1x(0), true) - check(eq1x(0), false) - check(ne1x(0), true) - - check(ltx1(0), true) - check(lex1(0), true) - check(gtx1(0), false) - check(gex1(0), false) - check(eqx1(0), false) - check(nex1(0), true) -end - -do --- pcall - assert(not pcall(function() - local a, b = 10.5, nil - return a < b - end)) -end - -do --- bit +bit - for i=1,100 do - assert(bit.tobit(i+0x7fffffff) < 0) - end - for i=1,100 do - assert(bit.tobit(i+0x7fffffff) <= 0) - end -end - -do --- string 1 255 - local a = "\255\255\255\255" - local b = "\1\1\1\1" - - assert(a > b) - assert(a > b) - assert(a >= b) - assert(b <= a) -end - -do --- String comparisons: - local function str_cmp(a, b, lt, gt, le, ge) - assert(ab == gt) - assert(a<=b == le) - assert(a>=b == ge) - assert((not (ab)) == (not gt)) - assert((not (a<=b)) == (not le)) - assert((not (a>=b)) == (not ge)) - end - - local function str_lo(a, b) - str_cmp(a, b, true, false, true, false) - end - - local function str_eq(a, b) - str_cmp(a, b, false, false, true, true) - end - - local function str_hi(a, b) - str_cmp(a, b, false, true, false, true) - end - - str_lo("a", "b") - str_eq("a", "a") - str_hi("b", "a") - - str_lo("a", "aa") - str_hi("aa", "a") - - str_lo("a", "a\0") - str_hi("a\0", "a") -end - -do --- obj_eq/ne - local function obj_eq(a, b) - assert(a==b == true) - assert(a~=b == false) - end - - local function obj_ne(a, b) - assert(a==b == false) - assert(a~=b == true) - end - - obj_eq(nil, nil) - obj_ne(nil, false) - obj_ne(nil, true) - - obj_ne(false, nil) - obj_eq(false, false) - obj_ne(false, true) - - obj_ne(true, nil) - obj_ne(true, false) - obj_eq(true, true) - - obj_eq(1, 1) - obj_ne(1, 2) - obj_ne(2, 1) - - obj_eq("a", "a") - obj_ne("a", "b") - obj_ne("a", 1) - obj_ne(1, "a") - - local t, t2 = {}, {} - obj_eq(t, t) - obj_ne(t, t2) - obj_ne(t, 1) - obj_ne(t, "") -end +local function lt(x, y) + if x < y then return true else return false end +end + +local function le(x, y) + if x <= y then return true else return false end +end + +local function gt(x, y) + if x > y then return true else return false end +end + +local function ge(x, y) + if x >= y then return true else return false end +end + +local function eq(x, y) + if x == y then return true else return false end +end + +local function ne(x, y) + if x ~= y then return true else return false end +end + + +local function ltx1(x) + if x < 1 then return true else return false end +end + +local function lex1(x) + if x <= 1 then return true else return false end +end + +local function gtx1(x) + if x > 1 then return true else return false end +end + +local function gex1(x) + if x >= 1 then return true else return false end +end + +local function eqx1(x) + if x == 1 then return true else return false end +end + +local function nex1(x) + if x ~= 1 then return true else return false end +end + + +local function lt1x(x) + if 1 < x then return true else return false end +end + +local function le1x(x) + if 1 <= x then return true else return false end +end + +local function gt1x(x) + if 1 > x then return true else return false end +end + +local function ge1x(x) + if 1 >= x then return true else return false end +end + +local function eq1x(x) + if 1 == x then return true else return false end +end + +local function ne1x(x) + if 1 ~= x then return true else return false end +end + +local function check(a, b) + if a ~= b then + error("check failed with "..tostring(a).." ~= "..tostring(b), 2) + end +end + +do --- 1,2 + local x,y = 1,2 + + check(xy, false) + check(x>=y, false) + check(x==y, false) + check(x~=y, true) + + check(1y, false) + check(1>=y, false) + check(1==y, false) + check(1~=y, true) + + check(x<2, true) + check(x<=2, true) + check(x>2, false) + check(x>=2, false) + check(x==2, false) + check(x~=2, true) + + check(lt(x,y), true) + check(le(x,y), true) + check(gt(x,y), false) + check(ge(x,y), false) + check(eq(y,x), false) + check(ne(y,x), true) +end + +do --- 2,1 + local x,y = 2,1 + + check(xy, true) + check(x>=y, true) + check(x==y, false) + check(x~=y, true) + + check(2y, true) + check(2>=y, true) + check(2==y, false) + check(2~=y, true) + + check(x<1, false) + check(x<=1, false) + check(x>1, true) + check(x>=1, true) + check(x==1, false) + check(x~=1, true) + + check(lt(x,y), false) + check(le(x,y), false) + check(gt(x,y), true) + check(ge(x,y), true) + check(eq(y,x), false) + check(ne(y,x), true) +end + +do --- 1,1 + local x,y = 1,1 + + check(xy, false) + check(x>=y, true) + check(x==y, true) + check(x~=y, false) + + check(1y, false) + check(1>=y, true) + check(1==y, true) + check(1~=y, false) + + check(x<1, false) + check(x<=1, true) + check(x>1, false) + check(x>=1, true) + check(x==1, true) + check(x~=1, false) + + check(lt(x,y), false) + check(le(x,y), true) + check(gt(x,y), false) + check(ge(x,y), true) + check(eq(y,x), true) + check(ne(y,x), false) +end + +do --- 2 + check(lt1x(2), true) + check(le1x(2), true) + check(gt1x(2), false) + check(ge1x(2), false) + check(eq1x(2), false) + check(ne1x(2), true) + + check(ltx1(2), false) + check(lex1(2), false) + check(gtx1(2), true) + check(gex1(2), true) + check(eqx1(2), false) + check(nex1(2), true) +end + +do --- 1 + check(lt1x(1), false) + check(le1x(1), true) + check(gt1x(1), false) + check(ge1x(1), true) + check(eq1x(1), true) + check(ne1x(1), false) + + check(ltx1(1), false) + check(lex1(1), true) + check(gtx1(1), false) + check(gex1(1), true) + check(eqx1(1), true) + check(nex1(1), false) +end + +do --- 0 + check(lt1x(0), false) + check(le1x(0), false) + check(gt1x(0), true) + check(ge1x(0), true) + check(eq1x(0), false) + check(ne1x(0), true) + + check(ltx1(0), true) + check(lex1(0), true) + check(gtx1(0), false) + check(gex1(0), false) + check(eqx1(0), false) + check(nex1(0), true) +end + +do --- pcall + assert(not pcall(function() + local a, b = 10.5, nil + return a < b + end)) +end + +do --- bit +bit + for i=1,100 do + assert(bit.tobit(i+0x7fffffff) < 0) + end + for i=1,100 do + assert(bit.tobit(i+0x7fffffff) <= 0) + end +end + +do --- string 1 255 + local a = "\255\255\255\255" + local b = "\1\1\1\1" + + assert(a > b) + assert(a > b) + assert(a >= b) + assert(b <= a) +end + +do --- String comparisons: + local function str_cmp(a, b, lt, gt, le, ge) + assert(ab == gt) + assert(a<=b == le) + assert(a>=b == ge) + assert((not (ab)) == (not gt)) + assert((not (a<=b)) == (not le)) + assert((not (a>=b)) == (not ge)) + end + + local function str_lo(a, b) + str_cmp(a, b, true, false, true, false) + end + + local function str_eq(a, b) + str_cmp(a, b, false, false, true, true) + end + + local function str_hi(a, b) + str_cmp(a, b, false, true, false, true) + end + + str_lo("a", "b") + str_eq("a", "a") + str_hi("b", "a") + + str_lo("a", "aa") + str_hi("aa", "a") + + str_lo("a", "a\0") + str_hi("a\0", "a") +end + +do --- obj_eq/ne + local function obj_eq(a, b) + assert(a==b == true) + assert(a~=b == false) + end + + local function obj_ne(a, b) + assert(a==b == false) + assert(a~=b == true) + end + + obj_eq(nil, nil) + obj_ne(nil, false) + obj_ne(nil, true) + + obj_ne(false, nil) + obj_eq(false, false) + obj_ne(false, true) + + obj_ne(true, nil) + obj_ne(true, false) + obj_eq(true, true) + + obj_eq(1, 1) + obj_ne(1, 2) + obj_ne(2, 1) + + obj_eq("a", "a") + obj_ne("a", "b") + obj_ne("a", 1) + obj_ne(1, "a") + + local t, t2 = {}, {} + obj_eq(t, t) + obj_ne(t, t2) + obj_ne(t, 1) + obj_ne(t, "") +end diff --git a/test/lang/compare_nan.lua b/test/lang/compare_nan.lua index 1468f83e1d..878f39a7f5 100644 --- a/test/lang/compare_nan.lua +++ b/test/lang/compare_nan.lua @@ -1,99 +1,99 @@ - -local function check(a, b) - if a ~= b then - error("check failed with "..tostring(a).." ~= "..tostring(b), 2) - end -end - -local nan, one = 0/0, 1 - -do --- nan nan - check(nannan, false) - check(nan>=nan, false) - check(nan==nan, false) - check(nan~=nan, true) -end - -do --- nan one - check(nanone, false) - check(nan>=one, false) - check(nan==one, false) - check(nan~=one, true) -end - -do --- one nan - check(onenan, false) - check(one>=nan, false) - check(one==nan, false) - check(one~=nan, true) -end - -do --- nan 1 - check(nan<1, false) - check(nan<=1, false) - check(nan>1, false) - check(nan>=1, false) - check(nan==1, false) - check(nan~=1, true) -end - -do --- 1 nan - check(1nan, false) - check(1>=nan, false) - check(1==nan, false) - check(1~=nan, true) -end - -do --- not nan nan - check(not (nannan), true) - check(not (nan>=nan), true) - check(not (nan==nan), true) - check(not (nan~=nan), false) -end - -do --- not nan one - check(not (nanone), true) - check(not (nan>=one), true) - check(not (nan==one), true) - check(not (nan~=one), false) -end - -do --- not one nan - check(not (onenan), true) - check(not (one>=nan), true) - check(not (one==nan), true) - check(not (one~=nan), false) -end - -do --- not nan 1 - check(not (nan<1), true) - check(not (nan<=1), true) - check(not (nan>1), true) - check(not (nan>=1), true) - check(not (nan==1), true) - check(not (nan~=1), false) -end - -do --- not 1 nan - check(not (1nan), true) - check(not (1>=nan), true) - check(not (1==nan), true) - check(not (1~=nan), false) -end - + +local function check(a, b) + if a ~= b then + error("check failed with "..tostring(a).." ~= "..tostring(b), 2) + end +end + +local nan, one = 0/0, 1 + +do --- nan nan + check(nannan, false) + check(nan>=nan, false) + check(nan==nan, false) + check(nan~=nan, true) +end + +do --- nan one + check(nanone, false) + check(nan>=one, false) + check(nan==one, false) + check(nan~=one, true) +end + +do --- one nan + check(onenan, false) + check(one>=nan, false) + check(one==nan, false) + check(one~=nan, true) +end + +do --- nan 1 + check(nan<1, false) + check(nan<=1, false) + check(nan>1, false) + check(nan>=1, false) + check(nan==1, false) + check(nan~=1, true) +end + +do --- 1 nan + check(1nan, false) + check(1>=nan, false) + check(1==nan, false) + check(1~=nan, true) +end + +do --- not nan nan + check(not (nannan), true) + check(not (nan>=nan), true) + check(not (nan==nan), true) + check(not (nan~=nan), false) +end + +do --- not nan one + check(not (nanone), true) + check(not (nan>=one), true) + check(not (nan==one), true) + check(not (nan~=one), false) +end + +do --- not one nan + check(not (onenan), true) + check(not (one>=nan), true) + check(not (one==nan), true) + check(not (one~=nan), false) +end + +do --- not nan 1 + check(not (nan<1), true) + check(not (nan<=1), true) + check(not (nan>1), true) + check(not (nan>=1), true) + check(not (nan==1), true) + check(not (nan~=1), false) +end + +do --- not 1 nan + check(not (1nan), true) + check(not (1>=nan), true) + check(not (1==nan), true) + check(not (1~=nan), false) +end + diff --git a/test/lang/concat.lua b/test/lang/concat.lua index c7af134f92..50dd450c99 100644 --- a/test/lang/concat.lua +++ b/test/lang/concat.lua @@ -1,101 +1,101 @@ -do --- Constant folding - local y - for i=1,100 do y = "a".."b" end - assert(y == "ab") - for i=1,100 do y = "ab"..(1).."cd"..(1.5) end - assert(y == "ab1cd1.5") -end - -do --- Fuse conversions to strings - local y - local x = "a" - for i=1,100 do y = x..i end - assert(y == "a100") - x = "a" - for i=1.5,100.5 do y = x..i end - assert(y == "a100.5") -end - -do --- Fuse string construction - local y - local x = "abc" - for i=1,100 do y = "x"..string.sub(x, 2) end - assert(y == "xbc") -end - -do --- CSE, sink - local y - local x = "a" - for i=1,100 do y = x.."b" end - assert(y == "ab") -end - -do --- CSE, two buffers in parallel, no sink - local y, z - local x1, x2 = "xx", "yy" - for i=1,100 do y = x1.."a"..x1; z = x1.."a"..x2 end - assert(y == "xxaxx") - assert(z == "xxayy") - x1 = "xx" - for i=1,100 do y = x1.."a"..x1; z = x1.."b"..x1 end - assert(y == "xxaxx") - assert(z == "xxbxx") -end - -do --- Append, CSE - local y, z - local x = "a" - for i=1,100 do - y = x.."b" - y = y.."c" - end - assert(y == "abc") - x = "a" - for i=1,100 do - y = x.."b" - z = y.."c" - end - assert(y == "ab") - assert(z == "abc") - x = "a" - for i=1,100 do - y = x.."b" - z = y..i - end - assert(y == "ab") - assert(z == "ab100") -end - -do --- Append, FOLD - local a, b = "x" - for i=1,100 do b = (a.."y").."" end - assert(b == "xy") -end - -do --- Append to buffer, sink - local x = "a" - for i=1,100 do x = x.."b" end - assert(x == "a"..string.rep("b", 100)) - x = "a" - for i=1,100 do x = x.."bc" end - assert(x == "a"..string.rep("bc", 100)) -end - -do --- Append to two buffers in parallel, no append, no sink - local y, z = "xx", "yy" - for i=1,100 do y = y.."a"; z = z.."b" end - assert(y == "xx"..string.rep("a", 100)) - assert(z == "yy"..string.rep("b", 100)) -end - -do --- Sink into side-exit - local x = "a" - local z - for i=1,200 do - local y = x.."b" - if i > 100 then - z = y..i - end - end - assert(z == "ab200") -end +do --- Constant folding + local y + for i=1,100 do y = "a".."b" end + assert(y == "ab") + for i=1,100 do y = "ab"..(1).."cd"..(1.5) end + assert(y == "ab1cd1.5") +end + +do --- Fuse conversions to strings + local y + local x = "a" + for i=1,100 do y = x..i end + assert(y == "a100") + x = "a" + for i=1.5,100.5 do y = x..i end + assert(y == "a100.5") +end + +do --- Fuse string construction + local y + local x = "abc" + for i=1,100 do y = "x"..string.sub(x, 2) end + assert(y == "xbc") +end + +do --- CSE, sink + local y + local x = "a" + for i=1,100 do y = x.."b" end + assert(y == "ab") +end + +do --- CSE, two buffers in parallel, no sink + local y, z + local x1, x2 = "xx", "yy" + for i=1,100 do y = x1.."a"..x1; z = x1.."a"..x2 end + assert(y == "xxaxx") + assert(z == "xxayy") + x1 = "xx" + for i=1,100 do y = x1.."a"..x1; z = x1.."b"..x1 end + assert(y == "xxaxx") + assert(z == "xxbxx") +end + +do --- Append, CSE + local y, z + local x = "a" + for i=1,100 do + y = x.."b" + y = y.."c" + end + assert(y == "abc") + x = "a" + for i=1,100 do + y = x.."b" + z = y.."c" + end + assert(y == "ab") + assert(z == "abc") + x = "a" + for i=1,100 do + y = x.."b" + z = y..i + end + assert(y == "ab") + assert(z == "ab100") +end + +do --- Append, FOLD + local a, b = "x" + for i=1,100 do b = (a.."y").."" end + assert(b == "xy") +end + +do --- Append to buffer, sink + local x = "a" + for i=1,100 do x = x.."b" end + assert(x == "a"..string.rep("b", 100)) + x = "a" + for i=1,100 do x = x.."bc" end + assert(x == "a"..string.rep("bc", 100)) +end + +do --- Append to two buffers in parallel, no append, no sink + local y, z = "xx", "yy" + for i=1,100 do y = y.."a"; z = z.."b" end + assert(y == "xx"..string.rep("a", 100)) + assert(z == "yy"..string.rep("b", 100)) +end + +do --- Sink into side-exit + local x = "a" + local z + for i=1,200 do + local y = x.."b" + if i > 100 then + z = y..i + end + end + assert(z == "ab200") +end diff --git a/test/lang/constant/index b/test/lang/constant/index index 61db9ef549..e738357d79 100644 --- a/test/lang/constant/index +++ b/test/lang/constant/index @@ -1,2 +1,2 @@ -number.lua -table.lua +number.lua +table.lua diff --git a/test/lang/constant/number.lua b/test/lang/constant/number.lua index c0514e7389..fb67356e7f 100644 --- a/test/lang/constant/number.lua +++ b/test/lang/constant/number.lua @@ -1,12 +1,12 @@ -do --- exp - assert(1e5 == 100000) - assert(1e+5 == 100000) - assert(1e-5 == 0.00001) -end - -do --- hex exp +hexfloat !lex - assert(0xe+9 == 23) - assert(0xep9 == 7168) - assert(0xep+9 == 7168) - assert(0xep-9 == 0.02734375) -end +do --- exp + assert(1e5 == 100000) + assert(1e+5 == 100000) + assert(1e-5 == 0.00001) +end + +do --- hex exp +hexfloat !lex + assert(0xe+9 == 23) + assert(0xep9 == 7168) + assert(0xep+9 == 7168) + assert(0xep-9 == 0.02734375) +end diff --git a/test/lang/constant/table.lua b/test/lang/constant/table.lua index 1e8e3de22c..899d0f671c 100644 --- a/test/lang/constant/table.lua +++ b/test/lang/constant/table.lua @@ -1,15 +1,15 @@ - -do --- tnew - local a = nil - local b = {} - local t = {[true] = a, [false] = b or 1} - assert(t[true] == nil) - assert(t[false] == b) -end - -do --- tdup - local b = {} - local t = {[true] = nil, [false] = b or 1} - assert(t[true] == nil) - assert(t[false] == b) -end + +do --- tnew + local a = nil + local b = {} + local t = {[true] = a, [false] = b or 1} + assert(t[true] == nil) + assert(t[false] == b) +end + +do --- tdup + local b = {} + local t = {[true] = nil, [false] = b or 1} + assert(t[true] == nil) + assert(t[false] == b) +end diff --git a/test/lang/coroutine.lua b/test/lang/coroutine.lua index 769e64ffab..405135c968 100644 --- a/test/lang/coroutine.lua +++ b/test/lang/coroutine.lua @@ -1,8 +1,8 @@ -do --- traceback - local co = coroutine.create(function() - local x = nil - local y = x.x - end) - assert(coroutine.resume(co) == false) - debug.traceback(co) -end +do --- traceback + local co = coroutine.create(function() + local x = nil + local y = x.x + end) + assert(coroutine.resume(co) == false) + debug.traceback(co) +end diff --git a/test/lang/for.lua b/test/lang/for.lua index b16508e1d3..4982b32b95 100644 --- a/test/lang/for.lua +++ b/test/lang/for.lua @@ -1,45 +1,45 @@ -do --- direction - local a,b,c = 10,1,-1 - for i=1,20 do - if c == -1 then - a,b,c = 1,10,1 - else - a,b,c = 10,1,-1 - end - local x = 0 - for i=a,b,c do for j=1,10 do end x=x+1 end - assert(x == 10) - end -end - -do --- coerce to integer at 13 - local n = 1 - local x = 0 - for i=1,20 do - for j=n,100 do x = x + 1 end - if i == 13 then n = "2" end - end - assert(x == 1993) -end - -do --- coerce to integer at 10 - local n = 1 - local x = 0 - for i=1,20 do - for j=n,100 do x = x + 1 end - if i == 10 then n = "2" end - end - assert(x == 1990) -end - -do --- cannot coerce to integer at 10 - local function f() - local n = 1 - local x = 0 - for i=1,20 do - for j=n,100 do x = x + 1 end - if i == 10 then n = "x" end - end - end - assert(not pcall(f)) -end +do --- direction + local a,b,c = 10,1,-1 + for i=1,20 do + if c == -1 then + a,b,c = 1,10,1 + else + a,b,c = 10,1,-1 + end + local x = 0 + for i=a,b,c do for j=1,10 do end x=x+1 end + assert(x == 10) + end +end + +do --- coerce to integer at 13 + local n = 1 + local x = 0 + for i=1,20 do + for j=n,100 do x = x + 1 end + if i == 13 then n = "2" end + end + assert(x == 1993) +end + +do --- coerce to integer at 10 + local n = 1 + local x = 0 + for i=1,20 do + for j=n,100 do x = x + 1 end + if i == 10 then n = "2" end + end + assert(x == 1990) +end + +do --- cannot coerce to integer at 10 + local function f() + local n = 1 + local x = 0 + for i=1,20 do + for j=n,100 do x = x + 1 end + if i == 10 then n = "x" end + end + end + assert(not pcall(f)) +end diff --git a/test/lang/gc.lua b/test/lang/gc.lua index 0c50450646..f820418084 100644 --- a/test/lang/gc.lua +++ b/test/lang/gc.lua @@ -1,30 +1,30 @@ -do --- rechain - local k - - collectgarbage() - - local t = {} - t.ac = 1 - - t.nn = 1 - t.mm = 1 - t.nn = nil - t.mm = nil - - k = "a".."i" - t[k] = 2 - - t.ad = 3 - - t[k] = nil - k = nil - - collectgarbage() - - k = "a".."f" - t[k] = 4 - - t.ak = 5 - - assert(t[k] == 4) -end +do --- rechain + local k + + collectgarbage() + + local t = {} + t.ac = 1 + + t.nn = 1 + t.mm = 1 + t.nn = nil + t.mm = nil + + k = "a".."i" + t[k] = 2 + + t.ad = 3 + + t[k] = nil + k = nil + + collectgarbage() + + k = "a".."f" + t[k] = 4 + + t.ak = 5 + + assert(t[k] == 4) +end diff --git a/test/lang/index b/test/lang/index index b466207f7c..df5ed675c5 100644 --- a/test/lang/index +++ b/test/lang/index @@ -1,17 +1,17 @@ -andor.lua -assignment.lua -compare.lua -compare_nan.lua -constant -for.lua -length.lua -modulo.lua -concat.lua -self.lua -upvalue -coroutine.lua -tail_recursion.lua -vararg_jit.lua -gc.lua -goto.lua +goto -meta +andor.lua +assignment.lua +compare.lua +compare_nan.lua +constant +for.lua +length.lua +modulo.lua +concat.lua +self.lua +upvalue +coroutine.lua +tail_recursion.lua +vararg_jit.lua +gc.lua +goto.lua +goto +meta diff --git a/test/lang/length.lua b/test/lang/length.lua index 1974b8257c..67c68ae70a 100644 --- a/test/lang/length.lua +++ b/test/lang/length.lua @@ -1,23 +1,23 @@ - -do --- length increasing and decreasing in loop - local t = {} - for i=1,100 do t[#t+1] = i end - assert(#t == 100) - for i=1,100 do t[#t] = nil end - assert(#t == 0) -end - -do --- length increasing in loop with existing element - local t = {} - t[90] = 999 - for i=1,100 do t[#t+1] = i end - assert(#t > 100 and t[#t] == 100) -end - -do --- length decreasing in loop with erased element - local t = {} - for i=1,100 do t[i] = i end - t[10] = nil - for i=1,99 do t[#t] = nil end - assert(#t == 0) -end + +do --- length increasing and decreasing in loop + local t = {} + for i=1,100 do t[#t+1] = i end + assert(#t == 100) + for i=1,100 do t[#t] = nil end + assert(#t == 0) +end + +do --- length increasing in loop with existing element + local t = {} + t[90] = 999 + for i=1,100 do t[#t+1] = i end + assert(#t > 100 and t[#t] == 100) +end + +do --- length decreasing in loop with erased element + local t = {} + for i=1,100 do t[i] = i end + t[10] = nil + for i=1,99 do t[#t] = nil end + assert(#t == 0) +end diff --git a/test/lang/meta/index b/test/lang/meta/index index 174eae08d7..f114e78d04 100644 --- a/test/lang/meta/index +++ b/test/lang/meta/index @@ -1,14 +1,14 @@ -arith.lua -arith_jit.lua -call.lua -cat.lua -comp.lua -comp_jit.lua -eq.lua -eq_jit.lua -framegap.lua -index.lua -len.lua -newindex.lua -nomm.lua -debuginfo.lua +arith.lua +arith_jit.lua +call.lua +cat.lua +comp.lua +comp_jit.lua +eq.lua +eq_jit.lua +framegap.lua +index.lua +len.lua +newindex.lua +nomm.lua +debuginfo.lua diff --git a/test/lang/self.lua b/test/lang/self.lua index 48f58d30c8..d37466642d 100644 --- a/test/lang/self.lua +++ b/test/lang/self.lua @@ -1,19 +1,19 @@ -do --- trivial setget - local t = {} - - function t:set(x) - self.a=x - end - - function t:get() - return self.a - end - - t:set("foo") - assert(t:get() == "foo") - assert(t.a == "foo") - - t:set(42) - assert(t:get() == 42) - assert(t.a == 42) -end +do --- trivial setget + local t = {} + + function t:set(x) + self.a=x + end + + function t:get() + return self.a + end + + t:set("foo") + assert(t:get() == "foo") + assert(t.a == "foo") + + t:set(42) + assert(t:get() == 42) + assert(t.a == 42) +end diff --git a/test/lang/tail_recursion.lua b/test/lang/tail_recursion.lua index 22bab72f95..78f071fd22 100644 --- a/test/lang/tail_recursion.lua +++ b/test/lang/tail_recursion.lua @@ -1,20 +1,20 @@ -do --- self - local tr1 - function tr1(n) - if n <= 0 then return 0 end - return tr1(n-1) - end - assert(tr1(200) == 0) -end - -do --- mutual - local tr1, tr2 - function tr1(n) - if n <= 0 then return 0 end - return tr2(n-1) - end - function tr2(n) - return tr1(n) - end - assert(tr2(200) == 0) -end +do --- self + local tr1 + function tr1(n) + if n <= 0 then return 0 end + return tr1(n-1) + end + assert(tr1(200) == 0) +end + +do --- mutual + local tr1, tr2 + function tr1(n) + if n <= 0 then return 0 end + return tr2(n-1) + end + function tr2(n) + return tr1(n) + end + assert(tr2(200) == 0) +end diff --git a/test/lang/upvalue/closure.lua b/test/lang/upvalue/closure.lua index 34083223c7..faa4de1c3c 100644 --- a/test/lang/upvalue/closure.lua +++ b/test/lang/upvalue/closure.lua @@ -1,84 +1,84 @@ -do --- for - local z1, z2 - for i=1,10 do - local function f() return i end - if z1 then z2 = f else z1 = f end - end - assert(z1() == 1) - assert(z2() == 10) -end - -do --- while - local z1, z2 - local i = 1 - while i <= 10 do - local j = i - local function f() return j end - if z1 then z2 = f else z1 = f end - i = i + 1 - end - assert(z1() == 1) - assert(z2() == 10) -end - -do --- repeat - local z1, z2 - local i = 1 - repeat - local j = i - local function f() return j end - if z1 then z2 = f else z1 = f end - i = i + 1 - until i > 10 - assert(z1() == 1) - assert(z2() == 10) -end - -do --- func - local function ff(x) - return function() return x end - end - local z1, z2 - for i=1,10 do - local f = ff(i) - if z1 then z2 = f else z1 = f end - end - assert(z1() == 1) - assert(z2() == 10) -end - -do --- recursive type change - local function f1(a) - if a > 0 then - local b = f1(a - 1) - return function() - if type(b) == "function" then - return a + b() - end - return a + b - end - end - return a - end - - local function f2(a) - return f1(a)() - end - - for i = 1, 41 do - local r = f2(4) + f2(4) - assert(r == 20) - end -end - -do --- Don't mark upvalue as immutable if written to after prototype definition - local x = 1 - local function f() - local y = 0 - for i=1,100 do y=y+x end - return y - end - assert(f() == 100) - x = 2 - assert(f() == 200) -end +do --- for + local z1, z2 + for i=1,10 do + local function f() return i end + if z1 then z2 = f else z1 = f end + end + assert(z1() == 1) + assert(z2() == 10) +end + +do --- while + local z1, z2 + local i = 1 + while i <= 10 do + local j = i + local function f() return j end + if z1 then z2 = f else z1 = f end + i = i + 1 + end + assert(z1() == 1) + assert(z2() == 10) +end + +do --- repeat + local z1, z2 + local i = 1 + repeat + local j = i + local function f() return j end + if z1 then z2 = f else z1 = f end + i = i + 1 + until i > 10 + assert(z1() == 1) + assert(z2() == 10) +end + +do --- func + local function ff(x) + return function() return x end + end + local z1, z2 + for i=1,10 do + local f = ff(i) + if z1 then z2 = f else z1 = f end + end + assert(z1() == 1) + assert(z2() == 10) +end + +do --- recursive type change + local function f1(a) + if a > 0 then + local b = f1(a - 1) + return function() + if type(b) == "function" then + return a + b() + end + return a + b + end + end + return a + end + + local function f2(a) + return f1(a)() + end + + for i = 1, 41 do + local r = f2(4) + f2(4) + assert(r == 20) + end +end + +do --- Don't mark upvalue as immutable if written to after prototype definition + local x = 1 + local function f() + local y = 0 + for i=1,100 do y=y+x end + return y + end + assert(f() == 100) + x = 2 + assert(f() == 200) +end diff --git a/test/lang/upvalue/index b/test/lang/upvalue/index index 58931de651..3c170db922 100644 --- a/test/lang/upvalue/index +++ b/test/lang/upvalue/index @@ -1 +1 @@ -closure.lua +closure.lua diff --git a/test/lib/base/assert.lua b/test/lib/base/assert.lua index 6f1ef548c1..9c30ba029c 100644 --- a/test/lib/base/assert.lua +++ b/test/lib/base/assert.lua @@ -1,33 +1,33 @@ -do --- pass through one - assert(assert(true) == true) - assert(assert(3) == 3) - assert(assert(1.5) == 1.5) - assert(assert("x") == "x") - local f = function() end - assert(assert(f) == f) - local t = {} - assert(assert(t) == t) -end - -do --- pass through many - local b, c = assert("b", "c") - assert(b == "b") - assert(c == "c") - local d, e, f, g = assert("d", 5, true, false) - assert(d == "d") - assert(e == 5) - assert(f == true) - assert(g == false) -end - -do --- raise on nil - local ok, err = pcall(assert, nil) - assert(ok == false) - assert(err == "assertion failed!") -end - -do --- raise on false - local ok, err = pcall(assert, false, "msg") - assert(ok == false) - assert(err == "msg") -end +do --- pass through one + assert(assert(true) == true) + assert(assert(3) == 3) + assert(assert(1.5) == 1.5) + assert(assert("x") == "x") + local f = function() end + assert(assert(f) == f) + local t = {} + assert(assert(t) == t) +end + +do --- pass through many + local b, c = assert("b", "c") + assert(b == "b") + assert(c == "c") + local d, e, f, g = assert("d", 5, true, false) + assert(d == "d") + assert(e == 5) + assert(f == true) + assert(g == false) +end + +do --- raise on nil + local ok, err = pcall(assert, nil) + assert(ok == false) + assert(err == "assertion failed!") +end + +do --- raise on false + local ok, err = pcall(assert, false, "msg") + assert(ok == false) + assert(err == "msg") +end diff --git a/test/lib/base/error.lua b/test/lib/base/error.lua index 74aac75437..9193085423 100644 --- a/test/lib/base/error.lua +++ b/test/lib/base/error.lua @@ -1,43 +1,43 @@ -do --- no message - local ok, msg = pcall(error) - assert(ok == false) - assert(msg == nil) -end - -do --- level 0 - local ok, msg = pcall(error, "emsg", 0) - assert(ok == false) - assert(msg == "emsg") -end - -do --- default level - local ok, msg = pcall(error, "emsg") - assert(ok == false) - assert(msg == "emsg") -end - -do --- default level in xpcall - local line - local ok, msg = xpcall(function() - local x - line = debug.getinfo(1, "l").currentline; error("emsg") - end, function(m) - assert(debug.getlocal(3, 1) == "x") - return m .."xp" - end) - assert(ok == false) - assert(msg:find("^.-:".. line ..": emsgxp$")) -end - -do --- level 2 in xpcall - local line - local ok, msg = xpcall(function() - local function f() error("emsg", 2) end - line = debug.getinfo(1, "l").currentline; f() - end, function(m) - assert(debug.getlocal(4, 1) == "f") - return m .."xp2" - end) - assert(ok == false) - assert(msg:find("^.-:".. line ..": emsgxp2$")) -end +do --- no message + local ok, msg = pcall(error) + assert(ok == false) + assert(msg == nil) +end + +do --- level 0 + local ok, msg = pcall(error, "emsg", 0) + assert(ok == false) + assert(msg == "emsg") +end + +do --- default level + local ok, msg = pcall(error, "emsg") + assert(ok == false) + assert(msg == "emsg") +end + +do --- default level in xpcall + local line + local ok, msg = xpcall(function() + local x + line = debug.getinfo(1, "l").currentline; error("emsg") + end, function(m) + assert(debug.getlocal(3, 1) == "x") + return m .."xp" + end) + assert(ok == false) + assert(msg:find("^.-:".. line ..": emsgxp$")) +end + +do --- level 2 in xpcall + local line + local ok, msg = xpcall(function() + local function f() error("emsg", 2) end + line = debug.getinfo(1, "l").currentline; f() + end, function(m) + assert(debug.getlocal(4, 1) == "f") + return m .."xp2" + end) + assert(ok == false) + assert(msg:find("^.-:".. line ..": emsgxp2$")) +end diff --git a/test/lib/base/getfenv.lua b/test/lib/base/getfenv.lua index 29e288c13f..9c00ed7cd1 100644 --- a/test/lib/base/getfenv.lua +++ b/test/lib/base/getfenv.lua @@ -1,13 +1,13 @@ -do --- untitled - local x - local function f() - x = getfenv(0) - end - local co = coroutine.create(f) - local t = {} - debug.setfenv(co, t) - for i=1,50 do f() f() f() end - assert(x == getfenv(0)) - coroutine.resume(co) - assert(x == t) -end +do --- untitled + local x + local function f() + x = getfenv(0) + end + local co = coroutine.create(f) + local t = {} + debug.setfenv(co, t) + for i=1,50 do f() f() f() end + assert(x == getfenv(0)) + coroutine.resume(co) + assert(x == t) +end diff --git a/test/lib/base/index b/test/lib/base/index index a78cff8dcb..942c53c0f2 100644 --- a/test/lib/base/index +++ b/test/lib/base/index @@ -1,11 +1,11 @@ -assert.lua -error.lua -getfenv.lua +lua<5.2 -getsetmetatable.lua -ipairs.lua -next.lua -pairs.lua -pcall_jit.lua -select.lua -tonumber_tostring.lua -xpcall_jit.lua +compat5.2 +assert.lua +error.lua +getfenv.lua +lua<5.2 +getsetmetatable.lua +ipairs.lua +next.lua +pairs.lua +pcall_jit.lua +select.lua +tonumber_tostring.lua +xpcall_jit.lua +compat5.2 diff --git a/test/lib/base/ipairs.lua b/test/lib/base/ipairs.lua index 66ac9f0ae3..a9de087e26 100644 --- a/test/lib/base/ipairs.lua +++ b/test/lib/base/ipairs.lua @@ -1,41 +1,41 @@ -do --- small integer values - local t = { 4,5,6,7,8,9,10 } - local n = 0 - for i,v in ipairs(t) do - assert(v == i+3) - n = n + 1 - end - assert(n == 7) -end - -do --- jit key=value - local t = {} - for i=1,100 do t[i]=i end - local n = 0 - for i,v in ipairs(t) do - assert(i == v) - n = n + 1 - end - assert(n == 100) -end - -do --- untitled - local t = {} - local o = {{}, {}} - for i=1,100 do - local c = i.."" - t[i] = c - o[1][c] = i - o[2][c] = i - end - o[1]["90"] = nil - - local n = 0 - for _, c in ipairs(t) do - for i = 1, 2 do - o[i][c] = o[i][c] or 1 - n = n + 1 - end - end - assert(n == 200) -end +do --- small integer values + local t = { 4,5,6,7,8,9,10 } + local n = 0 + for i,v in ipairs(t) do + assert(v == i+3) + n = n + 1 + end + assert(n == 7) +end + +do --- jit key=value + local t = {} + for i=1,100 do t[i]=i end + local n = 0 + for i,v in ipairs(t) do + assert(i == v) + n = n + 1 + end + assert(n == 100) +end + +do --- untitled + local t = {} + local o = {{}, {}} + for i=1,100 do + local c = i.."" + t[i] = c + o[1][c] = i + o[2][c] = i + end + o[1]["90"] = nil + + local n = 0 + for _, c in ipairs(t) do + for i = 1, 2 do + o[i][c] = o[i][c] or 1 + n = n + 1 + end + end + assert(n == 200) +end diff --git a/test/lib/base/next.lua b/test/lib/base/next.lua index af0ee6642c..0e40615afe 100644 --- a/test/lib/base/next.lua +++ b/test/lib/base/next.lua @@ -1,17 +1,17 @@ -do --- _G 1 - local ok, err = pcall(next, _G, 1) - assert(not ok) - local ok, err = pcall(function() next(_G, 1) end) - assert(not ok) -end - -do --- as iterator - local t = { foo = 9, bar = 10, 4, 5, 6 } - local r = {} - local function dummy() end - local function f(next) - for k,v in next,t,nil do r[#r+1] = k; if v == 5 then f(dummy) end end - end - f(next) - assert(#r == 5) -end +do --- _G 1 + local ok, err = pcall(next, _G, 1) + assert(not ok) + local ok, err = pcall(function() next(_G, 1) end) + assert(not ok) +end + +do --- as iterator + local t = { foo = 9, bar = 10, 4, 5, 6 } + local r = {} + local function dummy() end + local function f(next) + for k,v in next,t,nil do r[#r+1] = k; if v == 5 then f(dummy) end end + end + f(next) + assert(#r == 5) +end diff --git a/test/lib/base/select.lua b/test/lib/base/select.lua index 5c8ac55170..8278e5e999 100644 --- a/test/lib/base/select.lua +++ b/test/lib/base/select.lua @@ -1,105 +1,105 @@ - -do --- select # --- Test whether select("#", 3, 4) returns the correct number of arguments. - local x = 0 - for i=1,100 do - x = x + select("#", 3, 4) - end - assert(x == 200) -end - -do --- select modf --- Test whether select("#", func()) also works with func returning multiple values - local x = 0 - math.frexp(3) - for i=1,100 do - x = x + select("#", math.modf(i)) - end - assert(x == 200) -end - -do --- select 1 - local x = 0 - for i=1,100 do - x = x + select(1, i) - end - assert(x == 5050) -end - -do --- select 2 - local x, y = 0, 0 - for i=1,100 do - local a, b = select(2, 1, i, i+10) - x = x + a - y = y + b - end - assert(x == 5050 and y == 6050) -end - -do --- select vararg # - local function f(a, ...) - local x = 0 - for i=1,select('#', ...) do - x = x + select(i, ...) - end - assert(x == a) - end - for i=1,100 do - f(1, 1) - f(3, 1, 2) - f(15, 1, 2, 3, 4, 5) - f(0) - f(3200, string.byte(string.rep(" ", 100), 1, 100)) - end -end - -do --- select vararg i - local function f(a, ...) - local x = 0 - for i=1,20 do - local b = select(i, ...) - if b then x = x + b else x = x + 9 end - end - assert(x == a) - end - for i=1,100 do - f(172, 1) - f(165, 1, 2) - f(150, 1, 2, 3, 4, 5) - f(180) - f(640, string.byte(string.rep(" ", 100), 1, 100)) - end -end - -do --- select vararg 4 - local function f(a, ...) - local x = 0 - for i=1,20 do - local b = select(4, ...) - if b then x = x + b else x = x + 9 end - end - assert(x == a) - end - for i=1,100 do - f(180, 1) - f(180, 1, 2) - f(80, 1, 2, 3, 4, 5) - f(180) - f(640, string.byte(string.rep(" ", 100), 1, 100)) - end -end - -do --- varg-select specialisation requires guard against select - local select = select - local exptyp = "number" - local function f(...) - for i = 1, 100 do - assert(type((select('#', ...))) == exptyp) - if i == 75 then - select = function() return "" end - exptyp = "string" - end - end - end - f(1) -end + +do --- select # +-- Test whether select("#", 3, 4) returns the correct number of arguments. + local x = 0 + for i=1,100 do + x = x + select("#", 3, 4) + end + assert(x == 200) +end + +do --- select modf +-- Test whether select("#", func()) also works with func returning multiple values + local x = 0 + math.frexp(3) + for i=1,100 do + x = x + select("#", math.modf(i)) + end + assert(x == 200) +end + +do --- select 1 + local x = 0 + for i=1,100 do + x = x + select(1, i) + end + assert(x == 5050) +end + +do --- select 2 + local x, y = 0, 0 + for i=1,100 do + local a, b = select(2, 1, i, i+10) + x = x + a + y = y + b + end + assert(x == 5050 and y == 6050) +end + +do --- select vararg # + local function f(a, ...) + local x = 0 + for i=1,select('#', ...) do + x = x + select(i, ...) + end + assert(x == a) + end + for i=1,100 do + f(1, 1) + f(3, 1, 2) + f(15, 1, 2, 3, 4, 5) + f(0) + f(3200, string.byte(string.rep(" ", 100), 1, 100)) + end +end + +do --- select vararg i + local function f(a, ...) + local x = 0 + for i=1,20 do + local b = select(i, ...) + if b then x = x + b else x = x + 9 end + end + assert(x == a) + end + for i=1,100 do + f(172, 1) + f(165, 1, 2) + f(150, 1, 2, 3, 4, 5) + f(180) + f(640, string.byte(string.rep(" ", 100), 1, 100)) + end +end + +do --- select vararg 4 + local function f(a, ...) + local x = 0 + for i=1,20 do + local b = select(4, ...) + if b then x = x + b else x = x + 9 end + end + assert(x == a) + end + for i=1,100 do + f(180, 1) + f(180, 1, 2) + f(80, 1, 2, 3, 4, 5) + f(180) + f(640, string.byte(string.rep(" ", 100), 1, 100)) + end +end + +do --- varg-select specialisation requires guard against select + local select = select + local exptyp = "number" + local function f(...) + for i = 1, 100 do + assert(type((select('#', ...))) == exptyp) + if i == 75 then + select = function() return "" end + exptyp = "string" + end + end + end + f(1) +end diff --git a/test/lib/base/xpcall_jit.lua b/test/lib/base/xpcall_jit.lua index 32c8e1c472..f4993cc619 100644 --- a/test/lib/base/xpcall_jit.lua +++ b/test/lib/base/xpcall_jit.lua @@ -1,83 +1,83 @@ -local function tr(err) return "tr"..err end - -do --- square sum - local function f(x) return x*x end - local x = 0 - for i=1,100 do - local ok1, ok2, ok3, y = xpcall(xpcall, tr, xpcall, tr, f, tr, i) - if not ok1 or not ok2 or not ok3 then break end - x = x + y - end - assert(x == 338350) -end - -do --- sqrt square sum - local x = 0 - for i=1,100 do - local ok1, ok2, ok3, y = xpcall(xpcall, tr, xpcall, tr, math.sqrt, tr, i*i) - if not ok1 or not ok2 or not ok3 then break end - x = x + y - end - assert(x == 5050) -end - -do --- sum with error - local function f(x) - if x >= 150 then error("test", 0) end - return x end - local x = 0 - for i=1,200 do - local ok1, ok2, ok3, y = xpcall(xpcall, tr, xpcall, tr, f, tr, i) - if not ok1 or not ok2 or not ok3 then - assert(ok1 and ok2 and not ok3) - assert(y == "trtest") - break - end - x = x + y - end - assert(x == 11175) -end - -do --- square with error - local function f(x) - if x >= 150 then return x*x end - return x - end - local x = 0 - for i=1,200 do - local ok1, ok2, ok3, y = xpcall(xpcall, tr, xpcall, tr, f, tr, i) - if not ok1 or not ok2 or not ok3 then break end - x = x + y - end - assert(x == 1584100) -end - -do --- sum or square with error - local function f(x) - if x >= 150 then - if x >= 175 then error("test", 0) end - return x*x - end - return x - end - local x = 0 - for i=1,200 do - local ok1, ok2, ok3, y = xpcall(xpcall, tr, xpcall, tr, f, tr, i) - if not ok1 or not ok2 or not ok3 then - assert(ok1 and ok2 and not ok3) - assert(y == "trtest") - -- note: no break, so we get an exit to interpreter - else - x = x + y - end - end - assert(x == 668575) -end - -do --- xpcall swap after recorder error - local x = 0 - for i=1,100 do - local ok1, ok2, ok3, err = xpcall(xpcall, tr, xpcall, tr, error, tr, "test", 0) - assert(ok1 and ok2 and not ok3 and err == "trtest") - end -end +local function tr(err) return "tr"..err end + +do --- square sum + local function f(x) return x*x end + local x = 0 + for i=1,100 do + local ok1, ok2, ok3, y = xpcall(xpcall, tr, xpcall, tr, f, tr, i) + if not ok1 or not ok2 or not ok3 then break end + x = x + y + end + assert(x == 338350) +end + +do --- sqrt square sum + local x = 0 + for i=1,100 do + local ok1, ok2, ok3, y = xpcall(xpcall, tr, xpcall, tr, math.sqrt, tr, i*i) + if not ok1 or not ok2 or not ok3 then break end + x = x + y + end + assert(x == 5050) +end + +do --- sum with error + local function f(x) + if x >= 150 then error("test", 0) end + return x end + local x = 0 + for i=1,200 do + local ok1, ok2, ok3, y = xpcall(xpcall, tr, xpcall, tr, f, tr, i) + if not ok1 or not ok2 or not ok3 then + assert(ok1 and ok2 and not ok3) + assert(y == "trtest") + break + end + x = x + y + end + assert(x == 11175) +end + +do --- square with error + local function f(x) + if x >= 150 then return x*x end + return x + end + local x = 0 + for i=1,200 do + local ok1, ok2, ok3, y = xpcall(xpcall, tr, xpcall, tr, f, tr, i) + if not ok1 or not ok2 or not ok3 then break end + x = x + y + end + assert(x == 1584100) +end + +do --- sum or square with error + local function f(x) + if x >= 150 then + if x >= 175 then error("test", 0) end + return x*x + end + return x + end + local x = 0 + for i=1,200 do + local ok1, ok2, ok3, y = xpcall(xpcall, tr, xpcall, tr, f, tr, i) + if not ok1 or not ok2 or not ok3 then + assert(ok1 and ok2 and not ok3) + assert(y == "trtest") + -- note: no break, so we get an exit to interpreter + else + x = x + y + end + end + assert(x == 668575) +end + +do --- xpcall swap after recorder error + local x = 0 + for i=1,100 do + local ok1, ok2, ok3, err = xpcall(xpcall, tr, xpcall, tr, error, tr, "test", 0) + assert(ok1 and ok2 and not ok3 and err == "trtest") + end +end diff --git a/test/lib/bit.lua b/test/lib/bit.lua index a37b28a37e..1adf550781 100644 --- a/test/lib/bit.lua +++ b/test/lib/bit.lua @@ -1,98 +1,98 @@ -local bit = require"bit" -local byte, ipairs, tostring, pcall = string.byte, ipairs, tostring, pcall - -local vb = { - 0, 1, -1, 2, -2, 0x12345678, 0x87654321, - 0x33333333, 0x77777777, 0x55aa55aa, 0xaa55aa55, - 0x7fffffff, 0x80000000, 0xffffffff -} - -local function cksum(name, s, r) - local z = 0 - for i=1,#s do z = (z + byte(s, i)*i) % 2147483629 end - if z ~= r then - error("bit."..name.." test failed (got "..z..", expected "..r..")", 0) - end -end - -local function check_unop(name, r) - local f = bit[name] - local s = "" - if pcall(f) or pcall(f, "z") or pcall(f, true) then - error("bit."..name.." fails to detect argument errors", 0) - end - for _,x in ipairs(vb) do s = s..","..tostring(f(x)) end - cksum(name, s, r) -end - -local function check_binop(name, r) - local f = bit[name] - local s = "" - if pcall(f) or pcall(f, "z") or pcall(f, true) then - error("bit."..name.." fails to detect argument errors", 0) - end - for _,x in ipairs(vb) do - for _2,y in ipairs(vb) do s = s..","..tostring(f(x, y)) --[[io.write(_, " ", _2, " ", x, " ", y, " ", f(x, y), "\n")]] end - end - cksum(name, s, r) -end - -local function check_binop_range(name, r, yb, ye) - local f = bit[name] - local s = "" - if pcall(f) or pcall(f, "z") or pcall(f, true) or pcall(f, 1, true) then - error("bit."..name.." fails to detect argument errors", 0) - end - for _,x in ipairs(vb) do - for y=yb,ye do s = s..","..tostring(f(x, y)) end - end - cksum(name, s, r) -end - -local function check_shift(name, r) - check_binop_range(name, r, 0, 31) -end - -do --- Minimal sanity checks. - assert(0x7fffffff == 2147483647, "broken hex literals") - assert(0xffffffff == -1 or 0xffffffff == 2^32-1, "broken hex literals") - assert(tostring(-1) == "-1", "broken tostring()") - assert(tostring(0xffffffff) == "-1" or tostring(0xffffffff) == "4294967295", "broken tostring()") -end - -do --- Basic argument processing. - assert(bit.tobit(1) == 1) - assert(bit.band(1) == 1) - assert(bit.bxor(1,2) == 3) - assert(bit.bor(1,2,4,8,16,32,64,128) == 255) -end - -do --- unop test vectors - check_unop("tobit", 277312) - check_unop("bnot", 287870) - check_unop("bswap", 307611) -end - -do --- binop test vectors - check_binop("band", 41206764) - check_binop("bor", 51253663) - check_binop("bxor", 79322427) -end - -do --- shift test vectors - check_shift("lshift", 325260344) - check_shift("rshift", 139061800) - check_shift("arshift", 111364720) - check_shift("rol", 302401155) - check_shift("ror", 302316761) -end - -do --- tohex test vectors - check_binop_range("tohex", 47880306, -8, 8) -end - -do --- Don't propagate TOBIT narrowing across two conversions. - local tobit = bit.tobit - local k = 0x8000000000003 - for i=1,100 do assert(tobit(k % (2^32)) == 3) end -end +local bit = require"bit" +local byte, ipairs, tostring, pcall = string.byte, ipairs, tostring, pcall + +local vb = { + 0, 1, -1, 2, -2, 0x12345678, 0x87654321, + 0x33333333, 0x77777777, 0x55aa55aa, 0xaa55aa55, + 0x7fffffff, 0x80000000, 0xffffffff +} + +local function cksum(name, s, r) + local z = 0 + for i=1,#s do z = (z + byte(s, i)*i) % 2147483629 end + if z ~= r then + error("bit."..name.." test failed (got "..z..", expected "..r..")", 0) + end +end + +local function check_unop(name, r) + local f = bit[name] + local s = "" + if pcall(f) or pcall(f, "z") or pcall(f, true) then + error("bit."..name.." fails to detect argument errors", 0) + end + for _,x in ipairs(vb) do s = s..","..tostring(f(x)) end + cksum(name, s, r) +end + +local function check_binop(name, r) + local f = bit[name] + local s = "" + if pcall(f) or pcall(f, "z") or pcall(f, true) then + error("bit."..name.." fails to detect argument errors", 0) + end + for _,x in ipairs(vb) do + for _2,y in ipairs(vb) do s = s..","..tostring(f(x, y)) --[[io.write(_, " ", _2, " ", x, " ", y, " ", f(x, y), "\n")]] end + end + cksum(name, s, r) +end + +local function check_binop_range(name, r, yb, ye) + local f = bit[name] + local s = "" + if pcall(f) or pcall(f, "z") or pcall(f, true) or pcall(f, 1, true) then + error("bit."..name.." fails to detect argument errors", 0) + end + for _,x in ipairs(vb) do + for y=yb,ye do s = s..","..tostring(f(x, y)) end + end + cksum(name, s, r) +end + +local function check_shift(name, r) + check_binop_range(name, r, 0, 31) +end + +do --- Minimal sanity checks. + assert(0x7fffffff == 2147483647, "broken hex literals") + assert(0xffffffff == -1 or 0xffffffff == 2^32-1, "broken hex literals") + assert(tostring(-1) == "-1", "broken tostring()") + assert(tostring(0xffffffff) == "-1" or tostring(0xffffffff) == "4294967295", "broken tostring()") +end + +do --- Basic argument processing. + assert(bit.tobit(1) == 1) + assert(bit.band(1) == 1) + assert(bit.bxor(1,2) == 3) + assert(bit.bor(1,2,4,8,16,32,64,128) == 255) +end + +do --- unop test vectors + check_unop("tobit", 277312) + check_unop("bnot", 287870) + check_unop("bswap", 307611) +end + +do --- binop test vectors + check_binop("band", 41206764) + check_binop("bor", 51253663) + check_binop("bxor", 79322427) +end + +do --- shift test vectors + check_shift("lshift", 325260344) + check_shift("rshift", 139061800) + check_shift("arshift", 111364720) + check_shift("rol", 302401155) + check_shift("ror", 302316761) +end + +do --- tohex test vectors + check_binop_range("tohex", 47880306, -8, 8) +end + +do --- Don't propagate TOBIT narrowing across two conversions. + local tobit = bit.tobit + local k = 0x8000000000003 + for i=1,100 do assert(tobit(k % (2^32)) == 3) end +end diff --git a/test/lib/contents.lua b/test/lib/contents.lua index bb9f2cf79f..b2a1a7adbc 100644 --- a/test/lib/contents.lua +++ b/test/lib/contents.lua @@ -1,151 +1,151 @@ -local function check(m, expected, exclude) - local t = {} - local ex = {} - if exclude then - for k in exclude:gmatch"[^:]+" do - ex[k] = true - end - end - for k in pairs(m) do - if not ex[k] then - t[#t+1] = tostring(k) - end - end - table.sort(t) - local got = table.concat(t, ":") - if got ~= expected then - error("got: \""..got.."\"\nexpected: \""..expected.."\"", 2) - end -end - -do --- base - check(_G, "_G:_VERSION:arg:assert:collectgarbage:coroutine:debug:dofile:error:getmetatable:io:ipairs:load:loadfile:math:next:os:package:pairs:pcall:print:rawequal:rawget:rawset:require:select:setmetatable:string:table:tonumber:tostring:type:xpcall", "rawlen:bit:bit32:jit:gcinfo:setfenv:getfenv:loadstring:unpack:module:newproxy") -end - -do --- pre-5.2 base +lua<5.2 - assert(gcinfo) - assert(setfenv) - assert(getfenv) - assert(loadstring) - assert(unpack) - assert(module) - assert(newproxy) -end - -do --- 5.2 base +lua>=5.2 - assert(not gcinfo) - assert(not setfenv) - assert(not getfenv) - assert(not loadstring) - assert(not unpack) - assert(not module) - assert(not newproxy) -end - -do --- pre-5.2 base rawlen -compat5.2 - assert(not rawlen) -end - -do --- 5.2 base rawlen +compat5.2 - assert(rawlen) -end - -do --- math - check(math, "abs:acos:asin:atan:atan2:ceil:cos:cosh:deg:exp:floor:fmod:frexp:huge:ldexp:log:max:min:modf:pi:pow:rad:random:randomseed:sin:sinh:sqrt:tan:tanh", "log10:mod") -end - -do --- pre-5.2 math +lua<5.2 - assert(math.mod) - assert(math.log10) -end - -do --- 5.2 math +lua>=5.2 - assert(not math.mod) - assert(not math.log10) -end - -do --- string - check(string, "byte:char:dump:find:format:gmatch:gsub:len:lower:match:rep:reverse:sub:upper", "gfind") -end - -do --- pre-5.2 string +lua<5.2 - assert(string.gfind) -end - -do --- 5.2 string +lua>=5.2 - assert(not string.gfind) -end - -do --- pre-5.2 table +lua<5.2 - check(table, "concat:foreach:foreachi:getn:insert:maxn:remove:sort", "pack:unpack:setn:new") -end - -do --- 5.2 table +lua>=5.2 - check(table, "concat:insert:pack:remove:sort:unpack") -end - -do --- pre-5.2 table.pack -compat5.2 - assert(not table.pack) - assert(not table.unpack) -end - -do --- 5.2 table.pack +compat5.2 - assert(table.pack) - assert(table.unpack) -end - -do --- io - check(io, "close:flush:input:lines:open:output:popen:read:stderr:stdin:stdout:tmpfile:type:write") -end - -do --- io file - check(debug.getmetatable(io.stdin), "__gc:__index:__tostring:close:flush:lines:read:seek:setvbuf:write") -end - -do --- os - check(os, "clock:date:difftime:execute:exit:getenv:remove:rename:setlocale:time:tmpname") -end - -do --- debug - check(debug, "debug:gethook:getinfo:getlocal:getmetatable:getregistry:getupvalue:sethook:setlocal:setmetatable:setupvalue:traceback", "getfenv:setfenv:upvalueid:upvaluejoin:getuservalue:setuservalue") -end - --- TODO: Check versional differences in debug library - -do --- package - check(package, "config:cpath:loaded:loadlib:path:preload", "searchpath:loaders:searchers:seeall") -end - -do --- pre-5.2 package +lua<5.2 - assert(package.loaders) - assert(not package.searchers) - assert(package.seeall) -end - -do --- 5.2 package +lua>=5.2 - assert(not package.loaders) - assert(package.searchers) - assert(not package.seeall) -end - -do --- package.loaders - check(package.loaders or package.searchers, "1:2:3:4") -end - -do --- package.loaded - local loaded = {} - for k, v in pairs(package.loaded) do - if type(k) ~= "string" or (k:sub(1, 7) ~= "common." and k:sub(1, 4) ~= "jit.") then - loaded[k] = v - end - end - check(loaded, "_G:coroutine:debug:io:math:os:package:string:table", "bit:bit32:common:ffi:jit:table.new") -end - -do --- bit +bit - check(bit, "arshift:band:bnot:bor:bswap:bxor:lshift:rol:ror:rshift:tobit:tohex") -end - -do --- ffi +ffi - check(require"ffi", "C:abi:alignof:arch:cast:cdef:copy:errno:fill:gc:istype:load:metatype:new:offsetof:os:sizeof:string:typeinfo:typeof") -end +local function check(m, expected, exclude) + local t = {} + local ex = {} + if exclude then + for k in exclude:gmatch"[^:]+" do + ex[k] = true + end + end + for k in pairs(m) do + if not ex[k] then + t[#t+1] = tostring(k) + end + end + table.sort(t) + local got = table.concat(t, ":") + if got ~= expected then + error("got: \""..got.."\"\nexpected: \""..expected.."\"", 2) + end +end + +do --- base + check(_G, "_G:_VERSION:arg:assert:collectgarbage:coroutine:debug:dofile:error:getmetatable:io:ipairs:load:loadfile:math:next:os:package:pairs:pcall:print:rawequal:rawget:rawset:require:select:setmetatable:string:table:tonumber:tostring:type:xpcall", "rawlen:bit:bit32:jit:gcinfo:setfenv:getfenv:loadstring:unpack:module:newproxy") +end + +do --- pre-5.2 base +lua<5.2 + assert(gcinfo) + assert(setfenv) + assert(getfenv) + assert(loadstring) + assert(unpack) + assert(module) + assert(newproxy) +end + +do --- 5.2 base +lua>=5.2 + assert(not gcinfo) + assert(not setfenv) + assert(not getfenv) + assert(not loadstring) + assert(not unpack) + assert(not module) + assert(not newproxy) +end + +do --- pre-5.2 base rawlen -compat5.2 + assert(not rawlen) +end + +do --- 5.2 base rawlen +compat5.2 + assert(rawlen) +end + +do --- math + check(math, "abs:acos:asin:atan:atan2:ceil:cos:cosh:deg:exp:floor:fmod:frexp:huge:ldexp:log:max:min:modf:pi:pow:rad:random:randomseed:sin:sinh:sqrt:tan:tanh", "log10:mod") +end + +do --- pre-5.2 math +lua<5.2 + assert(math.mod) + assert(math.log10) +end + +do --- 5.2 math +lua>=5.2 + assert(not math.mod) + assert(not math.log10) +end + +do --- string + check(string, "byte:char:dump:find:format:gmatch:gsub:len:lower:match:rep:reverse:sub:upper", "gfind") +end + +do --- pre-5.2 string +lua<5.2 + assert(string.gfind) +end + +do --- 5.2 string +lua>=5.2 + assert(not string.gfind) +end + +do --- pre-5.2 table +lua<5.2 + check(table, "concat:foreach:foreachi:getn:insert:maxn:remove:sort", "pack:unpack:setn:new") +end + +do --- 5.2 table +lua>=5.2 + check(table, "concat:insert:pack:remove:sort:unpack") +end + +do --- pre-5.2 table.pack -compat5.2 + assert(not table.pack) + assert(not table.unpack) +end + +do --- 5.2 table.pack +compat5.2 + assert(table.pack) + assert(table.unpack) +end + +do --- io + check(io, "close:flush:input:lines:open:output:popen:read:stderr:stdin:stdout:tmpfile:type:write") +end + +do --- io file + check(debug.getmetatable(io.stdin), "__gc:__index:__tostring:close:flush:lines:read:seek:setvbuf:write") +end + +do --- os + check(os, "clock:date:difftime:execute:exit:getenv:remove:rename:setlocale:time:tmpname") +end + +do --- debug + check(debug, "debug:gethook:getinfo:getlocal:getmetatable:getregistry:getupvalue:sethook:setlocal:setmetatable:setupvalue:traceback", "getfenv:setfenv:upvalueid:upvaluejoin:getuservalue:setuservalue") +end + +-- TODO: Check versional differences in debug library + +do --- package + check(package, "config:cpath:loaded:loadlib:path:preload", "searchpath:loaders:searchers:seeall") +end + +do --- pre-5.2 package +lua<5.2 + assert(package.loaders) + assert(not package.searchers) + assert(package.seeall) +end + +do --- 5.2 package +lua>=5.2 + assert(not package.loaders) + assert(package.searchers) + assert(not package.seeall) +end + +do --- package.loaders + check(package.loaders or package.searchers, "1:2:3:4") +end + +do --- package.loaded + local loaded = {} + for k, v in pairs(package.loaded) do + if type(k) ~= "string" or (k:sub(1, 7) ~= "common." and k:sub(1, 4) ~= "jit.") then + loaded[k] = v + end + end + check(loaded, "_G:coroutine:debug:io:math:os:package:string:table", "bit:bit32:common:ffi:jit:table.new") +end + +do --- bit +bit + check(bit, "arshift:band:bnot:bor:bswap:bxor:lshift:rol:ror:rshift:tobit:tohex") +end + +do --- ffi +ffi + check(require"ffi", "C:abi:alignof:arch:cast:cdef:copy:errno:fill:gc:istype:load:metatype:new:offsetof:os:sizeof:string:typeinfo:typeof") +end diff --git a/test/lib/coroutine/index b/test/lib/coroutine/index index 4c9e320b48..9c5c17ec19 100644 --- a/test/lib/coroutine/index +++ b/test/lib/coroutine/index @@ -1 +1 @@ -yield.lua +yield.lua diff --git a/test/lib/coroutine/yield.lua b/test/lib/coroutine/yield.lua index 4cc98de9c5..d995bf87e1 100644 --- a/test/lib/coroutine/yield.lua +++ b/test/lib/coroutine/yield.lua @@ -1,109 +1,109 @@ -local create = coroutine.create -local wrap = coroutine.wrap -local resume = coroutine.resume -local yield = coroutine.yield - -do --- Stack overflow on return (create) - wrap(function() - local co = create(function() - yield(string.byte(string.rep(" ", 100), 1, 100)) - end) - assert(select('#', resume(co)) == 101) - end)() -end - -do --- Stack overflow on return (wrap) - wrap(function() - local f = wrap(function() - yield(string.byte(string.rep(" ", 100), 1, 100)) - end) - assert(select('#', f()) == 100) - end)() -end - -do --- cogen - local function cogen(x) - return wrap(function(n) repeat x = x+n; n = yield(x) until false end), - wrap(function(n) repeat x = x*n; n = yield(x) until false end) - end - - local a,b=cogen(3) - local c,d=cogen(5) - assert(d(b(c(a(d(b(c(a(1)))))))) == 168428160) -end - -do --- cofunc +luajit - local function verify(what, expect, ...) - local got = {...} - for i=1,100 do - if expect[i] ~= got[i] then - error("FAIL " .. what) - end - if expect[i] == nil then - break - end - end - end - - local function cofunc(...) - verify("call", { 1, "foo" }, ...) - verify("yield", { "bar" }, yield(2, "test")) - verify("pcall yield", { true, "again" }, pcall(yield, "from pcall")) - return "end" - end - - local co = create(cofunc) - verify("resume", { true, 2, "test" }, resume(co, 1, "foo")) - verify("resume pcall", { true, "from pcall" }, resume(co, "bar")) - verify("resume end", { true, "end" }, resume(co, "again")) -end - -do --- assorted +luajit - local function verify(expect, func, ...) - local co = create(func) - for i=1,100 do - local ok, res = resume(co, ...) - if not ok then - if expect[i] ~= nil then - error("too few results: ["..i.."] = "..tostring(expect[i]).." (got: "..tostring(res)..")") - end - break - end - if expect[i] ~= res then - error("bad result: ["..i.."] = "..tostring(res).." (should be: "..tostring(expect[i])..")") - end - end - end - - verify({ 42, 99 }, - function(x) pcall(yield, x) return 99 end, - 42) - - verify({ 42, 99 }, - function(x) pcall(function(y) yield(y) end, x) return 99 end, - 42) - - verify({ 42, 99 }, - function(x) xpcall(yield, debug.traceback, x) return 99 end, - 42) - - verify({ 45, 44, 43, 42, 99 }, - function(x, y) - for i in - function(o, k) - yield(o+k) - if k ~= 0 then return k-1 end - end,x,y do - end - return 99 - end, - 42, 3) - - verify({ 84, 99 }, - function(x) - local o = setmetatable({ x }, - {__add = function(a, b) yield(a[1]+b[1]) return 99 end }) - return o+o - end, - 42) -end +local create = coroutine.create +local wrap = coroutine.wrap +local resume = coroutine.resume +local yield = coroutine.yield + +do --- Stack overflow on return (create) + wrap(function() + local co = create(function() + yield(string.byte(string.rep(" ", 100), 1, 100)) + end) + assert(select('#', resume(co)) == 101) + end)() +end + +do --- Stack overflow on return (wrap) + wrap(function() + local f = wrap(function() + yield(string.byte(string.rep(" ", 100), 1, 100)) + end) + assert(select('#', f()) == 100) + end)() +end + +do --- cogen + local function cogen(x) + return wrap(function(n) repeat x = x+n; n = yield(x) until false end), + wrap(function(n) repeat x = x*n; n = yield(x) until false end) + end + + local a,b=cogen(3) + local c,d=cogen(5) + assert(d(b(c(a(d(b(c(a(1)))))))) == 168428160) +end + +do --- cofunc +luajit + local function verify(what, expect, ...) + local got = {...} + for i=1,100 do + if expect[i] ~= got[i] then + error("FAIL " .. what) + end + if expect[i] == nil then + break + end + end + end + + local function cofunc(...) + verify("call", { 1, "foo" }, ...) + verify("yield", { "bar" }, yield(2, "test")) + verify("pcall yield", { true, "again" }, pcall(yield, "from pcall")) + return "end" + end + + local co = create(cofunc) + verify("resume", { true, 2, "test" }, resume(co, 1, "foo")) + verify("resume pcall", { true, "from pcall" }, resume(co, "bar")) + verify("resume end", { true, "end" }, resume(co, "again")) +end + +do --- assorted +luajit + local function verify(expect, func, ...) + local co = create(func) + for i=1,100 do + local ok, res = resume(co, ...) + if not ok then + if expect[i] ~= nil then + error("too few results: ["..i.."] = "..tostring(expect[i]).." (got: "..tostring(res)..")") + end + break + end + if expect[i] ~= res then + error("bad result: ["..i.."] = "..tostring(res).." (should be: "..tostring(expect[i])..")") + end + end + end + + verify({ 42, 99 }, + function(x) pcall(yield, x) return 99 end, + 42) + + verify({ 42, 99 }, + function(x) pcall(function(y) yield(y) end, x) return 99 end, + 42) + + verify({ 42, 99 }, + function(x) xpcall(yield, debug.traceback, x) return 99 end, + 42) + + verify({ 45, 44, 43, 42, 99 }, + function(x, y) + for i in + function(o, k) + yield(o+k) + if k ~= 0 then return k-1 end + end,x,y do + end + return 99 + end, + 42, 3) + + verify({ 84, 99 }, + function(x) + local o = setmetatable({ x }, + {__add = function(a, b) yield(a[1]+b[1]) return 99 end }) + return o+o + end, + 42) +end diff --git a/test/lib/index b/test/lib/index index c15ccfd6a6..b22eaf883c 100644 --- a/test/lib/index +++ b/test/lib/index @@ -1,8 +1,8 @@ -base -bit.lua +bit -math -string -table -coroutine - +base +bit.lua +bit +math +string +table +coroutine + contents.lua \ No newline at end of file diff --git a/test/lib/math/abs.lua b/test/lib/math/abs.lua index 660a6cc37d..4223a78062 100644 --- a/test/lib/math/abs.lua +++ b/test/lib/math/abs.lua @@ -1,16 +1,16 @@ -local abs = math.abs -local expect_error = require"common.expect_error" - -do --- smoke - assert(abs(-1.5) == 1.5) - assert(abs("-1.5") == 1.5) -end - -do --- argcheck - expect_error(function() abs() end, - "bad argument #1 to 'abs' (number expected, got no value)") - expect_error(function() abs(false) end, - "bad argument #1 to 'abs' (number expected, got boolean)") - expect_error(function() abs("a") end, - "bad argument #1 to 'abs' (number expected, got string)") -end +local abs = math.abs +local expect_error = require"common.expect_error" + +do --- smoke + assert(abs(-1.5) == 1.5) + assert(abs("-1.5") == 1.5) +end + +do --- argcheck + expect_error(function() abs() end, + "bad argument #1 to 'abs' (number expected, got no value)") + expect_error(function() abs(false) end, + "bad argument #1 to 'abs' (number expected, got boolean)") + expect_error(function() abs("a") end, + "bad argument #1 to 'abs' (number expected, got string)") +end diff --git a/test/lib/math/constants.lua b/test/lib/math/constants.lua index 5f8a4f79d8..ec35b4cecb 100644 --- a/test/lib/math/constants.lua +++ b/test/lib/math/constants.lua @@ -1,8 +1,8 @@ -do --- pi - assert(math.pi == 3.141592653589793) -end - -do --- huge - assert(math.huge > 0) - assert(1/math.huge == 0) -end +do --- pi + assert(math.pi == 3.141592653589793) +end + +do --- huge + assert(math.huge > 0) + assert(1/math.huge == 0) +end diff --git a/test/lib/math/index b/test/lib/math/index index f17d52e780..944e1aebd4 100644 --- a/test/lib/math/index +++ b/test/lib/math/index @@ -1,3 +1,3 @@ -abs.lua -constants.lua -random.lua +abs.lua +constants.lua +random.lua diff --git a/test/lib/math/random.lua b/test/lib/math/random.lua index 4ee799b2e2..dc2ca00bda 100644 --- a/test/lib/math/random.lua +++ b/test/lib/math/random.lua @@ -1,47 +1,47 @@ -local random = math.random -local MAX_SEED = 10 - -do --- generally uniform in range [0, 1) - local N = 100 - local min, max = math.min, math.max - for j=1,MAX_SEED do - math.randomseed(j) - local lo, hi, sum = math.huge, -math.huge, 0 - for i=1,N do - local x = random() - assert(0 <= x and x < 1) - sum = sum + x - lo = min(lo, x) - hi = max(hi, x) - end - assert(lo*N < 15 and (1-hi)*N < 15) - assert(sum > N*0.45 and sum < N*0.55) - end -end - -do --- all in range [1, 10] - math.randomseed(1) - local counts = setmetatable({}, {__index = function() return 0 end}) - for i = 1, 100 do - local n = random(10) - counts[n] = counts[n] + 1 - end - for i = 1, 10 do - assert(counts[i]) - counts[i] = nil - end - assert(not next(counts)) -end - -do --- all in range [-3, 11] - math.randomseed(1) - local seen = setmetatable({}, {__index = function() return false end}) - for i = 1, 120 do - seen[random(-3, 11)] = true - end - for i = -3, 11 do - assert(seen[i]) - seen[i] = nil - end - assert(not next(seen)) -end +local random = math.random +local MAX_SEED = 10 + +do --- generally uniform in range [0, 1) + local N = 100 + local min, max = math.min, math.max + for j=1,MAX_SEED do + math.randomseed(j) + local lo, hi, sum = math.huge, -math.huge, 0 + for i=1,N do + local x = random() + assert(0 <= x and x < 1) + sum = sum + x + lo = min(lo, x) + hi = max(hi, x) + end + assert(lo*N < 15 and (1-hi)*N < 15) + assert(sum > N*0.45 and sum < N*0.55) + end +end + +do --- all in range [1, 10] + math.randomseed(1) + local counts = setmetatable({}, {__index = function() return 0 end}) + for i = 1, 100 do + local n = random(10) + counts[n] = counts[n] + 1 + end + for i = 1, 10 do + assert(counts[i]) + counts[i] = nil + end + assert(not next(counts)) +end + +do --- all in range [-3, 11] + math.randomseed(1) + local seen = setmetatable({}, {__index = function() return false end}) + for i = 1, 120 do + seen[random(-3, 11)] = true + end + for i = -3, 11 do + assert(seen[i]) + seen[i] = nil + end + assert(not next(seen)) +end diff --git a/test/lib/string/byte.lua b/test/lib/string/byte.lua index 21b1231737..697a2c2e72 100644 --- a/test/lib/string/byte.lua +++ b/test/lib/string/byte.lua @@ -1,92 +1,92 @@ -local band, bor = bit and bit.band, bit and bit.bor -local byte = string.byte - -do --- simple - local a, b = ("foo"):byte(1) - assert(type(a) == "number") - assert(b == nil) - local c, d = ("foo"):byte(2, 3) - assert(type(c) == "number") - assert(c == d) - assert(c ~= a) -end - -do --- Fixed slice [i,i+k] or overflow +bit - local s = "abcdefg" - local x,y,z - for j=100,107 do - for i=1,j do x,y,z = byte("abcdefg", band(i, 7), band(i+2, 7)) end - local a,b,c = byte("abcdefg", band(j, 7), band(j+2, 7)) - assert(x == a and y == b and z == c) - end - for j=100,107 do - for i=1,j do x,y,z = byte(s, band(i, 7), band(i+2, 7)) end - local a,b,c = byte(s, band(j, 7), band(j+2, 7)) - assert(x == a and y == b and z == c) - end -end - -do --- Positive slice [i,len] or overflow +bit - local s = "abc" - local x,y,z - for j=100,107 do - for i=1,j do x,y,z = byte("abc", band(i, 7), -1) end - local a,b,c = byte("abc", band(j, 7), -1) - assert(x == a and y == b and z == c) - end - for j=100,107 do - for i=1,j do x,y,z = byte(s, band(i, 7), -1) end - local a,b,c = byte(s, band(j, 7), -1) - assert(x == a and y == b and z == c) - end -end - -do --- Negative slice [-i,len] or underflow +bit - local s = "abc" - local x,y,z - for j=-100,-107,-1 do - for i=-1,j,-1 do x,y,z = byte("abc", bor(i, -8), -1) end - local a,b,c = byte("abc", bor(j, -8), -1) - assert(x == a and y == b and z == c) - end - for j=-100,-107,-1 do - for i=-1,j,-1 do x,y,z = byte(s, bor(i, -8), -1) end - local a,b,c = byte(s, bor(j, -8), -1) - assert(x == a and y == b and z == c) - end -end - -do --- Positive slice [1,i] or overflow +bit - local s = "abc" - local x,y,z - for j=100,107 do - for i=1,j do x,y,z = byte("abc", 1, band(i, 7)) end - local a,b,c = byte("abc", 1, band(j, 7)) - assert(x == a and y == b and z == c) - end - for j=100,107 do - for i=1,j do x,y,z = byte(s, 1, band(i, 7)) end - local a,b,c = byte(s, 1, band(j, 7)) - assert(x == a and y == b and z == c) - end -end - -do --- Negative slice [1,-i] or underflow +bit - local s = "abc" - local x,y,z - for j=-100,-107,-1 do - for i=-1,j,-1 do x,y,z = byte("abc", 1, bor(i, -8)) end - local a,b,c = byte("abc", 1, bor(j, -8)) - assert(x == a and y == b and z == c) - end - for j=-100,-107,-1 do - for i=-1,j,-1 do x,y,z = byte(s, 1, bor(i, -8)) end - local a,b,c = byte(s, 1, bor(j, -8)) - assert(x == a and y == b and z == c) - end -end - -do --- Check for slot stack overflow - local s = string.rep("x", 500) - for i=1,100 do byte(s, 1, 500) end -end +local band, bor = bit and bit.band, bit and bit.bor +local byte = string.byte + +do --- simple + local a, b = ("foo"):byte(1) + assert(type(a) == "number") + assert(b == nil) + local c, d = ("foo"):byte(2, 3) + assert(type(c) == "number") + assert(c == d) + assert(c ~= a) +end + +do --- Fixed slice [i,i+k] or overflow +bit + local s = "abcdefg" + local x,y,z + for j=100,107 do + for i=1,j do x,y,z = byte("abcdefg", band(i, 7), band(i+2, 7)) end + local a,b,c = byte("abcdefg", band(j, 7), band(j+2, 7)) + assert(x == a and y == b and z == c) + end + for j=100,107 do + for i=1,j do x,y,z = byte(s, band(i, 7), band(i+2, 7)) end + local a,b,c = byte(s, band(j, 7), band(j+2, 7)) + assert(x == a and y == b and z == c) + end +end + +do --- Positive slice [i,len] or overflow +bit + local s = "abc" + local x,y,z + for j=100,107 do + for i=1,j do x,y,z = byte("abc", band(i, 7), -1) end + local a,b,c = byte("abc", band(j, 7), -1) + assert(x == a and y == b and z == c) + end + for j=100,107 do + for i=1,j do x,y,z = byte(s, band(i, 7), -1) end + local a,b,c = byte(s, band(j, 7), -1) + assert(x == a and y == b and z == c) + end +end + +do --- Negative slice [-i,len] or underflow +bit + local s = "abc" + local x,y,z + for j=-100,-107,-1 do + for i=-1,j,-1 do x,y,z = byte("abc", bor(i, -8), -1) end + local a,b,c = byte("abc", bor(j, -8), -1) + assert(x == a and y == b and z == c) + end + for j=-100,-107,-1 do + for i=-1,j,-1 do x,y,z = byte(s, bor(i, -8), -1) end + local a,b,c = byte(s, bor(j, -8), -1) + assert(x == a and y == b and z == c) + end +end + +do --- Positive slice [1,i] or overflow +bit + local s = "abc" + local x,y,z + for j=100,107 do + for i=1,j do x,y,z = byte("abc", 1, band(i, 7)) end + local a,b,c = byte("abc", 1, band(j, 7)) + assert(x == a and y == b and z == c) + end + for j=100,107 do + for i=1,j do x,y,z = byte(s, 1, band(i, 7)) end + local a,b,c = byte(s, 1, band(j, 7)) + assert(x == a and y == b and z == c) + end +end + +do --- Negative slice [1,-i] or underflow +bit + local s = "abc" + local x,y,z + for j=-100,-107,-1 do + for i=-1,j,-1 do x,y,z = byte("abc", 1, bor(i, -8)) end + local a,b,c = byte("abc", 1, bor(j, -8)) + assert(x == a and y == b and z == c) + end + for j=-100,-107,-1 do + for i=-1,j,-1 do x,y,z = byte(s, 1, bor(i, -8)) end + local a,b,c = byte(s, 1, bor(j, -8)) + assert(x == a and y == b and z == c) + end +end + +do --- Check for slot stack overflow + local s = string.rep("x", 500) + for i=1,100 do byte(s, 1, 500) end +end diff --git a/test/lib/string/char.lua b/test/lib/string/char.lua index dff92e3202..544767de03 100644 --- a/test/lib/string/char.lua +++ b/test/lib/string/char.lua @@ -1,29 +1,29 @@ -local char = string.char - -do --- jit one char - local y - for i=1,100 do y = char(65) end - assert(y == "A") - local x = 97 - for i=1,100 do y = char(x) end - assert(y == "a") - x = "98" - for i=1,100 do y = char(x) end - assert(y == "b") - for i=1,100 do y = char(32+i) end - assert(y == "\132") -end - -do --- jit until out of bounds - local y - assert(not pcall(function() - for i=1,200 do y = char(100+i) end - end)) - assert(y == "\255") -end - -do --- jit five chars - local y - for i=1,100 do y = char(65, 66, i, 67, 68) end - assert(y == "ABdCD") -end +local char = string.char + +do --- jit one char + local y + for i=1,100 do y = char(65) end + assert(y == "A") + local x = 97 + for i=1,100 do y = char(x) end + assert(y == "a") + x = "98" + for i=1,100 do y = char(x) end + assert(y == "b") + for i=1,100 do y = char(32+i) end + assert(y == "\132") +end + +do --- jit until out of bounds + local y + assert(not pcall(function() + for i=1,200 do y = char(100+i) end + end)) + assert(y == "\255") +end + +do --- jit five chars + local y + for i=1,100 do y = char(65, 66, i, 67, 68) end + assert(y == "ABdCD") +end diff --git a/test/lib/string/dump.lua b/test/lib/string/dump.lua index ef0a9d56c8..216c6eb8bf 100644 --- a/test/lib/string/dump.lua +++ b/test/lib/string/dump.lua @@ -1,31 +1,31 @@ -local loadstring = loadstring or load - -do --- Must unpatch modified bytecode with ILOOP/JLOOP etc. - local function foo() - local t = {} - for i=1,100 do t[i] = i end - for a,b in ipairs(t) do end - local m = 0 - while m < 100 do m = m + 1 end - end - - local d1 = string.dump(foo) - foo() - assert(string.dump(foo) == d1) - if jit then jit.off(foo) end - foo() - assert(string.dump(foo) == d1) - local d2 = string.dump(loadstring(d1, ""), true) - local d3 = string.dump(assert(loadstring(d2, "")), true) - assert(d2 == d3) - assert(loadstring(string.dump(assert(loadstring(d2, ""))))) -end - -do --- roundtrip constants - local function f1() return -0x80000000 end - local function f2() return 0.971234567 end - assert(f1() == -0x80000000) - assert(loadstring(string.dump(f1), "")() == -0x80000000) - assert(f2() == 0.971234567) - assert(loadstring(string.dump(f2), "")() == 0.971234567) -end +local loadstring = loadstring or load + +do --- Must unpatch modified bytecode with ILOOP/JLOOP etc. + local function foo() + local t = {} + for i=1,100 do t[i] = i end + for a,b in ipairs(t) do end + local m = 0 + while m < 100 do m = m + 1 end + end + + local d1 = string.dump(foo) + foo() + assert(string.dump(foo) == d1) + if jit then jit.off(foo) end + foo() + assert(string.dump(foo) == d1) + local d2 = string.dump(loadstring(d1, ""), true) + local d3 = string.dump(assert(loadstring(d2, "")), true) + assert(d2 == d3) + assert(loadstring(string.dump(assert(loadstring(d2, ""))))) +end + +do --- roundtrip constants + local function f1() return -0x80000000 end + local function f2() return 0.971234567 end + assert(f1() == -0x80000000) + assert(loadstring(string.dump(f1), "")() == -0x80000000) + assert(f2() == 0.971234567) + assert(loadstring(string.dump(f2), "")() == 0.971234567) +end diff --git a/test/lib/string/format/index b/test/lib/string/format/index index 682f3b8ebe..4408853633 100644 --- a/test/lib/string/format/index +++ b/test/lib/string/format/index @@ -1 +1 @@ -num.lua +num.lua diff --git a/test/lib/string/format/num.lua b/test/lib/string/format/num.lua index 279f3c2304..e8cb33f3ce 100644 --- a/test/lib/string/format/num.lua +++ b/test/lib/string/format/num.lua @@ -1,184 +1,184 @@ -local format, type, tonumber = string.format, type, tonumber - -local function check(input, fstr, output, inputN) - local actual = format(fstr, inputN or tonumber(input)) - if actual == output then return end - local t = type(output) - if t == "string" then - if output:find"[[%]]" then - local s, e = actual:find((output:gsub("%.", "%%."))) - if s == 1 and e == #actual then return end - end - end - error(format("expected string.format(%q, %q) == %q, but got %q", - fstr, input, output, actual)) -end - -do --- small denormals at low precision +hexfloat !lex - assert(("%.9e"):format(0x1.0E00D1p-1050) == "8.742456525e-317") - assert(("%.13e"):format(0x1.1Cp-1068) == "3.5078660854729e-322") -end - -do --- smoke - local cases = { - -- input, %e, %f, %g - { "0", "0.000000e+00", "0.000000", "0"}, - { "1", "1.000000e+00", "1.000000", "1"}, - { "0.5", "5.000000e-01", "0.500000", "0.5"}, - { "123", "1.230000e+02", "123.000000", "123"}, - {"0.0078125", "7.812500e-03", "0.00781[23]", "0.0078125"}, - { "1.109375", "1.109375e+00", "1.109375", "1.1093[78]"}, - { "0.999995", "9.999950e-01", "0.999995", "0.999995"}, - {"0.9999995", "9.999995e-01", "1.000000", "1"}, - { "99999.95", "9.999995e+04", "99999.950000", "99999.9"}, - {"999999.95", "9.999999e+05", "999999.950000", "1e+06"}, - {"123456978", "1.234570e+08", "123456978.000000", "1.23457e+08"}, - { "33.3", "3.330000e+01", "33.300000", "33.3"}, - } - for _, t in ipairs(cases) do - local n = tonumber(t[1]) - check(t[1], "%e", t[2], n) - check(t[1], "%f", t[3], n) - check(t[1], "%g", t[4], n) - end -end - -do --- easily enumerable cases of %a, %A +hexfloat - for i = 1, 16 do - check(1+(i-1)/16, "%.1a", "0x1.".. ("0123456789abcdef"):sub(i,i) .."p+0") - check(16+(i-1), "%.1A", "0X1.".. ("0123456789ABCDEF"):sub(i,i) .."P+4") - end -end - -do --- easily enumerable cases of %f - for i = 1, 16 do - check(("1"):rep(i), "%#2.0f", ("1"):rep(i)..".") - end -end - -do --- easily enumerable cases of %e - local z, f, c = ("0"):byte(), math.floor, string.char - for p = 0, 14 do - local head = "1.".. ("0"):rep(p) - local fmt = "%#.".. c(z + f(p / 10), z + (p % 10)) .."e" - for i = 1, 99 do - local istr = c(z + f(i / 10), z + (i % 10)) - check("1e-".. istr, fmt, head .."e-".. istr) - check("1e+".. istr, fmt, head .."e+".. istr) - end - for i = 100, 308 do - local istr = c(z + f(i / 100), z + f(i / 10) % 10, z + (i % 10)) - check("1e-".. istr, fmt, head .."e-".. istr) - check("1e+".. istr, fmt, head .."e+".. istr) - end - end -end - -do --- assorted - check("0", "%.14g", "0") - check("1e-310", "%.0g", "1e-310") - check("1e8", "%010.5g", "000001e+08") - check("1e8", "% -10.5g", " 1e+08 ") - check("4e123", "%+#.0e", "+4.e+123") - check("1e49", "%.0f", "9999999999999999464902769475481793196872414789632") - check("1e50", "%.0f", "100000000000000007629769841091887003294964970946560") - check("1e50", "%.35g", "1.00000000000000007629769841091887e+50") - check("1e50", "%40.35g", " 1.00000000000000007629769841091887e+50") - check("1e50", "%#+40.34g", "+1.000000000000000076297698410918870e+50") - check("1e50", "%-40.35g", "1.00000000000000007629769841091887e+50 ") - check("0.5", "%.0f", "[01]") - check("0.25", "%.1f", "0.[23]") - check("999999.95", "%.7g", "999999.9") - check("999.99995", "%.7g", "1000") - check("6.9039613742e-314", "%.3e", "6.904e-314") - - check(1e-323, "%.99g", "9.8813129168249308835313758573644274473011960522864".. - "9528851171365001351014540417503730599672723271985e-324") - check(1e308, "%.99f", "1000000000000000010979063629440455417404923096773118".. - "463368106829031575854049114915371633289784946888990612496697211725".. - "156115902837431400883283070091981460460312716645029330271856974896".. - "995885590433383844661650011784268976262129451776280911957867074581".. - "22783970171784415105291802893207873272974885715430223118336.000000".. - "000000000000000000000000000000000000000000000000000000000000000000".. - "000000000000000000000000000") - check("1", "%.99f", "1."..("0"):rep(99)) - check("5", "%99g", (" "):rep(98).."5") - check("5", "%099g", ("0"):rep(98).."5") - check("5", "%-99g", "5".. (" "):rep(98)) - check("5", "%0-99g", "5".. (" "):rep(98)) - - check((2^53-1)*2^971, "%e", "1.797693e+308") - check((2^53-1)*2^971, "%.0e", "2e+308") - - check("0", "%.14g", "0") - - check("0.15", "%.1f", "0.1") - check("0.45", "%.1f", "0.5") - check("0.55", "%.1f", "0.6") - check("0.85", "%.1f", "0.8") -end - -do --- assorted %a +luajit>=2.1 - check((2^53-1)*2^971, "%a", "0x1.fffffffffffffp+1023") - check((2^53-1)*2^971, "%.0a", "0x2p+1023") - check("0", "%a", "0x0p+0") - check("1.53173828125", "%1.8a", "0x1.88200000p+0") - check("1.53173828125", "%8.1a", "0x1.9p+0") -- libc on OSX gets this wrong - check("1.5317", "%8.1a", "0x1.9p+0") - check("1.53", "%8.1a", "0x1.8p+0") - check("-1.5", "%11.2a", " -0x1.80p+0") - check("3.14159265358", "%a", "0x1.921fb5443d6f4p+1") - check("3.14159265358", "%A", "0X1.921FB5443D6F4P+1") -end - -do --- Cases where inprecision can easily affect rounding - check("2.28579528986935e-262", "%.14g", "2.2857952898694e-262") - check("4.86009084710405e+243", "%.14g", "4.8600908471041e+243") - check("6.28108398359615e+258", "%.14g", "6.2810839835962e+258") - check("4.29911075733405e+250", "%.14g", "4.2991107573341e+250") - check("8.5068432121065e+244", "% .13g", " 8.506843212107e+244") - check("8.1919113161235899e+233", "%.40g", "8.191911316123589934222156598061".. - "949037266e+233") - check("7.1022381748280933e+272", "%.40g", "7.102238174828093393858336547341".. - "897013319e+272") - check("5.8018368514358030e+261", "%.67g", "5.801836851435803025936253580958".. - "042578728799220447411839451694590343e+261") - check("7.9225909325493999e-199", "%.26g", "7.922590932549399935196127e-199") - check("2.4976643533685383e-153", "%.43g", "2.497664353368538321643894302495".. - "469512999562e-153") - check("9.796500001282779e+222", "%.4g", "9.797e+222") - check("7.7169235e-227", "%e", "7.716923e-227") - check("7.7169235000000044e-227", "%e", "7.716924e-227") - check("5.3996444915000004e+87", "%.9e", "5.399644492e+87") - check("2.03037546395e-49", "%.10e", "2.0303754640e-49") - check("3.38759425741500027e+65", "%.11e", "3.38759425742e+65") - check("1.013960434983135e-66", "%.0e", "1e-66") - check("1.32423054454835e-204", "%.13e", "1.3242305445484e-204") - check("5.9005060812045502e+100", "%.13e", "5.9005060812046e+100") -end - -do --- ExploringBinary.com/print-precision-of-dyadic-fractions-varies-by-language/ - check(5404319552844595/2^53, "%.53g", "0.5999999999999999777955395074968691".. - "9152736663818359375") - check(2^-1074, "%.99e", "4.940656458412465441765687928682213723650598026143".. - "247644255856825006755072702087518652998363616359924e-324") - check(1-2^-53, "%1.53f", "0.99999999999999988897769753748434595763683319091".. - "796875") -end - -do --- ExploringBinary.com/incorrect-floating-point-to-decimal-conversions/ - check("1.0551955", "%.7g", "1.055195") - check("8.330400913327153", "%.15f", "8.330400913327153") - check("9194.25055964485", "%.14g", "9194.2505596449") - check("816.2665949149578", "%.16g", "816.2665949149578") - check("95.47149571505499", "%.16g", "95.47149571505498") -end - -do --- big f +luajit>=2.1 - check("9.522938016739373", "%.15F", "9.522938016739372") -end - -do --- RandomASCII.wordpress.com/2013/02/07/ - check("6.10351562e-05", "%1.8e", "6.1035156[23]e%-05") - check("4.3037358649999999e-15", "%1.8e", "4.30373586e-15") -end +local format, type, tonumber = string.format, type, tonumber + +local function check(input, fstr, output, inputN) + local actual = format(fstr, inputN or tonumber(input)) + if actual == output then return end + local t = type(output) + if t == "string" then + if output:find"[[%]]" then + local s, e = actual:find((output:gsub("%.", "%%."))) + if s == 1 and e == #actual then return end + end + end + error(format("expected string.format(%q, %q) == %q, but got %q", + fstr, input, output, actual)) +end + +do --- small denormals at low precision +hexfloat !lex + assert(("%.9e"):format(0x1.0E00D1p-1050) == "8.742456525e-317") + assert(("%.13e"):format(0x1.1Cp-1068) == "3.5078660854729e-322") +end + +do --- smoke + local cases = { + -- input, %e, %f, %g + { "0", "0.000000e+00", "0.000000", "0"}, + { "1", "1.000000e+00", "1.000000", "1"}, + { "0.5", "5.000000e-01", "0.500000", "0.5"}, + { "123", "1.230000e+02", "123.000000", "123"}, + {"0.0078125", "7.812500e-03", "0.00781[23]", "0.0078125"}, + { "1.109375", "1.109375e+00", "1.109375", "1.1093[78]"}, + { "0.999995", "9.999950e-01", "0.999995", "0.999995"}, + {"0.9999995", "9.999995e-01", "1.000000", "1"}, + { "99999.95", "9.999995e+04", "99999.950000", "99999.9"}, + {"999999.95", "9.999999e+05", "999999.950000", "1e+06"}, + {"123456978", "1.234570e+08", "123456978.000000", "1.23457e+08"}, + { "33.3", "3.330000e+01", "33.300000", "33.3"}, + } + for _, t in ipairs(cases) do + local n = tonumber(t[1]) + check(t[1], "%e", t[2], n) + check(t[1], "%f", t[3], n) + check(t[1], "%g", t[4], n) + end +end + +do --- easily enumerable cases of %a, %A +hexfloat + for i = 1, 16 do + check(1+(i-1)/16, "%.1a", "0x1.".. ("0123456789abcdef"):sub(i,i) .."p+0") + check(16+(i-1), "%.1A", "0X1.".. ("0123456789ABCDEF"):sub(i,i) .."P+4") + end +end + +do --- easily enumerable cases of %f + for i = 1, 16 do + check(("1"):rep(i), "%#2.0f", ("1"):rep(i)..".") + end +end + +do --- easily enumerable cases of %e + local z, f, c = ("0"):byte(), math.floor, string.char + for p = 0, 14 do + local head = "1.".. ("0"):rep(p) + local fmt = "%#.".. c(z + f(p / 10), z + (p % 10)) .."e" + for i = 1, 99 do + local istr = c(z + f(i / 10), z + (i % 10)) + check("1e-".. istr, fmt, head .."e-".. istr) + check("1e+".. istr, fmt, head .."e+".. istr) + end + for i = 100, 308 do + local istr = c(z + f(i / 100), z + f(i / 10) % 10, z + (i % 10)) + check("1e-".. istr, fmt, head .."e-".. istr) + check("1e+".. istr, fmt, head .."e+".. istr) + end + end +end + +do --- assorted + check("0", "%.14g", "0") + check("1e-310", "%.0g", "1e-310") + check("1e8", "%010.5g", "000001e+08") + check("1e8", "% -10.5g", " 1e+08 ") + check("4e123", "%+#.0e", "+4.e+123") + check("1e49", "%.0f", "9999999999999999464902769475481793196872414789632") + check("1e50", "%.0f", "100000000000000007629769841091887003294964970946560") + check("1e50", "%.35g", "1.00000000000000007629769841091887e+50") + check("1e50", "%40.35g", " 1.00000000000000007629769841091887e+50") + check("1e50", "%#+40.34g", "+1.000000000000000076297698410918870e+50") + check("1e50", "%-40.35g", "1.00000000000000007629769841091887e+50 ") + check("0.5", "%.0f", "[01]") + check("0.25", "%.1f", "0.[23]") + check("999999.95", "%.7g", "999999.9") + check("999.99995", "%.7g", "1000") + check("6.9039613742e-314", "%.3e", "6.904e-314") + + check(1e-323, "%.99g", "9.8813129168249308835313758573644274473011960522864".. + "9528851171365001351014540417503730599672723271985e-324") + check(1e308, "%.99f", "1000000000000000010979063629440455417404923096773118".. + "463368106829031575854049114915371633289784946888990612496697211725".. + "156115902837431400883283070091981460460312716645029330271856974896".. + "995885590433383844661650011784268976262129451776280911957867074581".. + "22783970171784415105291802893207873272974885715430223118336.000000".. + "000000000000000000000000000000000000000000000000000000000000000000".. + "000000000000000000000000000") + check("1", "%.99f", "1."..("0"):rep(99)) + check("5", "%99g", (" "):rep(98).."5") + check("5", "%099g", ("0"):rep(98).."5") + check("5", "%-99g", "5".. (" "):rep(98)) + check("5", "%0-99g", "5".. (" "):rep(98)) + + check((2^53-1)*2^971, "%e", "1.797693e+308") + check((2^53-1)*2^971, "%.0e", "2e+308") + + check("0", "%.14g", "0") + + check("0.15", "%.1f", "0.1") + check("0.45", "%.1f", "0.5") + check("0.55", "%.1f", "0.6") + check("0.85", "%.1f", "0.8") +end + +do --- assorted %a +luajit>=2.1 + check((2^53-1)*2^971, "%a", "0x1.fffffffffffffp+1023") + check((2^53-1)*2^971, "%.0a", "0x2p+1023") + check("0", "%a", "0x0p+0") + check("1.53173828125", "%1.8a", "0x1.88200000p+0") + check("1.53173828125", "%8.1a", "0x1.9p+0") -- libc on OSX gets this wrong + check("1.5317", "%8.1a", "0x1.9p+0") + check("1.53", "%8.1a", "0x1.8p+0") + check("-1.5", "%11.2a", " -0x1.80p+0") + check("3.14159265358", "%a", "0x1.921fb5443d6f4p+1") + check("3.14159265358", "%A", "0X1.921FB5443D6F4P+1") +end + +do --- Cases where inprecision can easily affect rounding + check("2.28579528986935e-262", "%.14g", "2.2857952898694e-262") + check("4.86009084710405e+243", "%.14g", "4.8600908471041e+243") + check("6.28108398359615e+258", "%.14g", "6.2810839835962e+258") + check("4.29911075733405e+250", "%.14g", "4.2991107573341e+250") + check("8.5068432121065e+244", "% .13g", " 8.506843212107e+244") + check("8.1919113161235899e+233", "%.40g", "8.191911316123589934222156598061".. + "949037266e+233") + check("7.1022381748280933e+272", "%.40g", "7.102238174828093393858336547341".. + "897013319e+272") + check("5.8018368514358030e+261", "%.67g", "5.801836851435803025936253580958".. + "042578728799220447411839451694590343e+261") + check("7.9225909325493999e-199", "%.26g", "7.922590932549399935196127e-199") + check("2.4976643533685383e-153", "%.43g", "2.497664353368538321643894302495".. + "469512999562e-153") + check("9.796500001282779e+222", "%.4g", "9.797e+222") + check("7.7169235e-227", "%e", "7.716923e-227") + check("7.7169235000000044e-227", "%e", "7.716924e-227") + check("5.3996444915000004e+87", "%.9e", "5.399644492e+87") + check("2.03037546395e-49", "%.10e", "2.0303754640e-49") + check("3.38759425741500027e+65", "%.11e", "3.38759425742e+65") + check("1.013960434983135e-66", "%.0e", "1e-66") + check("1.32423054454835e-204", "%.13e", "1.3242305445484e-204") + check("5.9005060812045502e+100", "%.13e", "5.9005060812046e+100") +end + +do --- ExploringBinary.com/print-precision-of-dyadic-fractions-varies-by-language/ + check(5404319552844595/2^53, "%.53g", "0.5999999999999999777955395074968691".. + "9152736663818359375") + check(2^-1074, "%.99e", "4.940656458412465441765687928682213723650598026143".. + "247644255856825006755072702087518652998363616359924e-324") + check(1-2^-53, "%1.53f", "0.99999999999999988897769753748434595763683319091".. + "796875") +end + +do --- ExploringBinary.com/incorrect-floating-point-to-decimal-conversions/ + check("1.0551955", "%.7g", "1.055195") + check("8.330400913327153", "%.15f", "8.330400913327153") + check("9194.25055964485", "%.14g", "9194.2505596449") + check("816.2665949149578", "%.16g", "816.2665949149578") + check("95.47149571505499", "%.16g", "95.47149571505498") +end + +do --- big f +luajit>=2.1 + check("9.522938016739373", "%.15F", "9.522938016739372") +end + +do --- RandomASCII.wordpress.com/2013/02/07/ + check("6.10351562e-05", "%1.8e", "6.1035156[23]e%-05") + check("4.3037358649999999e-15", "%1.8e", "4.30373586e-15") +end diff --git a/test/lib/string/index b/test/lib/string/index index bad5cffec2..c0638e9c34 100644 --- a/test/lib/string/index +++ b/test/lib/string/index @@ -1,11 +1,11 @@ -metatable.lua -byte.lua -char.lua -dump.lua -format -len.lua -lower_upper.lua -multiple_functions.lua -rep.lua -reverse.lua -sub.lua +metatable.lua +byte.lua +char.lua +dump.lua +format +len.lua +lower_upper.lua +multiple_functions.lua +rep.lua +reverse.lua +sub.lua diff --git a/test/lib/string/len.lua b/test/lib/string/len.lua index 8d9c7e57a6..8ed7e8ae49 100644 --- a/test/lib/string/len.lua +++ b/test/lib/string/len.lua @@ -1,14 +1,14 @@ -local len = string.len -local expect_error = require"common.expect_error" - -do --- smoke - assert(len("abc") == 3) - assert(len(123) == 3) -end - -do --- argcheck - expect_error(function() len() end, - "bad argument #1 to 'len' (string expected, got nil)") - expect_error(function() len(false) end, - "bad argument #1 to 'len' (string expected, got boolean)") -end +local len = string.len +local expect_error = require"common.expect_error" + +do --- smoke + assert(len("abc") == 3) + assert(len(123) == 3) +end + +do --- argcheck + expect_error(function() len() end, + "bad argument #1 to 'len' (string expected, got nil)") + expect_error(function() len(false) end, + "bad argument #1 to 'len' (string expected, got boolean)") +end diff --git a/test/lib/string/lower_upper.lua b/test/lib/string/lower_upper.lua index 1a05fc353c..7370c44ce1 100644 --- a/test/lib/string/lower_upper.lua +++ b/test/lib/string/lower_upper.lua @@ -1,51 +1,51 @@ -do --- smoke - assert(("abc123DEF_<>"):lower() == "abc123def_<>") - assert(("abc123DEF_<>"):upper() == "ABC123DEF_<>") -end - -do --- repeated - local l = "the quick brown fox..." - local u = "THE QUICK BROWN FOX..." - local s = l - for i = 1, 75 do - s = s:upper() - assert(s == u) - s = s:lower() - assert(s == l) - end -end - -do --- repeated with growing string - local y, z - local x = "aBcDe" - for i=1,100 do - y = string.upper(x) - z = y.."fgh" - end - assert(y == "ABCDE") - assert(z == "ABCDEfgh") -end - -do --- misc upper - local y - for i=1,100 do y = string.upper("aBc9") end - assert(y == "ABC9") - local x = ":abCd+" - for i=1,100 do y = string.upper(x) end - assert(y == ":ABCD+") - x = 1234 - for i=1,100 do y = string.upper(x) end - assert(y == "1234") -end - -do --- misc lower - local y - for i=1,100 do y = string.lower("aBc9") end - assert(y == "abc9") - local x = ":abcd+" - for i=1,100 do y = string.lower(x) end - assert(y == ":abcd+") - x = 1234 - for i=1,100 do y = string.lower(x) end - assert(y == "1234") -end +do --- smoke + assert(("abc123DEF_<>"):lower() == "abc123def_<>") + assert(("abc123DEF_<>"):upper() == "ABC123DEF_<>") +end + +do --- repeated + local l = "the quick brown fox..." + local u = "THE QUICK BROWN FOX..." + local s = l + for i = 1, 75 do + s = s:upper() + assert(s == u) + s = s:lower() + assert(s == l) + end +end + +do --- repeated with growing string + local y, z + local x = "aBcDe" + for i=1,100 do + y = string.upper(x) + z = y.."fgh" + end + assert(y == "ABCDE") + assert(z == "ABCDEfgh") +end + +do --- misc upper + local y + for i=1,100 do y = string.upper("aBc9") end + assert(y == "ABC9") + local x = ":abCd+" + for i=1,100 do y = string.upper(x) end + assert(y == ":ABCD+") + x = 1234 + for i=1,100 do y = string.upper(x) end + assert(y == "1234") +end + +do --- misc lower + local y + for i=1,100 do y = string.lower("aBc9") end + assert(y == "abc9") + local x = ":abcd+" + for i=1,100 do y = string.lower(x) end + assert(y == ":abcd+") + x = 1234 + for i=1,100 do y = string.lower(x) end + assert(y == "1234") +end diff --git a/test/lib/string/metatable.lua b/test/lib/string/metatable.lua index 9861ee7e3c..d39ed43264 100644 --- a/test/lib/string/metatable.lua +++ b/test/lib/string/metatable.lua @@ -1,3 +1,3 @@ -do --- __index metamethod is string library - assert(debug.getmetatable("").__index == string) -end +do --- __index metamethod is string library + assert(debug.getmetatable("").__index == string) +end diff --git a/test/lib/string/multiple_functions.lua b/test/lib/string/multiple_functions.lua index 725803d66d..7b9d0f1383 100644 --- a/test/lib/string/multiple_functions.lua +++ b/test/lib/string/multiple_functions.lua @@ -1,16 +1,16 @@ -do --- string_op - local t, y = {}, {} - for i=1,100 do t[i] = string.char(i, 16+i, 32+i) end - for i=1,100 do t[i] = string.reverse(t[i]) end - assert(t[100] == "\132\116\100") - for i=1,100 do t[i] = string.reverse(t[i]) end - for i=1,100 do assert(t[i] == string.char(i, 16+i, 32+i)) end - for i=1,100 do y[i] = string.upper(t[i]) end - assert(y[65] == "AQA") - assert(y[97] == "AQ\129") - assert(y[100] == "DT\132") - for i=1,100 do y[i] = string.lower(t[i]) end - assert(y[65] == "aqa") - assert(y[97] == "aq\129") - assert(y[100] == "dt\132") -end +do --- string_op + local t, y = {}, {} + for i=1,100 do t[i] = string.char(i, 16+i, 32+i) end + for i=1,100 do t[i] = string.reverse(t[i]) end + assert(t[100] == "\132\116\100") + for i=1,100 do t[i] = string.reverse(t[i]) end + for i=1,100 do assert(t[i] == string.char(i, 16+i, 32+i)) end + for i=1,100 do y[i] = string.upper(t[i]) end + assert(y[65] == "AQA") + assert(y[97] == "AQ\129") + assert(y[100] == "DT\132") + for i=1,100 do y[i] = string.lower(t[i]) end + assert(y[65] == "aqa") + assert(y[97] == "aq\129") + assert(y[100] == "dt\132") +end diff --git a/test/lib/string/rep.lua b/test/lib/string/rep.lua index c97ec10bc9..550c15b8a8 100644 --- a/test/lib/string/rep.lua +++ b/test/lib/string/rep.lua @@ -1,68 +1,68 @@ -local rep = string.rep - -do --- smoke - assert(("p"):rep(0) == "") - assert(("a"):rep(3) == "aaa") - assert(("x\0z"):rep(4) == "x\0zx\0zx\0zx\0z") -end - -do --- versus concat - local s = "" - for i = 1, 75 do - s = s .. "{}" - assert(s == ("{}"):rep(i)) - end -end - -do --- misc - local y - for i=1,100 do y = rep("a", 10) end - assert(y == "aaaaaaaaaa") - for i=1,100 do y = rep("ab", 10) end - assert(y == "abababababababababab") - local x = "a" - for i=1,100 do y = rep(x, 10) end - assert(y == "aaaaaaaaaa") - local n = 10 - for i=1,100 do y = rep(x, n) end - assert(y == "aaaaaaaaaa") - x = "ab" - for i=1,100 do y = rep(x, n) end - assert(y == "abababababababababab") - x = 12 - n = "10" - for i=1,100 do y = rep(x, n) end - assert(y == "12121212121212121212") -end - -do --- separator +goto - local y - for i=1,100 do y = rep("ab", 10, "c") end - assert(y == "abcabcabcabcabcabcabcabcabcab") -end - -do --- iterate to table - local t = {} - for i=1,100 do t[i] = rep("ab", i-85) end - assert(t[100] == "ababababababababababababababab") -end - -do --- iterate to table with sep +goto - local t = {} - for i=1,100 do t[i] = rep("ab", i-85, "c") end - assert(t[85] == "") - assert(t[86] == "ab") - assert(t[87] == "abcab") - assert(t[100] == "abcabcabcabcabcabcabcabcabcabcabcabcabcabcab") -end - -do --- iterate and concat - local y, z - local x = "ab" - for i=1,100 do - y = rep(x, i-90) - z = y.."fgh" - end - assert(y == "abababababababababab") - assert(z == "ababababababababababfgh") -end +local rep = string.rep + +do --- smoke + assert(("p"):rep(0) == "") + assert(("a"):rep(3) == "aaa") + assert(("x\0z"):rep(4) == "x\0zx\0zx\0zx\0z") +end + +do --- versus concat + local s = "" + for i = 1, 75 do + s = s .. "{}" + assert(s == ("{}"):rep(i)) + end +end + +do --- misc + local y + for i=1,100 do y = rep("a", 10) end + assert(y == "aaaaaaaaaa") + for i=1,100 do y = rep("ab", 10) end + assert(y == "abababababababababab") + local x = "a" + for i=1,100 do y = rep(x, 10) end + assert(y == "aaaaaaaaaa") + local n = 10 + for i=1,100 do y = rep(x, n) end + assert(y == "aaaaaaaaaa") + x = "ab" + for i=1,100 do y = rep(x, n) end + assert(y == "abababababababababab") + x = 12 + n = "10" + for i=1,100 do y = rep(x, n) end + assert(y == "12121212121212121212") +end + +do --- separator +goto + local y + for i=1,100 do y = rep("ab", 10, "c") end + assert(y == "abcabcabcabcabcabcabcabcabcab") +end + +do --- iterate to table + local t = {} + for i=1,100 do t[i] = rep("ab", i-85) end + assert(t[100] == "ababababababababababababababab") +end + +do --- iterate to table with sep +goto + local t = {} + for i=1,100 do t[i] = rep("ab", i-85, "c") end + assert(t[85] == "") + assert(t[86] == "ab") + assert(t[87] == "abcab") + assert(t[100] == "abcabcabcabcabcabcabcabcabcabcabcabcabcabcab") +end + +do --- iterate and concat + local y, z + local x = "ab" + for i=1,100 do + y = rep(x, i-90) + z = y.."fgh" + end + assert(y == "abababababababababab") + assert(z == "ababababababababababfgh") +end diff --git a/test/lib/string/reverse.lua b/test/lib/string/reverse.lua index 34a8ffb013..deaade7cef 100644 --- a/test/lib/string/reverse.lua +++ b/test/lib/string/reverse.lua @@ -1,13 +1,13 @@ -local reverse = string.reverse - -do --- misc - local y - for i=1,100 do y = reverse("abc") end - assert(y == "cba") - local x = "abcd" - for i=1,100 do y = reverse(x) end - assert(y == "dcba") - x = 1234 - for i=1,100 do y = reverse(x) end - assert(y == "4321") -end +local reverse = string.reverse + +do --- misc + local y + for i=1,100 do y = reverse("abc") end + assert(y == "cba") + local x = "abcd" + for i=1,100 do y = reverse(x) end + assert(y == "dcba") + x = 1234 + for i=1,100 do y = reverse(x) end + assert(y == "4321") +end diff --git a/test/lib/string/sub.lua b/test/lib/string/sub.lua index 981f2924a0..ecb80216c9 100644 --- a/test/lib/string/sub.lua +++ b/test/lib/string/sub.lua @@ -1,189 +1,189 @@ -local band, bor = bit and bit.band, bit and bit.bor -local sub = string.sub -local expect_error = require"common.expect_error" - -do --- smoke - assert(sub("abc", 2) == "bc") - assert(sub(123, "2") == "23") -end - -do --- argcheck - expect_error(function() sub("abc", false) end, - "bad argument #2 to 'sub' (number expected, got boolean)") - expect_error(function() ("abc"):sub(false) end, - "bad argument #1 to 'sub' (number expected, got boolean)") -end - -do --- all bar substrings - local subs = { - {"b", "ba", "bar"}, - { "", "a", "ar"}, - { "", "", "r"} - } - for i = 1, 3 do - for j = 1, 3 do - assert(sub("bar", i, j) == subs[i][j]) - assert(sub("bar", -4+i, j) == subs[i][j]) - assert(sub("bar", i, -4+j) == subs[i][j]) - assert(sub("bar", -4+i, -4+j) == subs[i][j]) - end - end -end - -do --- Positive slice [i,len] or overflow +bit - local s = "abc" - local x - for j=100,107 do - for i=1,j do x = sub("abc", band(i, 7)) end - assert(x == sub("abc", band(j, 7))) - end - for j=100,107 do - for i=1,j do x = sub(s, band(i, 7)) end - assert(x == sub(s, band(j, 7))) - end -end - -do --- Negative slice [-i,len] or underflow +bit - local s = "abc" - local x - for j=-100,-107,-1 do - for i=-1,j,-1 do x = sub("abc", bor(i, -8)) end - assert(x == sub("abc", bor(j, -8))) - end - for j=-100,-107,-1 do - for i=-1,j,-1 do x = sub(s, bor(i, -8)) end - assert(x == sub(s, bor(j, -8))) - end -end - -do --- Positive slice [1,i] or overflow +bit - local s = "abc" - local x - for j=100,107 do - for i=1,j do x = sub("abc", 1, band(i, 7)) end - assert(x == sub("abc", 1, band(j, 7))) - end - for j=100,107 do - for i=1,j do x = sub(s, 1, band(i, 7)) end - assert(x == sub(s, 1, band(j, 7))) - end -end - -do --- Negative slice [1,-i] or underflow +bit - local s = "abc" - local x - for j=-100,-107,-1 do - for i=-1,j,-1 do x = sub("abc", 1, bor(i, -8)) end - assert(x == sub("abc", 1, bor(j, -8))) - end - for j=-100,-107,-1 do - for i=-1,j,-1 do x = sub(s, 1, bor(i, -8)) end - assert(x == sub(s, 1, bor(j, -8))) - end -end - -do --- jit sub 1 eq - local s = "abcde" - local x = 0 - for i=1,100 do - if sub(s, 1, 1) == "a" then x = x + 1 end - end - assert(x == 100) -end - -do --- jit sub 1 ne (contents) - local s = "abcde" - local x = 0 - for i=1,100 do - if sub(s, 1, 1) == "b" then x = x + 1 end - end - assert(x == 0) -end - -do --- jit sub 1 ne (rhs too long) - local s = "abcde" - local x = 0 - for i=1,100 do - if sub(s, 1, 1) == "ab" then x = x + 1 end - end - assert(x == 0) -end - -do --- jit sub 1,2 ne - local s = "abcde" - local x = 0 - for i=1,100 do - if sub(s, 1, 2) == "a" then x = x + 1 end - end - assert(x == 0) -end - -do --- jit sub 1,k eq - local s = "abcde" - local x = 0 - local k = 1 - for i=1,100 do - if sub(s, 1, k) == "a" then x = x + 1 end - end - assert(x == 100) -end - -do --- jit sub 1,k ne (contents) - local s = "abcde" - local x = 0 - local k = 1 - for i=1,100 do - if sub(s, 1, k) == "b" then x = x + 1 end - end - assert(x == 0) -end - -do --- jit sub 1,k ne (rhs too long) - local s = "abcde" - local x = 0 - local k = 1 - for i=1,100 do - if sub(s, 1, k) == "ab" then x = x + 1 end - end - assert(x == 0) -end - -do --- jit sub 1,2 eq - local s = "abcde" - local x = 0 - for i=1,100 do - if sub(s, 1, 2) == "ab" then x = x + 1 end - end - assert(x == 100) -end - -do --- jit sub 1,3 eq - local s = "abcde" - local x = 0 - for i=1,100 do - if sub(s, 1, 3) == "abc" then x = x + 1 end - end - assert(x == 100) -end - -do --- jit sub 1,4 eq - local s = "abcde" - local x = 0 - for i=1,100 do - if sub(s, 1, 4) == "abcd" then x = x + 1 end - end - assert(x == 100) -end - -do --- jit sub i,i - local t = {} - local line = string.rep("..XX", 100) - local i = 1 - local c = line:sub(i, i) - while c ~= "" and c ~= "Z" do - t[i] = c == "X" and "Y" or c - i = i + 1 - c = line:sub(i, i) - end - assert(table.concat(t) == string.rep("..YY", 100)) -end +local band, bor = bit and bit.band, bit and bit.bor +local sub = string.sub +local expect_error = require"common.expect_error" + +do --- smoke + assert(sub("abc", 2) == "bc") + assert(sub(123, "2") == "23") +end + +do --- argcheck + expect_error(function() sub("abc", false) end, + "bad argument #2 to 'sub' (number expected, got boolean)") + expect_error(function() ("abc"):sub(false) end, + "bad argument #1 to 'sub' (number expected, got boolean)") +end + +do --- all bar substrings + local subs = { + {"b", "ba", "bar"}, + { "", "a", "ar"}, + { "", "", "r"} + } + for i = 1, 3 do + for j = 1, 3 do + assert(sub("bar", i, j) == subs[i][j]) + assert(sub("bar", -4+i, j) == subs[i][j]) + assert(sub("bar", i, -4+j) == subs[i][j]) + assert(sub("bar", -4+i, -4+j) == subs[i][j]) + end + end +end + +do --- Positive slice [i,len] or overflow +bit + local s = "abc" + local x + for j=100,107 do + for i=1,j do x = sub("abc", band(i, 7)) end + assert(x == sub("abc", band(j, 7))) + end + for j=100,107 do + for i=1,j do x = sub(s, band(i, 7)) end + assert(x == sub(s, band(j, 7))) + end +end + +do --- Negative slice [-i,len] or underflow +bit + local s = "abc" + local x + for j=-100,-107,-1 do + for i=-1,j,-1 do x = sub("abc", bor(i, -8)) end + assert(x == sub("abc", bor(j, -8))) + end + for j=-100,-107,-1 do + for i=-1,j,-1 do x = sub(s, bor(i, -8)) end + assert(x == sub(s, bor(j, -8))) + end +end + +do --- Positive slice [1,i] or overflow +bit + local s = "abc" + local x + for j=100,107 do + for i=1,j do x = sub("abc", 1, band(i, 7)) end + assert(x == sub("abc", 1, band(j, 7))) + end + for j=100,107 do + for i=1,j do x = sub(s, 1, band(i, 7)) end + assert(x == sub(s, 1, band(j, 7))) + end +end + +do --- Negative slice [1,-i] or underflow +bit + local s = "abc" + local x + for j=-100,-107,-1 do + for i=-1,j,-1 do x = sub("abc", 1, bor(i, -8)) end + assert(x == sub("abc", 1, bor(j, -8))) + end + for j=-100,-107,-1 do + for i=-1,j,-1 do x = sub(s, 1, bor(i, -8)) end + assert(x == sub(s, 1, bor(j, -8))) + end +end + +do --- jit sub 1 eq + local s = "abcde" + local x = 0 + for i=1,100 do + if sub(s, 1, 1) == "a" then x = x + 1 end + end + assert(x == 100) +end + +do --- jit sub 1 ne (contents) + local s = "abcde" + local x = 0 + for i=1,100 do + if sub(s, 1, 1) == "b" then x = x + 1 end + end + assert(x == 0) +end + +do --- jit sub 1 ne (rhs too long) + local s = "abcde" + local x = 0 + for i=1,100 do + if sub(s, 1, 1) == "ab" then x = x + 1 end + end + assert(x == 0) +end + +do --- jit sub 1,2 ne + local s = "abcde" + local x = 0 + for i=1,100 do + if sub(s, 1, 2) == "a" then x = x + 1 end + end + assert(x == 0) +end + +do --- jit sub 1,k eq + local s = "abcde" + local x = 0 + local k = 1 + for i=1,100 do + if sub(s, 1, k) == "a" then x = x + 1 end + end + assert(x == 100) +end + +do --- jit sub 1,k ne (contents) + local s = "abcde" + local x = 0 + local k = 1 + for i=1,100 do + if sub(s, 1, k) == "b" then x = x + 1 end + end + assert(x == 0) +end + +do --- jit sub 1,k ne (rhs too long) + local s = "abcde" + local x = 0 + local k = 1 + for i=1,100 do + if sub(s, 1, k) == "ab" then x = x + 1 end + end + assert(x == 0) +end + +do --- jit sub 1,2 eq + local s = "abcde" + local x = 0 + for i=1,100 do + if sub(s, 1, 2) == "ab" then x = x + 1 end + end + assert(x == 100) +end + +do --- jit sub 1,3 eq + local s = "abcde" + local x = 0 + for i=1,100 do + if sub(s, 1, 3) == "abc" then x = x + 1 end + end + assert(x == 100) +end + +do --- jit sub 1,4 eq + local s = "abcde" + local x = 0 + for i=1,100 do + if sub(s, 1, 4) == "abcd" then x = x + 1 end + end + assert(x == 100) +end + +do --- jit sub i,i + local t = {} + local line = string.rep("..XX", 100) + local i = 1 + local c = line:sub(i, i) + while c ~= "" and c ~= "Z" do + t[i] = c == "X" and "Y" or c + i = i + 1 + c = line:sub(i, i) + end + assert(table.concat(t) == string.rep("..YY", 100)) +end diff --git a/test/lib/table/concat.lua b/test/lib/table/concat.lua index 514a883fc6..1f2a2f924d 100644 --- a/test/lib/table/concat.lua +++ b/test/lib/table/concat.lua @@ -1,55 +1,55 @@ -local concat, assert, pcall = table.concat, assert, pcall - -do --- table.concat - local t = {a=1,b=2,c=3,d=4,e=5} - t[1] = 4 - t[3] = 6 - local ok, err = pcall(concat, t, "", 1, 3) - assert(not ok and err:match("index 2 ")) - local q = {} - for i=1,100 do q[i] = {9,8,7} end - q[90] = t - for i=1,100 do - assert(pcall(concat, q[i], "", 1, 3) == (i ~= 90)) - end - t[2] = 5 -- index 1 - 3 in hash part - q[91] = {} - q[92] = {9} - for i=1,100 do q[i] = concat(q[i], "x") end - assert(q[90] == "4x5x6") - assert(q[91] == "") - assert(q[92] == "9") - assert(q[93] == "9x8x7") -end - -do --- table.concat must inhibit CSE and DSE - local t = {1,2,3} - local y, z - for i=1,100 do - y = concat(t, "x", 1, 3) - t[2] = i - z = concat(t, "x", 1, 3) - end - assert(y == "1x99x3") - assert(z == "1x100x3") -end - -do --- table.concat must inhibit CSE and DSE 2 - local y - for i=1,100 do - local t = {1,2,3} - t[2] = 4 - y = concat(t, "x") - t[2] = 9 - end - assert(y == "1x4x3") -end - -do --- table.concat must inhibit CSE and DSE 3 - local t = {[0]={}, {}, {}, {}} - for i=1,30 do - for j=3,0,-1 do - t[j].x = t[j-1] - end - end -end +local concat, assert, pcall = table.concat, assert, pcall + +do --- table.concat + local t = {a=1,b=2,c=3,d=4,e=5} + t[1] = 4 + t[3] = 6 + local ok, err = pcall(concat, t, "", 1, 3) + assert(not ok and err:match("index 2 ")) + local q = {} + for i=1,100 do q[i] = {9,8,7} end + q[90] = t + for i=1,100 do + assert(pcall(concat, q[i], "", 1, 3) == (i ~= 90)) + end + t[2] = 5 -- index 1 - 3 in hash part + q[91] = {} + q[92] = {9} + for i=1,100 do q[i] = concat(q[i], "x") end + assert(q[90] == "4x5x6") + assert(q[91] == "") + assert(q[92] == "9") + assert(q[93] == "9x8x7") +end + +do --- table.concat must inhibit CSE and DSE + local t = {1,2,3} + local y, z + for i=1,100 do + y = concat(t, "x", 1, 3) + t[2] = i + z = concat(t, "x", 1, 3) + end + assert(y == "1x99x3") + assert(z == "1x100x3") +end + +do --- table.concat must inhibit CSE and DSE 2 + local y + for i=1,100 do + local t = {1,2,3} + t[2] = 4 + y = concat(t, "x") + t[2] = 9 + end + assert(y == "1x4x3") +end + +do --- table.concat must inhibit CSE and DSE 3 + local t = {[0]={}, {}, {}, {}} + for i=1,30 do + for j=3,0,-1 do + t[j].x = t[j-1] + end + end +end diff --git a/test/lib/table/index b/test/lib/table/index index e400606b0d..bd3af0bef1 100644 --- a/test/lib/table/index +++ b/test/lib/table/index @@ -1,6 +1,6 @@ -concat.lua -insert.lua -new.lua +table.new -pack.lua +compat5.2 -remove.lua -sort.lua +concat.lua +insert.lua +new.lua +table.new +pack.lua +compat5.2 +remove.lua +sort.lua diff --git a/test/lib/table/new.lua b/test/lib/table/new.lua index 8e422477cc..483c1298fe 100644 --- a/test/lib/table/new.lua +++ b/test/lib/table/new.lua @@ -1,11 +1,11 @@ -local tnew = require"table.new" - -do --- table.new - local x, y - for i=1,100 do - x = tnew(100, 30) - assert(type(x) == "table") - if i == 90 then y = x end - end - assert(x ~= y) -end +local tnew = require"table.new" + +do --- table.new + local x, y + for i=1,100 do + x = tnew(100, 30) + assert(type(x) == "table") + if i == 90 then y = x end + end + assert(x ~= y) +end diff --git a/test/lib/table/pack.lua b/test/lib/table/pack.lua index b76e22fd51..5bd6ecbe0e 100644 --- a/test/lib/table/pack.lua +++ b/test/lib/table/pack.lua @@ -1,7 +1,7 @@ -do --- empty - local t = table.pack() - assert(type(t) == "table") - assert(t.n == 0) - assert(t[0] == nil) - assert(t[1] == nil) -end +do --- empty + local t = table.pack() + assert(type(t) == "table") + assert(t.n == 0) + assert(t[0] == nil) + assert(t[1] == nil) +end diff --git a/test/lib/table/sort.lua b/test/lib/table/sort.lua index c95a895e10..6a86fcf382 100644 --- a/test/lib/table/sort.lua +++ b/test/lib/table/sort.lua @@ -1,27 +1,27 @@ --- Really a test for lua_lessthan() -local N = 1000 - -do --- numbers - math.randomseed(42) - local t = {} - for i=1,N do t[i] = math.random(N) end - table.sort(t) - for i=2,N do assert(t[i-1] <= t[i]) end -end - -do --- strings - math.randomseed(42) - local t = {} - for i=1,N do t[i] = math.random(1, N/10).."" end - table.sort(t) - for i=2,N do assert(t[i-1] <= t[i]) end -end - -do --- tables - math.randomseed(42) - local mt = { __lt = function(a,b) return a[1] < b[1] end } - local t = {} - for i=1,N do t[i] = setmetatable({ math.random(N) }, mt) end - table.sort(t) - for i=2,N do assert(t[i-1][1] <= t[i][1]) end -end +-- Really a test for lua_lessthan() +local N = 1000 + +do --- numbers + math.randomseed(42) + local t = {} + for i=1,N do t[i] = math.random(N) end + table.sort(t) + for i=2,N do assert(t[i-1] <= t[i]) end +end + +do --- strings + math.randomseed(42) + local t = {} + for i=1,N do t[i] = math.random(1, N/10).."" end + table.sort(t) + for i=2,N do assert(t[i-1] <= t[i]) end +end + +do --- tables + math.randomseed(42) + local mt = { __lt = function(a,b) return a[1] < b[1] end } + local t = {} + for i=1,N do t[i] = setmetatable({ math.random(N) }, mt) end + table.sort(t) + for i=2,N do assert(t[i-1][1] <= t[i][1]) end +end diff --git a/test/opt/dse/array.lua b/test/opt/dse/array.lua index 867a7372c7..8c766248a3 100644 --- a/test/opt/dse/array.lua +++ b/test/opt/dse/array.lua @@ -1,197 +1,197 @@ -local assert = assert - --- Same value ---------------------------------------------------------------- - -do --- 1 --- Store with same ref and same value. --- 2nd store eliminated. All stores in loop eliminated. - local t = { 1, 2 } - for i=1,100 do - t[1] = 11 - assert(t[1] == 11) - t[1] = 11 - assert(t[1] == 11) - end - assert(t[1] == 11) -end - -do --- 2 --- Store with different tab, same idx and same value. --- All stores in loop eliminated. - local t1 = { 1, 2 } - local t2 = { 1, 2 } - for i=1,100 do - t1[1] = 11 - assert(t1[1] == 11) - t2[1] = 11 - assert(t2[1] == 11) - end - assert(t1[1] == 11) - assert(t2[1] == 11) -end - -do --- 3 --- Store with same tab, different const idx and same value. --- All stores in loop eliminated. Also disambiguated. - local t = { 1, 2 } - for i=1,100 do - t[1] = 11 - assert(t[1] == 11) - t[2] = 11 - assert(t[2] == 11) - end - assert(t[1] == 11) - assert(t[2] == 11) -end - -do --- 4 --- Store with different tab, different const idx and same value. --- All stores in loop eliminated. Also disambiguated. - local t1 = { 1, 2 } - local t2 = { 1, 2 } - for i=1,100 do - t1[1] = 11 - assert(t1[1] == 11) - t2[2] = 11 - assert(t2[2] == 11) - end - assert(t1[1] == 11) - assert(t2[2] == 11) -end - -do --- 5 --- Store with different tab, different non-const idx and same value. --- All stores in loop eliminated. Not disambiguated (but not needed). - local t1 = { 1, 2 } - local t2 = { 1, 2 } - local k = 1 - for i=1,100 do - t1[k] = 11 - assert(t1[k] == 11) - t2[2] = 11 - assert(t2[2] == 11) - end - assert(t1[1] == 11) - assert(t2[2] == 11) -end - -do --- 6 --- Store with same ref, same value and aliased loads. --- 2nd store eliminated. Not disambiguated (but not needed). - local t1 = { 1, 2 } - local t2 = t1 - for i=1,100 do - t1[1] = 11 - assert(t2[1] == 11) - t1[1] = 11 - assert(t2[1] == 11) - end - assert(t1[1] == 11) -end - --- Different value ----------------------------------------------------------- - -do --- 7 --- Store with same ref and different value. --- 1st store eliminated. All stores in loop eliminated. - local t = { 1, 2 } - for i=1,100 do - assert(true) - t[1] = 11 - assert(t[1] == 11) - t[1] = 22 - assert(t[1] == 22) - end - assert(t[1] == 22) -end - -do --- 8 --- Store with different tab, same idx and different value. --- Cannot eliminate any stores (would need dynamic disambiguation). - local t1 = { 1, 2 } - local t2 = { 1, 2 } - for i=1,100 do - assert(true) - t1[1] = 11 - assert(t1[1] == 11) - t2[1] = 22 - assert(t2[1] == 22) - end - assert(t1[1] == 11) - assert(t2[1] == 22) -end - -do --- 9 --- Store with same tab, different const idx and different value. --- Disambiguated. All stores in loop eliminated. - local t = { 1, 2 } - for i=1,100 do - assert(true) - t[1] = 11 - assert(t[1] == 11) - t[2] = 22 - assert(t[2] == 22) - end - assert(t[1] == 11) - assert(t[2] == 22) -end - -do --- 10 --- Store with different tab, different const idx and different value. --- Disambiguated. All stores in loop eliminated. - local t1 = { 1, 2 } - local t2 = { 1, 2 } - for i=1,100 do - assert(true) - t1[1] = 11 - assert(t1[1] == 11) - t2[2] = 22 - assert(t2[2] == 22) - end - assert(t1[1] == 11) - assert(t2[2] == 22) -end - -do --- 11 --- Store with different tab, different non-const idx and different value. --- Cannot eliminate any stores (would need dynamic disambiguation). - local t1 = { 1, 2 } - local t2 = { 1, 2 } - local k = 1 - for i=1,100 do - assert(true) - t1[k] = 11 - assert(t1[k] == 11) - t2[2] = 22 - assert(t2[2] == 22) - end - assert(t1[1] == 11) - assert(t2[2] == 22) -end - -do --- 12 --- Store with same ref, different value and aliased loads. --- Cannot eliminate any stores (would need dynamic disambiguation). - local t1 = { 1, 2 } - local t2 = t1 - for i=1,100 do - assert(true) - t1[1] = 11 - assert(t2[1] == 11) - t1[1] = 22 - assert(t2[1] == 22) - end - assert(t1[1] == 22) -end - -do --- CALLL must inhibit DSE. - local a,b - local t = {1,2} - for i=1,100 do - t[2]=nil - a=#t - t[2]=2 - b=#t - end - assert(a == 1 and b == 2) -end +local assert = assert + +-- Same value ---------------------------------------------------------------- + +do --- 1 +-- Store with same ref and same value. +-- 2nd store eliminated. All stores in loop eliminated. + local t = { 1, 2 } + for i=1,100 do + t[1] = 11 + assert(t[1] == 11) + t[1] = 11 + assert(t[1] == 11) + end + assert(t[1] == 11) +end + +do --- 2 +-- Store with different tab, same idx and same value. +-- All stores in loop eliminated. + local t1 = { 1, 2 } + local t2 = { 1, 2 } + for i=1,100 do + t1[1] = 11 + assert(t1[1] == 11) + t2[1] = 11 + assert(t2[1] == 11) + end + assert(t1[1] == 11) + assert(t2[1] == 11) +end + +do --- 3 +-- Store with same tab, different const idx and same value. +-- All stores in loop eliminated. Also disambiguated. + local t = { 1, 2 } + for i=1,100 do + t[1] = 11 + assert(t[1] == 11) + t[2] = 11 + assert(t[2] == 11) + end + assert(t[1] == 11) + assert(t[2] == 11) +end + +do --- 4 +-- Store with different tab, different const idx and same value. +-- All stores in loop eliminated. Also disambiguated. + local t1 = { 1, 2 } + local t2 = { 1, 2 } + for i=1,100 do + t1[1] = 11 + assert(t1[1] == 11) + t2[2] = 11 + assert(t2[2] == 11) + end + assert(t1[1] == 11) + assert(t2[2] == 11) +end + +do --- 5 +-- Store with different tab, different non-const idx and same value. +-- All stores in loop eliminated. Not disambiguated (but not needed). + local t1 = { 1, 2 } + local t2 = { 1, 2 } + local k = 1 + for i=1,100 do + t1[k] = 11 + assert(t1[k] == 11) + t2[2] = 11 + assert(t2[2] == 11) + end + assert(t1[1] == 11) + assert(t2[2] == 11) +end + +do --- 6 +-- Store with same ref, same value and aliased loads. +-- 2nd store eliminated. Not disambiguated (but not needed). + local t1 = { 1, 2 } + local t2 = t1 + for i=1,100 do + t1[1] = 11 + assert(t2[1] == 11) + t1[1] = 11 + assert(t2[1] == 11) + end + assert(t1[1] == 11) +end + +-- Different value ----------------------------------------------------------- + +do --- 7 +-- Store with same ref and different value. +-- 1st store eliminated. All stores in loop eliminated. + local t = { 1, 2 } + for i=1,100 do + assert(true) + t[1] = 11 + assert(t[1] == 11) + t[1] = 22 + assert(t[1] == 22) + end + assert(t[1] == 22) +end + +do --- 8 +-- Store with different tab, same idx and different value. +-- Cannot eliminate any stores (would need dynamic disambiguation). + local t1 = { 1, 2 } + local t2 = { 1, 2 } + for i=1,100 do + assert(true) + t1[1] = 11 + assert(t1[1] == 11) + t2[1] = 22 + assert(t2[1] == 22) + end + assert(t1[1] == 11) + assert(t2[1] == 22) +end + +do --- 9 +-- Store with same tab, different const idx and different value. +-- Disambiguated. All stores in loop eliminated. + local t = { 1, 2 } + for i=1,100 do + assert(true) + t[1] = 11 + assert(t[1] == 11) + t[2] = 22 + assert(t[2] == 22) + end + assert(t[1] == 11) + assert(t[2] == 22) +end + +do --- 10 +-- Store with different tab, different const idx and different value. +-- Disambiguated. All stores in loop eliminated. + local t1 = { 1, 2 } + local t2 = { 1, 2 } + for i=1,100 do + assert(true) + t1[1] = 11 + assert(t1[1] == 11) + t2[2] = 22 + assert(t2[2] == 22) + end + assert(t1[1] == 11) + assert(t2[2] == 22) +end + +do --- 11 +-- Store with different tab, different non-const idx and different value. +-- Cannot eliminate any stores (would need dynamic disambiguation). + local t1 = { 1, 2 } + local t2 = { 1, 2 } + local k = 1 + for i=1,100 do + assert(true) + t1[k] = 11 + assert(t1[k] == 11) + t2[2] = 22 + assert(t2[2] == 22) + end + assert(t1[1] == 11) + assert(t2[2] == 22) +end + +do --- 12 +-- Store with same ref, different value and aliased loads. +-- Cannot eliminate any stores (would need dynamic disambiguation). + local t1 = { 1, 2 } + local t2 = t1 + for i=1,100 do + assert(true) + t1[1] = 11 + assert(t2[1] == 11) + t1[1] = 22 + assert(t2[1] == 22) + end + assert(t1[1] == 22) +end + +do --- CALLL must inhibit DSE. + local a,b + local t = {1,2} + for i=1,100 do + t[2]=nil + a=#t + t[2]=2 + b=#t + end + assert(a == 1 and b == 2) +end diff --git a/test/opt/dse/field.lua b/test/opt/dse/field.lua index 9b544577fb..d8a5411c75 100644 --- a/test/opt/dse/field.lua +++ b/test/opt/dse/field.lua @@ -1,70 +1,70 @@ -local getmetatable, setmetatable = getmetatable, setmetatable - -do --- 1. Store with same ref and same value. All stores in loop eliminated. - local mt = {} - local t = {} - for i=1,100 do - setmetatable(t, mt) - assert(getmetatable(t) == mt) - setmetatable(t, mt) - assert(getmetatable(t) == mt) - end - assert(getmetatable(t) == mt) -end - -do --- 2. Store with different ref and same value. All stores in loop eliminated. - local mt = {} - local t1 = {} - local t2 = {} - for i=1,100 do - setmetatable(t1, mt) - assert(getmetatable(t1) == mt) - setmetatable(t2, mt) - assert(getmetatable(t2) == mt) - end - assert(getmetatable(t1) == mt) - assert(getmetatable(t2) == mt) -end - -do --- 3. Store with different ref and different value. Cannot eliminate any stores. - local mt1 = {} - local mt2 = {} - local t1 = {} - local t2 = {} - for i=1,100 do - setmetatable(t1, mt1) - assert(getmetatable(t1) == mt1) - setmetatable(t2, mt2) - assert(getmetatable(t2) == mt2) - end - assert(getmetatable(t1) == mt1) - assert(getmetatable(t2) == mt2) -end - -do --- 4. Store with same ref and different value. 2nd store remains in loop. - local mt1 = {} - local mt2 = {} - local t = {} - for i=1,100 do - setmetatable(t, mt1) - assert(getmetatable(t) == mt1) - setmetatable(t, mt2) - assert(getmetatable(t) == mt2) - end - assert(getmetatable(t) == mt2) -end - -do --- 5. Store with same ref, different value and aliased loads. --- Cannot eliminate any stores. - local mt1 = {} - local mt2 = {} - local t1 = {} - local t2 = t1 - for i=1,100 do - setmetatable(t1, mt1) - assert(getmetatable(t2) == mt1) - setmetatable(t1, mt2) - assert(getmetatable(t2) == mt2) - end - assert(getmetatable(t1) == mt2) -end +local getmetatable, setmetatable = getmetatable, setmetatable + +do --- 1. Store with same ref and same value. All stores in loop eliminated. + local mt = {} + local t = {} + for i=1,100 do + setmetatable(t, mt) + assert(getmetatable(t) == mt) + setmetatable(t, mt) + assert(getmetatable(t) == mt) + end + assert(getmetatable(t) == mt) +end + +do --- 2. Store with different ref and same value. All stores in loop eliminated. + local mt = {} + local t1 = {} + local t2 = {} + for i=1,100 do + setmetatable(t1, mt) + assert(getmetatable(t1) == mt) + setmetatable(t2, mt) + assert(getmetatable(t2) == mt) + end + assert(getmetatable(t1) == mt) + assert(getmetatable(t2) == mt) +end + +do --- 3. Store with different ref and different value. Cannot eliminate any stores. + local mt1 = {} + local mt2 = {} + local t1 = {} + local t2 = {} + for i=1,100 do + setmetatable(t1, mt1) + assert(getmetatable(t1) == mt1) + setmetatable(t2, mt2) + assert(getmetatable(t2) == mt2) + end + assert(getmetatable(t1) == mt1) + assert(getmetatable(t2) == mt2) +end + +do --- 4. Store with same ref and different value. 2nd store remains in loop. + local mt1 = {} + local mt2 = {} + local t = {} + for i=1,100 do + setmetatable(t, mt1) + assert(getmetatable(t) == mt1) + setmetatable(t, mt2) + assert(getmetatable(t) == mt2) + end + assert(getmetatable(t) == mt2) +end + +do --- 5. Store with same ref, different value and aliased loads. +-- Cannot eliminate any stores. + local mt1 = {} + local mt2 = {} + local t1 = {} + local t2 = t1 + for i=1,100 do + setmetatable(t1, mt1) + assert(getmetatable(t2) == mt1) + setmetatable(t1, mt2) + assert(getmetatable(t2) == mt2) + end + assert(getmetatable(t1) == mt2) +end diff --git a/test/opt/dse/index b/test/opt/dse/index index 6d9d9478ec..7b8ad1f4cd 100644 --- a/test/opt/dse/index +++ b/test/opt/dse/index @@ -1,2 +1,2 @@ -array.lua -field.lua +array.lua +field.lua diff --git a/test/opt/fold/index b/test/opt/fold/index index 3bc303fd0c..8b4648c788 100644 --- a/test/opt/fold/index +++ b/test/opt/fold/index @@ -1 +1 @@ -kfold.lua +kfold.lua diff --git a/test/opt/fold/kfold.lua b/test/opt/fold/kfold.lua index 1db29084db..4100bf9150 100644 --- a/test/opt/fold/kfold.lua +++ b/test/opt/fold/kfold.lua @@ -1,81 +1,81 @@ -do --- operators - local y = 0 - for i=1,100 do local a, b = 23, 11; y = a+b end; assert(y == 23+11) - for i=1,100 do local a, b = 23, 11; y = a-b end; assert(y == 23-11) - for i=1,100 do local a, b = 23, 11; y = a*b end; assert(y == 23*11) - for i=1,100 do local a, b = 23, 11; y = a/b end; assert(y == 23/11) - for i=1,100 do local a, b = 23, 11; y = a%b end; assert(y == 23%11) - for i=1,100 do local a, b = 23, 11; y = a^b end; assert(y == 23^11) - - for i=1,100 do local a, b = 23.5, 11.5; y = a+b end; assert(y == 23.5+11.5) - for i=1,100 do local a, b = 23.5, 11.5; y = a-b end; assert(y == 23.5-11.5) - for i=1,100 do local a, b = 23.5, 11.5; y = a*b end; assert(y == 23.5*11.5) - for i=1,100 do local a, b = 23.5, 11.5; y = a/b end; assert(y == 23.5/11.5) - for i=1,100 do local a, b = 23.5, 11.5; y = a%b end; assert(y == 23.5%11.5) -end - -do --- abs - local y = 0 - for i=1,100 do local a=23; y = math.abs(a) end; assert(y == math.abs(23)) - for i=1,100 do local a=-23; y = math.abs(a) end; assert(y == math.abs(-23)) - for i=1,100 do local a=23.5; y = math.abs(a) end; assert(y == math.abs(23.5)) - for i=1,100 do local a=-23.5; y = math.abs(a) end; assert(y==math.abs(-23.5)) - for i=1,100 do local a=-2^31; y = math.abs(a) end; assert(y==math.abs(-2^31)) -end - -do --- atan2 ldexp - local y = 0 - for i=1,100 do local a, b = 23, 11; y = math.atan2(a, b) end - assert(y == math.atan2(23, 11)) - for i=1,100 do local a, b = 23, 11; y = math.ldexp(a, b) end - assert(y == math.ldexp(23, 11)) -end - -do --- minmax - local y = 0 - for i=1,100 do local a, b = 23, 11; y = math.min(a, b) end - assert(y == math.min(23, 11)) - for i=1,100 do local a, b = 23, 11; y = math.max(a, b) end - assert(y == math.max(23, 11)) - for i=1,100 do local a, b = 23.5, 11.5; y = math.min(a, b) end - assert(y == math.min(23.5, 11.5)) - for i=1,100 do local a, b = 23.5, 11.5; y = math.max(a, b) end - assert(y == math.max(23.5, 11.5)) - for i=1,100 do local a, b = 11, 23; y = math.min(a, b) end - assert(y == math.min(11, 23)) - for i=1,100 do local a, b = 11, 23; y = math.max(a, b) end - assert(y == math.max(11, 23)) - for i=1,100 do local a, b = 11.5, 23.5; y = math.min(a, b) end - assert(y == math.min(11.5, 23.5)) - for i=1,100 do local a, b = 11.5, 23.5; y = math.max(a, b) end - assert(y == math.max(11.5, 23.5)) -end - -do --- floorceil - local y = 0 - for i=1,100 do local a=23; y=math.floor(a) end assert(y==math.floor(23)) - for i=1,100 do local a=23.5; y=math.floor(a) end assert(y==math.floor(23.5)) - for i=1,100 do local a=-23; y=math.floor(a) end assert(y==math.floor(-23)) - for i=1,100 do local a=-23.5; y=math.floor(a) end assert(y==math.floor(-23.5)) - for i=1,100 do local a=-0; y=math.floor(a) end assert(y==math.floor(-0)) - for i=1,100 do local a=23; y=math.ceil(a) end assert(y==math.ceil(23)) - for i=1,100 do local a=23.5; y=math.ceil(a) end assert(y==math.ceil(23.5)) - for i=1,100 do local a=-23; y=math.ceil(a) end assert(y==math.ceil(-23)) - for i=1,100 do local a=-23.5; y=math.ceil(a) end assert(y==math.ceil(-23.5)) - for i=1,100 do local a=-0; y=math.ceil(a) end assert(y==math.ceil(-0)) -end - -do --- sqrt exp log trig - local y = 0 - for i=1,100 do local a=23; y=math.sqrt(a) end assert(y==math.sqrt(23)) - for i=1,100 do local a=23; y=math.exp(a) end assert(y==math.exp(23)) - for i=1,100 do local a=23; y=math.log(a) end assert(y==math.log(23)) - for i=1,100 do local a=23; y=math.log10(a) end assert(y==math.log10(23)) - for i=1,100 do local a=23; y=math.sin(a) end assert(y==math.sin(23)) - for i=1,100 do local a=23; y=math.cos(a) end assert(y==math.cos(23)) - for i=1,100 do local a=23; y=math.tan(a) end assert(y==math.tan(23)) -end - -do --- exp - assert((10^-2 - 0.01) == 0) -end +do --- operators + local y = 0 + for i=1,100 do local a, b = 23, 11; y = a+b end; assert(y == 23+11) + for i=1,100 do local a, b = 23, 11; y = a-b end; assert(y == 23-11) + for i=1,100 do local a, b = 23, 11; y = a*b end; assert(y == 23*11) + for i=1,100 do local a, b = 23, 11; y = a/b end; assert(y == 23/11) + for i=1,100 do local a, b = 23, 11; y = a%b end; assert(y == 23%11) + for i=1,100 do local a, b = 23, 11; y = a^b end; assert(y == 23^11) + + for i=1,100 do local a, b = 23.5, 11.5; y = a+b end; assert(y == 23.5+11.5) + for i=1,100 do local a, b = 23.5, 11.5; y = a-b end; assert(y == 23.5-11.5) + for i=1,100 do local a, b = 23.5, 11.5; y = a*b end; assert(y == 23.5*11.5) + for i=1,100 do local a, b = 23.5, 11.5; y = a/b end; assert(y == 23.5/11.5) + for i=1,100 do local a, b = 23.5, 11.5; y = a%b end; assert(y == 23.5%11.5) +end + +do --- abs + local y = 0 + for i=1,100 do local a=23; y = math.abs(a) end; assert(y == math.abs(23)) + for i=1,100 do local a=-23; y = math.abs(a) end; assert(y == math.abs(-23)) + for i=1,100 do local a=23.5; y = math.abs(a) end; assert(y == math.abs(23.5)) + for i=1,100 do local a=-23.5; y = math.abs(a) end; assert(y==math.abs(-23.5)) + for i=1,100 do local a=-2^31; y = math.abs(a) end; assert(y==math.abs(-2^31)) +end + +do --- atan2 ldexp + local y = 0 + for i=1,100 do local a, b = 23, 11; y = math.atan2(a, b) end + assert(y == math.atan2(23, 11)) + for i=1,100 do local a, b = 23, 11; y = math.ldexp(a, b) end + assert(y == math.ldexp(23, 11)) +end + +do --- minmax + local y = 0 + for i=1,100 do local a, b = 23, 11; y = math.min(a, b) end + assert(y == math.min(23, 11)) + for i=1,100 do local a, b = 23, 11; y = math.max(a, b) end + assert(y == math.max(23, 11)) + for i=1,100 do local a, b = 23.5, 11.5; y = math.min(a, b) end + assert(y == math.min(23.5, 11.5)) + for i=1,100 do local a, b = 23.5, 11.5; y = math.max(a, b) end + assert(y == math.max(23.5, 11.5)) + for i=1,100 do local a, b = 11, 23; y = math.min(a, b) end + assert(y == math.min(11, 23)) + for i=1,100 do local a, b = 11, 23; y = math.max(a, b) end + assert(y == math.max(11, 23)) + for i=1,100 do local a, b = 11.5, 23.5; y = math.min(a, b) end + assert(y == math.min(11.5, 23.5)) + for i=1,100 do local a, b = 11.5, 23.5; y = math.max(a, b) end + assert(y == math.max(11.5, 23.5)) +end + +do --- floorceil + local y = 0 + for i=1,100 do local a=23; y=math.floor(a) end assert(y==math.floor(23)) + for i=1,100 do local a=23.5; y=math.floor(a) end assert(y==math.floor(23.5)) + for i=1,100 do local a=-23; y=math.floor(a) end assert(y==math.floor(-23)) + for i=1,100 do local a=-23.5; y=math.floor(a) end assert(y==math.floor(-23.5)) + for i=1,100 do local a=-0; y=math.floor(a) end assert(y==math.floor(-0)) + for i=1,100 do local a=23; y=math.ceil(a) end assert(y==math.ceil(23)) + for i=1,100 do local a=23.5; y=math.ceil(a) end assert(y==math.ceil(23.5)) + for i=1,100 do local a=-23; y=math.ceil(a) end assert(y==math.ceil(-23)) + for i=1,100 do local a=-23.5; y=math.ceil(a) end assert(y==math.ceil(-23.5)) + for i=1,100 do local a=-0; y=math.ceil(a) end assert(y==math.ceil(-0)) +end + +do --- sqrt exp log trig + local y = 0 + for i=1,100 do local a=23; y=math.sqrt(a) end assert(y==math.sqrt(23)) + for i=1,100 do local a=23; y=math.exp(a) end assert(y==math.exp(23)) + for i=1,100 do local a=23; y=math.log(a) end assert(y==math.log(23)) + for i=1,100 do local a=23; y=math.log10(a) end assert(y==math.log10(23)) + for i=1,100 do local a=23; y=math.sin(a) end assert(y==math.sin(23)) + for i=1,100 do local a=23; y=math.cos(a) end assert(y==math.cos(23)) + for i=1,100 do local a=23; y=math.tan(a) end assert(y==math.tan(23)) +end + +do --- exp + assert((10^-2 - 0.01) == 0) +end diff --git a/test/opt/fuse.lua b/test/opt/fuse.lua index 57c5c9df03..a68381ef07 100644 --- a/test/opt/fuse.lua +++ b/test/opt/fuse.lua @@ -1,5 +1,5 @@ -do --- Don't fuse i+101 on x64. --- (except if i is sign-extended to 64 bit or addressing is limited to 32 bit) - local t = {} - for i=-100,-1 do t[i+101] = 1 end -end +do --- Don't fuse i+101 on x64. +-- (except if i is sign-extended to 64 bit or addressing is limited to 32 bit) + local t = {} + for i=-100,-1 do t[i+101] = 1 end +end diff --git a/test/opt/fwd/hrefk_rollback.lua b/test/opt/fwd/hrefk_rollback.lua index 32ba95d28c..5a6ad87688 100644 --- a/test/opt/fwd/hrefk_rollback.lua +++ b/test/opt/fwd/hrefk_rollback.lua @@ -1,32 +1,32 @@ -do --- https://github.com/LuaJIT/LuaJIT/issues/124 - local function foo(a, b, f) - return f and (a.f0 < b.f1 and - b.f0 < a.f1 and - a.f2 < b.f3 and - b.f2 < a.f3) - end - - local function bar(f0, f1, f2, f3, X, f) - for _, v in ipairs(X) do - local b = {} - b.f0 = 0 - b.f2 = v - b.f1 = b.f0 + 1 - b.f3 = b.f2 + 1 - - if foo({f0 = f0, f1 = f1, f2 = f2, f3 = f3}, b, f) then - return false - end - end - - return true - end - - local X = { 0, 1, 0, 0 } - - for i = 1, 20 do - assert(bar(0, 1, 2, 3, X, true)) - end - - assert(not bar(0, 1, 1, 2, X, true)) -end +do --- https://github.com/LuaJIT/LuaJIT/issues/124 + local function foo(a, b, f) + return f and (a.f0 < b.f1 and + b.f0 < a.f1 and + a.f2 < b.f3 and + b.f2 < a.f3) + end + + local function bar(f0, f1, f2, f3, X, f) + for _, v in ipairs(X) do + local b = {} + b.f0 = 0 + b.f2 = v + b.f1 = b.f0 + 1 + b.f3 = b.f2 + 1 + + if foo({f0 = f0, f1 = f1, f2 = f2, f3 = f3}, b, f) then + return false + end + end + + return true + end + + local X = { 0, 1, 0, 0 } + + for i = 1, 20 do + assert(bar(0, 1, 2, 3, X, true)) + end + + assert(not bar(0, 1, 1, 2, X, true)) +end diff --git a/test/opt/fwd/index b/test/opt/fwd/index index 74d3bdbd69..5bb1537f0a 100644 --- a/test/opt/fwd/index +++ b/test/opt/fwd/index @@ -1,3 +1,3 @@ -hrefk_rollback.lua -tnew_tdup.lua -upval.lua +hrefk_rollback.lua +tnew_tdup.lua +upval.lua diff --git a/test/opt/fwd/tnew_tdup.lua b/test/opt/fwd/tnew_tdup.lua index 375863f69f..9e18fa3bd1 100644 --- a/test/opt/fwd/tnew_tdup.lua +++ b/test/opt/fwd/tnew_tdup.lua @@ -1,69 +1,69 @@ -do --- 1. - local x = 2 - for i=1,100 do - local t = {} -- TNEW: DCE - x = t.foo -- HREF -> niltv: folded - end - assert(x == nil) -end - -do --- 2. - local x = 2 - for i=1,100 do - local t = {1} -- TDUP: DCE - x = t.foo -- HREF -> niltv: folded - end - assert(x == nil) -end - -do --- 3. - local x = 2 - for i=1,100 do - local t = {} - t[1] = 11 -- NEWREF + HSTORE - x = t[1] -- AREF + ALOAD, no forwarding, no fold - end - assert(x == 11) -end - -do --- 4. HREFK not eliminated. Ditto for the EQ(FLOAD(t, #tab.hmask), k). - local x = 2 - for i=1,100 do - local t = {} - t.foo = 11 -- NEWREF + HSTORE - x = t.foo -- HREFK + HLOAD: store forwarding - end - assert(x == 11) -end - -do --- 5. HREFK not eliminated. Ditto for the EQ(FLOAD(t, #tab.hmask), k). - local x = 2 - for i=1,100 do - local t = {foo=11} -- TDUP - x = t.foo -- HREFK + non-nil HLOAD: folded - end - assert(x == 11) -end - -do --- 6. - local x = 2 - local k = 1 - for i=1,100 do - local t = {[0]=11} -- TDUP - t[k] = 22 -- AREF + ASTORE aliasing - x = t[0] -- AREF + ALOAD, no fold - end - assert(x == 11) -end - -do --- 7. - local setmetatable = setmetatable - local mt = { __newindex = function(t, k, v) - assert(k == "foo") - assert(v == 11) - end } - for i=1,100 do - local t = setmetatable({}, mt) - t.foo = 11 - end -end +do --- 1. + local x = 2 + for i=1,100 do + local t = {} -- TNEW: DCE + x = t.foo -- HREF -> niltv: folded + end + assert(x == nil) +end + +do --- 2. + local x = 2 + for i=1,100 do + local t = {1} -- TDUP: DCE + x = t.foo -- HREF -> niltv: folded + end + assert(x == nil) +end + +do --- 3. + local x = 2 + for i=1,100 do + local t = {} + t[1] = 11 -- NEWREF + HSTORE + x = t[1] -- AREF + ALOAD, no forwarding, no fold + end + assert(x == 11) +end + +do --- 4. HREFK not eliminated. Ditto for the EQ(FLOAD(t, #tab.hmask), k). + local x = 2 + for i=1,100 do + local t = {} + t.foo = 11 -- NEWREF + HSTORE + x = t.foo -- HREFK + HLOAD: store forwarding + end + assert(x == 11) +end + +do --- 5. HREFK not eliminated. Ditto for the EQ(FLOAD(t, #tab.hmask), k). + local x = 2 + for i=1,100 do + local t = {foo=11} -- TDUP + x = t.foo -- HREFK + non-nil HLOAD: folded + end + assert(x == 11) +end + +do --- 6. + local x = 2 + local k = 1 + for i=1,100 do + local t = {[0]=11} -- TDUP + t[k] = 22 -- AREF + ASTORE aliasing + x = t[0] -- AREF + ALOAD, no fold + end + assert(x == 11) +end + +do --- 7. + local setmetatable = setmetatable + local mt = { __newindex = function(t, k, v) + assert(k == "foo") + assert(v == 11) + end } + for i=1,100 do + local t = setmetatable({}, mt) + t.foo = 11 + end +end diff --git a/test/opt/fwd/upval.lua b/test/opt/fwd/upval.lua index 5bc1cc96cb..a3e83dff4e 100644 --- a/test/opt/fwd/upval.lua +++ b/test/opt/fwd/upval.lua @@ -1,50 +1,50 @@ -do --- 1. Open upvalue above base slot, aliasing an SSA value. - local x = 7 - local function a() x = x + 1 end - local function b() x = x + 2 end - for i=1,100 do a(); b(); x = x + 5 end - assert(x == 807) -end - -do --- 2. Open upvalue below base slot. UREFO CSE for a.x + b.x, but not x in loop. - -- ULOAD not disambiguated. 2x ULOAD + 2x USTORE (+ 1x DSE USTORE). - local x = 7 - (function() - local function a() x = x + 1 end - local function b() x = x + 2 end - for i=1,100 do a(); b(); x = x + 5 end - end)() - assert(x == 807) -end - -do --- 3. Closed upvalue. UREFC CSE for a.x + b.x, but not x in loop. - -- ULOAD not disambiguated. 2x ULOAD + 2x USTORE (+ 1x DSE for USTORE). - local xx = (function() - local x = 7 - local function a() x = x + 1 end - local function b() x = x + 2 end - return function() for i=1,100 do a(); b(); x = x + 5 end; return x end - end)()() - assert(xx == 807) -end - -do --- 4. Open upvalue below base slot. Forwarded. 1x USTORE (+ 1x DSE USTORE). - local x = 7 - (function() - local function a() x = x + 1 end - for i=1,100 do a(); a() end - end)() - assert(x == 207) -end - -do --- 5. Closed upvalue. Forwarded. 1x USTORE (+ 1x DSE USTORE). - local xx = (function() - local x = 7 - return function() - local function a() x = x + 1 end - for i=1,100 do a(); a() end - return x - end - end)()() - assert(xx == 207) -end +do --- 1. Open upvalue above base slot, aliasing an SSA value. + local x = 7 + local function a() x = x + 1 end + local function b() x = x + 2 end + for i=1,100 do a(); b(); x = x + 5 end + assert(x == 807) +end + +do --- 2. Open upvalue below base slot. UREFO CSE for a.x + b.x, but not x in loop. + -- ULOAD not disambiguated. 2x ULOAD + 2x USTORE (+ 1x DSE USTORE). + local x = 7 + (function() + local function a() x = x + 1 end + local function b() x = x + 2 end + for i=1,100 do a(); b(); x = x + 5 end + end)() + assert(x == 807) +end + +do --- 3. Closed upvalue. UREFC CSE for a.x + b.x, but not x in loop. + -- ULOAD not disambiguated. 2x ULOAD + 2x USTORE (+ 1x DSE for USTORE). + local xx = (function() + local x = 7 + local function a() x = x + 1 end + local function b() x = x + 2 end + return function() for i=1,100 do a(); b(); x = x + 5 end; return x end + end)()() + assert(xx == 807) +end + +do --- 4. Open upvalue below base slot. Forwarded. 1x USTORE (+ 1x DSE USTORE). + local x = 7 + (function() + local function a() x = x + 1 end + for i=1,100 do a(); a() end + end)() + assert(x == 207) +end + +do --- 5. Closed upvalue. Forwarded. 1x USTORE (+ 1x DSE USTORE). + local xx = (function() + local x = 7 + return function() + local function a() x = x + 1 end + for i=1,100 do a(); a() end + return x + end + end)()() + assert(xx == 207) +end diff --git a/test/opt/index b/test/opt/index index 2aeaa8f16d..94d50aecfd 100644 --- a/test/opt/index +++ b/test/opt/index @@ -1,6 +1,6 @@ -dse +dse -fold +fold -fwd +fwd -fuse.lua +fuse -loop +loop -sink +sink +dse +dse +fold +fold +fwd +fwd +fuse.lua +fuse +loop +loop +sink +sink diff --git a/test/opt/loop/index b/test/opt/loop/index index 321efe23fb..e582023481 100644 --- a/test/opt/loop/index +++ b/test/opt/loop/index @@ -1 +1 @@ -unroll.lua +unroll.lua diff --git a/test/opt/loop/unroll.lua b/test/opt/loop/unroll.lua index 4c856a5813..6fbd565afc 100644 --- a/test/opt/loop/unroll.lua +++ b/test/opt/loop/unroll.lua @@ -1,32 +1,32 @@ -do --- type instability on loop unroll -> record unroll - local flip = true - for i=1,100 do flip = not flip end - assert(flip == true) -end - -do --- untitled - local t = {} - local a, b, c = 1, "", t - for i=1,100 do a,b,c=b,c,a end - assert(c == 1 and a == "" and b == t) -end - -do --- FAILFOLD on loop unroll -> LJ_TRERR_GFAIL -> record unroll - local t = { 1, 2 } - local k = 2 - local x = 0 - for i=1,200 do - x = x + t[k] - k = k == 1 and 2 or 1 - end - assert(x == 300 and k == 2) -end - -do --- Unroll if inner loop aborts. - local j = 0 - for i = 1,100 do - repeat - j = j+1 - until true - end -end +do --- type instability on loop unroll -> record unroll + local flip = true + for i=1,100 do flip = not flip end + assert(flip == true) +end + +do --- untitled + local t = {} + local a, b, c = 1, "", t + for i=1,100 do a,b,c=b,c,a end + assert(c == 1 and a == "" and b == t) +end + +do --- FAILFOLD on loop unroll -> LJ_TRERR_GFAIL -> record unroll + local t = { 1, 2 } + local k = 2 + local x = 0 + for i=1,200 do + x = x + t[k] + k = k == 1 and 2 or 1 + end + assert(x == 300 and k == 2) +end + +do --- Unroll if inner loop aborts. + local j = 0 + for i = 1,100 do + repeat + j = j+1 + until true + end +end diff --git a/test/opt/sink/alloc.lua b/test/opt/sink/alloc.lua index a83e8f05ac..bb2a0f7272 100644 --- a/test/opt/sink/alloc.lua +++ b/test/opt/sink/alloc.lua @@ -1,126 +1,126 @@ -local assert = assert - -do --- DCE or sink trivial TNEW or TDUP. - for i=1,100 do local t={} end - for i=1,100 do local t={1} end -end - -do --- Sink TNEW/TDUP + ASTORE/HSTORE. - for i=1,100 do local t={i}; assert(t[1] == i) end - for i=1,100 do local t={foo=i}; assert(t.foo == i) end - for i=1,100 do local t={1,i}; assert(t[2] == i) end - for i=1,100 do local t={bar=1,foo=i}; assert(t.foo == i) end -end - -do --- Sink outermost table of nested TNEW. - local x - for i=1,100 do - local t = {[0]={{1,i}}} - if i == 90 then x = t end - assert(t[0][1][2] == i) - end - assert(x[0][1][2] == 90) - for i=1,100 do - local t = {foo={bar={baz=i}}} - if i == 90 then x = t end - assert(t.foo.bar.baz == i) - end - assert(x.foo.bar.baz == 90) -end - -do --- Sink one TNEW + FSTORE. - for i=1,100 do local t = setmetatable({}, {}) end -end - -do --- Sink TDUP or TDUP + HSTORE. Guard of HREFK eliminated. - local x - for i=1,100 do local t = { foo = 1 }; x = t.foo; end - assert(x == 1) - for i=1,100 do local t = { foo = i }; x = t.foo; end - assert(x == 100) -end - -do --- Sink of simplified complex add, unused in next iteration, drop PHI. - local x={1,2} - for i=1,100 do x = {x[1]+3, x[2]+4} end - assert(x[1] == 301) - assert(x[2] == 402) -end - -do --- Sink of complex add, unused in next iteration, drop PHI. - local x,k={1.5,2.5},{3.5,4.5} - for i=1,100 do x = {x[1]+k[1], x[2]+k[2]} end - assert(x[1] == 351.5) - assert(x[2] == 452.5) -end - -do --- Sink of TDUP with stored values that are both PHI and non-PHI. - local x,k={1,2},{3,4} - for i=1,100 do x = {x[1]+k[1], k[2]} end - assert(x[1] == 301) - assert(x[2] == 4) -end - -do --- Sink of CONV. - local t = {1} - local x,y - for i=1,200 do - local v = {i} - local w = {i+1} - x = v[1] - y = w[1] - if i > 100 then end - end - assert(x == 200 and y == 201) -end - -do --- Sink of stores with numbers. - local x = {1.5, 0} - for i=1,200 do x = {x[1]+1, 99.5}; x[2]=4.5; if i > 100 then end end - assert(x[1] == 201.5) - assert(x[2] == 4.5) -end - -do --- Sink of stores with constants. - for i=1,100 do local t = {false}; t[1] = true; if i > 100 then g=t end end -end - -do --- Sink with two references to the same table. - for i=1,200 do - local t = {i} - local q = t - if i > 100 then assert(t == q) end - end -end - -do --- point - local point - point = { - new = function(self, x, y) - return setmetatable({x=x, y=y}, self) - end, - __add = function(a, b) - return point:new(a.x + b.x, a.y + b.y) - end, - } - point.__index = point - local a, b = point:new(1, 1), point:new(2, 2) - for i=1,100 do a = (a + b) + b end - assert(a.x == 401) - assert(a.y == 401) - assert(getmetatable(a) == point) - for i=1,200 do a = (a + b) + b; if i > 100 then end end - assert(a.x == 1201) - assert(a.y == 1201) - assert(getmetatable(a) == point) -end - -do --- untitled - local t = {} - for i=1,20 do t[i] = 1 end - for i=1,20 do - for a,b in ipairs(t) do - local s = {i} - end - end -end +local assert = assert + +do --- DCE or sink trivial TNEW or TDUP. + for i=1,100 do local t={} end + for i=1,100 do local t={1} end +end + +do --- Sink TNEW/TDUP + ASTORE/HSTORE. + for i=1,100 do local t={i}; assert(t[1] == i) end + for i=1,100 do local t={foo=i}; assert(t.foo == i) end + for i=1,100 do local t={1,i}; assert(t[2] == i) end + for i=1,100 do local t={bar=1,foo=i}; assert(t.foo == i) end +end + +do --- Sink outermost table of nested TNEW. + local x + for i=1,100 do + local t = {[0]={{1,i}}} + if i == 90 then x = t end + assert(t[0][1][2] == i) + end + assert(x[0][1][2] == 90) + for i=1,100 do + local t = {foo={bar={baz=i}}} + if i == 90 then x = t end + assert(t.foo.bar.baz == i) + end + assert(x.foo.bar.baz == 90) +end + +do --- Sink one TNEW + FSTORE. + for i=1,100 do local t = setmetatable({}, {}) end +end + +do --- Sink TDUP or TDUP + HSTORE. Guard of HREFK eliminated. + local x + for i=1,100 do local t = { foo = 1 }; x = t.foo; end + assert(x == 1) + for i=1,100 do local t = { foo = i }; x = t.foo; end + assert(x == 100) +end + +do --- Sink of simplified complex add, unused in next iteration, drop PHI. + local x={1,2} + for i=1,100 do x = {x[1]+3, x[2]+4} end + assert(x[1] == 301) + assert(x[2] == 402) +end + +do --- Sink of complex add, unused in next iteration, drop PHI. + local x,k={1.5,2.5},{3.5,4.5} + for i=1,100 do x = {x[1]+k[1], x[2]+k[2]} end + assert(x[1] == 351.5) + assert(x[2] == 452.5) +end + +do --- Sink of TDUP with stored values that are both PHI and non-PHI. + local x,k={1,2},{3,4} + for i=1,100 do x = {x[1]+k[1], k[2]} end + assert(x[1] == 301) + assert(x[2] == 4) +end + +do --- Sink of CONV. + local t = {1} + local x,y + for i=1,200 do + local v = {i} + local w = {i+1} + x = v[1] + y = w[1] + if i > 100 then end + end + assert(x == 200 and y == 201) +end + +do --- Sink of stores with numbers. + local x = {1.5, 0} + for i=1,200 do x = {x[1]+1, 99.5}; x[2]=4.5; if i > 100 then end end + assert(x[1] == 201.5) + assert(x[2] == 4.5) +end + +do --- Sink of stores with constants. + for i=1,100 do local t = {false}; t[1] = true; if i > 100 then g=t end end +end + +do --- Sink with two references to the same table. + for i=1,200 do + local t = {i} + local q = t + if i > 100 then assert(t == q) end + end +end + +do --- point + local point + point = { + new = function(self, x, y) + return setmetatable({x=x, y=y}, self) + end, + __add = function(a, b) + return point:new(a.x + b.x, a.y + b.y) + end, + } + point.__index = point + local a, b = point:new(1, 1), point:new(2, 2) + for i=1,100 do a = (a + b) + b end + assert(a.x == 401) + assert(a.y == 401) + assert(getmetatable(a) == point) + for i=1,200 do a = (a + b) + b; if i > 100 then end end + assert(a.x == 1201) + assert(a.y == 1201) + assert(getmetatable(a) == point) +end + +do --- untitled + local t = {} + for i=1,20 do t[i] = 1 end + for i=1,20 do + for a,b in ipairs(t) do + local s = {i} + end + end +end diff --git a/test/opt/sink/index b/test/opt/sink/index index b3a78ebe09..137f46ab31 100644 --- a/test/opt/sink/index +++ b/test/opt/sink/index @@ -1,2 +1,2 @@ -alloc.lua -nosink.lua +alloc.lua +nosink.lua diff --git a/test/opt/sink/nosink.lua b/test/opt/sink/nosink.lua index 3a1bdf0752..762aaced57 100644 --- a/test/opt/sink/nosink.lua +++ b/test/opt/sink/nosink.lua @@ -1,109 +1,109 @@ -local assert = assert - -do --- Cannot sink TNEW, aliased load. - local k = 1 - for i=1,100 do local t={i}; assert(t[k]==i) end - for i=1,100 do local t={}; t[k]=i; assert(t[1]==i) end -end - -do --- Cannot sink TNEW, escaping to upvalue. - (function() - local uv - return function() - for i=1,100 do uv = {i} end - assert(uv[1] == 100) - end - end)()() -end - -do --- Cannot sink TNEW, escaping through a store. - local t = {} - for i=1,100 do t[1] = {i} end - for i=1,100 do t.foo = {i} end - for i=1,100 do setmetatable(t, {i}) end - assert(t[1][1] == 100) - assert(t.foo[1] == 100) - assert(getmetatable(t)[1] == 100) -end - -do --- Cannot sink TNEW, iteratively escaping through a store. - local t = {} - for i=1,100 do t[1] = {i}; t[1][1] = {i} end - assert(t[1][1][1] == 100) -end - -do --- Cannot sink TNEW, escaping to next iteration (unused in 1st variant). - local t; - for i=1,200 do t = {i} end - assert(t[1] == 200) - for i=1,200 do if i > 100 then assert(t[1] == i-1) end t = {i} end - assert(t[1] == 200) -end - -do --- Cannot sink TNEW, escaping to next iteration (snapshot ref). - local t,x - for i=1,100 do x=t; t={i} end - assert(t[1] == 100) - assert(x[1] == 99) -end - -do --- Cannot sink TNEW, escaping to next iteration (IR/snapshot ref). - local t - for i=1,100 do t={t} end - assert(type(t[1][1][1]) == "table") -end - -do --- Cannot sink inner TNEW, escaping to next iteration (IR ref). - -- (Could sink outer TNEW, but the logic for stores to PHI allocs is too simple). - local t = {42, 43} - for i=1,100 do t={t[2], {i}} end - assert(t[2][1] == 100) - assert(t[1][1] == 99) -end - -do --- Cannot sink TNEW, cross-PHI ref (and snapshot ref). - local x,y - for i=1,100 do x,y={i},x end - assert(x[1] == 100) - assert(y[1] == 99) -end - -do --- Cannot sink TNEW, cross-PHI ref (and snapshot ref). - local x,y - for i=1,100 do x,y=y,{i} end - assert(x[1] == 99) - assert(y[1] == 100) -end - -do --- Cannot sink TNEW, escaping to exit. - local function f(n, t) - if n == 0 then return t end - return (f(n-1, {t})) - end - local t = f(100, 42) - assert(type(t[1][1][1]) == "table") - t = f(3, 42) - assert(t[1][1][1] == 42) -end - -do --- Cannot sink TNEW, escaping to exit. - local function f(n) - if n == 0 then return 42 end - local t = f(n-1) - return {t} - end - for i=1,20 do - local t = f(100) - assert(type(t[1][1][1]) == "table") - end - local t = f(3) - assert(t[1][1][1] == 42) -end - -do --- Cannot sink, since nested inner table is non-PHI. - local a, b = {{1}}, {{1}} - for i=1,10000 do -- Need to force GC exit sometimes - a = {{a[1][1]+b[1][1]}} - end - assert(a[1][1] == 10001) -end +local assert = assert + +do --- Cannot sink TNEW, aliased load. + local k = 1 + for i=1,100 do local t={i}; assert(t[k]==i) end + for i=1,100 do local t={}; t[k]=i; assert(t[1]==i) end +end + +do --- Cannot sink TNEW, escaping to upvalue. + (function() + local uv + return function() + for i=1,100 do uv = {i} end + assert(uv[1] == 100) + end + end)()() +end + +do --- Cannot sink TNEW, escaping through a store. + local t = {} + for i=1,100 do t[1] = {i} end + for i=1,100 do t.foo = {i} end + for i=1,100 do setmetatable(t, {i}) end + assert(t[1][1] == 100) + assert(t.foo[1] == 100) + assert(getmetatable(t)[1] == 100) +end + +do --- Cannot sink TNEW, iteratively escaping through a store. + local t = {} + for i=1,100 do t[1] = {i}; t[1][1] = {i} end + assert(t[1][1][1] == 100) +end + +do --- Cannot sink TNEW, escaping to next iteration (unused in 1st variant). + local t; + for i=1,200 do t = {i} end + assert(t[1] == 200) + for i=1,200 do if i > 100 then assert(t[1] == i-1) end t = {i} end + assert(t[1] == 200) +end + +do --- Cannot sink TNEW, escaping to next iteration (snapshot ref). + local t,x + for i=1,100 do x=t; t={i} end + assert(t[1] == 100) + assert(x[1] == 99) +end + +do --- Cannot sink TNEW, escaping to next iteration (IR/snapshot ref). + local t + for i=1,100 do t={t} end + assert(type(t[1][1][1]) == "table") +end + +do --- Cannot sink inner TNEW, escaping to next iteration (IR ref). + -- (Could sink outer TNEW, but the logic for stores to PHI allocs is too simple). + local t = {42, 43} + for i=1,100 do t={t[2], {i}} end + assert(t[2][1] == 100) + assert(t[1][1] == 99) +end + +do --- Cannot sink TNEW, cross-PHI ref (and snapshot ref). + local x,y + for i=1,100 do x,y={i},x end + assert(x[1] == 100) + assert(y[1] == 99) +end + +do --- Cannot sink TNEW, cross-PHI ref (and snapshot ref). + local x,y + for i=1,100 do x,y=y,{i} end + assert(x[1] == 99) + assert(y[1] == 100) +end + +do --- Cannot sink TNEW, escaping to exit. + local function f(n, t) + if n == 0 then return t end + return (f(n-1, {t})) + end + local t = f(100, 42) + assert(type(t[1][1][1]) == "table") + t = f(3, 42) + assert(t[1][1][1] == 42) +end + +do --- Cannot sink TNEW, escaping to exit. + local function f(n) + if n == 0 then return 42 end + local t = f(n-1) + return {t} + end + for i=1,20 do + local t = f(100) + assert(type(t[1][1][1]) == "table") + end + local t = f(3) + assert(t[1][1][1] == 42) +end + +do --- Cannot sink, since nested inner table is non-PHI. + local a, b = {{1}}, {{1}} + for i=1,10000 do -- Need to force GC exit sometimes + a = {{a[1][1]+b[1][1]}} + end + assert(a[1][1] == 10001) +end diff --git a/test/test.lua b/test/test.lua index 1e842d4333..6d5fb6daa4 100644 --- a/test/test.lua +++ b/test/test.lua @@ -1,416 +1,416 @@ -local assert, io_open, io_lines, io_write, load, type, xpcall = - assert, io.open, io.lines, io.write, load, type, xpcall -local debug_traceback, math_random, tonumber, loadstring = - debug.traceback, math.random, tonumber, loadstring or load - -local dirsep = package.config:match"^(.-)\n" -local own_file = debug.getinfo(1, "S").source:match"^@(.*)" or arg[0] -local own_dir = own_file:match("^.*[/".. dirsep .."]") - -local function default_tags() - local tags = {} - - -- Lua version and features - tags.lua = tonumber(_VERSION:match"%d+%.%d+") - if table.pack then - tags["compat5.2"] = true - end - if loadstring"return 0xep+9" then - tags.hexfloat = true - end - if loadstring"goto x ::x::" then - tags["goto"] = true - end - - -- Libraries - for _, lib in ipairs{"bit", "ffi", "jit.profile", "table.new"} do - if pcall(require, lib) then - tags[lib] = true - end - end - - -- LuaJIT-specific - if jit then - tags.luajit = tonumber(jit.version:match"%d+%.%d+") - tags[jit.arch:lower()] = true - if jit.os ~= "Other" then - tags[jit.os:lower()] = true - end - if jit.status() then - tags.jit = true - end - for _, flag in ipairs{select(2, jit.status())} do - tags[flag:lower()] = true - end - end - - -- Environment - if dirsep == "\\" then - tags.windows = true - end - if tags.ffi then - local abi = require"ffi".abi - for _, param in ipairs{"le", "be", "fpu", "softfp", "hardfp", "eabi"} do - if abi(param) then - tags[param] = true - end - end - if abi"win" then tags.winabi = true end - if abi"32bit" then tags.abi32 = true end - if abi"64bit" then tags.abi64 = true end - else - local bytecode = string.dump(function()end) - if bytecode:find"^\27Lua[\80-\89]" then - tags[bytecode:byte(7, 7) == 0 and "be" or "le"] = true - tags["abi".. (bytecode:byte(9, 9) * 8)] = true - end - end - - return tags -end - -local function want_meta(opts, meta) - if not opts.want_meta_cache then - opts.want_meta_cache = setmetatable({}, {__index = function(t, meta) - local result = true - for polarity, tag, cond in meta:gmatch"([+-])([^ <>=]+)([<>=0-9.]*)" do - local tagval = opts.tags[tag] - local condresult - if cond == "" or not tagval then - condresult = tagval - else - condresult = assert(loadstring("return (...) ".. cond))(tagval) - end - if polarity == "-" then - condresult = not condresult - end - if not condresult then - result = false - break - end - end - t[meta] = result - return result - end}) - end - return opts.want_meta_cache[meta] -end - -local function parse_args(t) - local opts = { - tags = default_tags(), - want_meta = want_meta, - } - local result = opts - - local i, tlen = 1, #t - local joinedval = "" - local function flagval() - local val - if joinedval ~= "" then - val = joinedval:sub(2) - joinedval = "" - else - val = t[i] - if not val then error("Expected value after ".. t[i-1]) end - i = i + 1 - end - return val - end - - while i <= tlen do - local arg = t[i] - i = i + 1 - if arg:sub(1, 2) == "--" then - arg, joinedval = arg:match"^([^=]+)(=?.*)$" - if arg == "--quiet" then - opts.quiet = true - elseif arg == "--shuffle" then - local seed = tonumber(flagval()) - if not seed then error("Expected numeric seed after --shuffle") end - opts.shuffle = seed - elseif arg == "--shard" then - local i, s = flagval():match"^(%d+)/(%d+)$" - if not s then error("Expected integer/integer after --shard") end - opts.shard = {initial = tonumber(i), step = tonumber(s)} - elseif arg == "--version" then - io_write("LuaJIT test-suite runner v0.1\n") - result = nil - elseif arg == "--help" then - io_write("Usage: ", _G and _G.arg and _G.arg[-1] or "luajit", " ") - io_write(own_file, " [flags] [tags] [root] [numbers]\n") - io_write"\n" - io_write"Root specifies either a directory of tests, or the name of\n" - io_write"a particular .lua test file, defaulting to all tests if not given.\n" - io_write"Tags are specified in the form +tag_name or -tag_name, and\n" - io_write"are used to turn on or off groups of tests. For example,\n" - io_write"pass -ffi to skip tests relating to the ffi library, or\n" - io_write"pass +slow to enable running of slow tests.\n" - io_write"Numbers can be passed to only run particular tests.\n" - io_write"The available flags are:\n" - io_write" --quiet\n" - io_write" --shuffle=SEED\n" - io_write" --shard=INDEX/NUM_SHARDS\n" - io_write" --version\n" - io_write" --help\n" - result = nil - else - error("Unsupported flag: ".. arg) - end - if joinedval ~= "" then - error(arg .." does not expect an argument") - end - elseif arg:find"^[-+]" then - opts.tags[arg:sub(2)] = (arg:sub(1, 1) == "+") - elseif arg:find"^%d+$" then - if not opts.numbers_to_run then - opts.numbers_to_run = {} - end - opts.numbers_to_run[tonumber(arg)] = true - elseif not opts.root then - opts.root = arg - else - error("Unexpected argument ".. arg) - end - end - return result -end - -local function scan_tests(path, opts) - if path:sub(-4, -4) == "." then - local f = assert(io_open(path, "rb")) - local contents = f:read"*a" - f:close() - local prefix = "return {" - local code = contents:gsub("()(do +%-%-%- +)([^\r\n]+)", - function(pos, marker, info) - if pos ~= 1 then - pos = pos - 1 - if contents:sub(pos, pos) ~= "\n" then - return marker .. info - end - end - local result = ("%s%q,function()"):format(prefix, info) - prefix = "," - if info:find" !lex" and not opts:want_meta(info:sub((info:find" +[-+@!]"))) then - result = result .."end--[========[" - prefix = "]========]".. prefix - end - return result - end) - if prefix:sub(-1) ~= "," then - error("No tests found in ".. path) - end - prefix = prefix .."}" - return assert(load(function() - local result = code - code = code ~= prefix and prefix or nil - return result - end, "@".. path))() - else - if path ~= "" and path:sub(-1) ~= "/" and path:sub(-1) ~= dirsep then - path = path .. dirsep - end - local result = {} - local i = 1 - for line in io_lines(path .."index") do - if line ~= "" then - local metaidx = line:find" +[-+@]" - local name = line - local want_these = true - if metaidx then - name = line:sub(1, metaidx - 1) - want_these = opts:want_meta(line:sub(metaidx)) - end - if want_these then - result[i] = line - result[i+1] = scan_tests(path .. name, opts) - i = i + 2 - end - end - end - return result - end -end - -local function upvalue_iterator(f, i) - i = i + 1 - local name, val = debug.getupvalue(f, i) - return name and i, name, val -end - -local function upvalues_of(f) - return upvalue_iterator, f, 0 -end - -local function append_tree_to_plan(test_tree, opts, plan, prefix) - local prefi - for i = 1, #test_tree, 2 do - local info = test_tree[i] - local name = info - local want_these = true - local metaidx = info:find" +[-+@!]" - if metaidx then - name = info:sub(1, metaidx - 1) - want_these = opts:want_meta(info:sub(metaidx)) - end - local planlen = #plan - if want_these then - local test = test_tree[i+1] - if type(test) == "table" then - append_tree_to_plan(test, opts, plan, prefix .. name .. dirsep) - else - if not prefi then - prefi = prefix:sub(1, -2) - end - plan[#plan+1] = {prefi, name, test} - end - end - if metaidx and info:find"!" then - for modifier in info:gmatch"!([^ ]+)" do - if modifier == "private_G" then - local G = setmetatable({}, {__index = _G}) - G._G = G - local function Gfn() return G end - for i = planlen, #plan do - local test = plan[i][3] - if setfenv then - setfenv(test, G) - else - for i, name in upvalues_of(test) do - if name == "_ENV" then - debug.upvaluejoin(test, i, Gfn, 1) - break - end - end - end - end - elseif modifier == "lex" then - -- Handled during test scanning - else - error("Unsupported modifier \"".. modifier .."\" in ".. prefix) - end - end - end - end - return plan -end - -local function seal_globals() - local sealed_mt = {__newindex = function() - error("Tests should not mutate global state", 3) - end} - local function seal(t) - if getmetatable(t) then return end - setmetatable(t, sealed_mt) - for k, v in pairs(t) do - if type(v) == "table" then seal(v) end - end - end - seal(_G) - - if getmetatable(package.loaded) == sealed_mt then - setmetatable(package.loaded, nil) - end -end - -local function check_package_path() - local ok, res = pcall(require, "common.test_runner_canary") - if not ok then - if own_dir then - local _, psep, placeholder = package.config:match"^(.-)\n(.-)\n(.-)\n" - package.path = package.path .. psep .. own_dir .. placeholder ..".lua" - ok, res = pcall(require, "common.test_runner_canary") - end - if not ok then - error(res) - end - end - assert(res == "canary is alive") -end - -local function mutate_plan(plan, opts) - if opts.shuffle then - math.randomseed(opts.shuffle) - for i = #plan, 2, -1 do - local n = math_random(1, i) - plan[i], plan[n] = plan[n], plan[i] - end - end - if opts.shard then - local shard_plan = {} - for i = opts.shard.initial, #plan, opts.shard.step do - shard_plan[#shard_plan + 1] = plan[i] - end - plan = shard_plan - end - if opts.numbers_to_run then - for i = 1, #plan do - if not opts.numbers_to_run[i] then - plan[i][3] = false - end - end - for k in pairs(opts.numbers_to_run) do - if not plan[k] then - error("Test number ".. k .." is not part of the plan") - end - end - end - return plan -end - -local function execute_plan(plan, opts) - if #plan == 0 then - error("No tests selected") - end - local progress_format = ("[%%%dd/%d] "):format(#tostring(#plan), #plan) - local num_tests_run = 0 - local fail_numbers = {} - for i = 1, #plan do - local plan_i = plan[i] - local test = plan_i[3] - if test then - local file, name = plan_i[1], plan_i[2] - if not opts.quiet then - io_write(progress_format:format(i), file) - io_write(file == "" and "" or " --- ", name, "\n") - end - local ok, err = xpcall(test, debug_traceback) - if not ok then - if opts.quiet then - io_write(progress_format:format(i), file) - io_write(file == "" and "" or " --- ", name, "\n") - end - fail_numbers[#fail_numbers + 1] = i - io_write(err, "\n") - end - num_tests_run = num_tests_run + 1 - end - end - if #fail_numbers == 0 then - io_write(num_tests_run, " passed\n") - return true - else - io_write(num_tests_run - #fail_numbers, " passed, ") - io_write(#fail_numbers, " failed\n") - if not opts.quiet and num_tests_run ~= #fail_numbers then - io_write("to run just failing tests, pass command line arguments: ") - io_write(table.concat(fail_numbers, " "), "\n") - end - return false - end -end - -local opts = parse_args{...} -if not opts then - return -end -seal_globals() -check_package_path() -local test_tree = scan_tests(opts.root or own_dir or "", opts) -local plan = append_tree_to_plan(test_tree, opts, {}, "") -plan = mutate_plan(plan, opts) -local all_good = execute_plan(plan, opts) -if not all_good then - os.exit(1) -end +local assert, io_open, io_lines, io_write, load, type, xpcall = + assert, io.open, io.lines, io.write, load, type, xpcall +local debug_traceback, math_random, tonumber, loadstring = + debug.traceback, math.random, tonumber, loadstring or load + +local dirsep = package.config:match"^(.-)\n" +local own_file = debug.getinfo(1, "S").source:match"^@(.*)" or arg[0] +local own_dir = own_file:match("^.*[/".. dirsep .."]") + +local function default_tags() + local tags = {} + + -- Lua version and features + tags.lua = tonumber(_VERSION:match"%d+%.%d+") + if table.pack then + tags["compat5.2"] = true + end + if loadstring"return 0xep+9" then + tags.hexfloat = true + end + if loadstring"goto x ::x::" then + tags["goto"] = true + end + + -- Libraries + for _, lib in ipairs{"bit", "ffi", "jit.profile", "table.new"} do + if pcall(require, lib) then + tags[lib] = true + end + end + + -- LuaJIT-specific + if jit then + tags.luajit = tonumber(jit.version:match"%d+%.%d+") + tags[jit.arch:lower()] = true + if jit.os ~= "Other" then + tags[jit.os:lower()] = true + end + if jit.status() then + tags.jit = true + end + for _, flag in ipairs{select(2, jit.status())} do + tags[flag:lower()] = true + end + end + + -- Environment + if dirsep == "\\" then + tags.windows = true + end + if tags.ffi then + local abi = require"ffi".abi + for _, param in ipairs{"le", "be", "fpu", "softfp", "hardfp", "eabi"} do + if abi(param) then + tags[param] = true + end + end + if abi"win" then tags.winabi = true end + if abi"32bit" then tags.abi32 = true end + if abi"64bit" then tags.abi64 = true end + else + local bytecode = string.dump(function()end) + if bytecode:find"^\27Lua[\80-\89]" then + tags[bytecode:byte(7, 7) == 0 and "be" or "le"] = true + tags["abi".. (bytecode:byte(9, 9) * 8)] = true + end + end + + return tags +end + +local function want_meta(opts, meta) + if not opts.want_meta_cache then + opts.want_meta_cache = setmetatable({}, {__index = function(t, meta) + local result = true + for polarity, tag, cond in meta:gmatch"([+-])([^ <>=]+)([<>=0-9.]*)" do + local tagval = opts.tags[tag] + local condresult + if cond == "" or not tagval then + condresult = tagval + else + condresult = assert(loadstring("return (...) ".. cond))(tagval) + end + if polarity == "-" then + condresult = not condresult + end + if not condresult then + result = false + break + end + end + t[meta] = result + return result + end}) + end + return opts.want_meta_cache[meta] +end + +local function parse_args(t) + local opts = { + tags = default_tags(), + want_meta = want_meta, + } + local result = opts + + local i, tlen = 1, #t + local joinedval = "" + local function flagval() + local val + if joinedval ~= "" then + val = joinedval:sub(2) + joinedval = "" + else + val = t[i] + if not val then error("Expected value after ".. t[i-1]) end + i = i + 1 + end + return val + end + + while i <= tlen do + local arg = t[i] + i = i + 1 + if arg:sub(1, 2) == "--" then + arg, joinedval = arg:match"^([^=]+)(=?.*)$" + if arg == "--quiet" then + opts.quiet = true + elseif arg == "--shuffle" then + local seed = tonumber(flagval()) + if not seed then error("Expected numeric seed after --shuffle") end + opts.shuffle = seed + elseif arg == "--shard" then + local i, s = flagval():match"^(%d+)/(%d+)$" + if not s then error("Expected integer/integer after --shard") end + opts.shard = {initial = tonumber(i), step = tonumber(s)} + elseif arg == "--version" then + io_write("LuaJIT test-suite runner v0.1\n") + result = nil + elseif arg == "--help" then + io_write("Usage: ", _G and _G.arg and _G.arg[-1] or "luajit", " ") + io_write(own_file, " [flags] [tags] [root] [numbers]\n") + io_write"\n" + io_write"Root specifies either a directory of tests, or the name of\n" + io_write"a particular .lua test file, defaulting to all tests if not given.\n" + io_write"Tags are specified in the form +tag_name or -tag_name, and\n" + io_write"are used to turn on or off groups of tests. For example,\n" + io_write"pass -ffi to skip tests relating to the ffi library, or\n" + io_write"pass +slow to enable running of slow tests.\n" + io_write"Numbers can be passed to only run particular tests.\n" + io_write"The available flags are:\n" + io_write" --quiet\n" + io_write" --shuffle=SEED\n" + io_write" --shard=INDEX/NUM_SHARDS\n" + io_write" --version\n" + io_write" --help\n" + result = nil + else + error("Unsupported flag: ".. arg) + end + if joinedval ~= "" then + error(arg .." does not expect an argument") + end + elseif arg:find"^[-+]" then + opts.tags[arg:sub(2)] = (arg:sub(1, 1) == "+") + elseif arg:find"^%d+$" then + if not opts.numbers_to_run then + opts.numbers_to_run = {} + end + opts.numbers_to_run[tonumber(arg)] = true + elseif not opts.root then + opts.root = arg + else + error("Unexpected argument ".. arg) + end + end + return result +end + +local function scan_tests(path, opts) + if path:sub(-4, -4) == "." then + local f = assert(io_open(path, "rb")) + local contents = f:read"*a" + f:close() + local prefix = "return {" + local code = contents:gsub("()(do +%-%-%- +)([^\r\n]+)", + function(pos, marker, info) + if pos ~= 1 then + pos = pos - 1 + if contents:sub(pos, pos) ~= "\n" then + return marker .. info + end + end + local result = ("%s%q,function()"):format(prefix, info) + prefix = "," + if info:find" !lex" and not opts:want_meta(info:sub((info:find" +[-+@!]"))) then + result = result .."end--[========[" + prefix = "]========]".. prefix + end + return result + end) + if prefix:sub(-1) ~= "," then + error("No tests found in ".. path) + end + prefix = prefix .."}" + return assert(load(function() + local result = code + code = code ~= prefix and prefix or nil + return result + end, "@".. path))() + else + if path ~= "" and path:sub(-1) ~= "/" and path:sub(-1) ~= dirsep then + path = path .. dirsep + end + local result = {} + local i = 1 + for line in io_lines(path .."index") do + if line ~= "" then + local metaidx = line:find" +[-+@]" + local name = line + local want_these = true + if metaidx then + name = line:sub(1, metaidx - 1) + want_these = opts:want_meta(line:sub(metaidx)) + end + if want_these then + result[i] = line + result[i+1] = scan_tests(path .. name, opts) + i = i + 2 + end + end + end + return result + end +end + +local function upvalue_iterator(f, i) + i = i + 1 + local name, val = debug.getupvalue(f, i) + return name and i, name, val +end + +local function upvalues_of(f) + return upvalue_iterator, f, 0 +end + +local function append_tree_to_plan(test_tree, opts, plan, prefix) + local prefi + for i = 1, #test_tree, 2 do + local info = test_tree[i] + local name = info + local want_these = true + local metaidx = info:find" +[-+@!]" + if metaidx then + name = info:sub(1, metaidx - 1) + want_these = opts:want_meta(info:sub(metaidx)) + end + local planlen = #plan + if want_these then + local test = test_tree[i+1] + if type(test) == "table" then + append_tree_to_plan(test, opts, plan, prefix .. name .. dirsep) + else + if not prefi then + prefi = prefix:sub(1, -2) + end + plan[#plan+1] = {prefi, name, test} + end + end + if metaidx and info:find"!" then + for modifier in info:gmatch"!([^ ]+)" do + if modifier == "private_G" then + local G = setmetatable({}, {__index = _G}) + G._G = G + local function Gfn() return G end + for i = planlen, #plan do + local test = plan[i][3] + if setfenv then + setfenv(test, G) + else + for i, name in upvalues_of(test) do + if name == "_ENV" then + debug.upvaluejoin(test, i, Gfn, 1) + break + end + end + end + end + elseif modifier == "lex" then + -- Handled during test scanning + else + error("Unsupported modifier \"".. modifier .."\" in ".. prefix) + end + end + end + end + return plan +end + +local function seal_globals() + local sealed_mt = {__newindex = function() + error("Tests should not mutate global state", 3) + end} + local function seal(t) + if getmetatable(t) then return end + setmetatable(t, sealed_mt) + for k, v in pairs(t) do + if type(v) == "table" then seal(v) end + end + end + seal(_G) + + if getmetatable(package.loaded) == sealed_mt then + setmetatable(package.loaded, nil) + end +end + +local function check_package_path() + local ok, res = pcall(require, "common.test_runner_canary") + if not ok then + if own_dir then + local _, psep, placeholder = package.config:match"^(.-)\n(.-)\n(.-)\n" + package.path = package.path .. psep .. own_dir .. placeholder ..".lua" + ok, res = pcall(require, "common.test_runner_canary") + end + if not ok then + error(res) + end + end + assert(res == "canary is alive") +end + +local function mutate_plan(plan, opts) + if opts.shuffle then + math.randomseed(opts.shuffle) + for i = #plan, 2, -1 do + local n = math_random(1, i) + plan[i], plan[n] = plan[n], plan[i] + end + end + if opts.shard then + local shard_plan = {} + for i = opts.shard.initial, #plan, opts.shard.step do + shard_plan[#shard_plan + 1] = plan[i] + end + plan = shard_plan + end + if opts.numbers_to_run then + for i = 1, #plan do + if not opts.numbers_to_run[i] then + plan[i][3] = false + end + end + for k in pairs(opts.numbers_to_run) do + if not plan[k] then + error("Test number ".. k .." is not part of the plan") + end + end + end + return plan +end + +local function execute_plan(plan, opts) + if #plan == 0 then + error("No tests selected") + end + local progress_format = ("[%%%dd/%d] "):format(#tostring(#plan), #plan) + local num_tests_run = 0 + local fail_numbers = {} + for i = 1, #plan do + local plan_i = plan[i] + local test = plan_i[3] + if test then + local file, name = plan_i[1], plan_i[2] + if not opts.quiet then + io_write(progress_format:format(i), file) + io_write(file == "" and "" or " --- ", name, "\n") + end + local ok, err = xpcall(test, debug_traceback) + if not ok then + if opts.quiet then + io_write(progress_format:format(i), file) + io_write(file == "" and "" or " --- ", name, "\n") + end + fail_numbers[#fail_numbers + 1] = i + io_write(err, "\n") + end + num_tests_run = num_tests_run + 1 + end + end + if #fail_numbers == 0 then + io_write(num_tests_run, " passed\n") + return true + else + io_write(num_tests_run - #fail_numbers, " passed, ") + io_write(#fail_numbers, " failed\n") + if not opts.quiet and num_tests_run ~= #fail_numbers then + io_write("to run just failing tests, pass command line arguments: ") + io_write(table.concat(fail_numbers, " "), "\n") + end + return false + end +end + +local opts = parse_args{...} +if not opts then + return +end +seal_globals() +check_package_path() +local test_tree = scan_tests(opts.root or own_dir or "", opts) +local plan = append_tree_to_plan(test_tree, opts, {}, "") +plan = mutate_plan(plan, opts) +local all_good = execute_plan(plan, opts) +if not all_good then + os.exit(1) +end diff --git a/test/trace/exit_frame.lua b/test/trace/exit_frame.lua index c8297cb0bc..9537c56342 100644 --- a/test/trace/exit_frame.lua +++ b/test/trace/exit_frame.lua @@ -1,79 +1,79 @@ -do --- global assignments !private_G - g = 0 - gf = 1 - gz = 2 - - local function f(i) - if i == 90 then - gf = gf + 1 - return true - end - g = g + 1 - end - - local function z(i) - if f(i) then - gz = gz + 1 - end - end - - for j=1,5 do - for i=1,100 do z(i) end - end - - assert(g == 495) - assert(gf == 6) - assert(gz == 7) -end - -do --- mutual recursion - local f, g - function f(j) - if j >= 0 then return g(j-1) end - end - function g(j) - for i=1,200 do - if i > 100 then return f(j) end - end - end - for k=1,20 do g(20) end -end - -do --- multi-path mutual recursion - local f, g - function f(j, k) - if j >= 0 then return g(j-1, k) end - if k >= 0 then return g(20, k-1) end - end - function g(j, k) - for i=1,200 do - if i > 100 then return f(j, k) end - end - end - g(20, 20) -end - -do --- late mutual recursion - local k = 0 - local f, g - - function g(a) - -- 'a' is an SLOAD #1 from f's frame and still at slot #1 - -- Avoid losing a in exit if the SLOAD is ignored - if k > 10 then k = 0 end - k= k + 1 - return f(a) - end - - function f(a,b,c,d,e) - if not e then e =1 end - a=a+1 - if a > 1000 then return end - for i=1,100 do - e=e+1 - if i > 90 then return g(a) end - end - end - - f(1,2,3,4,5) -end +do --- global assignments !private_G + g = 0 + gf = 1 + gz = 2 + + local function f(i) + if i == 90 then + gf = gf + 1 + return true + end + g = g + 1 + end + + local function z(i) + if f(i) then + gz = gz + 1 + end + end + + for j=1,5 do + for i=1,100 do z(i) end + end + + assert(g == 495) + assert(gf == 6) + assert(gz == 7) +end + +do --- mutual recursion + local f, g + function f(j) + if j >= 0 then return g(j-1) end + end + function g(j) + for i=1,200 do + if i > 100 then return f(j) end + end + end + for k=1,20 do g(20) end +end + +do --- multi-path mutual recursion + local f, g + function f(j, k) + if j >= 0 then return g(j-1, k) end + if k >= 0 then return g(20, k-1) end + end + function g(j, k) + for i=1,200 do + if i > 100 then return f(j, k) end + end + end + g(20, 20) +end + +do --- late mutual recursion + local k = 0 + local f, g + + function g(a) + -- 'a' is an SLOAD #1 from f's frame and still at slot #1 + -- Avoid losing a in exit if the SLOAD is ignored + if k > 10 then k = 0 end + k= k + 1 + return f(a) + end + + function f(a,b,c,d,e) + if not e then e =1 end + a=a+1 + if a > 1000 then return end + for i=1,100 do + e=e+1 + if i > 90 then return g(a) end + end + end + + f(1,2,3,4,5) +end diff --git a/test/trace/exit_growstack.lua b/test/trace/exit_growstack.lua index 20accdf8bb..658a31a509 100644 --- a/test/trace/exit_growstack.lua +++ b/test/trace/exit_growstack.lua @@ -1,28 +1,28 @@ -do --- Exit needs to grow stack before slot fill. - local function f(i) - local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; - local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; - local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; - if i==90 then return end - end - for j=1,5 do - collectgarbage() -- Shrink stack. - for i=1,100 do f(i) end - end -end - -do --- Exit needs to grow stack after slot fill. - local function g(i) - if i==90 then return end - do return end - do - local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; - local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; - local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; - end - end - for j=1,5 do - collectgarbage() -- Shrink stack. - for i=1,100 do g(i) end - end -end +do --- Exit needs to grow stack before slot fill. + local function f(i) + local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; + local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; + local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; + if i==90 then return end + end + for j=1,5 do + collectgarbage() -- Shrink stack. + for i=1,100 do f(i) end + end +end + +do --- Exit needs to grow stack after slot fill. + local function g(i) + if i==90 then return end + do return end + do + local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; + local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; + local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; + end + end + for j=1,5 do + collectgarbage() -- Shrink stack. + for i=1,100 do g(i) end + end +end diff --git a/test/trace/exit_jfuncf.lua b/test/trace/exit_jfuncf.lua index 4895fbf0a7..67ad7c369d 100644 --- a/test/trace/exit_jfuncf.lua +++ b/test/trace/exit_jfuncf.lua @@ -1,30 +1,30 @@ -do --- everything - local assert = assert - - local function rec(a, b, c, d, e, f) - assert(f == a+1) - if b == 0 then return 7 end - do local x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x100 end - return rec(a, b-1, c, d, e, f)+1 - end - - -- Compile recursive function. - assert(rec(42, 200, 1, 2, 3, 43) == 207) - - local function trec() - return rec(42, 0, 1, 2, 3, 43) - end - - -- Compile function jumping to JFUNCF. - for i=1,200 do - gcinfo() - assert(trec() == 7) - end - - -- Shrink stack. - for j=1,10 do collectgarbage() end - - -- Cause an exit due to stack growth with PC pointing to JFUNCF. - -- Needs to load RD with nres+1 and not with the bytecode RD. - assert(trec() == 7) -end +do --- everything + local assert = assert + + local function rec(a, b, c, d, e, f) + assert(f == a+1) + if b == 0 then return 7 end + do local x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x100 end + return rec(a, b-1, c, d, e, f)+1 + end + + -- Compile recursive function. + assert(rec(42, 200, 1, 2, 3, 43) == 207) + + local function trec() + return rec(42, 0, 1, 2, 3, 43) + end + + -- Compile function jumping to JFUNCF. + for i=1,200 do + gcinfo() + assert(trec() == 7) + end + + -- Shrink stack. + for j=1,10 do collectgarbage() end + + -- Cause an exit due to stack growth with PC pointing to JFUNCF. + -- Needs to load RD with nres+1 and not with the bytecode RD. + assert(trec() == 7) +end diff --git a/test/trace/index b/test/trace/index index 2703d2f3b7..7299d4f0ee 100644 --- a/test/trace/index +++ b/test/trace/index @@ -1,6 +1,6 @@ -exit_frame.lua -exit_growstack.lua -exit_jfuncf.lua -phi -snap.lua -stitch.lua +exit_frame.lua +exit_growstack.lua +exit_jfuncf.lua +phi +snap.lua +stitch.lua diff --git a/test/trace/phi/index b/test/trace/phi/index index 76799b894f..74a07333c4 100644 --- a/test/trace/phi/index +++ b/test/trace/phi/index @@ -1,3 +1,3 @@ -copyspill.lua -ref.lua -rotate.lua +copyspill.lua +ref.lua +rotate.lua diff --git a/test/trace/phi/rotate.lua b/test/trace/phi/rotate.lua index b80f07e184..cb751e0b9f 100644 --- a/test/trace/phi/rotate.lua +++ b/test/trace/phi/rotate.lua @@ -1,149 +1,149 @@ -do --- rot8 - local function rot8r(n) - local a,b,c,d,e,f,g,h=1,2,3,4,5,6,7,8 - for x=1,n do - a,b,c,d,e,f,g,h=h,a,b,c,d,e,f,g - end - return table.concat{a,b,c,d,e,f,g,h} - end - - local function rot8l(n) - local a,b,c,d,e,f,g,h=1,2,3,4,5,6,7,8 - for x=1,n do - a,b,c,d,e,f,g,h=b,c,d,e,f,g,h,a - end - return table.concat{a,b,c,d,e,f,g,h} - end - - assert(rot8r(0) == "12345678") - assert(rot8r(10) == "78123456") - assert(rot8r(105) == "81234567") - assert(rot8r(0) == "12345678") - assert(rot8r(1) == "81234567") - assert(rot8r(2) == "78123456") - assert(rot8r(0) == "12345678") - assert(rot8r(1) == "81234567") - assert(rot8r(2) == "78123456") - assert(rot8r(105) == "81234567") - - assert(rot8l(0) == "12345678") - assert(rot8l(10) == "34567812") - assert(rot8l(105) == "23456781") - assert(rot8l(0) == "12345678") - assert(rot8l(1) == "23456781") - assert(rot8l(2) == "34567812") - assert(rot8l(0) == "12345678") - assert(rot8l(1) == "23456781") - assert(rot8l(2) == "34567812") - - assert(rot8r(100) == "56781234") - assert(rot8l(100) == "56781234") -end - -do --- rot9 - local function rot9r(n) - local a,b,c,d,e,f,g,h,i=1,2,3,4,5,6,7,8,9 - for x=1,n do - a,b,c,d,e,f,g,h,i=i,a,b,c,d,e,f,g,h - end - return table.concat{a,b,c,d,e,f,g,h,i} - end - - local function rot9l(n) - local a,b,c,d,e,f,g,h,i=1,2,3,4,5,6,7,8,9 - for x=1,n do - a,b,c,d,e,f,g,h,i=b,c,d,e,f,g,h,i,a - end - return table.concat{a,b,c,d,e,f,g,h,i} - end - - assert(rot9r(0) == "123456789") - assert(rot9r(10) == "912345678") - assert(rot9r(105) == "456789123") - assert(rot9r(0) == "123456789") - assert(rot9r(1) == "912345678") - assert(rot9r(2) == "891234567") - assert(rot9r(0) == "123456789") - assert(rot9r(1) == "912345678") - assert(rot9r(2) == "891234567") - assert(rot9r(105) == "456789123") - - assert(rot9l(0) == "123456789") - assert(rot9l(10) == "234567891") - assert(rot9l(105) == "789123456") - assert(rot9l(0) == "123456789") - assert(rot9l(1) == "234567891") - assert(rot9l(2) == "345678912") - assert(rot9l(0) == "123456789") - assert(rot9l(1) == "234567891") - assert(rot9l(2) == "345678912") - - assert(rot9r(100) == "912345678") - assert(rot9l(100) == "234567891") -end - -do --- rot18 - local function rot18r(N) - local a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 - for x=1,N do - a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r=r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q - end - return table.concat{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r} - end - - local function rot18l(N) - local a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 - for x=1,N do - a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r=b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,a - end - return table.concat{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r} - end - - assert(rot18r(0) == "123456789101112131415161718") - assert(rot18r(10) == "910111213141516171812345678") - assert(rot18r(105) == "456789101112131415161718123") - assert(rot18r(0) == "123456789101112131415161718") - assert(rot18r(1) == "181234567891011121314151617") - assert(rot18r(2) == "171812345678910111213141516") - assert(rot18r(0) == "123456789101112131415161718") - assert(rot18r(1) == "181234567891011121314151617") - assert(rot18r(2) == "171812345678910111213141516") - assert(rot18r(105) == "456789101112131415161718123") - - assert(rot18l(0) == "123456789101112131415161718") - assert(rot18l(10) == "111213141516171812345678910") - assert(rot18l(105) == "161718123456789101112131415") - assert(rot18l(0) == "123456789101112131415161718") - assert(rot18l(1) == "234567891011121314151617181") - assert(rot18l(2) == "345678910111213141516171812") - assert(rot18l(0) == "123456789101112131415161718") - assert(rot18l(1) == "234567891011121314151617181") - assert(rot18l(2) == "345678910111213141516171812") - - assert(rot18r(100) == "910111213141516171812345678") - assert(rot18l(100) == "111213141516171812345678910") -end - -do --- rotx - local function rot9r(n, m) - local a,b,c,d,e,f,g,h,i=1,2,3,4,5,6,7,8,9 - local s = "" - for x=1,n do - a,b,c,d,e,f,g,h,i=i,a,b,c,d,e,f,g,h - if x == m then s = table.concat{a,b,c,d,e,f,g,h,i} end - c,d = d,c - end - return table.concat{a,b,c,d,e,f,g,h,i, s} - end - - assert(rot9r(0,0) == "123456789") - assert(rot9r(10,0) == "893124567") - assert(rot9r(105,0) == "913245678") - assert(rot9r(105,90) == "913245678891324567") - assert(rot9r(0,0) == "123456789") - assert(rot9r(1,0) == "913245678") - assert(rot9r(2,0) == "893124567") - assert(rot9r(1,1) == "913245678912345678") - assert(rot9r(2,1) == "893124567912345678") - assert(rot9r(2,2) == "893124567891324567") -end +do --- rot8 + local function rot8r(n) + local a,b,c,d,e,f,g,h=1,2,3,4,5,6,7,8 + for x=1,n do + a,b,c,d,e,f,g,h=h,a,b,c,d,e,f,g + end + return table.concat{a,b,c,d,e,f,g,h} + end + + local function rot8l(n) + local a,b,c,d,e,f,g,h=1,2,3,4,5,6,7,8 + for x=1,n do + a,b,c,d,e,f,g,h=b,c,d,e,f,g,h,a + end + return table.concat{a,b,c,d,e,f,g,h} + end + + assert(rot8r(0) == "12345678") + assert(rot8r(10) == "78123456") + assert(rot8r(105) == "81234567") + assert(rot8r(0) == "12345678") + assert(rot8r(1) == "81234567") + assert(rot8r(2) == "78123456") + assert(rot8r(0) == "12345678") + assert(rot8r(1) == "81234567") + assert(rot8r(2) == "78123456") + assert(rot8r(105) == "81234567") + + assert(rot8l(0) == "12345678") + assert(rot8l(10) == "34567812") + assert(rot8l(105) == "23456781") + assert(rot8l(0) == "12345678") + assert(rot8l(1) == "23456781") + assert(rot8l(2) == "34567812") + assert(rot8l(0) == "12345678") + assert(rot8l(1) == "23456781") + assert(rot8l(2) == "34567812") + + assert(rot8r(100) == "56781234") + assert(rot8l(100) == "56781234") +end + +do --- rot9 + local function rot9r(n) + local a,b,c,d,e,f,g,h,i=1,2,3,4,5,6,7,8,9 + for x=1,n do + a,b,c,d,e,f,g,h,i=i,a,b,c,d,e,f,g,h + end + return table.concat{a,b,c,d,e,f,g,h,i} + end + + local function rot9l(n) + local a,b,c,d,e,f,g,h,i=1,2,3,4,5,6,7,8,9 + for x=1,n do + a,b,c,d,e,f,g,h,i=b,c,d,e,f,g,h,i,a + end + return table.concat{a,b,c,d,e,f,g,h,i} + end + + assert(rot9r(0) == "123456789") + assert(rot9r(10) == "912345678") + assert(rot9r(105) == "456789123") + assert(rot9r(0) == "123456789") + assert(rot9r(1) == "912345678") + assert(rot9r(2) == "891234567") + assert(rot9r(0) == "123456789") + assert(rot9r(1) == "912345678") + assert(rot9r(2) == "891234567") + assert(rot9r(105) == "456789123") + + assert(rot9l(0) == "123456789") + assert(rot9l(10) == "234567891") + assert(rot9l(105) == "789123456") + assert(rot9l(0) == "123456789") + assert(rot9l(1) == "234567891") + assert(rot9l(2) == "345678912") + assert(rot9l(0) == "123456789") + assert(rot9l(1) == "234567891") + assert(rot9l(2) == "345678912") + + assert(rot9r(100) == "912345678") + assert(rot9l(100) == "234567891") +end + +do --- rot18 + local function rot18r(N) + local a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 + for x=1,N do + a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r=r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q + end + return table.concat{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r} + end + + local function rot18l(N) + local a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 + for x=1,N do + a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r=b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,a + end + return table.concat{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r} + end + + assert(rot18r(0) == "123456789101112131415161718") + assert(rot18r(10) == "910111213141516171812345678") + assert(rot18r(105) == "456789101112131415161718123") + assert(rot18r(0) == "123456789101112131415161718") + assert(rot18r(1) == "181234567891011121314151617") + assert(rot18r(2) == "171812345678910111213141516") + assert(rot18r(0) == "123456789101112131415161718") + assert(rot18r(1) == "181234567891011121314151617") + assert(rot18r(2) == "171812345678910111213141516") + assert(rot18r(105) == "456789101112131415161718123") + + assert(rot18l(0) == "123456789101112131415161718") + assert(rot18l(10) == "111213141516171812345678910") + assert(rot18l(105) == "161718123456789101112131415") + assert(rot18l(0) == "123456789101112131415161718") + assert(rot18l(1) == "234567891011121314151617181") + assert(rot18l(2) == "345678910111213141516171812") + assert(rot18l(0) == "123456789101112131415161718") + assert(rot18l(1) == "234567891011121314151617181") + assert(rot18l(2) == "345678910111213141516171812") + + assert(rot18r(100) == "910111213141516171812345678") + assert(rot18l(100) == "111213141516171812345678910") +end + +do --- rotx + local function rot9r(n, m) + local a,b,c,d,e,f,g,h,i=1,2,3,4,5,6,7,8,9 + local s = "" + for x=1,n do + a,b,c,d,e,f,g,h,i=i,a,b,c,d,e,f,g,h + if x == m then s = table.concat{a,b,c,d,e,f,g,h,i} end + c,d = d,c + end + return table.concat{a,b,c,d,e,f,g,h,i, s} + end + + assert(rot9r(0,0) == "123456789") + assert(rot9r(10,0) == "893124567") + assert(rot9r(105,0) == "913245678") + assert(rot9r(105,90) == "913245678891324567") + assert(rot9r(0,0) == "123456789") + assert(rot9r(1,0) == "913245678") + assert(rot9r(2,0) == "893124567") + assert(rot9r(1,1) == "913245678912345678") + assert(rot9r(2,1) == "893124567912345678") + assert(rot9r(2,2) == "893124567891324567") +end diff --git a/test/trace/snap.lua b/test/trace/snap.lua index ca31595f0e..ba26326e0f 100644 --- a/test/trace/snap.lua +++ b/test/trace/snap.lua @@ -1,47 +1,47 @@ -do --- gcexit - local x = 0 - local t - for i=1,1000 do - if i >= 100 then - -- causes an exit for atomic phase - -- must not merge snapshot #0 with comparison since it has the wrong PC - if i < 150 then x=x+1 end - t = {i} - end - end - assert(x == 50) - assert(t[1] == 1000) -end - - -do --- top !private_G - function randomtable(entries, depth) - if depth == 0 then - return tostring(math.random(2)) -- snapshot between return and CALLMT - end - local t = {} - for k=1,entries do - t[k] = randomtable(entries, depth-1) - end - return t - end - - local t = randomtable(10, 2) -end - -do --- top2 - local function f() - gcinfo() - local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ - local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ - local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ - local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ - local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ - local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ - end - - for i=1,100 do - f() - if i % 3 == 0 then collectgarbage() end - end -end +do --- gcexit + local x = 0 + local t + for i=1,1000 do + if i >= 100 then + -- causes an exit for atomic phase + -- must not merge snapshot #0 with comparison since it has the wrong PC + if i < 150 then x=x+1 end + t = {i} + end + end + assert(x == 50) + assert(t[1] == 1000) +end + + +do --- top !private_G + function randomtable(entries, depth) + if depth == 0 then + return tostring(math.random(2)) -- snapshot between return and CALLMT + end + local t = {} + for k=1,entries do + t[k] = randomtable(entries, depth-1) + end + return t + end + + local t = randomtable(10, 2) +end + +do --- top2 + local function f() + gcinfo() + local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ + local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ + local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ + local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ + local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ + local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ + end + + for i=1,100 do + f() + if i % 3 == 0 then collectgarbage() end + end +end diff --git a/test/trace/stitch.lua b/test/trace/stitch.lua index 55ce5c4151..3f7f97342f 100644 --- a/test/trace/stitch.lua +++ b/test/trace/stitch.lua @@ -1,19 +1,19 @@ -do --- octal - local tonumber = tonumber - local function octal(s) return tonumber(s, 8) end - for i=1,100 do - octal("1") - octal("1") - octal("1") - end -end - -do --- coroutines - local t = { - [0] = function() end, - coroutine.wrap(function() while true do coroutine.yield() end end), - } - for i=1,100 do - t[i % 2]() - end -end +do --- octal + local tonumber = tonumber + local function octal(s) return tonumber(s, 8) end + for i=1,100 do + octal("1") + octal("1") + octal("1") + end +end + +do --- coroutines + local t = { + [0] = function() end, + coroutine.wrap(function() while true do coroutine.yield() end end), + } + for i=1,100 do + t[i % 2]() + end +end