summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-03-27 14:56:10 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-03-27 14:56:10 -0300
commitd12262068d689eacc452a459a021df0ad8f6d46c (patch)
treed3e839cd1ddf3daf5e12c8f472c10a980b7d9d8c
parent0443ad9e288825b6e4441eb11104bcdb4ff4593a (diff)
downloadlua-d12262068d689eacc452a459a021df0ad8f6d46c.tar.gz
lua-d12262068d689eacc452a459a021df0ad8f6d46c.tar.bz2
lua-d12262068d689eacc452a459a021df0ad8f6d46c.zip
Small optimizations in range checks
Checks of the form '1 <= x && x <= M' were rewritten in the form '(unsigned)x - 1 < (unsigned)M', which is usually more efficient. (Other similar checks have similar translations.) Although some compilers do these optimizations, that does not happen for all compilers or all cases.
-rw-r--r--lapi.c10
-rw-r--r--ltable.c10
-rw-r--r--ltablib.c8
-rw-r--r--testes/utf8.lua3
4 files changed, 20 insertions, 11 deletions
diff --git a/lapi.c b/lapi.c
index 06396ad3..661fdb14 100644
--- a/lapi.c
+++ b/lapi.c
@@ -936,8 +936,8 @@ LUA_API int lua_setiuservalue (lua_State *L, int idx, int n) {
936 api_checknelems(L, 1); 936 api_checknelems(L, 1);
937 o = index2value(L, idx); 937 o = index2value(L, idx);
938 api_check(L, ttisfulluserdata(o), "full userdata expected"); 938 api_check(L, ttisfulluserdata(o), "full userdata expected");
939 if (!(0 < n && n <= uvalue(o)->nuvalue)) 939 if (!(cast_uint(n) - 1u < cast_uint(uvalue(o)->nuvalue)))
940 res = 0; 940 res = 0; /* 'n' not in [1, uvalue(o)->nuvalue] */
941 else { 941 else {
942 setobj(L, &uvalue(o)->uv[n - 1].uv, s2v(L->top - 1)); 942 setobj(L, &uvalue(o)->uv[n - 1].uv, s2v(L->top - 1));
943 luaC_barrierback(L, gcvalue(o), s2v(L->top - 1)); 943 luaC_barrierback(L, gcvalue(o), s2v(L->top - 1));
@@ -1313,7 +1313,8 @@ static const char *aux_upvalue (TValue *fi, int n, TValue **val,
1313 switch (ttypetag(fi)) { 1313 switch (ttypetag(fi)) {
1314 case LUA_TCCL: { /* C closure */ 1314 case LUA_TCCL: { /* C closure */
1315 CClosure *f = clCvalue(fi); 1315 CClosure *f = clCvalue(fi);
1316 if (!(1 <= n && n <= f->nupvalues)) return NULL; 1316 if (!(cast_uint(n) - 1u < cast_uint(f->nupvalues)))
1317 return NULL; /* 'n' not in [1, f->nupvalues] */
1317 *val = &f->upvalue[n-1]; 1318 *val = &f->upvalue[n-1];
1318 if (owner) *owner = obj2gco(f); 1319 if (owner) *owner = obj2gco(f);
1319 return ""; 1320 return "";
@@ -1322,7 +1323,8 @@ static const char *aux_upvalue (TValue *fi, int n, TValue **val,
1322 LClosure *f = clLvalue(fi); 1323 LClosure *f = clLvalue(fi);
1323 TString *name; 1324 TString *name;
1324 Proto *p = f->p; 1325 Proto *p = f->p;
1325 if (!(1 <= n && n <= p->sizeupvalues)) return NULL; 1326 if (!(cast_uint(n) - 1u < cast_uint(p->sizeupvalues)))
1327 return NULL; /* 'n' not in [1, p->sizeupvalues] */
1326 *val = f->upvals[n-1]->v; 1328 *val = f->upvals[n-1]->v;
1327 if (owner) *owner = obj2gco(f->upvals[n - 1]); 1329 if (owner) *owner = obj2gco(f->upvals[n - 1]);
1328 name = p->upvalues[n-1].name; 1330 name = p->upvalues[n-1].name;
diff --git a/ltable.c b/ltable.c
index e12381b2..628c640c 100644
--- a/ltable.c
+++ b/ltable.c
@@ -48,8 +48,8 @@
48 48
49/* 49/*
50** MAXASIZE is the maximum size of the array part. It is the minimum 50** MAXASIZE is the maximum size of the array part. It is the minimum
51** between 2^MAXABITS and the maximum size such that, measured in bytes, 51** between 2^MAXABITS and the maximum size that, measured in bytes,
52** it fits in a 'size_t'. 52** fits in a 'size_t'.
53*/ 53*/
54#define MAXASIZE luaM_limitN(1u << MAXABITS, TValue) 54#define MAXASIZE luaM_limitN(1u << MAXABITS, TValue)
55 55
@@ -269,7 +269,7 @@ static const TValue *getgeneric (Table *t, const TValue *key) {
269** the array part of a table, 0 otherwise. 269** the array part of a table, 0 otherwise.
270*/ 270*/
271static unsigned int arrayindex (lua_Integer k) { 271static unsigned int arrayindex (lua_Integer k) {
272 if (0 < k && l_castS2U(k) <= MAXASIZE) 272 if (l_castS2U(k) - 1u < MAXASIZE) /* 'k' in [1, MAXASIZE]? */
273 return cast_uint(k); /* 'key' is an appropriate array index */ 273 return cast_uint(k); /* 'key' is an appropriate array index */
274 else 274 else
275 return 0; 275 return 0;
@@ -286,7 +286,7 @@ static unsigned int findindex (lua_State *L, Table *t, TValue *key,
286 unsigned int i; 286 unsigned int i;
287 if (ttisnil(key)) return 0; /* first iteration */ 287 if (ttisnil(key)) return 0; /* first iteration */
288 i = ttisinteger(key) ? arrayindex(ivalue(key)) : 0; 288 i = ttisinteger(key) ? arrayindex(ivalue(key)) : 0;
289 if (i != 0 && i <= asize) /* is 'key' inside array part? */ 289 if (i - 1u < asize) /* is 'key' inside array part? */
290 return i; /* yes; that's the index */ 290 return i; /* yes; that's the index */
291 else { 291 else {
292 const TValue *n = getgeneric(t, key); 292 const TValue *n = getgeneric(t, key);
@@ -678,7 +678,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
678** changing the real size of the array). 678** changing the real size of the array).
679*/ 679*/
680const TValue *luaH_getint (Table *t, lua_Integer key) { 680const TValue *luaH_getint (Table *t, lua_Integer key) {
681 if (l_castS2U(key) - 1u < t->alimit) /* (1 <= key && key <= t->alimit)? */ 681 if (l_castS2U(key) - 1u < t->alimit) /* 'key' in [1, t->alimit]? */
682 return &t->array[key - 1]; 682 return &t->array[key - 1];
683 else if (!limitequalsasize(t) && /* key still may be in the array part? */ 683 else if (!limitequalsasize(t) && /* key still may be in the array part? */
684 (l_castS2U(key) == t->alimit + 1 || 684 (l_castS2U(key) == t->alimit + 1 ||
diff --git a/ltablib.c b/ltablib.c
index 29c53e94..a9169f9e 100644
--- a/ltablib.c
+++ b/ltablib.c
@@ -69,7 +69,9 @@ static int tinsert (lua_State *L) {
69 case 3: { 69 case 3: {
70 lua_Integer i; 70 lua_Integer i;
71 pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */ 71 pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */
72 luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); 72 /* check whether 'pos' is in [1, e] */
73 luaL_argcheck(L, (lua_Unsigned)pos - 1u < (lua_Unsigned)e, 2,
74 "position out of bounds");
73 for (i = e; i > pos; i--) { /* move up elements */ 75 for (i = e; i > pos; i--) { /* move up elements */
74 lua_geti(L, 1, i - 1); 76 lua_geti(L, 1, i - 1);
75 lua_seti(L, 1, i); /* t[i] = t[i - 1] */ 77 lua_seti(L, 1, i); /* t[i] = t[i - 1] */
@@ -89,7 +91,9 @@ static int tremove (lua_State *L) {
89 lua_Integer size = aux_getn(L, 1, TAB_RW); 91 lua_Integer size = aux_getn(L, 1, TAB_RW);
90 lua_Integer pos = luaL_optinteger(L, 2, size); 92 lua_Integer pos = luaL_optinteger(L, 2, size);
91 if (pos != size) /* validate 'pos' if given */ 93 if (pos != size) /* validate 'pos' if given */
92 luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds"); 94 /* check whether 'pos' is in [1, size + 1] */
95 luaL_argcheck(L, (lua_Unsigned)pos - 1u <= (lua_Unsigned)size, 1,
96 "position out of bounds");
93 lua_geti(L, 1, pos); /* result = t[pos] */ 97 lua_geti(L, 1, pos); /* result = t[pos] */
94 for ( ; pos < size; pos++) { 98 for ( ; pos < size; pos++) {
95 lua_geti(L, 1, pos + 1); 99 lua_geti(L, 1, pos + 1);
diff --git a/testes/utf8.lua b/testes/utf8.lua
index 86ec1b00..b3b7687f 100644
--- a/testes/utf8.lua
+++ b/testes/utf8.lua
@@ -123,6 +123,9 @@ checkerror("continuation byte", utf8.offset, "𦧺", 1, 2)
123checkerror("continuation byte", utf8.offset, "𦧺", 1, 2) 123checkerror("continuation byte", utf8.offset, "𦧺", 1, 2)
124checkerror("continuation byte", utf8.offset, "\x80", 1) 124checkerror("continuation byte", utf8.offset, "\x80", 1)
125 125
126-- error in indices for len
127checkerror("out of string", utf8.len, "abc", 0, 2)
128checkerror("out of string", utf8.len, "abc", 1, 4)
126 129
127 130
128local s = "hello World" 131local s = "hello World"