lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I wrote:
> Currently LJ2 happily misinterprets negative indexes for these
> functions. Sooo ... what to do? I guess I'll have to bite the
> bullet and support some undefined behavior, too. :-/
> 
> Patch will follow shortly.

Ok, here it is. Timm, can you please check whether this fixes
your original problem? Thank you!

--Mike
--- a/src/lib_aux.c
+++ b/src/lib_aux.c
@@ -24,6 +24,11 @@
 #define abs_index(L, i) \
   ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1)
 
+static LJ_AINLINE int abs_narg(lua_State *L, int narg)
+{
+  return LJ_LIKELY(narg >= 0) ? narg : (L->top - L->base) + narg + 1;
+}
+
 /* -- Type checks --------------------------------------------------------- */
 
 LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
@@ -34,18 +39,19 @@ LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
 
 LUALIB_API void luaL_checktype(lua_State *L, int narg, int tt)
 {
+  narg = abs_narg(L, narg);
   if (lua_type(L, narg) != tt)
     lj_err_argt(L, narg, tt);
 }
 
 LUALIB_API void luaL_checkany(lua_State *L, int narg)
 {
-  lj_lib_checkany(L, narg);
+  lj_lib_checkany(L, abs_narg(L, narg));
 }
 
 LUALIB_API const char *luaL_checklstring(lua_State *L, int narg, size_t *len)
 {
-  GCstr *s = lj_lib_checkstr(L, narg);
+  GCstr *s = lj_lib_checkstr(L, abs_narg(L, narg));
   if (len != NULL) *len = s->len;
   return strdata(s);
 }
@@ -53,7 +59,7 @@ LUALIB_API const char *luaL_checklstring(lua_State *L, int narg, size_t *len)
 LUALIB_API const char *luaL_optlstring(lua_State *L, int narg,
 				       const char *def, size_t *len)
 {
-  GCstr *s = lj_lib_optstr(L, narg);
+  GCstr *s = lj_lib_optstr(L, abs_narg(L, narg));
   if (s) {
     if (len != NULL) *len = s->len;
     return strdata(s);
@@ -64,11 +70,12 @@ LUALIB_API const char *luaL_optlstring(lua_State *L, int narg,
 
 LUALIB_API lua_Number luaL_checknumber(lua_State *L, int narg)
 {
-  return lj_lib_checknum(L, narg);
+  return lj_lib_checknum(L, abs_narg(L, narg));
 }
 
 LUALIB_API lua_Number luaL_optnumber(lua_State *L, int narg, lua_Number def)
 {
+  narg = abs_narg(L, narg);
   lj_lib_opt(L, narg,
     return lj_lib_checknum(L, narg);
   ,
@@ -79,14 +86,15 @@ LUALIB_API lua_Number luaL_optnumber(lua_State *L, int narg, lua_Number def)
 LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int narg)
 {
 #if LJ_64
-  return (lua_Integer)lj_lib_checknum(L, narg);
+  return (lua_Integer)lj_lib_checknum(L, abs_narg(L, narg));
 #else
-  return lj_lib_checkint(L, narg);
+  return lj_lib_checkint(L, abs_narg(L, narg));
 #endif
 }
 
 LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int narg, lua_Integer def)
 {
+  narg = abs_narg(L, narg);
 #if LJ_64
   lj_lib_opt(L, narg,
     return (lua_Integer)lj_lib_checknum(L, narg);
@@ -101,9 +109,12 @@ LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int narg, lua_Integer def)
 LUALIB_API int luaL_checkoption(lua_State *L, int narg, const char *def,
 				const char *const lst[])
 {
-  GCstr *s = lj_lib_optstr(L, narg);
-  const char *opt = s ? strdata(s) : def;
+  GCstr *s;
+  const char *opt;
   uint32_t i;
+  narg = abs_narg(L, narg);
+  s = lj_lib_optstr(L, narg);
+  opt = s ? strdata(s) : def;
   if (!opt) lj_err_argt(L, narg, LUA_TSTRING);
   for (i = 0; lst[i]; i++)
     if (strcmp(lst[i], opt) == 0)