/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode:nil -*-
   jnithrow.c -- Java Native Interface methods relating to exceptions.
   Created: Chris Toshok <toshok@hungry.com>, 26-Jul-1997
 */
/*
  This file is part of Japhar, the GNU Virtual Machine for Java Bytecodes.
  Japhar is a project of The Hungry Programmers, GNU, and OryxSoft.

  Copyright (C) 1997, 1998, 1999 The Hungry Programmers

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

  This library 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
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "jniint.h"
#include "ClazzFile.h"

jint
JNIFUNC(Throw)(JNIEnv *env,
               jthrowable obj)
{
  HungryEnv *henv = JNIEnvToHEnv(env);

  if (henv->_exception != NULL)
    {
      return -1;
    }
  else
    {
      ExceptionInfo *exc_info;

      henv->_exception = (*env)->NewGlobalRef(env, obj);

      if (!HVM_ObjectGetNativeState(henv->_exception))
        {
          exc_info = (ExceptionInfo*)PR_CALLOC(sizeof(ExceptionInfo));
          HVM_ObjectSetNativeState(henv->_exception, exc_info);
        }

      return 0;
    }
}

jint
JNIFUNC(ThrowNew)(JNIEnv *env,
                  jclass clazz,
                  const char *message)
{
  HungryEnv *henv = JNIEnvToHEnv(env);
  ClazzFile *cf = jclass_to_clazzfile(henv, clazz);
  japhar_object *exc = HVM_ExceptionCreate(henv, cf, message);

  henv->_exception = (*env)->NewGlobalRef(env, exc);

  return 0;
}

jthrowable
JNIFUNC(ExceptionOccurred)(JNIEnv *env)
{
  HungryEnv *henv = JNIEnvToHEnv(env);

  return henv->_exception;
}

void
JNIFUNC(ExceptionDescribe)(JNIEnv *env)
{
  HungryEnv *henv = JNIEnvToHEnv(env);
  jobject exception = henv->_exception;

  /* if there really wasn't an exception, just return. */
  if (!exception) return;

  toplevel_exception_handler(henv, exception);
}
    
void
JNIFUNC(ExceptionClear)(JNIEnv *env)
{
  HungryEnv *henv = JNIEnvToHEnv(env);

  if (henv->_exception)
    (*env)->DeleteGlobalRef(env, henv->_exception);

  henv->_exception = NULL;
}

void
JNIFUNC(FatalError)(JNIEnv *env,
                    const char *msg)
{
  abort_with_message(msg);
}
