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 |
