BUG/MAJOR: lua: some function are not yieldable, the forced yield causes errors

The hook function called each nth Lua instructions just
do a yield. Sometimes this yield is not allowed, because
some functions are not compatible.

The Lua-5.3 permits to known if the yield is avalaible with
the function lua_isyieldable().

If the processing is interrupted in non yieldable state,
we try to execute a yield asap. The yield will be may
available at the end of the non-yieldable currently
executed function. So, we require interrupt at the end
of the current function.

But, Lua cannot yield when its returning from a function,
so, we can fix the interrupt hook to 1 instruction,
expecting that the function is finnished.

During this time, the execution timeout is always checked.
diff --git a/src/hlua.c b/src/hlua.c
index e3769a0..0923cfd 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -644,7 +644,36 @@
 
 void hlua_hook(lua_State *L, lua_Debug *ar)
 {
-	hlua_yieldk(L, 0, 0, NULL, TICK_ETERNITY, HLUA_CTRLYIELD);
+	struct hlua *hlua = hlua_gethlua(L);
+
+	/* Lua cannot yield when its returning from a function,
+	 * so, we can fix the interrupt hook to 1 instruction,
+	 * expecting that the function is finnished.
+	 */
+	if (lua_gethookmask(L) & LUA_MASKRET) {
+		lua_sethook(hlua->T, hlua_hook, LUA_MASKCOUNT, 1);
+		return;
+	}
+
+	/* restore the interrupt condition. */
+	lua_sethook(hlua->T, hlua_hook, LUA_MASKCOUNT, hlua_nb_instruction);
+
+	/* If we interrupt the Lua processing in yieldable state, we yield.
+	 * If the state is not yieldable, trying yield causes an error.
+	 */
+	if (lua_isyieldable(L))
+		WILL_LJMP(hlua_yieldk(L, 0, 0, NULL, TICK_ETERNITY, HLUA_CTRLYIELD));
+
+	/* If we cannot yield, check the timeout. */
+	if (tick_is_expired(hlua->expire, now_ms)) {
+		lua_pushfstring(L, "execution timeout");
+		WILL_LJMP(lua_error(L));
+	}
+
+	/* Try to interrupt the process at the end of the current
+	 * unyieldable function.
+	 */
+	lua_sethook(hlua->T, hlua_hook, LUA_MASKRET|LUA_MASKCOUNT, hlua_nb_instruction);
 }
 
 /* This function start or resumes the Lua stack execution. If the flag