diff options
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 135 |
1 files changed, 59 insertions, 76 deletions
@@ -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 | */ |
292 | void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, | 290 | void 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 | */ |
335 | void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | 327 | void 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 | } |