# New Ticket Created by  Robert G. Jakabosky 
# Please include the string:  [perl #57568]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=57568 >



I have separated the bugfixes into different patch files and included one 
large patch file (all_changes.patch) that includes all the other patches.

fix_assignlist.patch:
In Lua you can swap variables using an assignlist like this:
v1,v2 = v2,v1
The problem is that both v1 & v2 would equal the value in v2.  The value in v1 
was lost.  To fix this I added the use of temp registers to store the values 
before the final assignments.  The life.lua script was effected by this bug.

test_swap_assignlist.patch:
Adds test case for bug fixed in 'fix_assignlist.patch'

fix_environ_reg_cache.patch:
Accessing a global in Lua after using a logical "and" operation would cause a 
crash if the second operand was a global variable and the first operand was 
false.  The POST pass was caching the register name used to access global 
variable to speed up global access.  That cached register needs to be cleared 
after method calls and branches.  It wasn't being cleared after the 
logical "and" operation so the next global access try using a register that 
will not be set if the branch wasn't taken.  This bug is why the life.lua 
script was crashing.

test_global_access.patch:
Adds test case for bug fixed in 'fix_environ_reg_cache.patch'

fix_fornum.patch:
The loop count variable in "for" loops was being passed by reference instead 
of by value as is required for numbers in Lua.  To fix this I added a temp 
register for the real loop counter and cloned that value into the count 
variable that is visible to the loop code.  This bug effected the sieve.lua 
script making it return only 1 prime.

fix_lua_bytecode_loader.patch:
This patch fixes the loading of Lua bytecode files.

test_fix_bisect_output.patch:
The expected output for the bisect.lua script seems to be wrong.  I have 
tested that script with Lua 5.1.3 on three different computers and the output 
doesn't match the expected output for this test case.  Even the "Live demo" 
on lua.org: http://www.lua.org/cgi-bin/demo matches the output from my three 
computers.  This patch updates the expected output file so it matches the 
output from the official Lua output.

test_from_lua.patch:
Removes TODO on bisect & sieve tests.  Changes skip message for life test 
from "crash" to "uses to much memory with default runcore"

The life.lua script uses too much memory (>1 Gbyte) when using the 
slow/fast/computed-goto cores and even when the JIT is turned on.  Using 
the "--leak-test" option doesn't show any leaks and the "--gc-debug" option 
doesn't improve memory usage.  The CGP & switched cores don't have this 
problem they use less then 60 Mbytes.

diffstats for all_changes.patch:
 src/POSTGrammar.tg       |   14 ++++++++++----
 src/lib/luaaux.pir       |    2 +-
 t/assign.t               |   30 +++++++++++++++++++++++++++++-
 t/expr.t                 |   18 +++++++++++++++++-
 t/test-from-lua.t        |   12 +-----------
 t/test/bisect-output.txt |    6 +++---
 6 files changed, 61 insertions(+), 21 deletions(-)

-- 
Robert G. Jakabosky
Index: languages/lua/t/test/bisect-output.txt
===================================================================
--- languages/lua/t/test/bisect-output.txt	(revision 29974)
+++ languages/lua/t/test/bisect-output.txt	(working copy)
@@ -11,12 +11,12 @@
 10 c=1.32470703125 a=1.32421875 b=1.3251953125
 11 c=1.324951171875 a=1.32470703125 b=1.3251953125
 12 c=1.3248291015625 a=1.32470703125 b=1.324951171875
-13 c=1.3247680664063 a=1.32470703125 b=1.3248291015625
-14 c=1.3247375488281 a=1.32470703125 b=1.3247680664063
+13 c=1.3247680664062 a=1.32470703125 b=1.3248291015625
+14 c=1.3247375488281 a=1.32470703125 b=1.3247680664062
 15 c=1.3247222900391 a=1.32470703125 b=1.3247375488281
 16 c=1.3247146606445 a=1.32470703125 b=1.3247222900391
 17 c=1.3247184753418 a=1.3247146606445 b=1.3247222900391
 18 c=1.3247165679932 a=1.3247146606445 b=1.3247184753418
 19 c=1.3247175216675 a=1.3247165679932 b=1.3247184753418
 20 c=1.3247179985046 a=1.3247175216675 b=1.3247184753418
-after 20 steps, root is 1.3247179985046387 with error 9.5e-007, f=1.8e-007
+after 20 steps, root is 1.3247179985046387 with error 9.5e-07, f=1.8e-07
Index: languages/lua/t/test-from-lua.t
===================================================================
--- languages/lua/t/test-from-lua.t	(revision 29974)
+++ languages/lua/t/test-from-lua.t	(working copy)
@@ -61,14 +61,9 @@
 #       bisection method for solving non-linear equations
 #
 
