浏览代码

Be careful with SETLIST extra argument

SETLIST only has an extra argument if `k==1`. We weren't aware of this
and ended up would sometimes reference an extra argument that did not
exist. GCC would sometimes complain that the invalid argument was
causing an integer overflow.

    if (0) {
        last += GETARG_Ax(INVALID)
    }

The fix is to turn this if-statement into a compile-time test.
Hugo Musso Gualandi 4 年之前
父节点
当前提交
1308b446e1
共有 1 个文件被更改,包括 7 次插入7 次删除
  1. 7 7
      src/luaot.c

+ 7 - 7
src/luaot.c

@@ -1388,6 +1388,7 @@ void create_function(Proto *f)
                 break;
             }
             case OP_SETLIST: {
+                int has_extra_arg = TESTARG_k(instr);
                 println("        int n = GETARG_B(i);");
                 println("        unsigned int last = GETARG_C(i);");
                 println("        Table *h = hvalue(s2v(ra));");
@@ -1396,10 +1397,9 @@ void create_function(Proto *f)
                 println("        else");
                 println("          L->top = ci->top;  /* correct top in case of emergency GC */");
                 println("        last += n;");
-                println("        int has_extra_arg = TESTARG_k(i);"); // (!)
-                println("        if (has_extra_arg) {");
-                println("          last += GETARG_Ax(0x%08x) * (MAXARG_C + 1);", f->code[pc+1]); // (!)
-                println("        }");
+                if (has_extra_arg) {
+                 println("        last += GETARG_Ax(0x%08x) * (MAXARG_C + 1);", f->code[pc+1]); // (!)
+                }
                 println("        if (last > luaH_realasize(h))  /* needs more space? */");
                 println("          luaH_resizearray(L, h, last);  /* preallocate it at once */");
                 println("        for (; n > 0; n--) {");
@@ -1408,9 +1408,9 @@ void create_function(Proto *f)
                 println("          last--;");
                 println("          luaC_barrierback(L, obj2gco(h), val);");
                 println("        }");
-                println("        if (has_extra_arg) {");  // (!)
-                println("          goto LUAOT_SKIP1;"); // (!)
-                println("        }");                     // (!)
+                if (has_extra_arg) {
+                 println("        goto LUAOT_SKIP1;"); // (!)
+                }
                 break;
             }
             case OP_CLOSURE: {