diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-10-30 15:04:19 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-10-30 15:04:19 -0300 |
commit | 2316ec4c24a475e091ec3153a5bd908801a3a109 (patch) | |
tree | ce14172ed7d7dc8874ea282a97d41f4b380f419e /testes | |
parent | a006514ea138a29b6031058d9002b48a572b5dd6 (diff) | |
download | lua-github-2316ec4c24a475e091ec3153a5bd908801a3a109.tar.gz |
Back with optimization for 'if cond then goto'
Statements like 'if cond then goto label' generate code so that the
jump in the 'if' goes directly to the given label. This optimization
cannot be done when the jump is backwards leaving the scope of some
variable, as it cannot add the needed 'close' instruction. (The jumps
were already generated by the 'if'.)
This commit also added 'likely'/'unlikely' for tests for errors in
the parser, and it changed the way breaks outside loops are detected.
(Now they are detected like other goto's with undefined labels.)
Diffstat (limited to 'testes')
-rw-r--r-- | testes/code.lua | 20 | ||||
-rw-r--r-- | testes/goto.lua | 16 |
2 files changed, 35 insertions, 1 deletions
diff --git a/testes/code.lua b/testes/code.lua index 9b3f2b68..4d44fa6a 100644 --- a/testes/code.lua +++ b/testes/code.lua @@ -339,8 +339,26 @@ check(function (a, b) checkequal( function (a) while a < 10 do a = a + 1 end end, -function (a) while true do if not(a < 10) then break end; a = a + 1; end end +function (a) + ::loop:: + if not (a < 10) then goto exit end + a = a + 1 + goto loop +::exit:: +end ) +checkequal( +function (a) repeat local x = a + 1; a = x until a > 0 end, +function (a) + ::loop:: do + local x = a + 1 + a = x + end + if not (a > 0) then goto loop end +end +) + + print 'OK' diff --git a/testes/goto.lua b/testes/goto.lua index 85038d02..92f048fb 100644 --- a/testes/goto.lua +++ b/testes/goto.lua @@ -249,6 +249,22 @@ assert(testG(2) == "2") assert(testG(3) == "3") assert(testG(4) == 5) assert(testG(5) == 10) + +do + -- if x back goto out of scope of upvalue + local X + goto L1 + + ::L2:: goto L3 + + ::L1:: do + local scoped a = function () X = true end + assert(X == nil) + if a then goto L2 end -- jumping back out of scope of 'a' + end + + ::L3:: assert(X == true) -- checks that 'a' was correctly closed +end -------------------------------------------------------------------------------- |