diff options
Diffstat (limited to 'lvm.c')
| -rw-r--r-- | lvm.c | 50 |
1 files changed, 28 insertions, 22 deletions
| @@ -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 | */ |
| 376 | static int l_strcmp (const TString *ls, const TString *rs) { | 377 | static 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 | } |
