diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-05-15 17:56:25 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-05-15 17:56:25 -0300 |
commit | 351ccd733298e08c41937c1baf22a68e62bfeca9 (patch) | |
tree | be290db6b41e949c74d6699c7a01963c7cec9b21 /lvm.c | |
parent | 6443185167c77adcc8552a3fee7edab7895db1a9 (diff) | |
download | lua-351ccd733298e08c41937c1baf22a68e62bfeca9.tar.gz lua-351ccd733298e08c41937c1baf22a68e62bfeca9.tar.bz2 lua-351ccd733298e08c41937c1baf22a68e62bfeca9.zip |
Towards a new implementation of arrays
The array part of a table wastes too much space, due to padding.
To avoid that, we need to store values in the array as something
different from a TValue. Therefore, the API for table access
should not assume that any value in a table lives in a *TValue.
This commit is the first step to remove that assumption: functions
luaH_get*, instead of returning a *TValue where the value lives,
receive a *TValue where to put the value being accessed.
(We still have to change the luaH_set* functions.)
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 67 |
1 files changed, 28 insertions, 39 deletions
@@ -284,12 +284,12 @@ static int floatforloop (StkId ra) { | |||
284 | ** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to | 284 | ** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to |
285 | ** t[k] entry (which must be empty). | 285 | ** t[k] entry (which must be empty). |
286 | */ | 286 | */ |
287 | void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, | 287 | void luaV_finishget1 (lua_State *L, const TValue *t, TValue *key, StkId val, |
288 | const TValue *slot) { | 288 | int aux) { |
289 | int loop; /* counter to avoid infinite loops */ | 289 | int loop; /* counter to avoid infinite loops */ |
290 | const TValue *tm; /* metamethod */ | 290 | const TValue *tm; /* metamethod */ |
291 | for (loop = 0; loop < MAXTAGLOOP; loop++) { | 291 | for (loop = 0; loop < MAXTAGLOOP; loop++) { |
292 | if (slot == NULL) { /* 't' is not a table? */ | 292 | if (aux == HNOTATABLE) { /* 't' is not a table? */ |
293 | lua_assert(!ttistable(t)); | 293 | lua_assert(!ttistable(t)); |
294 | tm = luaT_gettmbyobj(L, t, TM_INDEX); | 294 | tm = luaT_gettmbyobj(L, t, TM_INDEX); |
295 | if (l_unlikely(notm(tm))) | 295 | if (l_unlikely(notm(tm))) |
@@ -297,7 +297,6 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, | |||
297 | /* else will try the metamethod */ | 297 | /* else will try the metamethod */ |
298 | } | 298 | } |
299 | else { /* 't' is a table */ | 299 | else { /* 't' is a table */ |
300 | lua_assert(isempty(slot)); | ||
301 | tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */ | 300 | tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */ |
302 | if (tm == NULL) { /* no metamethod? */ | 301 | if (tm == NULL) { /* no metamethod? */ |
303 | setnilvalue(s2v(val)); /* result is nil */ | 302 | setnilvalue(s2v(val)); /* result is nil */ |
@@ -310,10 +309,9 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, | |||
310 | return; | 309 | return; |
311 | } | 310 | } |
312 | t = tm; /* else try to access 'tm[key]' */ | 311 | t = tm; /* else try to access 'tm[key]' */ |
313 | if (luaV_fastget(L, t, key, slot, luaH_get)) { /* fast track? */ | 312 | luaV_fastget1(t, key, s2v(val), luaH_get1, aux); |
314 | setobj2s(L, val, slot); /* done */ | 313 | if (aux == HOK) |
315 | return; | 314 | return; /* done */ |
316 | } | ||
317 | /* else repeat (tail call 'luaV_finishget') */ | 315 | /* else repeat (tail call 'luaV_finishget') */ |
318 | } | 316 | } |
319 | luaG_runerror(L, "'__index' chain too long; possible loop"); | 317 | luaG_runerror(L, "'__index' chain too long; possible loop"); |
@@ -1250,58 +1248,51 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1250 | } | 1248 | } |
1251 | vmcase(OP_GETTABUP) { | 1249 | vmcase(OP_GETTABUP) { |
1252 | StkId ra = RA(i); | 1250 | StkId ra = RA(i); |
1253 | const TValue *slot; | ||
1254 | TValue *upval = cl->upvals[GETARG_B(i)]->v.p; | 1251 | TValue *upval = cl->upvals[GETARG_B(i)]->v.p; |
1255 | TValue *rc = KC(i); | 1252 | TValue *rc = KC(i); |
1256 | TString *key = tsvalue(rc); /* key must be a string */ | 1253 | TString *key = tsvalue(rc); /* key must be a string */ |
1257 | if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { | 1254 | int aux; |
1258 | setobj2s(L, ra, slot); | 1255 | luaV_fastget1(upval, key, s2v(ra), luaH_getshortstr1, aux); |
1259 | } | 1256 | if (aux != HOK) |
1260 | else | 1257 | Protect(luaV_finishget1(L, upval, rc, ra, aux)); |
1261 | Protect(luaV_finishget(L, upval, rc, ra, slot)); | ||
1262 | vmbreak; | 1258 | vmbreak; |
1263 | } | 1259 | } |
1264 | vmcase(OP_GETTABLE) { | 1260 | vmcase(OP_GETTABLE) { |
1265 | StkId ra = RA(i); | 1261 | StkId ra = RA(i); |
1266 | const TValue *slot; | ||
1267 | TValue *rb = vRB(i); | 1262 | TValue *rb = vRB(i); |
1268 | TValue *rc = vRC(i); | 1263 | TValue *rc = vRC(i); |
1269 | lua_Unsigned n; | 1264 | int aux; |
1270 | if (ttisinteger(rc) /* fast track for integers? */ | 1265 | if (ttisinteger(rc)) { /* fast track for integers? */ |
1271 | ? (cast_void(n = ivalue(rc)), luaV_fastgeti(L, rb, n, slot)) | 1266 | luaV_fastgeti1(rb, ivalue(rc), s2v(ra), aux); |
1272 | : luaV_fastget(L, rb, rc, slot, luaH_get)) { | ||
1273 | setobj2s(L, ra, slot); | ||
1274 | } | 1267 | } |
1275 | else | 1268 | else |
1276 | Protect(luaV_finishget(L, rb, rc, ra, slot)); | 1269 | luaV_fastget1(rb, rc, s2v(ra), luaH_get1, aux); |
1270 | if (aux != HOK) /* fast track for integers? */ | ||
1271 | Protect(luaV_finishget1(L, rb, rc, ra, aux)); | ||
1277 | vmbreak; | 1272 | vmbreak; |
1278 | } | 1273 | } |
1279 | vmcase(OP_GETI) { | 1274 | vmcase(OP_GETI) { |
1280 | StkId ra = RA(i); | 1275 | StkId ra = RA(i); |
1281 | const TValue *slot; | ||
1282 | TValue *rb = vRB(i); | 1276 | TValue *rb = vRB(i); |
1283 | int c = GETARG_C(i); | 1277 | int c = GETARG_C(i); |
1284 | if (luaV_fastgeti(L, rb, c, slot)) { | 1278 | int aux; |
1285 | setobj2s(L, ra, slot); | 1279 | luaV_fastgeti1(rb, c, s2v(ra), aux); |
1286 | } | 1280 | if (aux != HOK) { |
1287 | else { | ||
1288 | TValue key; | 1281 | TValue key; |
1289 | setivalue(&key, c); | 1282 | setivalue(&key, c); |
1290 | Protect(luaV_finishget(L, rb, &key, ra, slot)); | 1283 | Protect(luaV_finishget1(L, rb, &key, ra, aux)); |
1291 | } | 1284 | } |
1292 | vmbreak; | 1285 | vmbreak; |
1293 | } | 1286 | } |
1294 | vmcase(OP_GETFIELD) { | 1287 | vmcase(OP_GETFIELD) { |
1295 | StkId ra = RA(i); | 1288 | StkId ra = RA(i); |
1296 | const TValue *slot; | ||
1297 | TValue *rb = vRB(i); | 1289 | TValue *rb = vRB(i); |
1298 | TValue *rc = KC(i); | 1290 | TValue *rc = KC(i); |
1299 | TString *key = tsvalue(rc); /* key must be a string */ | 1291 | TString *key = tsvalue(rc); /* key must be a string */ |
1300 | if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) { | 1292 | int aux; |
1301 | setobj2s(L, ra, slot); | 1293 | luaV_fastget1(rb, key, s2v(ra), luaH_getshortstr1, aux); |
1302 | } | 1294 | if (aux != HOK) |
1303 | else | 1295 | Protect(luaV_finishget1(L, rb, rc, ra, aux)); |
1304 | Protect(luaV_finishget(L, rb, rc, ra, slot)); | ||
1305 | vmbreak; | 1296 | vmbreak; |
1306 | } | 1297 | } |
1307 | vmcase(OP_SETTABUP) { | 1298 | vmcase(OP_SETTABUP) { |
@@ -1381,16 +1372,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1381 | } | 1372 | } |
1382 | vmcase(OP_SELF) { | 1373 | vmcase(OP_SELF) { |
1383 | StkId ra = RA(i); | 1374 | StkId ra = RA(i); |
1384 | const TValue *slot; | 1375 | int aux; |
1385 | TValue *rb = vRB(i); | 1376 | TValue *rb = vRB(i); |
1386 | TValue *rc = RKC(i); | 1377 | TValue *rc = RKC(i); |
1387 | TString *key = tsvalue(rc); /* key must be a string */ | 1378 | TString *key = tsvalue(rc); /* key must be a string */ |
1388 | setobj2s(L, ra + 1, rb); | 1379 | setobj2s(L, ra + 1, rb); |
1389 | if (luaV_fastget(L, rb, key, slot, luaH_getstr)) { | 1380 | luaV_fastget1(rb, key, s2v(ra), luaH_getstr1, aux); |
1390 | setobj2s(L, ra, slot); | 1381 | if (aux != HOK) |
1391 | } | 1382 | Protect(luaV_finishget1(L, rb, rc, ra, aux)); |
1392 | else | ||
1393 | Protect(luaV_finishget(L, rb, rc, ra, slot)); | ||
1394 | vmbreak; | 1383 | vmbreak; |
1395 | } | 1384 | } |
1396 | vmcase(OP_ADDI) { | 1385 | vmcase(OP_ADDI) { |