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 | } |