diff options
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 76 |
1 files changed, 37 insertions, 39 deletions
@@ -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 | ||
@@ -356,30 +358,32 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | |||
356 | 358 | ||
357 | 359 | ||
358 | /* | 360 | /* |
359 | ** Compare two strings 'ls' x 'rs', returning an integer less-equal- | 361 | ** Compare two strings 'ts1' x 'ts2', returning an integer less-equal- |
360 | ** -greater than zero if 'ls' is less-equal-greater than 'rs'. | 362 | ** -greater than zero if 'ts1' is less-equal-greater than 'ts2'. |
361 | ** The code is a little tricky because it allows '\0' in the strings | 363 | ** The code is a little tricky because it allows '\0' in the strings |
362 | ** and it uses 'strcoll' (to respect locales) for each segments | 364 | ** and it uses 'strcoll' (to respect locales) for each segment |
363 | ** of the strings. | 365 | ** of the strings. Note that segments can compare equal but still |
366 | ** have different lengths. | ||
364 | */ | 367 | */ |
365 | static int l_strcmp (const TString *ls, const TString *rs) { | 368 | static int l_strcmp (const TString *ts1, const TString *ts2) { |
366 | const char *l = getstr(ls); | 369 | const char *s1 = getstr(ts1); |
367 | size_t ll = tsslen(ls); | 370 | size_t rl1 = tsslen(ts1); /* real length */ |
368 | const char *r = getstr(rs); | 371 | const char *s2 = getstr(ts2); |
369 | size_t lr = tsslen(rs); | 372 | size_t rl2 = tsslen(ts2); |
370 | for (;;) { /* for each segment */ | 373 | for (;;) { /* for each segment */ |
371 | int temp = strcoll(l, r); | 374 | int temp = strcoll(s1, s2); |
372 | if (temp != 0) /* not equal? */ | 375 | if (temp != 0) /* not equal? */ |
373 | return temp; /* done */ | 376 | return temp; /* done */ |
374 | else { /* strings are equal up to a '\0' */ | 377 | else { /* strings are equal up to a '\0' */ |
375 | size_t len = strlen(l); /* index of first '\0' in both strings */ | 378 | size_t zl1 = strlen(s1); /* index of first '\0' in 's1' */ |
376 | if (len == lr) /* 'rs' is finished? */ | 379 | size_t zl2 = strlen(s2); /* index of first '\0' in 's2' */ |
377 | return (len == ll) ? 0 : 1; /* check 'ls' */ | 380 | if (zl2 == rl2) /* 's2' is finished? */ |
378 | else if (len == ll) /* 'ls' is finished? */ | 381 | return (zl1 == rl1) ? 0 : 1; /* check 's1' */ |
379 | return -1; /* 'ls' is less than 'rs' ('rs' is not finished) */ | 382 | else if (zl1 == rl1) /* 's1' is finished? */ |
380 | /* both strings longer than 'len'; go on comparing after the '\0' */ | 383 | return -1; /* 's1' is less than 's2' ('s2' is not finished) */ |
381 | len++; | 384 | /* both strings longer than 'zl'; go on comparing after the '\0' */ |
382 | l += len; ll -= len; r += len; lr -= len; | 385 | zl1++; zl2++; |
386 | s1 += zl1; rl1 -= zl1; s2 += zl2; rl2 -= zl2; | ||
383 | } | 387 | } |
384 | } | 388 | } |
385 | } | 389 | } |
@@ -614,8 +618,9 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { | |||
614 | static void copy2buff (StkId top, int n, char *buff) { | 618 | static void copy2buff (StkId top, int n, char *buff) { |
615 | size_t tl = 0; /* size already copied */ | 619 | size_t tl = 0; /* size already copied */ |
616 | do { | 620 | do { |
617 | size_t l = vslen(s2v(top - n)); /* length of string being copied */ | 621 | TString *st = tsvalue(s2v(top - n)); |
618 | memcpy(buff + tl, svalue(s2v(top - n)), l * sizeof(char)); | 622 | size_t l = tsslen(st); /* length of string being copied */ |
623 | memcpy(buff + tl, getstr(st), l * sizeof(char)); | ||
619 | tl += l; | 624 | tl += l; |
620 | } while (--n > 0); | 625 | } while (--n > 0); |
621 | } | 626 | } |
@@ -641,11 +646,11 @@ void luaV_concat (lua_State *L, int total) { | |||
641 | } | 646 | } |
642 | else { | 647 | else { |
643 | /* at least two non-empty string values; get as many as possible */ | 648 | /* at least two non-empty string values; get as many as possible */ |
644 | size_t tl = vslen(s2v(top - 1)); | 649 | size_t tl = tsslen(tsvalue(s2v(top - 1))); |
645 | TString *ts; | 650 | TString *ts; |
646 | /* collect total length and number of strings */ | 651 | /* collect total length and number of strings */ |
647 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { | 652 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { |
648 | size_t l = vslen(s2v(top - n - 1)); | 653 | size_t l = tsslen(tsvalue(s2v(top - n - 1))); |
649 | if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) { | 654 | if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) { |
650 | L->top.p = top - total; /* pop strings to avoid wasting stack */ | 655 | L->top.p = top - total; /* pop strings to avoid wasting stack */ |
651 | luaG_runerror(L, "string length overflow"); | 656 | luaG_runerror(L, "string length overflow"); |
@@ -659,7 +664,7 @@ void luaV_concat (lua_State *L, int total) { | |||
659 | } | 664 | } |
660 | else { /* long string; copy strings directly to final result */ | 665 | else { /* long string; copy strings directly to final result */ |
661 | ts = luaS_createlngstrobj(L, tl); | 666 | ts = luaS_createlngstrobj(L, tl); |
662 | copy2buff(top, n, getstr(ts)); | 667 | copy2buff(top, n, getlngstr(ts)); |
663 | } | 668 | } |
664 | setsvalue2s(L, top - n, ts); /* create result */ | 669 | setsvalue2s(L, top - n, ts); /* create result */ |
665 | } | 670 | } |
@@ -1145,18 +1150,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1145 | startfunc: | 1150 | startfunc: |
1146 | trap = L->hookmask; | 1151 | trap = L->hookmask; |
1147 | returning: /* trap already set */ | 1152 | returning: /* trap already set */ |
1148 | cl = clLvalue(s2v(ci->func.p)); | 1153 | cl = ci_func(ci); |
1149 | k = cl->p->k; | 1154 | k = cl->p->k; |
1150 | pc = ci->u.l.savedpc; | 1155 | pc = ci->u.l.savedpc; |
1151 | if (l_unlikely(trap)) { | 1156 | if (l_unlikely(trap)) |
1152 | if (pc == cl->p->code) { /* first instruction (not resuming)? */ | 1157 | trap = luaG_tracecall(L); |
1153 | if (cl->p->is_vararg) | ||
1154 | trap = 0; /* hooks will start after VARARGPREP instruction */ | ||
1155 | else /* check 'call' hook */ | ||
1156 | luaD_hookcall(L, ci); | ||
1157 | } | ||
1158 | ci->u.l.trap = 1; /* assume trap is on, for now */ | ||
1159 | } | ||
1160 | base = ci->func.p + 1; | 1158 | base = ci->func.p + 1; |
1161 | /* main loop of interpreter */ | 1159 | /* main loop of interpreter */ |
1162 | for (;;) { | 1160 | for (;;) { |
@@ -1242,7 +1240,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1242 | StkId ra = RA(i); | 1240 | StkId ra = RA(i); |
1243 | TValue *upval = cl->upvals[GETARG_B(i)]->v.p; | 1241 | TValue *upval = cl->upvals[GETARG_B(i)]->v.p; |
1244 | TValue *rc = KC(i); | 1242 | TValue *rc = KC(i); |
1245 | TString *key = tsvalue(rc); /* key must be a string */ | 1243 | TString *key = tsvalue(rc); /* key must be a short string */ |
1246 | int hres; | 1244 | int hres; |
1247 | luaV_fastget(upval, key, s2v(ra), luaH_getshortstr, hres); | 1245 | luaV_fastget(upval, key, s2v(ra), luaH_getshortstr, hres); |
1248 | if (hres != HOK) | 1246 | if (hres != HOK) |
@@ -1280,7 +1278,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1280 | StkId ra = RA(i); | 1278 | StkId ra = RA(i); |
1281 | TValue *rb = vRB(i); | 1279 | TValue *rb = vRB(i); |
1282 | TValue *rc = KC(i); | 1280 | TValue *rc = KC(i); |
1283 | TString *key = tsvalue(rc); /* key must be a string */ | 1281 | TString *key = tsvalue(rc); /* key must be a short string */ |
1284 | int hres; | 1282 | int hres; |
1285 | luaV_fastget(rb, key, s2v(ra), luaH_getshortstr, hres); | 1283 | luaV_fastget(rb, key, s2v(ra), luaH_getshortstr, hres); |
1286 | if (hres != HOK) | 1284 | if (hres != HOK) |
@@ -1292,7 +1290,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1292 | TValue *upval = cl->upvals[GETARG_A(i)]->v.p; | 1290 | TValue *upval = cl->upvals[GETARG_A(i)]->v.p; |
1293 | TValue *rb = KB(i); | 1291 | TValue *rb = KB(i); |
1294 | TValue *rc = RKC(i); | 1292 | TValue *rc = RKC(i); |
1295 | TString *key = tsvalue(rb); /* key must be a string */ | 1293 | TString *key = tsvalue(rb); /* key must be a short string */ |
1296 | luaV_fastset(upval, key, rc, hres, luaH_psetshortstr); | 1294 | luaV_fastset(upval, key, rc, hres, luaH_psetshortstr); |
1297 | if (hres == HOK) | 1295 | if (hres == HOK) |
1298 | luaV_finishfastset(L, upval, rc); | 1296 | luaV_finishfastset(L, upval, rc); |
@@ -1337,7 +1335,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1337 | int hres; | 1335 | int hres; |
1338 | TValue *rb = KB(i); | 1336 | TValue *rb = KB(i); |
1339 | TValue *rc = RKC(i); | 1337 | TValue *rc = RKC(i); |
1340 | TString *key = tsvalue(rb); /* key must be a string */ | 1338 | TString *key = tsvalue(rb); /* key must be a short string */ |
1341 | luaV_fastset(s2v(ra), key, rc, hres, luaH_psetshortstr); | 1339 | luaV_fastset(s2v(ra), key, rc, hres, luaH_psetshortstr); |
1342 | if (hres == HOK) | 1340 | if (hres == HOK) |
1343 | luaV_finishfastset(L, s2v(ra), rc); | 1341 | luaV_finishfastset(L, s2v(ra), rc); |