-TODO:
-{
-    local $TODO = 'floating point format';
-
 $code = Parrot::Test::slurp_file(File::Spec->catfile( @dir, 'bisect.lua' ));
 $out = Parrot::Test::slurp_file(File::Spec->catfile( @dir, 'bisect-output.txt' ));
 language_output_is( 'lua', $code, $out, 'bisect' );
-}
 
 #
 #   cf.lua
@@ -142,7 +137,7 @@
 
 SKIP:
 {
-    skip('crash', 1) unless ($test_prog eq 'lua');
+    skip('uses too much memory with default runcore', 1) unless ($test_prog eq 'lua');
 
 $code = Parrot::Test::slurp_file(File::Spec->catfile( @dir, 'life.lua' ));
 $out = Parrot::Test::slurp_file(File::Spec->catfile( @dir, 'life-output.txt' ));
@@ -175,14 +170,9 @@
 #       the sieve of of Eratosthenes programmed with coroutines
 #
 
-TODO:
-{
-    local $TODO = 'just one ?';
-
 $code = Parrot::Test::slurp_file(File::Spec->catfile( @dir, 'sieve.lua' ));
 $out = Parrot::Test::slurp_file(File::Spec->catfile( @dir, 'sieve-output.txt' ));
 language_output_is( 'lua', $code, $out, 'sieve' );
-}
 
 #
 #   sort.lua
Index: languages/lua/src/lib/luaaux.pir
===================================================================
--- languages/lua/src/lib/luaaux.pir	(revision 29974)
+++ languages/lua/src/lib/luaaux.pir	(working copy)
@@ -585,7 +585,7 @@
     pir = $P1.'translate'()
     .local pmc pir_comp
     pir_comp = compreg 'PIR'
-    $P0 = pir_comp.'compile'(pir)
+    $P0 = pir_comp(pir)
     $P0 = $P0[1]
     .local pmc env
     env = get_hll_global '_G'
Index: languages/lua/src/POSTGrammar.tg
===================================================================
--- languages/lua/src/POSTGrammar.tg	(revision 29974)
+++ languages/lua/src/POSTGrammar.tg	(working copy)
@@ -682,7 +682,9 @@
     rpost = tree.'get'('post', $P0)
     ops.'push'(rpost)
     $S1 = rpost.'result'()
-    push tmp, $S1
+    $S2 = ops.'unique'('$P')
+    ops.'push_pirop'('clone', $S2, $S1)
+    push tmp, $S2
     if iter goto L1
     $I0 = rpost.'has_call_in_last_op'()
     unless $I0 goto L1
Index: languages/lua/src/POSTGrammar.tg
===================================================================
--- languages/lua/src/POSTGrammar.tg	(revision 29974)
+++ languages/lua/src/POSTGrammar.tg	(working copy)
@@ -312,6 +312,8 @@
     ops.'push_pirop'('clone', $S0, expr2)
     ops.'push_new'('POST::Label', 'result'=>endlabel)
     ops.'result'($S0)
+    null $P0
+    set_hll_global ['Lua::POST'], '$?environ', $P0
     .return (ops)
 }
 
Index: languages/lua/src/POSTGrammar.tg
===================================================================
--- languages/lua/src/POSTGrammar.tg	(revision 29974)
+++ languages/lua/src/POSTGrammar.tg	(working copy)
@@ -438,15 +438,16 @@
     $P1 = $P0[2]
     e_step = tree.'get'('post', $P1)
     ops.'push'(e_step)
-    .local string var
+    .local string loc_v
     $P0 = node[0]
     $P0 = tree.'get'('post', $P0)
     $P1 = $P0.'pop'()
     ops.'push'($P0)
     $P1 = $P0.'pop'()
     $P0.'push'($P1)
-    var = $P1.'result'()
-    .local string limit, step
+    loc_v = $P1.'result'()
+    .local string var, limit, step
+    var = ops.'unique'('$P')
     limit = ops.'unique'('$P')
     step = ops.'unique'('$P')
     ops.'push_pirop'('inline', var, limit, step, e_var, e_limit, e_step, 'inline'=>'    (%0, %1, %2) = checkforloop(%3, %4, %5)')
@@ -468,6 +469,7 @@
     ops.'push_new'('POST::Label', 'result'=>orlabel)
     ops.'push_pirop'('lt', var, limit, endlabel)
     ops.'push_new'('POST::Label', 'result'=>blklabel)
+    ops.'push_pirop'('clone', loc_v, var)
     .local pmc blk
     $P0 = node[2]
     blk = tree.'get'('post', $P0)
Index: languages/lua/t/expr.t
===================================================================
--- languages/lua/t/expr.t	(revision 29974)
+++ languages/lua/t/expr.t	(working copy)
@@ -24,7 +24,7 @@
 use FindBin;
 use lib "$FindBin::Bin";
 
