From 758c1ef445ab27d89bace746111add04083a8e20 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 15 Jul 2019 14:59:35 -0300 Subject: Unification of size representation in OP_NEWTABLE and OP_SETLIST Opcodes OP_NEWTABLE and OP_SETLIST use the same representation to store the size of the array part of a table. This new representation can go up to 2^33 (8 + 25 bits). --- lcode.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'lcode.c') diff --git a/lcode.c b/lcode.c index 1ff32ed7..a0d7757a 100644 --- a/lcode.c +++ b/lcode.c @@ -372,7 +372,7 @@ static void removelastinstruction (FuncState *fs) { ** Emit instruction 'i', checking for array sizes and saving also its ** line information. Return 'i' position. */ -static int luaK_code (FuncState *fs, Instruction i) { +int luaK_code (FuncState *fs, Instruction i) { Proto *f = fs->f; /* put new instruction in code array */ luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, @@ -430,7 +430,7 @@ static int codesJ (FuncState *fs, OpCode o, int sj, int k) { /* ** Emit an "extra argument" instruction (format 'iAx') */ -int luaK_codeextraarg (FuncState *fs, int a) { +static int codeextraarg (FuncState *fs, int a) { lua_assert(a <= MAXARG_Ax); return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); } @@ -446,7 +446,7 @@ static int luaK_codek (FuncState *fs, int reg, int k) { return luaK_codeABx(fs, OP_LOADK, reg, k); else { int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); - luaK_codeextraarg(fs, k); + codeextraarg(fs, k); return p; } } @@ -1672,6 +1672,22 @@ void luaK_fixline (FuncState *fs, int line) { } +void luaK_settablesize (FuncState *fs, int pc, int ra, int rc, int rb) { + Instruction *inst = &fs->f->code[pc]; + int extra = 0; + int k = 0; + if (rb != 0) + rb = luaO_ceillog2(rb) + 1; /* hash size */ + if (rc > MAXARG_C) { /* does it need the extra argument? */ + extra = rc / (MAXARG_C + 1); + rc %= (MAXARG_C + 1); + k = 1; + } + *inst = CREATE_ABCk(OP_NEWTABLE, ra, rb, rc, k); + *(inst + 1) = CREATE_Ax(OP_EXTRAARG, extra); +} + + /* ** Emit a SETLIST instruction. ** 'base' is register that keeps table; @@ -1680,17 +1696,17 @@ void luaK_fixline (FuncState *fs, int line) { ** table (or LUA_MULTRET to add up to stack top). */ void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { - int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; - int b = (tostore == LUA_MULTRET) ? 0 : tostore; lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH); - if (c <= MAXARG_C) - luaK_codeABC(fs, OP_SETLIST, base, b, c); - else if (c <= MAXARG_Ax) { - luaK_codeABC(fs, OP_SETLIST, base, b, 0); - luaK_codeextraarg(fs, c); + if (tostore == LUA_MULTRET) + tostore = 0; + if (nelems <= MAXARG_C) + luaK_codeABC(fs, OP_SETLIST, base, tostore, nelems); + else { + int extra = nelems / (MAXARG_C + 1); + nelems %= (MAXARG_C + 1); + luaK_codeABCk(fs, OP_SETLIST, base, tostore, nelems, 1); + codeextraarg(fs, extra); } - else - luaX_syntaxerror(fs->ls, "constructor too long"); fs->freereg = base + 1; /* free registers with list values */ } -- cgit v1.2.3-55-g6feb