More checks and documentation for uses of EXTRA_STACK
diff --git a/ldo.c b/ldo.c
index 1349890..419b3db 100644
--- a/ldo.c
+++ b/ldo.c
@@ -602,12 +602,17 @@
 ** Call a function (C or Lua) through C. 'inc' can be 1 (increment
 ** number of recursive invocations in the C stack) or nyci (the same
 ** plus increment number of non-yieldable calls).
+** This function can be called with some use of EXTRA_STACK, so it should
+** check the stack before doing anything else. 'luaD_precall' already
+** does that.
 */
 l_sinline void ccall (lua_State *L, StkId func, int nResults, int inc) {
   CallInfo *ci;
   L->nCcalls += inc;
-  if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
+  if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) {
+    checkstackp(L, 0, func);  /* free any use of EXTRA_STACK */
     luaE_checkcstack(L);
+  }
   if ((ci = luaD_precall(L, func, nResults)) != NULL) {  /* Lua function? */
     ci->callstatus = CIST_FRESH;  /* mark that it is a "fresh" execute */
     luaV_execute(L, ci);  /* call it */
diff --git a/ldo.h b/ldo.h
index 4cbdb84..4661aa0 100644
--- a/ldo.h
+++ b/ldo.h
@@ -37,6 +37,13 @@
 
 
 /* macro to check stack size, preserving 'p' */
+#define checkstackp(L,n,p)  \
+  luaD_checkstackaux(L, n, \
+    ptrdiff_t t__ = savestack(L, p),  /* save 'p' */ \
+    p = restorestack(L, t__))  /* 'pos' part: restore 'p' */
+
+
+/* macro to check stack size and GC, preserving 'p' */
 #define checkstackGCp(L,n,p)  \
   luaD_checkstackaux(L, n, \
     ptrdiff_t t__ = savestack(L, p);  /* save 'p' */ \
diff --git a/lobject.c b/lobject.c
index 301aa90..a2c0060 100644
--- a/lobject.c
+++ b/lobject.c
@@ -386,29 +386,39 @@
 ** ===================================================================
 */
 
-/* size for buffer space used by 'luaO_pushvfstring' */
-#define BUFVFS		200
+/*
+** Size for buffer space used by 'luaO_pushvfstring'. It should be
+** (LUA_IDSIZE + MAXNUMBER2STR) + a minimal space for basic messages,
+** so that 'luaG_addinfo' can work directly on the buffer.
+*/
+#define BUFVFS		(LUA_IDSIZE + MAXNUMBER2STR + 95)
 
 /* buffer used by 'luaO_pushvfstring' */
 typedef struct BuffFS {
   lua_State *L;
-  int pushed;  /* number of string pieces already on the stack */
+  int pushed;  /* true if there is a part of the result on the stack */
   int blen;  /* length of partial string in 'space' */
   char space[BUFVFS];  /* holds last part of the result */
 } BuffFS;
 
 
 /*
-** Push given string to the stack, as part of the buffer, and
-** join the partial strings in the stack into one.
+** Push given string to the stack, as part of the result, and
+** join it to previous partial result if there is one.
+** It may call 'luaV_concat' while using one slot from EXTRA_STACK.
+** This call cannot invoke metamethods, as both operands must be
+** strings. It can, however, raise an error if the result is too
+** long. In that case, 'luaV_concat' frees the extra slot before
+** raising the error.
 */
-static void pushstr (BuffFS *buff, const char *str, size_t l) {
+static void pushstr (BuffFS *buff, const char *str, size_t lstr) {
   lua_State *L = buff->L;
-  setsvalue2s(L, L->top, luaS_newlstr(L, str, l));
-  L->top++;  /* may use one extra slot */
-  buff->pushed++;
-  luaV_concat(L, buff->pushed);  /* join partial results into one */
-  buff->pushed = 1;
+  setsvalue2s(L, L->top, luaS_newlstr(L, str, lstr));
+  L->top++;  /* may use one slot from EXTRA_STACK */
+  if (!buff->pushed)  /* no previous string on the stack? */
+    buff->pushed = 1;  /* now there is one */
+  else  /* join previous string with new one */
+    luaV_concat(L, 2);
 }
 
 
@@ -454,7 +464,7 @@
 
 
 /*
-** Add a number to the buffer.
+** Add a numeral to the buffer.
 */
 static void addnum2buff (BuffFS *buff, TValue *num) {
   char *numbuff = getbuff(buff, MAXNUMBER2STR);
diff --git a/lobject.h b/lobject.h
index 0e05b3e..77cc606 100644
--- a/lobject.h
+++ b/lobject.h
@@ -52,6 +52,8 @@
   lua_CFunction f; /* light C functions */
   lua_Integer i;   /* integer numbers */
   lua_Number n;    /* float numbers */
+  /* not used, but may avoid warnings for uninitialized value */
+  lu_byte ub;
 } Value;
 
 
diff --git a/testes/calls.lua b/testes/calls.lua
index ff72d8f..ee8cce7 100644
--- a/testes/calls.lua
+++ b/testes/calls.lua
@@ -151,6 +151,16 @@
 end
 
 
+do   -- C-stack overflow while handling C-stack overflow
+  local function loop ()
+    assert(pcall(loop))
+  end
+
+  local err, msg = xpcall(loop, loop)
+  assert(not err and string.find(msg, "error"))
+end
+
+
 
 do   -- tail calls x chain of __call
   local n = 10000   -- depth