-use Parrot::Test tests => 12;
+use Parrot::Test tests => 13;
 use Test::More;
 
 language_output_is( 'lua', <<'CODE', <<'OUT', 'modulo' );
@@ -175,6 +175,22 @@
 37
 OUT
 
+language_output_is( 'lua', <<'CODE', <<'OUT', 'mix access to globals and logical and op' );
+some_global="global"
+
+-- access a global like print
+print("test")
+-- use "and" or "or" logical operation
+-- access a global in the second operand.
+-- make sure the second operand is not evaluated at runtime.
+out=false and some_global
+-- access another global like print
+print(out)
+CODE
+test
+false
+OUT
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4
Index: languages/lua/t/assign.t
===================================================================
--- languages/lua/t/assign.t	(revision 29974)
+++ languages/lua/t/assign.t	(working copy)
@@ -24,7 +24,7 @@
 use FindBin;
 use lib "$FindBin::Bin";
 
-use Parrot::Test tests => 9;
+use Parrot::Test tests => 10;
 use Test::More;
 
 language_output_is( 'lua', <<'CODE', <<'OUT', 'global variable' );
@@ -132,6 +132,34 @@
 4
 OUT
 
+language_output_is( 'lua', <<'CODE', <<'OUT', 'assignment list swap values.' );
+local n1 = 1
+local n2 = 2
+local n3 = 3
+local n4 = 4
+
+print(n1)
+print(n2)
+print(n3)
+print(n4)
+
+n1,n2,n3,n4 = n4,n3,n2,n1
+
+print(n1)
+print(n2)
+print(n3)
+print(n4)
+CODE
+1
+2
+3
+4
+4
+3
+2
+1
+OUT
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4
Index: languages/lua/t/expr.t
===================================================================
--- languages/lua/t/expr.t	(revision 29974)
+++ languages/lua/t/expr.t	(working copy)
@@ -24,7 +24,7 @@
 use FindBin;
 use lib "$FindBin::Bin";
 
-use Parrot::Test tests => 12;
+use Parrot::Test tests => 13;
 use Test::More;
 
 language_output_is( 'lua', <<'CODE', <<'OUT', 'modulo' );
@@ -175,6 +175,22 @@
 37
 OUT
 
+language_output_is( 'lua', <<'CODE', <<'OUT', 'mix access to globals and logical and op' );
+some_global="global"
+
+-- access a global like print
+print("test")
+-- use "and" or "or" logical operation
+-- access a global in the second operand.
+-- make sure the second operand is not evaluated at runtime.
+out=false and some_global
+-- access another global like print
+print(out)
+CODE
+test
+false
+OUT
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4
Index: languages/lua/t/assign.t
===================================================================
--- languages/lua/t/assign.t	(revision 29974)
+++ languages/lua/t/assign.t	(working copy)
@@ -24,7 +24,7 @@
 use FindBin;
 use lib "$FindBin::Bin";
 
-use Parrot::Test tests => 9;
+use Parrot::Test tests => 10;
 use Test::More;
 
 language_output_is( 'lua', <<'CODE', <<'OUT', 'global variable' );
@@ -132,6 +132,34 @@
 4
 OUT
 
+language_output_is( 'lua', <<'CODE', <<'OUT', 'assignment list swap values.' );
+local n1 = 1
+local n2 = 2
+local n3 = 3
+local n4 = 4
+
+print(n1)
+print(n2)
+print(n3)
+print(n4)
+
+n1,n2,n3,n4 = n4,n3,n2,n1
+
+print(n1)
+print(n2)
+print(n3)
+print(n4)
+CODE
+1
+2
+3
+4
+4
+3
+2
+1
+OUT
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4
Index: languages/lua/t/test/bisect-output.txt
===================================================================
--- languages/lua/t/test/bisect-output.txt	(revision 29974)
+++ languages/lua/t/test/bisect-output.txt	(working copy)
@@ -11,12 +11,12 @@
 10 c=1.32470703125 a=1.32421875 b=1.3251953125
 11 c=1.324951171875 a=1.32470703125 b=1.3251953125
 12 c=1.3248291015625 a=1.32470703125 b=1.324951171875
-13 c=1.3247680664063 a=1.32470703125 b=1.3248291015625
-14 c=1.3247375488281 a=1.32470703125 b=1.3247680664063
+13 c=1.3247680664062 a=1.32470703125 b=1.3248291015625
+14 c=1.3247375488281 a=1.32470703125 b=1.3247680664062
 15 c=1.3247222900391 a=1.32470703125 b=1.3247375488281
 16 c=1.3247146606445 a=1.32470703125 b=1.3247222900391
 17 c=1.3247184753418 a=1.3247146606445 b=1.3247222900391
 18 c=1.3247165679932 a=1.3247146606445 b=1.3247184753418
 19 c=1.3247175216675 a=1.3247165679932 b=1.3247184753418
 20 c=1.3247179985046 a=1.3247175216675 b=1.3247184753418
