Merge branch 'master' into nextversion
diff --git a/lauxlib.c b/lauxlib.c
index 8d23bc7..f48060e 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -1043,9 +1043,14 @@
 }
 
 
+/*
+** Standard panic funcion just prints an error message. The test
+** with 'lua_type' avoids possible memory errors in 'lua_tostring'.
+*/
 static int panic (lua_State *L) {
-  const char *msg = lua_tostring(L, -1);
-  if (msg == NULL) msg = "error object is not a string";
+  const char *msg = (lua_type(L, -1) == LUA_TSTRING)
+                  ? lua_tostring(L, -1)
+                  : "error object is not a string";
   lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
                         msg);
   return 0;  /* return to Lua to abort */
diff --git a/ldebug.c b/ldebug.c
index 8b4bd54..aa3277c 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -927,12 +927,12 @@
   }
   pc++;  /* reference is always next instruction */
   ci->u.l.savedpc = pc;  /* save 'pc' */
-  counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT));
+  counthook = (mask & LUA_MASKCOUNT) && (--L->hookcount == 0);
   if (counthook)
     resethookcount(L);  /* reset count */
   else if (!(mask & LUA_MASKLINE))
     return 1;  /* no line hook and count != 0; nothing to be done now */
-  if (ci->callstatus & CIST_HOOKYIELD) {  /* called hook last time? */
+  if (ci->callstatus & CIST_HOOKYIELD) {  /* hook yielded last time? */
     ci->callstatus &= ~CIST_HOOKYIELD;  /* erase mark */
     return 1;  /* do not call hook again (VM yielded, so it did not move) */
   }
@@ -954,7 +954,6 @@
   if (L->status == LUA_YIELD) {  /* did hook yield? */
     if (counthook)
       L->hookcount = 1;  /* undo decrement to zero */
-    ci->u.l.savedpc--;  /* undo increment (resume will increment it again) */
     ci->callstatus |= CIST_HOOKYIELD;  /* mark that it yielded */
     luaD_throw(L, LUA_YIELD);
   }
diff --git a/ldo.c b/ldo.c
index e9f9138..05b14ec 100644
--- a/ldo.c
+++ b/ldo.c
@@ -792,6 +792,10 @@
     lua_assert(L->status == LUA_YIELD);
     L->status = LUA_OK;  /* mark that it is running (again) */
     if (isLua(ci)) {  /* yielded inside a hook? */
+      /* undo increment made by 'luaG_traceexec': instruction was not
+         executed yet */
+      lua_assert(ci->callstatus & CIST_HOOKYIELD);
+      ci->u.l.savedpc--;
       L->top.p = firstArg;  /* discard arguments */
       luaV_execute(L, ci);  /* just continue running Lua code */
     }
diff --git a/lstring.c b/lstring.c
index 8701b70..9570e79 100644
--- a/lstring.c
+++ b/lstring.c
@@ -241,7 +241,7 @@
     return internshrstr(L, str, l);
   else {
     TString *ts;
-    if (l_unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char)))
+    if (l_unlikely(l * sizeof(char) >= (MAX_SIZE - sizeof(TString))))
       luaM_toobig(L);
     ts = luaS_createlngstrobj(L, l);
     memcpy(getlngstr(ts), str, l * sizeof(char));
diff --git a/ltests.c b/ltests.c
index 6de62e5..6081aba 100644
--- a/ltests.c
+++ b/ltests.c
@@ -73,8 +73,9 @@
 
 
 static int tpanic (lua_State *L) {
-  const char *msg = lua_tostring(L, -1);
-  if (msg == NULL) msg = "error object is not a string";
+  const char *msg = (lua_type(L, -1) == LUA_TSTRING)
+                  ? lua_tostring(L, -1)
+                  : "error object is not a string";
   return (badexit("PANIC: unprotected error in call to Lua API (%s)\n",
                    msg, NULL),
           0);  /* do not return to Lua */
diff --git a/lvm.c b/lvm.c
index e4c026f..78e39b7 100644
--- a/lvm.c
+++ b/lvm.c
@@ -655,7 +655,7 @@
       /* collect total length and number of strings */
       for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) {
         size_t l = tsslen(tsvalue(s2v(top - n - 1)));
-        if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) {
+        if (l_unlikely(l >= MAX_SIZE - sizeof(TString) - tl)) {
           L->top.p = top - total;  /* pop strings to avoid wasting stack */
           luaG_runerror(L, "string length overflow");
         }
diff --git a/manual/manual.of b/manual/manual.of
index 42269ff..e3cbddb 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -4552,6 +4552,10 @@
 may be invalidated by the garbage collector if the
 corresponding Lua value is removed from the stack @see{constchar}.
 
+This function can raise memory errors only
+when converting a number to a string
+(as then it may have to create a new string).
+
 }
 
 @APIEntry{lua_Number lua_tonumber (lua_State *L, int index);|
diff --git a/testes/coroutine.lua b/testes/coroutine.lua
index 6c15db0..664ef5f 100644
--- a/testes/coroutine.lua
+++ b/testes/coroutine.lua
@@ -610,18 +610,20 @@
     -- (bug in 5.2/5.3)
     c = coroutine.create(function (a, ...)
       T.sethook("yield 0", "l")   -- will yield on next two lines
-      assert(a == 10)
+      local b = a
       return ...
     end)
 
     assert(coroutine.resume(c, 1, 2, 3))   -- start coroutine
     local n,v = debug.getlocal(c, 0, 1)    -- check its local
-    assert(n == "a" and v == 1)
+    assert(n == "a" and v == 1 and debug.getlocal(c, 0, 2) ~= "b")
     assert(debug.setlocal(c, 0, 1, 10))     -- test 'setlocal'
     local t = debug.getinfo(c, 0)        -- test 'getinfo'
-    assert(t.currentline == t.linedefined + 1)
+    assert(t.currentline == t.linedefined + 2)
     assert(not debug.getinfo(c, 1))      -- no other level
     assert(coroutine.resume(c))          -- run next line
+    local n,v = debug.getlocal(c, 0, 2)    -- check next local
+    assert(n == "b" and v == 10)
     v = {coroutine.resume(c)}         -- finish coroutine
     assert(v[1] == true and v[2] == 2 and v[3] == 3 and v[4] == undef)
     assert(not coroutine.resume(c))