aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-11-03 15:39:14 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-11-03 15:39:14 -0300
commitfa075b79530af1cbc977349f2e467d69ce01202c (patch)
tree300e10cd086a9812331b954d46552dbf420b0a8a /lvm.c
parent08a077d673b25cf1fbfe21794f240f4ff4999667 (diff)
parent7923dbbf72da303ca1cca17efd24725668992f15 (diff)
downloadlua-fa075b79530af1cbc977349f2e467d69ce01202c.tar.gz
lua-fa075b79530af1cbc977349f2e467d69ce01202c.tar.bz2
lua-fa075b79530af1cbc977349f2e467d69ce01202c.zip
Merge branch 'master' into newarray
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c76
1 files changed, 37 insertions, 39 deletions
diff --git a/lvm.c b/lvm.c
index 927272df..9b71ff31 100644
--- a/lvm.c
+++ b/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
@@ -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*/
365static int l_strcmp (const TString *ls, const TString *rs) { 368static 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) {
614static void copy2buff (StkId top, int n, char *buff) { 618static 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);