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.
diff --git a/lapi.c b/lapi.c
index 06396ad..661fdb1 100644
--- a/lapi.c
+++ b/lapi.c
@@ -936,8 +936,8 @@
   api_checknelems(L, 1);
   o = index2value(L, idx);
   api_check(L, ttisfulluserdata(o), "full userdata expected");
-  if (!(0 < n && n <= uvalue(o)->nuvalue))
-    res = 0;
+  if (!(cast_uint(n) - 1u < cast_uint(uvalue(o)->nuvalue)))
+    res = 0;  /* 'n' not in [1, uvalue(o)->nuvalue] */
   else {
     setobj(L, &uvalue(o)->uv[n - 1].uv, s2v(L->top - 1));
     luaC_barrierback(L, gcvalue(o), s2v(L->top - 1));
@@ -1313,7 +1313,8 @@
   switch (ttypetag(fi)) {
     case LUA_TCCL: {  /* C closure */
       CClosure *f = clCvalue(fi);
-      if (!(1 <= n && n <= f->nupvalues)) return NULL;
+      if (!(cast_uint(n) - 1u < cast_uint(f->nupvalues)))
+        return NULL;  /* 'n' not in [1, f->nupvalues] */
       *val = &f->upvalue[n-1];
       if (owner) *owner = obj2gco(f);
       return "";
@@ -1322,7 +1323,8 @@
       LClosure *f = clLvalue(fi);
       TString *name;
       Proto *p = f->p;
-      if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
+      if (!(cast_uint(n) - 1u  < cast_uint(p->sizeupvalues)))
+        return NULL;  /* 'n' not in [1, p->sizeupvalues] */
       *val = f->upvals[n-1]->v;
       if (owner) *owner = obj2gco(f->upvals[n - 1]);
       name = p->upvalues[n-1].name;
diff --git a/ltable.c b/ltable.c
index e12381b..628c640 100644
--- a/ltable.c
+++ b/ltable.c
@@ -48,8 +48,8 @@
 
 /*
 ** MAXASIZE is the maximum size of the array part. It is the minimum
-** between 2^MAXABITS and the maximum size such that, measured in bytes,
-** it fits in a 'size_t'.
+** between 2^MAXABITS and the maximum size that, measured in bytes,
+** fits in a 'size_t'.
 */
 #define MAXASIZE	luaM_limitN(1u << MAXABITS, TValue)
 
@@ -269,7 +269,7 @@
 ** the array part of a table, 0 otherwise.
 */
 static unsigned int arrayindex (lua_Integer k) {
-  if (0 < k && l_castS2U(k) <= MAXASIZE)
+  if (l_castS2U(k) - 1u < MAXASIZE)  /* 'k' in [1, MAXASIZE]? */
     return cast_uint(k);  /* 'key' is an appropriate array index */
   else
     return 0;
@@ -286,7 +286,7 @@
   unsigned int i;
   if (ttisnil(key)) return 0;  /* first iteration */
   i = ttisinteger(key) ? arrayindex(ivalue(key)) : 0;
-  if (i != 0 && i <= asize)  /* is 'key' inside array part? */
+  if (i - 1u < asize)  /* is 'key' inside array part? */
     return i;  /* yes; that's the index */
   else {
     const TValue *n = getgeneric(t, key);
@@ -678,7 +678,7 @@
 ** changing the real size of the array).
 */
 const TValue *luaH_getint (Table *t, lua_Integer key) {
-  if (l_castS2U(key) - 1u < t->alimit)  /* (1 <= key && key <= t->alimit)? */
+  if (l_castS2U(key) - 1u < t->alimit)  /* 'key' in [1, t->alimit]? */
     return &t->array[key - 1];
   else if (!limitequalsasize(t) &&  /* key still may be in the array part? */
            (l_castS2U(key) == t->alimit + 1 ||
diff --git a/ltablib.c b/ltablib.c
index 29c53e9..a9169f9 100644
--- a/ltablib.c
+++ b/ltablib.c
@@ -69,7 +69,9 @@
     case 3: {
       lua_Integer i;
       pos = luaL_checkinteger(L, 2);  /* 2nd argument is the position */
-      luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds");
+      /* check whether 'pos' is in [1, e] */
+      luaL_argcheck(L, (lua_Unsigned)pos - 1u < (lua_Unsigned)e, 2,
+                       "position out of bounds");
       for (i = e; i > pos; i--) {  /* move up elements */
         lua_geti(L, 1, i - 1);
         lua_seti(L, 1, i);  /* t[i] = t[i - 1] */
@@ -89,7 +91,9 @@
   lua_Integer size = aux_getn(L, 1, TAB_RW);
   lua_Integer pos = luaL_optinteger(L, 2, size);
   if (pos != size)  /* validate 'pos' if given */
-    luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds");
+    /* check whether 'pos' is in [1, size + 1] */
+    luaL_argcheck(L, (lua_Unsigned)pos - 1u <= (lua_Unsigned)size, 1,
+                     "position out of bounds");
   lua_geti(L, 1, pos);  /* result = t[pos] */
   for ( ; pos < size; pos++) {
     lua_geti(L, 1, pos + 1);
diff --git a/testes/utf8.lua b/testes/utf8.lua
index 86ec1b0..b3b7687 100644
--- a/testes/utf8.lua
+++ b/testes/utf8.lua
@@ -123,6 +123,9 @@
 checkerror("continuation byte", utf8.offset, "𦧺", 1, 2)
 checkerror("continuation byte", utf8.offset, "\x80", 1)
 
+-- error in indices for len
+checkerror("out of string", utf8.len, "abc", 0, 2)
+checkerror("out of string", utf8.len, "abc", 1, 4)
 
 
 local s = "hello World"