lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> This one was a pain to minify from the original ~200kb test... until I
> realized that it needs a minimum number of unique constants to trigger.
> 
> -- begin test case --
> [...]

So, it seems that the order in 'codebinexpval' matters, after all :-)
(Dibyendu, remember this [1]?)

Roughly: (1 + _ENV.B) should generate the following code, when '1' and 'B'
do not fit as immediate operands:

    7 - LOADK          0    5            -- R0 = "B"
    8 - LOADK          1    6            -- R1 = 1
    9 - GETTABUP       0    0    0       -- R0 = _ENV[R0]
   10 - ADD            0    1    0       -- R0 = R1 + R0

On instruction 9, Lua would try to free register R0, as "B" will not be
needed after that point; that triggers the assertion, because R1 is
still being used. (Without the assertion, it would free R1 instead of
R0, resulting in wrong opcodes.)

Changing the order of the calls to 'luaK_exp2RK' in 'codebinexpval'
generates the following code:

    7 - LOADK          0    5            -- R0 = "B"
    8 - GETTABUP       0    0    0       -- R0 = _ENV[R0]
    9 - LOADK          1    6            -- R1 = 1
   10 - ADD            0    1    0       -- R0 = R1 + R0

Now, when Lua tries to free register R0 in instruction 8, there is
no problem. (It then goes on to immediately reuse R0 for the result
of the GETTABUP operation.)

The fix seems to be only this:

===================================================================
--- lcode.c	2016/06/20 19:12:46	2.110
+++ lcode.c	2016/07/18 15:43:41
@@ -1018,8 +1018,8 @@
 */
 static void codebinexpval (FuncState *fs, OpCode op,
                            expdesc *e1, expdesc *e2, int line) {
-  int rk1 = luaK_exp2RK(fs, e1);  /* both operands are "RK" */
-  int rk2 = luaK_exp2RK(fs, e2);
+  int rk2 = luaK_exp2RK(fs, e2);  /* both operands are "RK" */
+  int rk1 = luaK_exp2RK(fs, e1);
   freeexps(fs, e1, e2);
   e1->u.info = luaK_codeABC(fs, op, 0, rk1, rk2);  /* generate opcode */
   e1->k = VRELOCABLE;  /* all those operations are relocatable */
===================================================================


[1] http://lua-users.org/lists/lua-l/2016-06/msg00151.html

-- Roberto