diff --git a/lauxlib.c b/lauxlib.c
index e4b12587..d37d2f8c 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -170,19 +170,27 @@ LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
 
 LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) {
   lua_Debug ar;
+  const char *argword;
   if (!lua_getstack(L, 0, &ar))  /* no stack frame? */
     return luaL_error(L, "bad argument #%d (%s)", arg, extramsg);
-  lua_getinfo(L, "n", &ar);
-  if (strcmp(ar.namewhat, "method") == 0) {
-    arg--;  /* do not count 'self' */
-    if (arg == 0)  /* error is in the self argument itself? */
-      return luaL_error(L, "calling '%s' on bad self (%s)",
-                           ar.name, extramsg);
+  lua_getinfo(L, "nt", &ar);
+  if (arg <= ar.extraargs)  /* error in an extra argument? */
+    argword =  "extra argument";
+  else {
+    arg -= ar.extraargs;  /* do not count extra arguments */
+    if (strcmp(ar.namewhat, "method") == 0) {  /* colon syntax? */
+      arg--;  /* do not count (extra) self argument */
+      if (arg == 0)  /* error in self argument? */
+        return luaL_error(L, "calling '%s' on bad self (%s)",
+                               ar.name, extramsg);
+      /* else go through; error in a regular argument */
+    }
+    argword = "argument";
   }
   if (ar.name == NULL)
     ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";
-  return luaL_error(L, "bad argument #%d to '%s' (%s)",
-                        arg, ar.name, extramsg);
+  return luaL_error(L, "bad %s #%d to '%s' (%s)",
+                       argword, arg, ar.name, extramsg);
 }
 
 
diff --git a/ldblib.c b/ldblib.c
index a0a06dd7..c7b74812 100644
--- a/ldblib.c
+++ b/ldblib.c
@@ -191,8 +191,10 @@ static int db_getinfo (lua_State *L) {
     settabsi(L, "ftransfer", ar.ftransfer);
     settabsi(L, "ntransfer", ar.ntransfer);
   }
-  if (strchr(options, 't'))
+  if (strchr(options, 't')) {
     settabsb(L, "istailcall", ar.istailcall);
+    settabsi(L, "extraargs", ar.extraargs);
+  }
   if (strchr(options, 'L'))
     treatstackoption(L, L1, "activelines");
   if (strchr(options, 'f'))
diff --git a/ldebug.c b/ldebug.c
index d1b47c56..ee3ac17f 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -352,7 +352,15 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
         break;
       }
       case 't': {
-        ar->istailcall = (ci != NULL && (ci->callstatus & CIST_TAIL));
+        if (ci != NULL) {
+          ar->istailcall = !!(ci->callstatus & CIST_TAIL);
+          ar->extraargs =
+                   cast_uchar((ci->callstatus & MAX_CCMT) >> CIST_CCMT);
+        }
+        else {
+          ar->istailcall = 0;
+          ar->extraargs = 0;
+        }
         break;
       }
       case 'n': {
diff --git a/ltests.c b/ltests.c
index 8191f14a..3edf805e 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1900,6 +1900,10 @@ static struct X { int x; } x;
     else if EQ("closeslot") {
       lua_closeslot(L1, getnum);
     }
+    else if EQ("argerror") {
+      int arg = getnum;
+      luaL_argerror(L1, arg, getstring);
+    }
     else luaL_error(L, "unknown instruction %s", buff);
   }
   return 0;
