Fix recently introduced ScopedExceptionHandler.

can't use setjmp inside a function that is not the parent.
just write and use some macros.

Otherwise the "else" from handler.Set() was never reached, which caused a unit
test to fail.
This commit is contained in:
Török Edvin 2010-11-10 14:53:39 +02:00
parent 6bbbf1cc25
commit 3a35520bf9

View file

@ -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)