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

   Copyright (C) 1986-2023 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-defs.h"
#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 occured.  */
	  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);
}