diff --git a/lua.h b/lua.h
index 5fbc9d34..aefa3b8c 100644
--- a/lua.h
+++ b/lua.h
@@ -504,6 +504,7 @@ struct lua_Debug {
   unsigned char nups;	/* (u) number of upvalues */
   unsigned char nparams;/* (u) number of parameters */
   char isvararg;        /* (u) */
+  unsigned char extraargs;  /* (t) number of extra arguments */
   char istailcall;	/* (t) */
   int ftransfer;   /* (r) index of first value transferred */
   int ntransfer;   /* (r) number of transferred values */
diff --git a/manual/manual.of b/manual/manual.of
index ce42ff51..a441cea1 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -4850,6 +4850,7 @@ typedef struct lua_Debug {
   unsigned char nups;         /* (u) number of upvalues */
   unsigned char nparams;      /* (u) number of parameters */
   char isvararg;              /* (u) */
+  unsigned char extraargs;    /* (t) number of extra arguments */
   char istailcall;            /* (t) */
   int ftransfer;              /* (r) index of first value transferred */
   int ntransfer;              /* (r) number of transferred values */
@@ -4938,6 +4939,14 @@ true if this function invocation was called by a tail call.
 In this case, the caller of this level is not in the stack.
 }
 
+@item{@id{extraargs}|
+The number of extra arguments added by the call
+to functions called through @idx{__call} metamethods.
+(Each @idx{__call} metavalue adds a single extra argument,
+the object being called,
+but there may be a chain of @idx{__call} metavalues.)
+}
+
 @item{@id{nups}|
 the number of upvalues of the function.
 }
@@ -5045,7 +5054,7 @@ fills in the fields @id{source}, @id{short_src},
 @id{linedefined}, @id{lastlinedefined}, and @id{what};
 }
 
-@item{@Char{t}| fills in the field @id{istailcall};
+@item{@Char{t}| fills in the fields @id{istailcall} and @id{extraargs};
 }
 
 @item{@Char{u}| fills in the fields
@@ -7993,7 +8002,7 @@ returns @fail plus the position of the first invalid byte.
 
 @LibEntry{utf8.offset (s, n [, i])|
 
-Returns the the position of the @id{n}-th character of @id{s}
+Returns the position of the @id{n}-th character of @id{s}
 (counting from byte position @id{i}) as two integers:
 The index (in bytes) where its encoding starts and the
 index (in bytes) where it ends.
diff --git a/testes/calls.lua b/testes/calls.lua
index 12312d60..31028215 100644
--- a/testes/calls.lua
+++ b/testes/calls.lua
@@ -204,6 +204,17 @@ do   print"testing chains of '__call'"
     assert(Res[i][1] == i)
   end
   assert(Res[N + 1] == "a" and Res[N + 2] == "b" and Res[N + 3] == "c")
+
+  local function u (...)
+    local n = debug.getinfo(1, 't').extraargs
+    assert(select("#", ...) == n)
+    return n
+  end
+
+  for i = 0, N do
+    assert(u() == i)
+    u = setmetatable({}, {__call = u})
+  end
 end
 
 
diff --git a/testes/db.lua b/testes/db.lua
index 49ff8e3e..fc0db9ea 100644
--- a/testes/db.lua
+++ b/testes/db.lua
@@ -624,6 +624,9 @@ local function f (x)
     end
 end
 
+assert(debug.getinfo(print, 't').istailcall == false)
+assert(debug.getinfo(print, 't').extraargs == 0)
+
 function g(x) return f(x) end
 
 function g1(x) g(x) end
diff --git a/testes/errors.lua b/testes/errors.lua
index 80d91a92..0925fe58 100644
--- a/testes/errors.lua
+++ b/testes/errors.lua
@@ -117,6 +117,31 @@ else
     return 1
   ]]
   assert(string.find(res, "xuxu.-main chunk"))
+
+  do   -- tests for error messages about extra arguments from __call
+    local function createobj (n)
+      -- function that raises an error on its n-th argument
+      local code = string.format("argerror %d 'msg'", n)
+      local func = T.makeCfunc(code)
+      -- create a chain of 2 __call objects
+      local M = setmetatable({}, {__call = func})
+      M = setmetatable({}, {__call = M})
+      -- put it as a method for a new object
+      return {foo = M}
+    end
+
+  _G.a = createobj(1)   -- error in first (extra) argument
+  checkmessage("a:foo()", "bad extra argument #1")
+
+  _G.a = createobj(2)   -- error in second (extra) argument
+  checkmessage("a:foo()", "bad extra argument #2")
+
+  _G.a = createobj(3)   -- error in self (after two extra arguments)
+  checkmessage("a:foo()", "bad self")
+
+  _G.a = createobj(4)  -- error in first regular argument (after self)
+  checkmessage("a:foo()", "bad argument #1")
+  end
 end