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