diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-01-10 13:54:51 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-01-10 13:54:51 -0300 |
commit | 7ca3c40b50b385ead6b8bc4c54de97b61d11a12a (patch) | |
tree | 5c5998f39760b07e05135df56b8a828f2fb685c1 /testes/code.lua | |
parent | 8a3a49250ce4a7e46ec9e90810a61d9f97aece3d (diff) | |
download | lua-7ca3c40b50b385ead6b8bc4c54de97b61d11a12a.tar.gz lua-7ca3c40b50b385ead6b8bc4c54de97b61d11a12a.tar.bz2 lua-7ca3c40b50b385ead6b8bc4c54de97b61d11a12a.zip |
Another way to compile goto's
The compilation of a goto or a label just create an entry and generate
boilerplate code for the gotos. As we don't know yet whether it needs a
CLOSE, we code a jump followed by a CLOSE, which is then dead code.
When a block ends (and then we know for sure whether there are variables
that need to be closed), we check the goto's against the labels of that
block. When closing a goto against a label, if it needs a CLOSE, the
compiler swaps the order of the jump and the CLOSE, making the CLOSE
active.
Diffstat (limited to 'testes/code.lua')
-rw-r--r-- | testes/code.lua | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/testes/code.lua b/testes/code.lua index 08b3e23f..50ce7392 100644 --- a/testes/code.lua +++ b/testes/code.lua | |||
@@ -412,13 +412,22 @@ checkequal(function (l) local a; return 0 <= a and a <= l end, | |||
412 | function (l) local a; return not (not(a >= 0) or not(a <= l)) end) | 412 | function (l) local a; return not (not(a >= 0) or not(a <= l)) end) |
413 | 413 | ||
414 | 414 | ||
415 | -- if-break optimizations | ||
416 | check(function (a, b) | 415 | check(function (a, b) |
417 | while a do | 416 | while a do |
418 | if b then break else a = a + 1 end | 417 | if b then break else a = a + 1 end |
419 | end | 418 | end |
420 | end, | 419 | end, |
421 | 'TEST', 'JMP', 'TEST', 'JMP', 'ADDI', 'MMBINI', 'JMP', 'RETURN0') | 420 | 'TEST', 'JMP', 'TEST', 'JMP', 'JMP', 'CLOSE', 'JMP', 'ADDI', 'MMBINI', 'JMP', 'RETURN0') |
421 | |||
422 | check(function () | ||
423 | do | ||
424 | goto exit -- don't need to close | ||
425 | local x <close> = nil | ||
426 | goto exit -- must close | ||
427 | end | ||
428 | ::exit:: | ||
429 | end, 'JMP', 'CLOSE', 'LOADNIL', 'TBC', | ||
430 | 'CLOSE', 'JMP', 'CLOSE', 'RETURN') | ||
422 | 431 | ||
423 | checkequal(function () return 6 or true or nil end, | 432 | checkequal(function () return 6 or true or nil end, |
424 | function () return k6 or kTrue or kNil end) | 433 | function () return k6 or kTrue or kNil end) |