aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-11-07 17:26:15 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-11-07 17:26:15 -0300
commit37c215b43f27a1c41e8a920987e1c3bd7b34330d (patch)
treef14f4417384cffb9d2e5ef3c09621555a5d1e9a2 /lvm.c
parent9e99f3071d07767f9e882c4abf3537f75ce2d161 (diff)
parentfa075b79530af1cbc977349f2e467d69ce01202c (diff)
downloadlua-37c215b43f27a1c41e8a920987e1c3bd7b34330d.tar.gz
lua-37c215b43f27a1c41e8a920987e1c3bd7b34330d.tar.bz2
lua-37c215b43f27a1c41e8a920987e1c3bd7b34330d.zip
Merge branch 'newarray' into nextversion
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c135
1 files changed, 59 insertions, 76 deletions
diff --git a/lvm.c b/lvm.c
index 0a6d6270..e4c026fd 100644
--- a/lvm.c
+++ b/lvm.c
@@ -286,15 +286,13 @@ static int floatforloop (StkId ra) {
286 286
287/* 287/*
288** Finish the table access 'val = t[key]'. 288** Finish the table access 'val = t[key]'.
289** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to
290** t[k] entry (which must be empty).
291*/ 289*/
292void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, 290void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
293 const TValue *slot) { 291 int hres) {
294 int loop; /* counter to avoid infinite loops */ 292 int loop; /* counter to avoid infinite loops */
295 const TValue *tm; /* metamethod */ 293 const TValue *tm; /* metamethod */
296 for (loop = 0; loop < MAXTAGLOOP; loop++) { 294 for (loop = 0; loop < MAXTAGLOOP; loop++) {
297 if (slot == NULL) { /* 't' is not a table? */ 295 if (hres == HNOTATABLE) { /* 't' is not a table? */
298 lua_assert(!ttistable(t)); 296 lua_assert(!ttistable(t));
299 tm = luaT_gettmbyobj(L, t, TM_INDEX); 297 tm = luaT_gettmbyobj(L, t, TM_INDEX);
300 if (l_unlikely(notm(tm))) 298 if (l_unlikely(notm(tm)))
@@ -302,7 +300,6 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
302 /* else will try the metamethod */ 300 /* else will try the metamethod */
303 } 301 }
304 else { /* 't' is a table */ 302 else { /* 't' is a table */
305 lua_assert(isempty(slot));
306 tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */ 303 tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */
307 if (tm == NULL) { /* no metamethod? */ 304 if (tm == NULL) { /* no metamethod? */
308 setnilvalue(s2v(val)); /* result is nil */ 305 setnilvalue(s2v(val)); /* result is nil */
@@ -315,10 +312,9 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
315 return; 312 return;
316 } 313 }
317 t = tm; /* else try to access 'tm[key]' */ 314 t = tm; /* else try to access 'tm[key]' */
318 if (luaV_fastget(L, t, key, slot, luaH_get)) { /* fast track? */ 315 luaV_fastget(t, key, s2v(val), luaH_get, hres);
319 setobj2s(L, val, slot); /* done */ 316 if (hres == HOK)
320 return; 317 return; /* done */
321 }
322 /* else repeat (tail call 'luaV_finishget') */ 318 /* else repeat (tail call 'luaV_finishget') */
323 } 319 }
324 luaG_runerror(L, "'__index' chain too long; possible loop"); 320 luaG_runerror(L, "'__index' chain too long; possible loop");
@@ -327,22 +323,17 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
327 323
328/* 324/*
329** Finish a table assignment 't[key] = val'. 325** Finish a table assignment 't[key] = val'.
330** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points
331** to the entry 't[key]', or to a value with an absent key if there
332** is no such entry. (The value at 'slot' must be empty, otherwise
333** 'luaV_fastget' would have done the job.)
334*/ 326*/
335void luaV_finishset (lua_State *L, const TValue *t, TValue *key, 327void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
336 TValue *val, const TValue *slot) { 328 TValue *val, int hres) {
337 int loop; /* counter to avoid infinite loops */ 329 int loop; /* counter to avoid infinite loops */
338 for (loop = 0; loop < MAXTAGLOOP; loop++) { 330 for (loop = 0; loop < MAXTAGLOOP; loop++) {
339 const TValue *tm; /* '__newindex' metamethod */ 331 const TValue *tm; /* '__newindex' metamethod */
340 if (slot != NULL) { /* is 't' a table? */ 332 if (hres != HNOTATABLE) { /* is 't' a table? */
341 Table *h = hvalue(t); /* save 't' table */ 333 Table *h = hvalue(t); /* save 't' table */
342 lua_assert(isempty(slot)); /* slot must be empty */
343 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ 334 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
344 if (tm == NULL) { /* no metamethod? */ 335 if (tm == NULL) { /* no metamethod? */
345 luaH_finishset(L, h, key, slot, val); /* set new value */ 336 luaH_finishset(L, h, key, val, hres); /* set new value */
346 invalidateTMcache(h); 337 invalidateTMcache(h);
347 luaC_barrierback(L, obj2gco(h), val); 338 luaC_barrierback(L, obj2gco(h), val);
348 return; 339 return;
@@ -360,10 +351,9 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
360 return; 351 return;
361 } 352 }
362 t = tm; /* else repeat assignment over 'tm' */ 353 t = tm; /* else repeat assignment over 'tm' */
363 if (luaV_fastget(L, t, key, slot, luaH_get)) { 354 luaV_fastset(t, key, val, hres, luaH_pset);
364 luaV_finishfastset(L, t, slot, val); 355 if (hres == HOK)
365 return; /* done */ 356 return; /* done */
366 }
367 /* else 'return luaV_finishset(L, t, key, val, slot)' (loop) */ 357 /* else 'return luaV_finishset(L, t, key, val, slot)' (loop) */
368 } 358 }
369 luaG_runerror(L, "'__newindex' chain too long; possible loop"); 359 luaG_runerror(L, "'__newindex' chain too long; possible loop");
@@ -1252,114 +1242,109 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1252 } 1242 }
1253 vmcase(OP_GETTABUP) { 1243 vmcase(OP_GETTABUP) {
1254 StkId ra = RA(i); 1244 StkId ra = RA(i);
1255 const TValue *slot;
1256 TValue *upval = cl->upvals[GETARG_B(i)]->v.p; 1245 TValue *upval = cl->upvals[GETARG_B(i)]->v.p;
1257 TValue *rc = KC(i); 1246 TValue *rc = KC(i);
1258 TString *key = tsvalue(rc); /* key must be a short string */ 1247 TString *key = tsvalue(rc); /* key must be a short string */
1259 if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { 1248 int hres;
1260 setobj2s(L, ra, slot); 1249 luaV_fastget(upval, key, s2v(ra), luaH_getshortstr, hres);
1261 } 1250 if (hres != HOK)
1262 else 1251 Protect(luaV_finishget(L, upval, rc, ra, hres));
1263 Protect(luaV_finishget(L, upval, rc, ra, slot));
1264 vmbreak; 1252 vmbreak;
1265 } 1253 }
1266 vmcase(OP_GETTABLE) { 1254 vmcase(OP_GETTABLE) {
1267 StkId ra = RA(i); 1255 StkId ra = RA(i);
1268 const TValue *slot;
1269 TValue *rb = vRB(i); 1256 TValue *rb = vRB(i);
1270 TValue *rc = vRC(i); 1257 TValue *rc = vRC(i);
1271 lua_Unsigned n; 1258 int hres;
1272 if (ttisinteger(rc) /* fast track for integers? */ 1259 if (ttisinteger(rc)) { /* fast track for integers? */
1273 ? (cast_void(n = ivalue(rc)), luaV_fastgeti(L, rb, n, slot)) 1260 luaV_fastgeti(rb, ivalue(rc), s2v(ra), hres);
1274 : luaV_fastget(L, rb, rc, slot, luaH_get)) {
1275 setobj2s(L, ra, slot);
1276 } 1261 }
1277 else 1262 else
1278 Protect(luaV_finishget(L, rb, rc, ra, slot)); 1263 luaV_fastget(rb, rc, s2v(ra), luaH_get, hres);
1264 if (hres != HOK) /* fast track for integers? */
1265 Protect(luaV_finishget(L, rb, rc, ra, hres));
1279 vmbreak; 1266 vmbreak;
1280 } 1267 }
1281 vmcase(OP_GETI) { 1268 vmcase(OP_GETI) {
1282 StkId ra = RA(i); 1269 StkId ra = RA(i);
1283 const TValue *slot;
1284 TValue *rb = vRB(i); 1270 TValue *rb = vRB(i);
1285 int c = GETARG_C(i); 1271 int c = GETARG_C(i);
1286 if (luaV_fastgeti(L, rb, c, slot)) { 1272 int hres;
1287 setobj2s(L, ra, slot); 1273 luaV_fastgeti(rb, c, s2v(ra), hres);
1288 } 1274 if (hres != HOK) {
1289 else {
1290 TValue key; 1275 TValue key;
1291 setivalue(&key, c); 1276 setivalue(&key, c);
1292 Protect(luaV_finishget(L, rb, &key, ra, slot)); 1277 Protect(luaV_finishget(L, rb, &key, ra, hres));
1293 } 1278 }
1294 vmbreak; 1279 vmbreak;
1295 } 1280 }
1296 vmcase(OP_GETFIELD) { 1281 vmcase(OP_GETFIELD) {
1297 StkId ra = RA(i); 1282 StkId ra = RA(i);
1298 const TValue *slot;
1299 TValue *rb = vRB(i); 1283 TValue *rb = vRB(i);
1300 TValue *rc = KC(i); 1284 TValue *rc = KC(i);
1301 TString *key = tsvalue(rc); /* key must be a short string */ 1285 TString *key = tsvalue(rc); /* key must be a short string */
1302 if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) { 1286 int hres;
1303 setobj2s(L, ra, slot); 1287 luaV_fastget(rb, key, s2v(ra), luaH_getshortstr, hres);
1304 } 1288 if (hres != HOK)
1305 else 1289 Protect(luaV_finishget(L, rb, rc, ra, hres));
1306 Protect(luaV_finishget(L, rb, rc, ra, slot));
1307 vmbreak; 1290 vmbreak;
1308 } 1291 }
1309 vmcase(OP_SETTABUP) { 1292 vmcase(OP_SETTABUP) {
1310 const TValue *slot; 1293 int hres;
1311 TValue *upval = cl->upvals[GETARG_A(i)]->v.p; 1294 TValue *upval = cl->upvals[GETARG_A(i)]->v.p;
1312 TValue *rb = KB(i); 1295 TValue *rb = KB(i);
1313 TValue *rc = RKC(i); 1296 TValue *rc = RKC(i);
1314 TString *key = tsvalue(rb); /* key must be a short string */ 1297 TString *key = tsvalue(rb); /* key must be a short string */
1315 if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { 1298 luaV_fastset(upval, key, rc, hres, luaH_psetshortstr);
1316 luaV_finishfastset(L, upval, slot, rc); 1299 if (hres == HOK)
1317 } 1300 luaV_finishfastset(L, upval, rc);
1318 else 1301 else
1319 Protect(luaV_finishset(L, upval, rb, rc, slot)); 1302 Protect(luaV_finishset(L, upval, rb, rc, hres));
1320 vmbreak; 1303 vmbreak;
1321 } 1304 }
1322 vmcase(OP_SETTABLE) { 1305 vmcase(OP_SETTABLE) {
1323 StkId ra = RA(i); 1306 StkId ra = RA(i);
1324 const TValue *slot; 1307 int hres;
1325 TValue *rb = vRB(i); /* key (table is in 'ra') */ 1308 TValue *rb = vRB(i); /* key (table is in 'ra') */
1326 TValue *rc = RKC(i); /* value */ 1309 TValue *rc = RKC(i); /* value */
1327 lua_Unsigned n; 1310 if (ttisinteger(rb)) { /* fast track for integers? */
1328 if (ttisinteger(rb) /* fast track for integers? */ 1311 luaV_fastseti(s2v(ra), ivalue(rb), rc, hres);
1329 ? (cast_void(n = ivalue(rb)), luaV_fastgeti(L, s2v(ra), n, slot)) 1312 }
1330 : luaV_fastget(L, s2v(ra), rb, slot, luaH_get)) { 1313 else {
1331 luaV_finishfastset(L, s2v(ra), slot, rc); 1314 luaV_fastset(s2v(ra), rb, rc, hres, luaH_pset);
1332 } 1315 }
1316 if (hres == HOK)
1317 luaV_finishfastset(L, s2v(ra), rc);
1333 else 1318 else
1334 Protect(luaV_finishset(L, s2v(ra), rb, rc, slot)); 1319 Protect(luaV_finishset(L, s2v(ra), rb, rc, hres));
1335 vmbreak; 1320 vmbreak;
1336 } 1321 }
1337 vmcase(OP_SETI) { 1322 vmcase(OP_SETI) {
1338 StkId ra = RA(i); 1323 StkId ra = RA(i);
1339 const TValue *slot; 1324 int hres;
1340 int c = GETARG_B(i); 1325 int b = GETARG_B(i);
1341 TValue *rc = RKC(i); 1326 TValue *rc = RKC(i);
1342 if (luaV_fastgeti(L, s2v(ra), c, slot)) { 1327 luaV_fastseti(s2v(ra), b, rc, hres);
1343 luaV_finishfastset(L, s2v(ra), slot, rc); 1328 if (hres == HOK)
1344 } 1329 luaV_finishfastset(L, s2v(ra), rc);
1345 else { 1330 else {
1346 TValue key; 1331 TValue key;
1347 setivalue(&key, c); 1332 setivalue(&key, b);
1348 Protect(luaV_finishset(L, s2v(ra), &key, rc, slot)); 1333 Protect(luaV_finishset(L, s2v(ra), &key, rc, hres));
1349 } 1334 }
1350 vmbreak; 1335 vmbreak;
1351 } 1336 }
1352 vmcase(OP_SETFIELD) { 1337 vmcase(OP_SETFIELD) {
1353 StkId ra = RA(i); 1338 StkId ra = RA(i);
1354 const TValue *slot; 1339 int hres;
1355 TValue *rb = KB(i); 1340 TValue *rb = KB(i);
1356 TValue *rc = RKC(i); 1341 TValue *rc = RKC(i);
1357 TString *key = tsvalue(rb); /* key must be a short string */ 1342 TString *key = tsvalue(rb); /* key must be a short string */
1358 if (luaV_fastget(L, s2v(ra), key, slot, luaH_getshortstr)) { 1343 luaV_fastset(s2v(ra), key, rc, hres, luaH_psetshortstr);
1359 luaV_finishfastset(L, s2v(ra), slot, rc); 1344 if (hres == HOK)
1360 } 1345 luaV_finishfastset(L, s2v(ra), rc);
1361 else 1346 else
1362 Protect(luaV_finishset(L, s2v(ra), rb, rc, slot)); 1347 Protect(luaV_finishset(L, s2v(ra), rb, rc, hres));
1363 vmbreak; 1348 vmbreak;
1364 } 1349 }
1365 vmcase(OP_NEWTABLE) { 1350 vmcase(OP_NEWTABLE) {
@@ -1383,16 +1368,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1383 } 1368 }
1384 vmcase(OP_SELF) { 1369 vmcase(OP_SELF) {
1385 StkId ra = RA(i); 1370 StkId ra = RA(i);
1386 const TValue *slot; 1371 int hres;
1387 TValue *rb = vRB(i); 1372 TValue *rb = vRB(i);
1388 TValue *rc = RKC(i); 1373 TValue *rc = RKC(i);
1389 TString *key = tsvalue(rc); /* key must be a string */ 1374 TString *key = tsvalue(rc); /* key must be a string */
1390 setobj2s(L, ra + 1, rb); 1375 setobj2s(L, ra + 1, rb);
1391 if (luaV_fastget(L, rb, key, slot, luaH_getstr)) { 1376 luaV_fastget(rb, key, s2v(ra), luaH_getstr, hres);
1392 setobj2s(L, ra, slot); 1377 if (hres != HOK)
1393 } 1378 Protect(luaV_finishget(L, rb, rc, ra, hres));
1394 else
1395 Protect(luaV_finishget(L, rb, rc, ra, slot));
1396 vmbreak; 1379 vmbreak;
1397 } 1380 }
1398 vmcase(OP_ADDI) { 1381 vmcase(OP_ADDI) {
@@ -1873,7 +1856,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1873 luaH_resizearray(L, h, last); /* preallocate it at once */ 1856 luaH_resizearray(L, h, last); /* preallocate it at once */
1874 for (; n > 0; n--) { 1857 for (; n > 0; n--) {
1875 TValue *val = s2v(ra + n); 1858 TValue *val = s2v(ra + n);
1876 setobj2t(L, &h->array[last - 1], val); 1859 obj2arr(h, last, val);
1877 last--; 1860 last--;
1878 luaC_barrierback(L, obj2gco(h), val); 1861 luaC_barrierback(L, obj2gco(h), val);
1879 } 1862 }