diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-03-19 10:53:18 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-03-19 10:53:18 -0300 |
commit | 9b37a4695ebf50b37b5b4fb279ae948f23b5b6a0 (patch) | |
tree | 2a6b0f6c1c2eb962bb383175eb0a67ea81a4564d /testes | |
parent | 1e0c73d5b643707335b06abd2546a83d9439d14c (diff) | |
download | lua-9b37a4695ebf50b37b5b4fb279ae948f23b5b6a0.tar.gz lua-9b37a4695ebf50b37b5b4fb279ae948f23b5b6a0.tar.bz2 lua-9b37a4695ebf50b37b5b4fb279ae948f23b5b6a0.zip |
New semantics for the integer 'for' loop
The numerical 'for' loop over integers now uses a precomputed counter
to control its number of iteractions. This change eliminates several
weird cases caused by overflows (wrap-around) in the control variable.
(It also ensures that every integer loop halts.)
Also, the special opcodes for the usual case of step==1 were removed.
(The new code is already somewhat complex for the usual case,
but efficient.)
Diffstat (limited to 'testes')
-rw-r--r-- | testes/code.lua | 4 | ||||
-rw-r--r-- | testes/db.lua | 2 | ||||
-rw-r--r-- | testes/nextvar.lua | 73 |
3 files changed, 71 insertions, 8 deletions
diff --git a/testes/code.lua b/testes/code.lua index 834ff5e2..128ca2cb 100644 --- a/testes/code.lua +++ b/testes/code.lua | |||
@@ -303,9 +303,9 @@ check(function (x) return x & 2.0 end, 'LOADF', 'BAND', 'RETURN1') | |||
303 | 303 | ||
304 | -- basic 'for' loops | 304 | -- basic 'for' loops |
305 | check(function () for i = -10, 10.5 do end end, | 305 | check(function () for i = -10, 10.5 do end end, |
306 | 'LOADI', 'LOADK', 'LOADI', 'FORPREP1', 'FORLOOP1', 'RETURN0') | 306 | 'LOADI', 'LOADK', 'LOADI', 'FORPREP', 'FORLOOP', 'RETURN0') |
307 | check(function () for i = 0xfffffff, 10.0, 1 do end end, | 307 | check(function () for i = 0xfffffff, 10.0, 1 do end end, |
308 | 'LOADK', 'LOADF', 'LOADI', 'FORPREP1', 'FORLOOP1', 'RETURN0') | 308 | 'LOADK', 'LOADF', 'LOADI', 'FORPREP', 'FORLOOP', 'RETURN0') |
309 | 309 | ||
310 | -- bug in constant folding for 5.1 | 310 | -- bug in constant folding for 5.1 |
311 | check(function () return -nil end, 'LOADNIL', 'UNM', 'RETURN1') | 311 | check(function () return -nil end, 'LOADNIL', 'UNM', 'RETURN1') |
diff --git a/testes/db.lua b/testes/db.lua index 976962b0..0858dd20 100644 --- a/testes/db.lua +++ b/testes/db.lua | |||
@@ -162,7 +162,7 @@ test([[for i,v in pairs{'a','b'} do | |||
162 | end | 162 | end |
163 | ]], {1,2,1,2,1,3}) | 163 | ]], {1,2,1,2,1,3}) |
164 | 164 | ||
165 | test([[for i=1,4 do a=1 end]], {1,1,1,1,1}) | 165 | test([[for i=1,4 do a=1 end]], {1,1,1,1}, true) |
166 | 166 | ||
167 | 167 | ||
168 | do -- testing line info/trace with large gaps in source | 168 | do -- testing line info/trace with large gaps in source |
diff --git a/testes/nextvar.lua b/testes/nextvar.lua index d2306ed1..e769ccdd 100644 --- a/testes/nextvar.lua +++ b/testes/nextvar.lua | |||
@@ -76,7 +76,7 @@ while a < lim do | |||
76 | a = math.ceil(a*1.3) | 76 | a = math.ceil(a*1.3) |
77 | end | 77 | end |
78 | 78 | ||
79 | 79 | ||
80 | local function check (t, na, nh) | 80 | local function check (t, na, nh) |
81 | local a, h = T.querytab(t) | 81 | local a, h = T.querytab(t) |
82 | if a ~= na or h ~= nh then | 82 | if a ~= na or h ~= nh then |
@@ -100,7 +100,7 @@ local s = 'return {' | |||
100 | for i=1,lim do | 100 | for i=1,lim do |
101 | s = s..i..',' | 101 | s = s..i..',' |
102 | local s = s | 102 | local s = s |
103 | for k=0,lim do | 103 | for k=0,lim do |
104 | local t = load(s..'}', '')() | 104 | local t = load(s..'}', '')() |
105 | assert(#t == i) | 105 | assert(#t == i) |
106 | check(t, fb(i), mp2(k)) | 106 | check(t, fb(i), mp2(k)) |
@@ -279,7 +279,7 @@ do -- clear global table | |||
279 | end | 279 | end |
280 | 280 | ||
281 | 281 | ||
282 | -- | 282 | -- |
283 | 283 | ||
284 | local function checknext (a) | 284 | local function checknext (a) |
285 | local b = {} | 285 | local b = {} |
@@ -500,7 +500,7 @@ else --[ | |||
500 | mt.__newindex = nil | 500 | mt.__newindex = nil |
501 | mt.__len = nil | 501 | mt.__len = nil |
502 | local tab2 = {} | 502 | local tab2 = {} |
503 | local u2 = T.newuserdata(0) | 503 | local u2 = T.newuserdata(0) |
504 | debug.setmetatable(u2, {__newindex = function (_, k, v) tab2[k] = v end}) | 504 | debug.setmetatable(u2, {__newindex = function (_, k, v) tab2[k] = v end}) |
505 | table.move(u, 1, 4, 1, u2) | 505 | table.move(u, 1, 4, 1, u2) |
506 | assert(#tab2 == 4 and tab2[1] == tab[1] and tab2[4] == tab[4]) | 506 | assert(#tab2 == 4 and tab2[1] == tab[1] and tab2[4] == tab[4]) |
@@ -601,6 +601,69 @@ do -- checking types | |||
601 | 601 | ||
602 | end | 602 | end |
603 | 603 | ||
604 | |||
605 | do -- testing other strange cases for numeric 'for' | ||
606 | |||
607 | local function checkfor (from, to, step, t) | ||
608 | local c = 0 | ||
609 | for i = from, to, step do | ||
610 | c = c + 1 | ||
611 | assert(i == t[c]) | ||
612 | end | ||
613 | assert(c == #t) | ||
614 | end | ||
615 | |||
616 | local maxi = math.maxinteger | ||
617 | local mini = math.mininteger | ||
618 | |||
619 | checkfor(mini, maxi, maxi, {mini, -1, maxi - 1}) | ||
620 | |||
621 | checkfor(mini, math.huge, maxi, {mini, -1, maxi - 1}) | ||
622 | |||
623 | checkfor(maxi, mini, mini, {maxi, -1}) | ||
624 | |||
625 | checkfor(maxi, mini, -maxi, {maxi, 0, -maxi}) | ||
626 | |||
627 | checkfor(maxi, -math.huge, mini, {maxi, -1}) | ||
628 | |||
629 | checkfor(maxi, mini, 1, {}) | ||
630 | checkfor(mini, maxi, -1, {}) | ||
631 | |||
632 | checkfor(maxi - 6, maxi, 3, {maxi - 6, maxi - 3, maxi}) | ||
633 | checkfor(mini + 4, mini, -2, {mini + 4, mini + 2, mini}) | ||
634 | |||
635 | local step = maxi // 10 | ||
636 | local c = mini | ||
637 | for i = mini, maxi, step do | ||
638 | assert(i == c) | ||
639 | c = c + step | ||
640 | end | ||
641 | |||
642 | c = maxi | ||
643 | for i = maxi, mini, -step do | ||
644 | assert(i == c) | ||
645 | c = c - step | ||
646 | end | ||
647 | |||
648 | checkfor(maxi, maxi, maxi, {maxi}) | ||
649 | checkfor(maxi, maxi, mini, {maxi}) | ||
650 | checkfor(mini, mini, maxi, {mini}) | ||
651 | checkfor(mini, mini, mini, {mini}) | ||
652 | end | ||
653 | |||
654 | |||
655 | checkerror("'for' step is zero", function () | ||
656 | for i = 1, 10, 0 do end | ||
657 | end) | ||
658 | |||
659 | checkerror("'for' step is zero", function () | ||
660 | for i = 1, -10, 0 do end | ||
661 | end) | ||
662 | |||
663 | checkerror("'for' step is zero", function () | ||
664 | for i = 1.0, -10, 0.0 do end | ||
665 | end) | ||
666 | |||
604 | collectgarbage() | 667 | collectgarbage() |
605 | 668 | ||
606 | 669 | ||
@@ -657,7 +720,7 @@ a[3] = 30 | |||
657 | -- testing ipairs with metamethods | 720 | -- testing ipairs with metamethods |
658 | a = {n=10} | 721 | a = {n=10} |
659 | setmetatable(a, { __index = function (t,k) | 722 | setmetatable(a, { __index = function (t,k) |
660 | if k <= t.n then return k * 10 end | 723 | if k <= t.n then return k * 10 end |
661 | end}) | 724 | end}) |
662 | i = 0 | 725 | i = 0 |
663 | for k,v in ipairs(a) do | 726 | for k,v in ipairs(a) do |