@ -176,15 +176,11 @@ void cli_dbgmsg_internal(const char *str, ...);
class ScopedExceptionHandler {
class ScopedExceptionHandler {
public :
public :
bool Set ( ) {
jmp_buf & getEnv ( ) { return env ; }
if ( setjmp ( env ) = = 0 ) {
void Set ( ) {
/* set the exception handler's return location to here for the
/* set the exception handler's return location to here for the
* current thread */
* current thread */
ExceptionReturn . set ( ( const jmp_buf * ) & env ) ;
ExceptionReturn . set ( ( const jmp_buf * ) & env ) ;
return true ;
}
cli_warnmsg ( " [JIT]: recovered from error \n " ) ;
return false ;
}
}
~ ScopedExceptionHandler ( ) {
~ ScopedExceptionHandler ( ) {
/* leaving scope, remove exception handler for current thread */
/* leaving scope, remove exception handler for current thread */
@ -193,10 +189,17 @@ class ScopedExceptionHandler {
private :
private :
jmp_buf env ;
jmp_buf env ;
} ;
} ;
# define HANDLER_TRY(handler) \
if ( setjmp ( handler . getEnv ( ) ) = = 0 ) { \
handler . Set ( ) ;
# define HANDLER_END(handler) \
} else cli_warnmsg ( " [Bytecode JIT]: recovered from error \n " ) ;
void do_shutdown ( ) {
void do_shutdown ( ) {
ScopedExceptionHandler handler ;
ScopedExceptionHandler handler ;
if ( handler . Set ( ) ) {
HANDLER_TRY ( handler ) {
// TODO: be on the safe side, and clear errors here,
// TODO: be on the safe side, and clear errors here,
// otherwise destructor calls report_fatal_error
// otherwise destructor calls report_fatal_error
( ( class raw_fd_ostream & ) errs ( ) ) . clear_error ( ) ;
( ( class raw_fd_ostream & ) errs ( ) ) . clear_error ( ) ;
@ -205,6 +208,7 @@ void do_shutdown() {
( ( class raw_fd_ostream & ) errs ( ) ) . clear_error ( ) ;
( ( class raw_fd_ostream & ) errs ( ) ) . clear_error ( ) ;
}
}
HANDLER_END ( handler ) ;
remove_fatal_error_handler ( ) ;
remove_fatal_error_handler ( ) ;
}
}
@ -1836,12 +1840,13 @@ static int bytecode_execute(intptr_t code, struct cli_bc_ctx *ctx)
{
{
ScopedExceptionHandler handler ;
ScopedExceptionHandler handler ;
// execute;
// execute;
if ( handler . Set ( ) ) {
HANDLER_TRY ( handler ) {
// setup exception handler to longjmp back here
// setup exception handler to longjmp back here
uint32_t result = ( ( uint32_t ( * ) ( struct cli_bc_ctx * ) ) ( intptr_t ) code ) ( ctx ) ;
uint32_t result = ( ( uint32_t ( * ) ( struct cli_bc_ctx * ) ) ( intptr_t ) code ) ( ctx ) ;
* ( uint32_t * ) ctx - > values = result ;
* ( uint32_t * ) ctx - > values = result ;
return 0 ;
return 0 ;
}
}
HANDLER_END ( handler ) ;
cli_warnmsg ( " [Bytecode JIT]: JITed code intercepted runtime error! \n " ) ;
cli_warnmsg ( " [Bytecode JIT]: JITed code intercepted runtime error! \n " ) ;
return CL_EBYTECODE ;
return CL_EBYTECODE ;
}
}
@ -1943,10 +1948,7 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
ScopedExceptionHandler handler ;
ScopedExceptionHandler handler ;
LLVMApiScopedLock scopedLock ;
LLVMApiScopedLock scopedLock ;
// setup exception handler to longjmp back here
// setup exception handler to longjmp back here
if ( ! handler . Set ( ) ) {
HANDLER_TRY ( handler ) {
cli_errmsg ( " [Bytecode JIT] *** FATAL error encountered during bytecode generation \n " ) ;
return CL_EBYTECODE ;
}
// LLVM itself never throws exceptions, but operator new may throw bad_alloc
// LLVM itself never throws exceptions, but operator new may throw bad_alloc
try {
try {
Module * M = new Module ( " ClamAV jit module " , bcs - > engine - > Context ) ;
Module * M = new Module ( " ClamAV jit module " , bcs - > engine - > Context ) ;
@ -2130,6 +2132,10 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
cli_errmsg ( " [Bytecode JIT]: Unexpected unknown exception occured \n " ) ;
cli_errmsg ( " [Bytecode JIT]: Unexpected unknown exception occured \n " ) ;
return CL_EBYTECODE ;
return CL_EBYTECODE ;
}
}
return 0 ;
} HANDLER_END ( handler ) ;
cli_errmsg ( " [Bytecode JIT] *** FATAL error encountered during bytecode generation \n " ) ;
return CL_EBYTECODE ;
}
}
int bytecode_init ( void )
int bytecode_init ( void )