소스 검색

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: {