diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-02-24 11:14:44 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-02-24 11:14:44 -0300 |
commit | 59c88f846d1dcd901a4420651aedf27816618923 (patch) | |
tree | 0e76a066c383cbc99cc2f60b8b4f97c5df45e479 /lstrlib.c | |
parent | c03c527fd207b4ad8f5a8e0f4f2c176bd227c979 (diff) | |
download | lua-59c88f846d1dcd901a4420651aedf27816618923.tar.gz lua-59c88f846d1dcd901a4420651aedf27816618923.tar.bz2 lua-59c88f846d1dcd901a4420651aedf27816618923.zip |
Broadening the use of branch hints
More uses of macros 'likely'/'unlikely' (renamed to
'l_likely'/'l_unlikely'), both in range (extended to the
libraries) and in scope (extended to hooks, stack growth).
Diffstat (limited to 'lstrlib.c')
-rw-r--r-- | lstrlib.c | 41 |
1 files changed, 22 insertions, 19 deletions
@@ -152,8 +152,9 @@ static int str_rep (lua_State *L) { | |||
152 | const char *s = luaL_checklstring(L, 1, &l); | 152 | const char *s = luaL_checklstring(L, 1, &l); |
153 | lua_Integer n = luaL_checkinteger(L, 2); | 153 | lua_Integer n = luaL_checkinteger(L, 2); |
154 | const char *sep = luaL_optlstring(L, 3, "", &lsep); | 154 | const char *sep = luaL_optlstring(L, 3, "", &lsep); |
155 | if (n <= 0) lua_pushliteral(L, ""); | 155 | if (n <= 0) |
156 | else if (l + lsep < l || l + lsep > MAXSIZE / n) /* may overflow? */ | 156 | lua_pushliteral(L, ""); |
157 | else if (l_unlikely(l + lsep < l || l + lsep > MAXSIZE / n)) | ||
157 | return luaL_error(L, "resulting string too large"); | 158 | return luaL_error(L, "resulting string too large"); |
158 | else { | 159 | else { |
159 | size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep; | 160 | size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep; |
@@ -181,7 +182,7 @@ static int str_byte (lua_State *L) { | |||
181 | size_t pose = getendpos(L, 3, pi, l); | 182 | size_t pose = getendpos(L, 3, pi, l); |
182 | int n, i; | 183 | int n, i; |
183 | if (posi > pose) return 0; /* empty interval; return no values */ | 184 | if (posi > pose) return 0; /* empty interval; return no values */ |
184 | if (pose - posi >= (size_t)INT_MAX) /* arithmetic overflow? */ | 185 | if (l_unlikely(pose - posi >= (size_t)INT_MAX)) /* arithmetic overflow? */ |
185 | return luaL_error(L, "string slice too long"); | 186 | return luaL_error(L, "string slice too long"); |
186 | n = (int)(pose - posi) + 1; | 187 | n = (int)(pose - posi) + 1; |
187 | luaL_checkstack(L, n, "string slice too long"); | 188 | luaL_checkstack(L, n, "string slice too long"); |
@@ -235,7 +236,7 @@ static int str_dump (lua_State *L) { | |||
235 | luaL_checktype(L, 1, LUA_TFUNCTION); | 236 | luaL_checktype(L, 1, LUA_TFUNCTION); |
236 | lua_settop(L, 1); /* ensure function is on the top of the stack */ | 237 | lua_settop(L, 1); /* ensure function is on the top of the stack */ |
237 | state.init = 0; | 238 | state.init = 0; |
238 | if (lua_dump(L, writer, &state, strip) != 0) | 239 | if (l_unlikely(lua_dump(L, writer, &state, strip) != 0)) |
239 | return luaL_error(L, "unable to dump given function"); | 240 | return luaL_error(L, "unable to dump given function"); |
240 | luaL_pushresult(&state.B); | 241 | luaL_pushresult(&state.B); |
241 | return 1; | 242 | return 1; |
@@ -275,7 +276,8 @@ static int tonum (lua_State *L, int arg) { | |||
275 | 276 | ||
276 | static void trymt (lua_State *L, const char *mtname) { | 277 | static void trymt (lua_State *L, const char *mtname) { |
277 | lua_settop(L, 2); /* back to the original arguments */ | 278 | lua_settop(L, 2); /* back to the original arguments */ |
278 | if (lua_type(L, 2) == LUA_TSTRING || !luaL_getmetafield(L, 2, mtname)) | 279 | if (l_unlikely(lua_type(L, 2) == LUA_TSTRING || |
280 | !luaL_getmetafield(L, 2, mtname))) | ||
279 | luaL_error(L, "attempt to %s a '%s' with a '%s'", mtname + 2, | 281 | luaL_error(L, "attempt to %s a '%s' with a '%s'", mtname + 2, |
280 | luaL_typename(L, -2), luaL_typename(L, -1)); | 282 | luaL_typename(L, -2), luaL_typename(L, -1)); |
281 | lua_insert(L, -3); /* put metamethod before arguments */ | 283 | lua_insert(L, -3); /* put metamethod before arguments */ |
@@ -383,7 +385,8 @@ static const char *match (MatchState *ms, const char *s, const char *p); | |||
383 | 385 | ||
384 | static int check_capture (MatchState *ms, int l) { | 386 | static int check_capture (MatchState *ms, int l) { |
385 | l -= '1'; | 387 | l -= '1'; |
386 | if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) | 388 | if (l_unlikely(l < 0 || l >= ms->level || |
389 | ms->capture[l].len == CAP_UNFINISHED)) | ||
387 | return luaL_error(ms->L, "invalid capture index %%%d", l + 1); | 390 | return luaL_error(ms->L, "invalid capture index %%%d", l + 1); |
388 | return l; | 391 | return l; |
389 | } | 392 | } |
@@ -400,14 +403,14 @@ static int capture_to_close (MatchState *ms) { | |||
400 | static const char *classend (MatchState *ms, const char *p) { | 403 | static const char *classend (MatchState *ms, const char *p) { |
401 | switch (*p++) { | 404 | switch (*p++) { |
402 | case L_ESC: { | 405 | case L_ESC: { |
403 | if (p == ms->p_end) | 406 | if (l_unlikely(p == ms->p_end)) |
404 | luaL_error(ms->L, "malformed pattern (ends with '%%')"); | 407 | luaL_error(ms->L, "malformed pattern (ends with '%%')"); |
405 | return p+1; | 408 | return p+1; |
406 | } | 409 | } |
407 | case '[': { | 410 | case '[': { |
408 | if (*p == '^') p++; | 411 | if (*p == '^') p++; |
409 | do { /* look for a ']' */ | 412 | do { /* look for a ']' */ |
410 | if (p == ms->p_end) | 413 | if (l_unlikely(p == ms->p_end)) |
411 | luaL_error(ms->L, "malformed pattern (missing ']')"); | 414 | luaL_error(ms->L, "malformed pattern (missing ']')"); |
412 | if (*(p++) == L_ESC && p < ms->p_end) | 415 | if (*(p++) == L_ESC && p < ms->p_end) |
413 | p++; /* skip escapes (e.g. '%]') */ | 416 | p++; /* skip escapes (e.g. '%]') */ |
@@ -482,7 +485,7 @@ static int singlematch (MatchState *ms, const char *s, const char *p, | |||
482 | 485 | ||
483 | static const char *matchbalance (MatchState *ms, const char *s, | 486 | static const char *matchbalance (MatchState *ms, const char *s, |
484 | const char *p) { | 487 | const char *p) { |
485 | if (p >= ms->p_end - 1) | 488 | if (l_unlikely(p >= ms->p_end - 1)) |
486 | luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')"); | 489 | luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')"); |
487 | if (*s != *p) return NULL; | 490 | if (*s != *p) return NULL; |
488 | else { | 491 | else { |
@@ -565,7 +568,7 @@ static const char *match_capture (MatchState *ms, const char *s, int l) { | |||
565 | 568 | ||
566 | 569 | ||
567 | static const char *match (MatchState *ms, const char *s, const char *p) { | 570 | static const char *match (MatchState *ms, const char *s, const char *p) { |
568 | if (ms->matchdepth-- == 0) | 571 | if (l_unlikely(ms->matchdepth-- == 0)) |
569 | luaL_error(ms->L, "pattern too complex"); | 572 | luaL_error(ms->L, "pattern too complex"); |
570 | init: /* using goto's to optimize tail recursion */ | 573 | init: /* using goto's to optimize tail recursion */ |
571 | if (p != ms->p_end) { /* end of pattern? */ | 574 | if (p != ms->p_end) { /* end of pattern? */ |
@@ -599,7 +602,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) { | |||
599 | case 'f': { /* frontier? */ | 602 | case 'f': { /* frontier? */ |
600 | const char *ep; char previous; | 603 | const char *ep; char previous; |
601 | p += 2; | 604 | p += 2; |
602 | if (*p != '[') | 605 | if (l_unlikely(*p != '[')) |
603 | luaL_error(ms->L, "missing '[' after '%%f' in pattern"); | 606 | luaL_error(ms->L, "missing '[' after '%%f' in pattern"); |
604 | ep = classend(ms, p); /* points to what is next */ | 607 | ep = classend(ms, p); /* points to what is next */ |
605 | previous = (s == ms->src_init) ? '\0' : *(s - 1); | 608 | previous = (s == ms->src_init) ? '\0' : *(s - 1); |
@@ -699,7 +702,7 @@ static const char *lmemfind (const char *s1, size_t l1, | |||
699 | static size_t get_onecapture (MatchState *ms, int i, const char *s, | 702 | static size_t get_onecapture (MatchState *ms, int i, const char *s, |
700 | const char *e, const char **cap) { | 703 | const char *e, const char **cap) { |
701 | if (i >= ms->level) { | 704 | if (i >= ms->level) { |
702 | if (i != 0) | 705 | if (l_unlikely(i != 0)) |
703 | luaL_error(ms->L, "invalid capture index %%%d", i + 1); | 706 | luaL_error(ms->L, "invalid capture index %%%d", i + 1); |
704 | *cap = s; | 707 | *cap = s; |
705 | return e - s; | 708 | return e - s; |
@@ -707,7 +710,7 @@ static size_t get_onecapture (MatchState *ms, int i, const char *s, | |||
707 | else { | 710 | else { |
708 | ptrdiff_t capl = ms->capture[i].len; | 711 | ptrdiff_t capl = ms->capture[i].len; |
709 | *cap = ms->capture[i].init; | 712 | *cap = ms->capture[i].init; |
710 | if (capl == CAP_UNFINISHED) | 713 | if (l_unlikely(capl == CAP_UNFINISHED)) |
711 | luaL_error(ms->L, "unfinished capture"); | 714 | luaL_error(ms->L, "unfinished capture"); |
712 | else if (capl == CAP_POSITION) | 715 | else if (capl == CAP_POSITION) |
713 | lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1); | 716 | lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1); |
@@ -926,7 +929,7 @@ static int add_value (MatchState *ms, luaL_Buffer *b, const char *s, | |||
926 | luaL_addlstring(b, s, e - s); /* keep original text */ | 929 | luaL_addlstring(b, s, e - s); /* keep original text */ |
927 | return 0; /* no changes */ | 930 | return 0; /* no changes */ |
928 | } | 931 | } |
929 | else if (!lua_isstring(L, -1)) | 932 | else if (l_unlikely(!lua_isstring(L, -1))) |
930 | return luaL_error(L, "invalid replacement value (a %s)", | 933 | return luaL_error(L, "invalid replacement value (a %s)", |
931 | luaL_typename(L, -1)); | 934 | luaL_typename(L, -1)); |
932 | else { | 935 | else { |
@@ -1058,7 +1061,7 @@ static int lua_number2strx (lua_State *L, char *buff, int sz, | |||
1058 | for (i = 0; i < n; i++) | 1061 | for (i = 0; i < n; i++) |
1059 | buff[i] = toupper(uchar(buff[i])); | 1062 | buff[i] = toupper(uchar(buff[i])); |
1060 | } | 1063 | } |
1061 | else if (fmt[SIZELENMOD] != 'a') | 1064 | else if (l_unlikely(fmt[SIZELENMOD] != 'a')) |
1062 | return luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented"); | 1065 | return luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented"); |
1063 | return n; | 1066 | return n; |
1064 | } | 1067 | } |
@@ -1411,7 +1414,7 @@ static int getnum (const char **fmt, int df) { | |||
1411 | */ | 1414 | */ |
1412 | static int getnumlimit (Header *h, const char **fmt, int df) { | 1415 | static int getnumlimit (Header *h, const char **fmt, int df) { |
1413 | int sz = getnum(fmt, df); | 1416 | int sz = getnum(fmt, df); |
1414 | if (sz > MAXINTSIZE || sz <= 0) | 1417 | if (l_unlikely(sz > MAXINTSIZE || sz <= 0)) |
1415 | return luaL_error(h->L, "integral size (%d) out of limits [1,%d]", | 1418 | return luaL_error(h->L, "integral size (%d) out of limits [1,%d]", |
1416 | sz, MAXINTSIZE); | 1419 | sz, MAXINTSIZE); |
1417 | return sz; | 1420 | return sz; |
@@ -1452,7 +1455,7 @@ static KOption getoption (Header *h, const char **fmt, int *size) { | |||
1452 | case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring; | 1455 | case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring; |
1453 | case 'c': | 1456 | case 'c': |
1454 | *size = getnum(fmt, -1); | 1457 | *size = getnum(fmt, -1); |
1455 | if (*size == -1) | 1458 | if (l_unlikely(*size == -1)) |
1456 | luaL_error(h->L, "missing size for format option 'c'"); | 1459 | luaL_error(h->L, "missing size for format option 'c'"); |
1457 | return Kchar; | 1460 | return Kchar; |
1458 | case 'z': return Kzstr; | 1461 | case 'z': return Kzstr; |
@@ -1491,7 +1494,7 @@ static KOption getdetails (Header *h, size_t totalsize, | |||
1491 | else { | 1494 | else { |
1492 | if (align > h->maxalign) /* enforce maximum alignment */ | 1495 | if (align > h->maxalign) /* enforce maximum alignment */ |
1493 | align = h->maxalign; | 1496 | align = h->maxalign; |
1494 | if ((align & (align - 1)) != 0) /* is 'align' not a power of 2? */ | 1497 | if (l_unlikely((align & (align - 1)) != 0)) /* not a power of 2? */ |
1495 | luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); | 1498 | luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); |
1496 | *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1); | 1499 | *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1); |
1497 | } | 1500 | } |
@@ -1683,7 +1686,7 @@ static lua_Integer unpackint (lua_State *L, const char *str, | |||
1683 | else if (size > SZINT) { /* must check unread bytes */ | 1686 | else if (size > SZINT) { /* must check unread bytes */ |
1684 | int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC; | 1687 | int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC; |
1685 | for (i = limit; i < size; i++) { | 1688 | for (i = limit; i < size; i++) { |
1686 | if ((unsigned char)str[islittle ? i : size - 1 - i] != mask) | 1689 | if (l_unlikely((unsigned char)str[islittle ? i : size - 1 - i] != mask)) |
1687 | luaL_error(L, "%d-byte integer does not fit into Lua Integer", size); | 1690 | luaL_error(L, "%d-byte integer does not fit into Lua Integer", size); |
1688 | } | 1691 | } |
1689 | } | 1692 | } |