From 7a1bf87c6e856bbccc6b771834588803f518cd54 Mon Sep 17 00:00:00 2001 From: Kyle Galloway Date: Fri, 16 Feb 2007 00:05:39 +0000 Subject: interpret.cc (_Jv_InterpMethod::check_handler): New method. 2007-02-15 Kyle Galloway * interpret.cc (_Jv_InterpMethod::check_handler): New method. * interpret-run.cc: Change the catch section to report exception events and to use the new check_handler method. * include/java-interp.h (_Jv_InterpMethod): Add check_handler. * gnu/gcj/jvmti/ExceptionEvent.java: New file. * gnu/gcj/jvmti/ExceptionEvent.h: New file. * gnu/gcj/jvmti/natExceptionEvent.cc: New file. * libjava/classpath/lib/gnu/gcj/jvmti/ExceptionEvent.class: New file. * sources.am: Added ExceptionEvent.java. * Makefile.am: Added natExceptionEvent.cc * Makefile.in: Regenerated. * include/Makefile.in: Regenerated. * gcj/Makefile.in: Regenerated. From-SVN: r122019 --- libjava/interpret.cc | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'libjava/interpret.cc') diff --git a/libjava/interpret.cc b/libjava/interpret.cc index 8a4edac..dbd5323 100644 --- a/libjava/interpret.cc +++ b/libjava/interpret.cc @@ -43,6 +43,7 @@ details. */ #include #include #include +#include #ifdef INTERPRETER @@ -1366,6 +1367,51 @@ _Jv_InterpMethod::insn_index (pc_t pc) return -1; } +// Method to check if an exception is caught at some location in a method +// (meth). Returns true if this method (meth) contains a catch block for the +// exception (ex). False otherwise. If there is a catch block, it sets the pc +// to the location of the beginning of the catch block. +jboolean +_Jv_InterpMethod::check_handler (pc_t *pc, _Jv_InterpMethod *meth, + java::lang::Throwable *ex) +{ +#ifdef DIRECT_THREADED + void *logical_pc = (void *) ((insn_slot *) (*pc) - 1); +#else + int logical_pc = (*pc) - 1 - meth->bytecode (); +#endif + _Jv_InterpException *exc = meth->exceptions (); + jclass exc_class = ex->getClass (); + + for (int i = 0; i < meth->exc_count; i++) + { + if (PCVAL (exc[i].start_pc) <= logical_pc + && logical_pc < PCVAL (exc[i].end_pc)) + { +#ifdef DIRECT_THREADED + jclass handler = (jclass) exc[i].handler_type.p; +#else + jclass handler = NULL; + if (exc[i].handler_type.i != 0) + handler + = (_Jv_Linker::resolve_pool_entry (meth->defining_class, + ex$ +#endif /* DIRECT_THREADED */ + if (handler == NULL || handler->isAssignableFrom (exc_class)) + { +#ifdef DIRECT_THREADED + (*pc) = (insn_slot *) exc[i].handler_pc.p; +#else + (*pc) = meth->bytecode () + exc[i].handler_pc.i; +#endif /* DIRECT_THREADED */ + return true; + } + } + } + return false; +} + + void _Jv_InterpMethod::get_line_table (jlong& start, jlong& end, jintArray& line_numbers, -- cgit v1.1