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

   Copyright (C) 1986-2022 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_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_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);
}