-after 20 steps, root is 1.3247179985046387 with error 9.5e-007, f=1.8e-007
+after 20 steps, root is 1.3247179985046387 with error 9.5e-07, f=1.8e-07
Index: languages/lua/t/test-from-lua.t
===================================================================
--- languages/lua/t/test-from-lua.t	(revision 29974)
+++ languages/lua/t/test-from-lua.t	(working copy)
@@ -61,14 +61,9 @@
 #       bisection method for solving non-linear equations
 #
 
-TODO:
-{
-    local $TODO = 'floating point format';
-
 $code = Parrot::Test::slurp_file(File::Spec->catfile( @dir, 'bisect.lua' ));
 $out = Parrot::Test::slurp_file(File::Spec->catfile( @dir, 'bisect-output.txt' ));
 language_output_is( 'lua', $code, $out, 'bisect' );
-}
 
 #
 #   cf.lua
@@ -142,7 +137,7 @@
 
 SKIP:
 {
-    skip('crash', 1) unless ($test_prog eq 'lua');
+    skip('uses too much memory with default runcore', 1) unless ($test_prog eq 'lua');
 
 $code = Parrot::Test::slurp_file(File::Spec->catfile( @dir, 'life.lua' ));
 $out = Parrot::Test::slurp_file(File::Spec->catfile( @dir, 'life-output.txt' ));
@@ -175,14 +170,9 @@
 #       the sieve of of Eratosthenes programmed with coroutines
 #
 
-TODO:
-{
-    local $TODO = 'just one ?';
-
 $code = Parrot::Test::slurp_file(File::Spec->catfile( @dir, 'sieve.lua' ));
 $out = Parrot::Test::slurp_file(File::Spec->catfile( @dir, 'sieve-output.txt' ));
 language_output_is( 'lua', $code, $out, 'sieve' );
-}
 
 #
 #   sort.lua
Index: languages/lua/src/POSTGrammar.tg
===================================================================
--- languages/lua/src/POSTGrammar.tg	(revision 29974)
+++ languages/lua/src/POSTGrammar.tg	(working copy)
@@ -312,6 +312,8 @@
     ops.'push_pirop'('clone', $S0, expr2)
     ops.'push_new'('POST::Label', 'result'=>endlabel)
     ops.'result'($S0)
+    null $P0
+    set_hll_global ['Lua::POST'], '$?environ', $P0
     .return (ops)
 }
 
@@ -438,15 +440,16 @@
     $P1 = $P0[2]
     e_step = tree.'get'('post', $P1)
     ops.'push'(e_step)
-    .local string var
+    .local string loc_v
     $P0 = node[0]
     $P0 = tree.'get'('post', $P0)
     $P1 = $P0.'pop'()
     ops.'push'($P0)
     $P1 = $P0.'pop'()
     $P0.'push'($P1)
-    var = $P1.'result'()
-    .local string limit, step
+    loc_v = $P1.'result'()
+    .local string var, limit, step
+    var = ops.'unique'('$P')
     limit = ops.'unique'('$P')
     step = ops.'unique'('$P')
     ops.'push_pirop'('inline', var, limit, step, e_var, e_limit, e_step, 'inline'=>'    (%0, %1, %2) = checkforloop(%3, %4, %5)')
@@ -468,6 +471,7 @@
     ops.'push_new'('POST::Label', 'result'=>orlabel)
     ops.'push_pirop'('lt', var, limit, endlabel)
     ops.'push_new'('POST::Label', 'result'=>blklabel)
+    ops.'push_pirop'('clone', loc_v, var)
     .local pmc blk
     $P0 = node[2]
     blk = tree.'get'('post', $P0)
@@ -682,7 +686,9 @@
     rpost = tree.'get'('post', $P0)
     ops.'push'(rpost)
     $S1 = rpost.'result'()
-    push tmp, $S1
+    $S2 = ops.'unique'('$P')
+    ops.'push_pirop'('clone', $S2, $S1)
+    push tmp, $S2
     if iter goto L1
     $I0 = rpost.'has_call_in_last_op'()
     unless $I0 goto L1
Index: languages/lua/src/lib/luaaux.pir
===================================================================
--- languages/lua/src/lib/luaaux.pir	(revision 29974)
+++ languages/lua/src/lib/luaaux.pir	(working copy)
@@ -585,7 +585,7 @@
     pir = $P1.'translate'()
     .local pmc pir_comp
     pir_comp = compreg 'PIR'
-    $P0 = pir_comp.'compile'(pir)
+    $P0 = pir_comp(pir)
     $P0 = $P0[1]
     .local pmc env
     env = get_hll_global '_G'

Reply via email to