Pārlūkot izejas kodu

Add NEWTABLE .. SELF

Hugo Musso Gualandi 3 gadi atpakaļ
vecāks
revīzija
49022759e4
2 mainītis faili ar 63 papildinājumiem un 21 dzēšanām
  1. 54 0
      src/functions_header.c
  2. 9 21
      src/luaot_functions.c

+ 54 - 0
src/functions_header.c

@@ -151,6 +151,12 @@ typedef struct {
 #undef  halfProtect
 #define halfProtect(exp)  (savestate(L,ctx->ci), (exp))
 
+#undef checkGC
+#define checkGC(L,c)  \
+	{ luaC_condGC(L, (savepc(L), L->top = (c)), \
+                         updatetrap(ctx->ci)); \
+           luai_threadyield(L); }
+
 //
 // Our modified version of vmfetch(). Since instr and index are compile time
 // constants, the C compiler should be able to optimize the code in many cases.
@@ -366,3 +372,51 @@ void luaot_SETFIELD(lua_State *L, LuaotExecuteState *ctx, const Instruction *pc,
     else
       Protect(luaV_finishset(L, s2v(ra), rb, rc, slot));
 }
+
+static
+void luaot_NEWTABLE_0(lua_State *L, LuaotExecuteState *ctx, const Instruction *pc,
+                      StkId ra, int b, int c)
+{
+    Table *t;
+    if (b > 0)
+      b = 1 << (b - 1);  /* size is 2^(b - 1) */
+    lua_assert((!TESTARG_k(i)) == (GETARG_Ax(0x%08x) == 0));
+    /* skip extra argument */
+    L->top = ra + 1;  /* correct top in case of emergency GC */
+    t = luaH_new(L);  /* memory allocation */
+    sethvalue2s(L, ra, t);
+    if (b != 0 || c != 0)
+      luaH_resize(L, t, c, b);  /* idem */
+    checkGC(L, ra + 1);
+}
+
+static
+void luaot_NEWTABLE_1(lua_State *L, LuaotExecuteState *ctx, const Instruction *pc,
+                      StkId ra, int b, int c)
+{
+    Table *t;
+    if (b > 0)
+      b = 1 << (b - 1);  /* size is 2^(b - 1) */
+    lua_assert((!TESTARG_k(i)) == (GETARG_Ax(0x%08x) == 0));
+    /* skip extra argument */
+    L->top = ra + 1;  /* correct top in case of emergency GC */
+    t = luaH_new(L);  /* memory allocation */
+    sethvalue2s(L, ra, t);
+    if (b != 0 || c != 0)
+      luaH_resize(L, t, c, b);  /* idem */
+    checkGC(L, ra + 1);
+}
+
+static
+void luaot_SELF(lua_State *L, LuaotExecuteState *ctx, const Instruction *pc,
+                StkId ra, TValue *rb, TValue *rc)
+{
+    const TValue *slot;
+    TString *key = tsvalue(rc);  /* key must be a string */
+    setobj2s(L, ra + 1, rb);
+    if (luaV_fastget(L, rb, key, slot, luaH_getstr)) {
+      setobj2s(L, ra, slot);
+    }
+    else
+      Protect(luaV_finishget(L, rb, rc, ra, slot));
+}

+ 9 - 21
src/luaot_functions.c

@@ -209,33 +209,21 @@ void create_function(Proto *f)
             case OP_NEWTABLE: {
                 println("    int b = GETARG_B(i);  /* log2(hash size) + 1 */");
                 println("    int c = GETARG_C(i);  /* array size */");
-                println("    Table *t;");
-                println("    if (b > 0)");
-                println("      b = 1 << (b - 1);  /* size is 2^(b - 1) */");
-                println("    lua_assert((!TESTARG_k(i)) == (GETARG_Ax(0x%08x) == 0));", f->code[pc+1]);
-                println("    if (TESTARG_k(i))");
-                println("      c += GETARG_Ax(0x%08x) * (MAXARG_C + 1);", f->code[pc+1]);
-                println("    /* skip extra argument */"); // (!)
-                println("    L->top = ra + 1;  /* correct top in case of emergency GC */");
-                println("    t = luaH_new(L);  /* memory allocation */");
-                println("    sethvalue2s(L, ra, t);");
-                println("    if (b != 0 || c != 0)");
-                println("      luaH_resize(L, t, c, b);  /* idem */");
-                println("    checkGC(L, ra + 1);");
+                println("    int k = TESTARK_k(i);");
+                println("    lua_assert((!k) == (GETARG_Ax(0x%08x) == 0));", f->code[pc+1]);
+                println("    if (k) {");
+                println("        luaot_NEWTABLE_1(L, ctx, pc, ra, b, c);");
+                println("    } else {");
+                println("        c += GETARG_Ax(0x%08x) * (MAXARG_C + 1);", f->code[pc+1]);
+                println("        luaot_NEWTABLE_1(L, ctx, pc, ra, b, c);");
+                println("    }");
                 println("    goto LUAOT_SKIP1;"); // (!)
                 break;
             }
             case OP_SELF: {
-                println("    const TValue *slot;");
                 println("    TValue *rb = vRB(i);");
                 println("    TValue *rc = RKC(i);");
-                println("    TString *key = tsvalue(rc);  /* key must be a string */");
-                println("    setobj2s(L, ra + 1, rb);");
-                println("    if (luaV_fastget(L, rb, key, slot, luaH_getstr)) {");
-                println("      setobj2s(L, ra, slot);");
-                println("    }");
-                println("    else");
-                println("      Protect(luaV_finishget(L, rb, rc, ra, slot));");
+                println("    luaot_SELF(L, ctx, pc, ra, rb, rc);");
                 break;
             }
             case OP_ADDI: {