/* Do the work for 'lua_resume' in protected mode. Most of the work depends on the status of the coroutine: initial state, suspended inside a hook, or regularly suspended (optionally with a continuation function), plus erroneous cases: non-suspended coroutine or dead coroutine.  */
static void resume(lua_State *L, void *ud)
/* Do the work for 'lua_resume' in protected mode. Most of the work depends on the status of the coroutine: initial state, suspended inside a hook, or regularly suspended (optionally with a continuation function), plus erroneous cases: non-suspended coroutine or dead coroutine.  */
static void resume(lua_State *L, void *ud)
{
    if (!luaD_precall(L, firstArg - 1, LUA_MULTRET))
      luaV_execute(L);
  }
  else {
    lua_assert(L->status == LUA_YIELD);
    L->status = LUA_OK;
    ci->func = restorestack(L, ci->extra);
    if (isLua(ci))
      luaV_execute(L);
    else {
      if (ci->u.c.k != NULL) {
        lua_unlock(L);
        n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx);
        lua_lock(L);
        api_checknelems(L, n);
        firstArg = L->top - n;
      }
      luaD_poscall(L, ci, firstArg, n);
    }
    unroll(L, NULL);
  }
}