diff options
Diffstat (limited to 'src/3rdParty/lua/lvm.c')
-rw-r--r-- | src/3rdParty/lua/lvm.c | 80 |
1 files changed, 41 insertions, 39 deletions
diff --git a/src/3rdParty/lua/lvm.c b/src/3rdParty/lua/lvm.c index 2e84dc6..4d71cff 100644 --- a/src/3rdParty/lua/lvm.c +++ b/src/3rdParty/lua/lvm.c | |||
@@ -91,8 +91,10 @@ static int l_strton (const TValue *obj, TValue *result) { | |||
91 | lua_assert(obj != result); | 91 | lua_assert(obj != result); |
92 | if (!cvt2num(obj)) /* is object not a string? */ | 92 | if (!cvt2num(obj)) /* is object not a string? */ |
93 | return 0; | 93 | return 0; |
94 | else | 94 | else { |
95 | return (luaO_str2num(svalue(obj), result) == vslen(obj) + 1); | 95 | TString *st = tsvalue(obj); |
96 | return (luaO_str2num(getstr(st), result) == tsslen(st) + 1); | ||
97 | } | ||
96 | } | 98 | } |
97 | 99 | ||
98 | 100 | ||
@@ -366,30 +368,32 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | |||
366 | 368 | ||
367 | 369 | ||
368 | /* | 370 | /* |
369 | ** Compare two strings 'ls' x 'rs', returning an integer less-equal- | 371 | ** Compare two strings 'ts1' x 'ts2', returning an integer less-equal- |
370 | ** -greater than zero if 'ls' is less-equal-greater than 'rs'. | 372 | ** -greater than zero if 'ts1' is less-equal-greater than 'ts2'. |
371 | ** The code is a little tricky because it allows '\0' in the strings | 373 | ** The code is a little tricky because it allows '\0' in the strings |
372 | ** and it uses 'strcoll' (to respect locales) for each segments | 374 | ** and it uses 'strcoll' (to respect locales) for each segment |
373 | ** of the strings. | 375 | ** of the strings. Note that segments can compare equal but still |
376 | ** have different lengths. | ||
374 | */ | 377 | */ |
375 | static int l_strcmp (const TString *ls, const TString *rs) { | 378 | static int l_strcmp (const TString *ts1, const TString *ts2) { |
376 | const char *l = getstr(ls); | 379 | const char *s1 = getstr(ts1); |
377 | size_t ll = tsslen(ls); | 380 | size_t rl1 = tsslen(ts1); /* real length */ |
378 | const char *r = getstr(rs); | 381 | const char *s2 = getstr(ts2); |
379 | size_t lr = tsslen(rs); | 382 | size_t rl2 = tsslen(ts2); |
380 | for (;;) { /* for each segment */ | 383 | for (;;) { /* for each segment */ |
381 | int temp = strcoll(l, r); | 384 | int temp = strcoll(s1, s2); |
382 | if (temp != 0) /* not equal? */ | 385 | if (temp != 0) /* not equal? */ |
383 | return temp; /* done */ | 386 | return temp; /* done */ |
384 | else { /* strings are equal up to a '\0' */ | 387 | else { /* strings are equal up to a '\0' */ |
385 | size_t len = strlen(l); /* index of first '\0' in both strings */ | 388 | size_t zl1 = strlen(s1); /* index of first '\0' in 's1' */ |
386 | if (len == lr) /* 'rs' is finished? */ | 389 | size_t zl2 = strlen(s2); /* index of first '\0' in 's2' */ |
387 | return (len == ll) ? 0 : 1; /* check 'ls' */ | 390 | if (zl2 == rl2) /* 's2' is finished? */ |
388 | else if (len == ll) /* 'ls' is finished? */ | 391 | return (zl1 == rl1) ? 0 : 1; /* check 's1' */ |
389 | return -1; /* 'ls' is less than 'rs' ('rs' is not finished) */ | 392 | else if (zl1 == rl1) /* 's1' is finished? */ |
390 | /* both strings longer than 'len'; go on comparing after the '\0' */ | 393 | return -1; /* 's1' is less than 's2' ('s2' is not finished) */ |
391 | len++; | 394 | /* both strings longer than 'zl'; go on comparing after the '\0' */ |
392 | l += len; ll -= len; r += len; lr -= len; | 395 | zl1++; zl2++; |
396 | s1 += zl1; rl1 -= zl1; s2 += zl2; rl2 -= zl2; | ||
393 | } | 397 | } |
394 | } | 398 | } |
395 | } | 399 | } |
@@ -624,8 +628,9 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { | |||
624 | static void copy2buff (StkId top, int n, char *buff) { | 628 | static void copy2buff (StkId top, int n, char *buff) { |
625 | size_t tl = 0; /* size already copied */ | 629 | size_t tl = 0; /* size already copied */ |
626 | do { | 630 | do { |
627 | size_t l = vslen(s2v(top - n)); /* length of string being copied */ | 631 | TString *st = tsvalue(s2v(top - n)); |
628 | memcpy(buff + tl, svalue(s2v(top - n)), l * sizeof(char)); | 632 | size_t l = tsslen(st); /* length of string being copied */ |
633 | memcpy(buff + tl, getstr(st), l * sizeof(char)); | ||
629 | tl += l; | 634 | tl += l; |
630 | } while (--n > 0); | 635 | } while (--n > 0); |
631 | } | 636 | } |
@@ -651,11 +656,11 @@ void luaV_concat (lua_State *L, int total) { | |||
651 | } | 656 | } |
652 | else { | 657 | else { |
653 | /* at least two non-empty string values; get as many as possible */ | 658 | /* at least two non-empty string values; get as many as possible */ |
654 | size_t tl = vslen(s2v(top - 1)); | 659 | size_t tl = tsslen(tsvalue(s2v(top - 1))); |
655 | TString *ts; | 660 | TString *ts; |
656 | /* collect total length and number of strings */ | 661 | /* collect total length and number of strings */ |
657 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { | 662 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { |
658 | size_t l = vslen(s2v(top - n - 1)); | 663 | size_t l = tsslen(tsvalue(s2v(top - n - 1))); |
659 | if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) { | 664 | if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) { |
660 | L->top.p = top - total; /* pop strings to avoid wasting stack */ | 665 | L->top.p = top - total; /* pop strings to avoid wasting stack */ |
661 | luaG_runerror(L, "string length overflow"); | 666 | luaG_runerror(L, "string length overflow"); |
@@ -669,7 +674,7 @@ void luaV_concat (lua_State *L, int total) { | |||
669 | } | 674 | } |
670 | else { /* long string; copy strings directly to final result */ | 675 | else { /* long string; copy strings directly to final result */ |
671 | ts = luaS_createlngstrobj(L, tl); | 676 | ts = luaS_createlngstrobj(L, tl); |
672 | copy2buff(top, n, getstr(ts)); | 677 | copy2buff(top, n, getlngstr(ts)); |
673 | } | 678 | } |
674 | setsvalue2s(L, top - n, ts); /* create result */ | 679 | setsvalue2s(L, top - n, ts); /* create result */ |
675 | } | 680 | } |
@@ -1155,18 +1160,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1155 | startfunc: | 1160 | startfunc: |
1156 | trap = L->hookmask; | 1161 | trap = L->hookmask; |
1157 | returning: /* trap already set */ | 1162 | returning: /* trap already set */ |
1158 | cl = clLvalue(s2v(ci->func.p)); | 1163 | cl = ci_func(ci); |
1159 | k = cl->p->k; | 1164 | k = cl->p->k; |
1160 | pc = ci->u.l.savedpc; | 1165 | pc = ci->u.l.savedpc; |
1161 | if (l_unlikely(trap)) { | 1166 | if (l_unlikely(trap)) |
1162 | if (pc == cl->p->code) { /* first instruction (not resuming)? */ | 1167 | trap = luaG_tracecall(L); |
1163 | if (cl->p->is_vararg) | ||
1164 | trap = 0; /* hooks will start after VARARGPREP instruction */ | ||
1165 | else /* check 'call' hook */ | ||
1166 | luaD_hookcall(L, ci); | ||
1167 | } | ||
1168 | ci->u.l.trap = 1; /* assume trap is on, for now */ | ||
1169 | } | ||
1170 | base = ci->func.p + 1; | 1168 | base = ci->func.p + 1; |
1171 | /* main loop of interpreter */ | 1169 | /* main loop of interpreter */ |
1172 | for (;;) { | 1170 | for (;;) { |
@@ -1253,7 +1251,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1253 | const TValue *slot; | 1251 | const TValue *slot; |
1254 | TValue *upval = cl->upvals[GETARG_B(i)]->v.p; | 1252 | TValue *upval = cl->upvals[GETARG_B(i)]->v.p; |
1255 | TValue *rc = KC(i); | 1253 | TValue *rc = KC(i); |
1256 | TString *key = tsvalue(rc); /* key must be a string */ | 1254 | TString *key = tsvalue(rc); /* key must be a short string */ |
1257 | if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { | 1255 | if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { |
1258 | setobj2s(L, ra, slot); | 1256 | setobj2s(L, ra, slot); |
1259 | } | 1257 | } |
@@ -1296,7 +1294,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1296 | const TValue *slot; | 1294 | const TValue *slot; |
1297 | TValue *rb = vRB(i); | 1295 | TValue *rb = vRB(i); |
1298 | TValue *rc = KC(i); | 1296 | TValue *rc = KC(i); |
1299 | TString *key = tsvalue(rc); /* key must be a string */ | 1297 | TString *key = tsvalue(rc); /* key must be a short string */ |
1300 | if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) { | 1298 | if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) { |
1301 | setobj2s(L, ra, slot); | 1299 | setobj2s(L, ra, slot); |
1302 | } | 1300 | } |
@@ -1309,7 +1307,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1309 | TValue *upval = cl->upvals[GETARG_A(i)]->v.p; | 1307 | TValue *upval = cl->upvals[GETARG_A(i)]->v.p; |
1310 | TValue *rb = KB(i); | 1308 | TValue *rb = KB(i); |
1311 | TValue *rc = RKC(i); | 1309 | TValue *rc = RKC(i); |
1312 | TString *key = tsvalue(rb); /* key must be a string */ | 1310 | TString *key = tsvalue(rb); /* key must be a short string */ |
1313 | if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { | 1311 | if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { |
1314 | luaV_finishfastset(L, upval, slot, rc); | 1312 | luaV_finishfastset(L, upval, slot, rc); |
1315 | } | 1313 | } |
@@ -1352,7 +1350,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1352 | const TValue *slot; | 1350 | const TValue *slot; |
1353 | TValue *rb = KB(i); | 1351 | TValue *rb = KB(i); |
1354 | TValue *rc = RKC(i); | 1352 | TValue *rc = RKC(i); |
1355 | TString *key = tsvalue(rb); /* key must be a string */ | 1353 | TString *key = tsvalue(rb); /* key must be a short string */ |
1356 | if (luaV_fastget(L, s2v(ra), key, slot, luaH_getshortstr)) { | 1354 | if (luaV_fastget(L, s2v(ra), key, slot, luaH_getshortstr)) { |
1357 | luaV_finishfastset(L, s2v(ra), slot, rc); | 1355 | luaV_finishfastset(L, s2v(ra), slot, rc); |
1358 | } | 1356 | } |
@@ -1410,6 +1408,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1410 | vmbreak; | 1408 | vmbreak; |
1411 | } | 1409 | } |
1412 | vmcase(OP_MODK) { | 1410 | vmcase(OP_MODK) { |
1411 | savestate(L, ci); /* in case of division by 0 */ | ||
1413 | op_arithK(L, luaV_mod, luaV_modf); | 1412 | op_arithK(L, luaV_mod, luaV_modf); |
1414 | vmbreak; | 1413 | vmbreak; |
1415 | } | 1414 | } |
@@ -1422,6 +1421,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1422 | vmbreak; | 1421 | vmbreak; |
1423 | } | 1422 | } |
1424 | vmcase(OP_IDIVK) { | 1423 | vmcase(OP_IDIVK) { |
1424 | savestate(L, ci); /* in case of division by 0 */ | ||
1425 | op_arithK(L, luaV_idiv, luai_numidiv); | 1425 | op_arithK(L, luaV_idiv, luai_numidiv); |
1426 | vmbreak; | 1426 | vmbreak; |
1427 | } | 1427 | } |
@@ -1470,6 +1470,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1470 | vmbreak; | 1470 | vmbreak; |
1471 | } | 1471 | } |
1472 | vmcase(OP_MOD) { | 1472 | vmcase(OP_MOD) { |
1473 | savestate(L, ci); /* in case of division by 0 */ | ||
1473 | op_arith(L, luaV_mod, luaV_modf); | 1474 | op_arith(L, luaV_mod, luaV_modf); |
1474 | vmbreak; | 1475 | vmbreak; |
1475 | } | 1476 | } |
@@ -1482,6 +1483,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1482 | vmbreak; | 1483 | vmbreak; |
1483 | } | 1484 | } |
1484 | vmcase(OP_IDIV) { /* floor division */ | 1485 | vmcase(OP_IDIV) { /* floor division */ |
1486 | savestate(L, ci); /* in case of division by 0 */ | ||
1485 | op_arith(L, luaV_idiv, luai_numidiv); | 1487 | op_arith(L, luaV_idiv, luai_numidiv); |
1486 | vmbreak; | 1488 | vmbreak; |
1487 | } | 1489 | } |