/* Exception (throw catch) mechanism, for GDB, the GNU debugger.

   Copyright (C) 1986-2024 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "common-exceptions.h"
#include <forward_list>

/* Possible catcher states.  */
enum catcher_state {
  /* Initial state, a new catcher has just been created.  */
  CATCHER_CREATED,
  /* The catch code is running.  */
  CATCHER_RUNNING,
  CATCHER_RUNNING_1,
  /* The catch code threw an exception.  */
  CATCHER_ABORTING
};

/* Possible catcher actions.  */
enum catcher_action {
  CATCH_ITER,
  CATCH_ITER_1,
  CATCH_THROWING
};

struct catcher
{
  enum catcher_state state = CATCHER_CREATED;
  /* Jump buffer pointing back at the exception handler.  */
  jmp_buf buf;
  /* Status buffer belonging to the exception handler.  */
  struct gdb_exception exception;
};

/* Where to go for throw_exception().  */
static std::forward_list<struct catcher> catchers;

jmp_buf *
exceptions_state_mc_init ()
{
  catchers.emplace_front ();
  return &catchers.front ().buf;
}

/* Catcher state machine.  Returns non-zero if the m/c should be run
   again, zero if it should abort.  */

static int
exceptions_state_mc (enum catcher_action action)
{
  switch (catchers.front ().state)
    {
    case CATCHER_CREATED:
      switch (action)
	{
	case CATCH_ITER:
	  /* Allow the code to run the catcher.  */
	  catchers.front ().state = CATCHER_RUNNING;
	  return 1;
	default:
	  internal_error (_("bad state"));
	}
    case CATCHER_RUNNING:
      switch (action)
	{
	case CATCH_ITER:
	  /* No error/quit has occurred.  */
	  return 0;
	case CATCH_ITER_1:
	  catchers.front ().state = CATCHER_RUNNING_1;
	  return 1;
	case CATCH_THROWING:
	  catchers.front ().state = CATCHER_ABORTING;
	  /* See also throw_exception.  */
	  return 1;
	default:
	  internal_error (_("bad switch"));
	}
    case CATCHER_RUNNING_1:
      switch (action)
	{
	case CATCH_ITER:
	  /* The did a "break" from the inner while loop.  */
	  return 0;
	case CATCH_ITER_1:
	  catchers.front ().state = CATCHER_RUNNING;
	  return 0;
	case CATCH_THROWING:
	  catchers.front ().state = CATCHER_ABORTING;
	  /* See also throw_exception.  */
	  return 1;
	default:
	  internal_error (_("bad switch"));
	}
    case CATCHER_ABORTING:
      switch (action)
	{
	case CATCH_ITER:
	  {
	    /* Exit normally if this catcher can handle this
	       exception.  The caller analyses the func return
	       values.  */
	    return 0;
	  }
	default:
	  internal_error (_("bad state"));
	}
    default:
      internal_error (_("bad switch"));
    }
}

int
exceptions_state_mc_catch (struct gdb_exception *exception,
			   int mask)
{
  *exception = std::move (catchers.front ().exception);
  catchers.pop_front ();

  if (exception->reason < 0)
    {
      if (mask & RETURN_MASK (exception->reason))
	{
	  /* Exit normally and let the caller handle the
	     exception.  */
	  return 1;
	}

      /* The caller didn't request that the event be caught, relay the
	 event to the next exception_catch/CATCH_SJLJ.  */
      throw_exception_sjlj (*exception);
    }

  /* No exception was thrown.  */
  return 0;
}

int
exceptions_state_mc_action_iter (void)
{
  return exceptions_state_mc (CATCH_ITER);
}

int
exceptions_state_mc_action_iter_1 (void)
{
  return exceptions_state_mc (CATCH_ITER_1);
}

/* Return EXCEPTION to the nearest containing CATCH_SJLJ block.  */

void
throw_exception_sjlj (const struct gdb_exception &exception)
{
  /* Jump to the nearest CATCH_SJLJ block, communicating REASON to
     that call via setjmp's return value.  Note that REASON can't be
     zero, by definition in common-exceptions.h.  */
  exceptions_state_mc (CATCH_THROWING);
  enum return_reason reason = exception.reason;
  catchers.front ().exception = exception;
  longjmp (catchers.front ().buf, reason);
}

/* Implementation of throw_exception that uses C++ try/catch.  */

void
throw_exception (gdb_exception &&exception)
{
  if (exception.reason == RETURN_QUIT)
    throw gdb_exception_quit (std::move (exception));
  else if (exception.reason == RETURN_FORCED_QUIT)
    throw gdb_exception_forced_quit (std::move (exception));
  else if (exception.reason == RETURN_ERROR)
    throw gdb_exception_error (std::move (exception));
  else
    gdb_assert_not_reached ("invalid return reason");
}

static void ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0)
throw_it (enum return_reason reason, enum errors error, const char *fmt,
	  va_list ap)
{
  if (reason == RETURN_QUIT)
    throw gdb_exception_quit (fmt, ap);
  else if (reason == RETURN_FORCED_QUIT)
    throw gdb_exception_forced_quit (fmt, ap);
  else if (reason == RETURN_ERROR)
    throw gdb_exception_error (error, fmt, ap);
  else
    gdb_assert_not_reached ("invalid return reason");
}

void
throw_verror (enum errors error, const char *fmt, va_list ap)
{
  throw_it (RETURN_ERROR, error, fmt, ap);
}

void
throw_vquit (const char *fmt, va_list ap)
{
  throw_it (RETURN_QUIT, GDB_NO_ERROR, fmt, ap);
}

void
throw_error (enum errors error, const char *fmt, ...)
{
  va_list args;

  va_start (args, fmt);
  throw_verror (error, fmt, args);
  va_end (args);
}

void
throw_quit (const char *fmt, ...)
{
  va_list args;

  va_start (args, fmt);
  throw_vquit (fmt, args);
  va_end (args);
}

void
throw_forced_quit (const char *fmt, ...)
{
  va_list args;

  va_start (args, fmt);
  throw_it (RETURN_FORCED_QUIT, GDB_NO_ERROR, fmt, args);
  va_end (args);
}
