/* -*- Mode: C; c-file-style: "gnu" -*-
   jvmdiev.c -- JVMDI Event Functions
   Created: Hernan Otero <hernan_otero@bigfoot.com>, 18-Jul-1998.
 */
/*
  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) 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 "jvmdiint.h"
#include "interp.h"
#include "objects.h"
#include "log.h"

#include <stdlib.h>
#include <assert.h>

#define MYLOG "JVMDI"

static JVMDI_EventHook jvmdi_hook;

JNIEXPORT jvmdiError JNICALL
JVMDI_SetEventHook(JNIEnv *env,
		   JVMDI_EventHook hook)
{
  assert(env != NULL);
  jvmdi_hook = hook;
  return JVMDI_ERROR_NONE;
}

JNIEXPORT void JNICALL
jvmdi_SingleStepEvent(JNIEnv *env,
		      jthread thread,
		      jclass clazz,
		      jmethodID method,
		      jint location)
{
  if (jvmdi_hook)
    {
      JVMDI_Event event;
      event.kind = JVMDI_EVENT_SINGLE_STEP;
      event.u.single_step.thread = thread;
      event.u.single_step.clazz = clazz;
      event.u.single_step.method = method;
      event.u.single_step.location = location;

      (*jvmdi_hook)(env, &event);
    }
}

JNIEXPORT void JNICALL
jvmdi_BreakpointEvent(JNIEnv *env,
		      jthread thread,
		      jclass clazz,
		      jmethodID method,
		      jint location)
{
  if (jvmdi_hook)
    {
      JVMDI_Event event;
      event.kind = JVMDI_EVENT_BREAKPOINT;
      event.u.breakpoint.thread = thread;
      event.u.breakpoint.clazz = clazz;
      event.u.breakpoint.method = method;
      event.u.breakpoint.location = location;

      (*jvmdi_hook)(env, &event);
    }
}

JNIEXPORT void JNICALL
jvmdi_FramePopEvent(JNIEnv *env,
		    jthread thread,
		    jframeID frame)
{
  if (jvmdi_hook)
    {
      JVMDI_Event event;
      event.kind = JVMDI_EVENT_FRAME_POP;
      event.u.frame_pop.thread = thread;
      event.u.frame_pop.frame = frame;

      (*jvmdi_hook)(env, &event);
    }
}

JNIEXPORT void JNICALL
jvmdi_ExceptionEvent(JNIEnv *env,
		     jthread thread,
		     jclass clazz,
		     jmethodID method,
		     jint location,
		     jobject exception,
		     jclass catch_clazz,
		     jmethodID catch_method,
		     jint catch_location)
{
  if (jvmdi_hook)
    {
      JVMDI_Event event;
      event.kind = JVMDI_EVENT_EXCEPTION;
      event.u.exception.thread = thread;
      event.u.exception.clazz = clazz;
      event.u.exception.method = method;
      event.u.exception.location = location;
      event.u.exception.exception = exception;
      event.u.exception.catch_clazz = catch_clazz;
      event.u.exception.catch_method = catch_method;
      event.u.exception.catch_location = catch_location;

      (*jvmdi_hook)(env, &event);
    }
}

JNIEXPORT void JNICALL
jvmdi_UserEvent(JNIEnv *env,
		jobject object,
		jint key)
{
  if (jvmdi_hook)
    {
      JVMDI_Event event;
      event.kind = JVMDI_EVENT_USER_DEFINED;
      event.u.user.object = object;
      event.u.user.key = key;

      (*jvmdi_hook)(env, &event);
    }
}

JNIEXPORT void JNICALL
jvmdi_ThreadEndEvent(JNIEnv *env,
		     jthread thread)
{
  if (jvmdi_hook)
    {
      JVMDI_Event event;
      event.kind = JVMDI_EVENT_THREAD_END;
      event.u.thread_change.thread = thread;

      (*jvmdi_hook)(env, &event);
    }
}

JNIEXPORT void JNICALL
jvmdi_ThreadStartEvent(JNIEnv *env,
		       jthread thread)
{
  if (jvmdi_hook)
    {
      JVMDI_Event event;
      event.kind = JVMDI_EVENT_THREAD_START;
      event.u.thread_change.thread = thread;

      (*jvmdi_hook)(env, &event);
    }
}
