소스 검색

bug: Lua can generate wrong code in functions with too many constants

Roberto Ierusalimschy 9 년 전
부모
커밋
fc6b32bcaa
2개의 변경된 파일32개의 추가작업 그리고 5개의 파일을 삭제
  1. 26 2
      bugs
  2. 6 3
      lcode.c

+ 26 - 2
bugs

@@ -3652,9 +3652,9 @@ It needs an "interceptor" 'memcmp' function that continues
 reading memory after a difference is found.]],
 patch = [[
 2c2
-< ** $Id: loslib.c,v 1.64 2016/04/18 13:06:55 roberto Exp roberto $
+< ** $Id: bugs,v 1.149 2016/07/15 17:24:09 roberto Exp roberto $
 ---
-> ** $Id: loslib.c,v 1.64 2016/04/18 13:06:55 roberto Exp $
+> ** $Id: bugs,v 1.149 2016/07/15 17:24:09 roberto Exp roberto $
 263c263,264
 <   for (option = LUA_STRFTIMEOPTIONS; *option != '\0'; option += oplen) {
 ---
@@ -3664,6 +3664,30 @@ patch = [[
 }
 
 
+Bug{
+what = [[Lua can generate wrong code in functions with too many constants]],
+report = [[Marco Schöpl, 2016/07/17]],
+since = [[5.3.3]],
+fix = nil,
+example = [[See http://lua-users.org/lists/lua-l/2016-07/msg00303.html]],
+patch = [[
+--- 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 */
+]]
+}
+
+
 --[=[
 Bug{
 what = [[ ]],

+ 6 - 3
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 2.109 2016/05/13 19:09:21 roberto Exp roberto $
+** $Id: lcode.c,v 2.110 2016/06/20 19:12:46 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -1015,11 +1015,14 @@ static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) {
 ** (everything but logical operators 'and'/'or' and comparison
 ** operators).
 ** Expression to produce final result will be encoded in 'e1'.
+** Because 'luaK_exp2RK' can free registers, its calls must be
+** in "stack order" (that is, first on 'e2', which may have more
+** recent registers to be released).
 */
 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 */