aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-06-22 11:41:48 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-06-22 11:41:48 -0300
commitab6a94952215b1f66436d8eeebded1dad9fa5409 (patch)
treeba66254537defc76602ce351d962b899ddfe1b29 /lvm.c
parent86e8039a72646cd9192fd08a6f1771c90b872ff6 (diff)
parentea39042e13645f63713425c05cc9ee4cfdcf0a40 (diff)
downloadlua-ab6a94952215b1f66436d8eeebded1dad9fa5409.tar.gz
lua-ab6a94952215b1f66436d8eeebded1dad9fa5409.tar.bz2
lua-ab6a94952215b1f66436d8eeebded1dad9fa5409.zip
Merge branch 'master' into nextversion
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/lvm.c b/lvm.c
index 8ab8753d..a3128c3d 100644
--- a/lvm.c
+++ b/lvm.c
@@ -367,30 +367,32 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
367 367
368 368
369/* 369/*
370** Compare two strings 'ls' x 'rs', returning an integer less-equal- 370** Compare two strings 'ts1' x 'ts2', returning an integer less-equal-
371** -greater than zero if 'ls' is less-equal-greater than 'rs'. 371** -greater than zero if 'ts1' is less-equal-greater than 'ts2'.
372** The code is a little tricky because it allows '\0' in the strings 372** The code is a little tricky because it allows '\0' in the strings
373** and it uses 'strcoll' (to respect locales) for each segments 373** and it uses 'strcoll' (to respect locales) for each segment
374** of the strings. 374** of the strings. Note that segments can compare equal but still
375** have different lengths.
375*/ 376*/
376static int l_strcmp (const TString *ls, const TString *rs) { 377static int l_strcmp (const TString *ts1, const TString *ts2) {
377 const char *l = getstr(ls); 378 const char *s1 = getstr(ts1);
378 size_t ll = tsslen(ls); 379 size_t rl1 = tsslen(ts1); /* real length */
379 const char *r = getstr(rs); 380 const char *s2 = getstr(ts2);
380 size_t lr = tsslen(rs); 381 size_t rl2 = tsslen(ts2);
381 for (;;) { /* for each segment */ 382 for (;;) { /* for each segment */
382 int temp = strcoll(l, r); 383 int temp = strcoll(s1, s2);
383 if (temp != 0) /* not equal? */ 384 if (temp != 0) /* not equal? */
384 return temp; /* done */ 385 return temp; /* done */
385 else { /* strings are equal up to a '\0' */ 386 else { /* strings are equal up to a '\0' */
386 size_t len = strlen(l); /* index of first '\0' in both strings */ 387 size_t zl1 = strlen(s1); /* index of first '\0' in 's1' */
387 if (len == lr) /* 'rs' is finished? */ 388 size_t zl2 = strlen(s2); /* index of first '\0' in 's2' */
388 return (len == ll) ? 0 : 1; /* check 'ls' */ 389 if (zl2 == rl2) /* 's2' is finished? */
389 else if (len == ll) /* 'ls' is finished? */ 390 return (zl1 == rl1) ? 0 : 1; /* check 's1' */
390 return -1; /* 'ls' is less than 'rs' ('rs' is not finished) */ 391 else if (zl1 == rl1) /* 's1' is finished? */
391 /* both strings longer than 'len'; go on comparing after the '\0' */ 392 return -1; /* 's1' is less than 's2' ('s2' is not finished) */
392 len++; 393 /* both strings longer than 'zl'; go on comparing after the '\0' */
393 l += len; ll -= len; r += len; lr -= len; 394 zl1++; zl2++;
395 s1 += zl1; rl1 -= zl1; s2 += zl2; rl2 -= zl2;
394 } 396 }
395 } 397 }
396} 398}
@@ -1254,7 +1256,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1254 const TValue *slot; 1256 const TValue *slot;
1255 TValue *upval = cl->upvals[GETARG_B(i)]->v.p; 1257 TValue *upval = cl->upvals[GETARG_B(i)]->v.p;
1256 TValue *rc = KC(i); 1258 TValue *rc = KC(i);
1257 TString *key = tsvalue(rc); /* key must be a string */ 1259 TString *key = tsvalue(rc); /* key must be a short string */
1258 if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { 1260 if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) {
1259 setobj2s(L, ra, slot); 1261 setobj2s(L, ra, slot);
1260 } 1262 }
@@ -1297,7 +1299,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1297 const TValue *slot; 1299 const TValue *slot;
1298 TValue *rb = vRB(i); 1300 TValue *rb = vRB(i);
1299 TValue *rc = KC(i); 1301 TValue *rc = KC(i);
1300 TString *key = tsvalue(rc); /* key must be a string */ 1302 TString *key = tsvalue(rc); /* key must be a short string */
1301 if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) { 1303 if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) {
1302 setobj2s(L, ra, slot); 1304 setobj2s(L, ra, slot);
1303 } 1305 }
@@ -1310,7 +1312,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1310 TValue *upval = cl->upvals[GETARG_A(i)]->v.p; 1312 TValue *upval = cl->upvals[GETARG_A(i)]->v.p;
1311 TValue *rb = KB(i); 1313 TValue *rb = KB(i);
1312 TValue *rc = RKC(i); 1314 TValue *rc = RKC(i);
1313 TString *key = tsvalue(rb); /* key must be a string */ 1315 TString *key = tsvalue(rb); /* key must be a short string */
1314 if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { 1316 if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) {
1315 luaV_finishfastset(L, upval, slot, rc); 1317 luaV_finishfastset(L, upval, slot, rc);
1316 } 1318 }
@@ -1353,7 +1355,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1353 const TValue *slot; 1355 const TValue *slot;
1354 TValue *rb = KB(i); 1356 TValue *rb = KB(i);
1355 TValue *rc = RKC(i); 1357 TValue *rc = RKC(i);
1356 TString *key = tsvalue(rb); /* key must be a string */ 1358 TString *key = tsvalue(rb); /* key must be a short string */
1357 if (luaV_fastget(L, s2v(ra), key, slot, luaH_getshortstr)) { 1359 if (luaV_fastget(L, s2v(ra), key, slot, luaH_getshortstr)) {
1358 luaV_finishfastset(L, s2v(ra), slot, rc); 1360 luaV_finishfastset(L, s2v(ra), slot, rc);
1359 } 1361 }
@@ -1411,6 +1413,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1411 vmbreak; 1413 vmbreak;
1412 } 1414 }
1413 vmcase(OP_MODK) { 1415 vmcase(OP_MODK) {
1416 savestate(L, ci); /* in case of division by 0 */
1414 op_arithK(L, luaV_mod, luaV_modf); 1417 op_arithK(L, luaV_mod, luaV_modf);
1415 vmbreak; 1418 vmbreak;
1416 } 1419 }
@@ -1423,6 +1426,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1423 vmbreak; 1426 vmbreak;
1424 } 1427 }
1425 vmcase(OP_IDIVK) { 1428 vmcase(OP_IDIVK) {
1429 savestate(L, ci); /* in case of division by 0 */
1426 op_arithK(L, luaV_idiv, luai_numidiv); 1430 op_arithK(L, luaV_idiv, luai_numidiv);
1427 vmbreak; 1431 vmbreak;
1428 } 1432 }
@@ -1471,6 +1475,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1471 vmbreak; 1475 vmbreak;
1472 } 1476 }
1473 vmcase(OP_MOD) { 1477 vmcase(OP_MOD) {
1478 savestate(L, ci); /* in case of division by 0 */
1474 op_arith(L, luaV_mod, luaV_modf); 1479 op_arith(L, luaV_mod, luaV_modf);
1475 vmbreak; 1480 vmbreak;
1476 } 1481 }
@@ -1483,6 +1488,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1483 vmbreak; 1488 vmbreak;
1484 } 1489 }
1485 vmcase(OP_IDIV) { /* floor division */ 1490 vmcase(OP_IDIV) { /* floor division */
1491 savestate(L, ci); /* in case of division by 0 */
1486 op_arith(L, luaV_idiv, luai_numidiv); 1492 op_arith(L, luaV_idiv, luai_numidiv);
1487 vmbreak; 1493 vmbreak;
1488 } 1494 }