WALA/com.ibm.wala.cast/source/c/include/Exceptions.h

75 lines
2.1 KiB
C++
Executable File

#ifndef EXCEPTIONS_H
#define EXCEPTIONS_H
/**
* The combination of the macroes and the Exceptions class declared
* in this file is used to provide a (shaky) veneer of exception handling
* to JNI code.
*
* The idea is that a C function called from JNI will be enclosed with
* TRY/CATCH macroes, and the CPP_EXP_NAME variable defined will be passed
* to callees who might want to throw an exception. The callees will use
* the THROW macro to throw exceptions. When a THROW is executed, control
* is transferred to the CATCH, and a RuntimeException is thrown to the
* calling Java code when the C code returns.
*
* WARNING: this is C code, so you should know better than to expect any
* kind of robust, high-level exception-handling semantics. The way to use
* this code is to put a TRY/CATCH combination in the JNI entry point, to do
* only trivial things after the CATCH, and to use only THROW anywhere else.
*
* The implementation does the obvious dance with setjmp and longjmp, which
* is one reason it is rather shaky. For instance, TRY has to be a macro,
* because otherwise the jump buffer would be invalidated when the TRY function
* returned.
*/
#include <jni.h>
extern "C" {
#include <setjmp.h>
}
#define TRY(CPP_EXP_NAME, JAVA_ENV_VAR) \
{ jmp_buf jump_buffer; \
if (setjmp(jump_buffer) == 0) { \
Exceptions CPP_EXP_NAME(JAVA_ENV_VAR, jump_buffer);
#define CATCH() \
} \
} \
#define THROW(CPP_EXP_NAME, MESSAGE) \
(CPP_EXP_NAME).throwException(__FILE__, __LINE__, MESSAGE)
#define THROW_ANY_EXCEPTION(CPP_EXP_NAME) \
(CPP_EXP_NAME).throwAnyException(__FILE__, __LINE__)
#ifdef _MSC_VER
#ifdef BUILD_CAST_DLL
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif
class DLLEXPORT Exceptions {
#else
class Exceptions {
#endif
private:
JNIEnv *_java_env;
jmp_buf& _c_env;
jclass _jre;
jmethodID _ctr;
jmethodID _wrapper_ctr;
public:
Exceptions(JNIEnv *java_env, jmp_buf& c_env);
void throwException(char *file_name, int line_number);
void throwAnyException(char *file_name, int line_number);
void throwException(char *file_name, int line_number, char *c_message);
};
#endif