diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-06-28 11:18:14 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-06-28 11:18:14 -0300 |
commit | c403e456b66ddacf7f8f974323e9cffdfe6365d4 (patch) | |
tree | 2e25027eface85c3156359e4ec182b4a9215903b /lvm.c | |
parent | 6ac7219da31df0238dc33c2d4457f69bfe0c1e79 (diff) | |
download | lua-c403e456b66ddacf7f8f974323e9cffdfe6365d4.tar.gz lua-c403e456b66ddacf7f8f974323e9cffdfe6365d4.tar.bz2 lua-c403e456b66ddacf7f8f974323e9cffdfe6365d4.zip |
New instruction format for SETLIST/NEWTABLE
New instruction format 'ivABC' (a variant of iABC where parameter vC has
10 bits) allows constructors of up to 1024 elements to be coded without
EXTRAARG.
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 25 |
1 files changed, 15 insertions, 10 deletions
@@ -1359,14 +1359,15 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1359 | } | 1359 | } |
1360 | vmcase(OP_NEWTABLE) { | 1360 | vmcase(OP_NEWTABLE) { |
1361 | StkId ra = RA(i); | 1361 | StkId ra = RA(i); |
1362 | int b = GETARG_B(i); /* log2(hash size) + 1 */ | 1362 | int b = GETARG_vB(i); /* log2(hash size) + 1 */ |
1363 | int c = GETARG_C(i); /* array size */ | 1363 | int c = GETARG_vC(i); /* array size */ |
1364 | Table *t; | 1364 | Table *t; |
1365 | if (b > 0) | 1365 | if (b > 0) |
1366 | b = 1 << (b - 1); /* size is 2^(b - 1) */ | 1366 | b = 1 << (b - 1); /* hash size is 2^(b - 1) */ |
1367 | lua_assert((!TESTARG_k(i)) == (GETARG_Ax(*pc) == 0)); | 1367 | if (TESTARG_k(i)) { /* non-zero extra argument? */ |
1368 | if (TESTARG_k(i)) /* non-zero extra argument? */ | 1368 | lua_assert(GETARG_Ax(*pc) != 0); |
1369 | c += GETARG_Ax(*pc) * (MAXARG_C + 1); /* add it to size */ | 1369 | c += GETARG_Ax(*pc) * (MAXARG_vC + 1); /* add it to array size */ |
1370 | } | ||
1370 | pc++; /* skip extra argument */ | 1371 | pc++; /* skip extra argument */ |
1371 | L->top.p = ra + 1; /* correct top in case of emergency GC */ | 1372 | L->top.p = ra + 1; /* correct top in case of emergency GC */ |
1372 | t = luaH_new(L); /* memory allocation */ | 1373 | t = luaH_new(L); /* memory allocation */ |
@@ -1850,8 +1851,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1850 | }} | 1851 | }} |
1851 | vmcase(OP_SETLIST) { | 1852 | vmcase(OP_SETLIST) { |
1852 | StkId ra = RA(i); | 1853 | StkId ra = RA(i); |
1853 | int n = GETARG_B(i); | 1854 | int n = GETARG_vB(i); |
1854 | unsigned int last = GETARG_C(i); | 1855 | unsigned int last = GETARG_vC(i); |
1855 | Table *h = hvalue(s2v(ra)); | 1856 | Table *h = hvalue(s2v(ra)); |
1856 | if (n == 0) | 1857 | if (n == 0) |
1857 | n = cast_int(L->top.p - ra) - 1; /* get up to the top */ | 1858 | n = cast_int(L->top.p - ra) - 1; /* get up to the top */ |
@@ -1859,11 +1860,15 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1859 | L->top.p = ci->top.p; /* correct top in case of emergency GC */ | 1860 | L->top.p = ci->top.p; /* correct top in case of emergency GC */ |
1860 | last += n; | 1861 | last += n; |
1861 | if (TESTARG_k(i)) { | 1862 | if (TESTARG_k(i)) { |
1862 | last += GETARG_Ax(*pc) * (MAXARG_C + 1); | 1863 | last += GETARG_Ax(*pc) * (MAXARG_vC + 1); |
1863 | pc++; | 1864 | pc++; |
1864 | } | 1865 | } |
1865 | if (last > luaH_realasize(h)) /* needs more space? */ | 1866 | /* when 'n' is known, table should have proper size */ |
1867 | if (last > luaH_realasize(h)) { /* needs more space? */ | ||
1868 | /* fixed-size sets should have space preallocated */ | ||
1869 | lua_assert(GETARG_vB(i) == 0); | ||
1866 | luaH_resizearray(L, h, last); /* preallocate it at once */ | 1870 | luaH_resizearray(L, h, last); /* preallocate it at once */ |
1871 | } | ||
1867 | for (; n > 0; n--) { | 1872 | for (; n > 0; n--) { |
1868 | TValue *val = s2v(ra + n); | 1873 | TValue *val = s2v(ra + n); |
1869 | obj2arr(h, last - 1, val); | 1874 | obj2arr(h, last - 1, val); |