// -*- C++ -*- Manage the thread-local exception globals.
// Copyright (C) 2001-2022 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC 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, or (at your option)
// any later version.
//
// GCC 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.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

#include <bits/c++config.h>
#include <exception>
#include <cstdlib>
#include "cxxabi.h"
#include "unwind-cxx.h"
#include "bits/gthr.h"

#if _GLIBCXX_HOSTED
using std::free;
using std::malloc;
#else
// In a freestanding environment, these functions may not be
// available -- but for now, we assume that they are.
extern "C" void *malloc (std::size_t);
extern "C" void free(void *);
#endif

using namespace __cxxabiv1;

#if _GLIBCXX_HAVE_TLS

namespace
{
  abi::__cxa_eh_globals*
  get_global() _GLIBCXX_NOTHROW
  {
    static __thread abi::__cxa_eh_globals global;
    return &global;
  }
} // anonymous namespace

extern "C" __cxa_eh_globals*
__cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW
{ return get_global(); }

extern "C" __cxa_eh_globals*
__cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
{ return get_global(); }


#else

#if __has_cpp_attribute(clang::require_constant_initialization)
#  define __constinit [[clang::require_constant_initialization]]
#endif

namespace
{
  struct constant_init
  {
    union {
      unsigned char unused;
      __cxa_eh_globals obj;
    };
    constexpr constant_init() : obj() { }

    ~constant_init() { /* do nothing, union member is not destroyed */ }
  };

  // Single-threaded fallback buffer.
  __constinit constant_init eh_globals;
}

#if __GTHREADS

static void
eh_globals_dtor(void* ptr)
{
  if (ptr)
    {
      __cxa_eh_globals* g = reinterpret_cast<__cxa_eh_globals*>(ptr);
      __cxa_exception* exn = g->caughtExceptions;
      __cxa_exception* next;
      while (exn)
	{
	  next = exn->nextException;
	  _Unwind_DeleteException(&exn->unwindHeader);
	  exn = next;
	}
      free(ptr);
    }
}

struct __eh_globals_init
{
  __gthread_key_t  	_M_key;
  static bool 		_S_init;

  __eh_globals_init()
  {
    if (__gthread_active_p())
      _S_init = __gthread_key_create(&_M_key, eh_globals_dtor) == 0;
  }

  ~__eh_globals_init()
  {
    if (_S_init)
      {
	/* Set it before the call, so that, should
	   __gthread_key_delete throw an exception, it won't rely on
	   the key being deleted.  */
	_S_init = false;
	__gthread_key_delete(_M_key);
      }
  }

  __eh_globals_init(const __eh_globals_init&) = delete;
  __eh_globals_init& operator=(const __eh_globals_init&) = delete;
};

bool __eh_globals_init::_S_init = false;

static __eh_globals_init init;

extern "C" __cxa_eh_globals*
__cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW
{
  __cxa_eh_globals* g;
  if (init._S_init)
    g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key));
  else
    g = &eh_globals.obj;
  return g;
}

extern "C" __cxa_eh_globals*
__cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
{
  __cxa_eh_globals* g;
  if (init._S_init)
    {
      g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key));
      if (!g)
	{
	  void* v = malloc(sizeof(__cxa_eh_globals));
	  if (v == 0 || __gthread_setspecific(init._M_key, v) != 0)
	    std::terminate();
	  g = static_cast<__cxa_eh_globals*>(v);
	  g->caughtExceptions = 0;
	  g->uncaughtExceptions = 0;
#ifdef __ARM_EABI_UNWINDER__
	  g->propagatingExceptions = 0;
#endif
	}
    }
  else
    g = &eh_globals.obj;
  return g;
}

#else

extern "C" __cxa_eh_globals*
__cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW
{ return &eh_globals.obj; }

extern "C" __cxa_eh_globals*
__cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
{ return &eh_globals.obj; }

#endif

#endif
