Browse code

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.

Török Edvin authored on 2010/11/10 21:53:39
Showing 1 changed files
... ...
@@ -176,15 +176,11 @@ void cli_dbgmsg_internal(const char *str, ...);
176 176
 
177 177
 class ScopedExceptionHandler {
178 178
     public:
179
-	bool Set() {
180
-	    if (setjmp(env) == 0) {
181
-		/* set the exception handler's return location to here for the
182
-		 * current thread */
183
-		ExceptionReturn.set((const jmp_buf*)&env);
184
-		return true;
185
-	    }
186
-	    cli_warnmsg("[JIT]: recovered from error\n");
187
-	    return false;
179
+	jmp_buf &getEnv() { return env;}
180
+	void Set() {
181
+	    /* set the exception handler's return location to here for the
182
+	     * current thread */
183
+	    ExceptionReturn.set((const jmp_buf*)&env);
188 184
 	}
189 185
 	~ScopedExceptionHandler() {
190 186
 	    /* leaving scope, remove exception handler for current thread */
... ...
@@ -193,10 +189,17 @@ class ScopedExceptionHandler {
193 193
     private:
194 194
 	jmp_buf env;
195 195
 };
196
+#define HANDLER_TRY(handler) \
197
+    if (setjmp(handler.getEnv()) == 0) {\
198
+	handler.Set();
199
+
200
+#define HANDLER_END(handler) \
201
+    } else cli_warnmsg("[Bytecode JIT]: recovered from error\n");
202
+
196 203
 
197 204
 void do_shutdown() {
198 205
     ScopedExceptionHandler handler;
199
-    if (handler.Set()) {
206
+    HANDLER_TRY(handler) {
200 207
 	// TODO: be on the safe side, and clear errors here,
201 208
 	// otherwise destructor calls report_fatal_error
202 209
 	((class raw_fd_ostream&)errs()).clear_error();
... ...
@@ -205,6 +208,7 @@ void do_shutdown() {
205 205
 
206 206
 	((class raw_fd_ostream&)errs()).clear_error();
207 207
     }
208
+    HANDLER_END(handler);
208 209
     remove_fatal_error_handler();
209 210
 }
210 211
 
... ...
@@ -1836,12 +1840,13 @@ static int bytecode_execute(intptr_t code, struct cli_bc_ctx *ctx)
1836 1836
 {
1837 1837
     ScopedExceptionHandler handler;
1838 1838
     // execute;
1839
-    if (handler.Set()) {
1839
+    HANDLER_TRY(handler) {
1840 1840
 	// setup exception handler to longjmp back here
1841 1841
 	uint32_t result = ((uint32_t (*)(struct cli_bc_ctx *))(intptr_t)code)(ctx);
1842 1842
 	*(uint32_t*)ctx->values = result;
1843 1843
 	return 0;
1844 1844
     }
1845
+    HANDLER_END(handler);
1845 1846
     cli_warnmsg("[Bytecode JIT]: JITed code intercepted runtime error!\n");
1846 1847
     return CL_EBYTECODE;
1847 1848
 }
... ...
@@ -1943,10 +1948,7 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
1943 1943
   ScopedExceptionHandler handler;
1944 1944
   LLVMApiScopedLock scopedLock;
1945 1945
   // setup exception handler to longjmp back here
1946
-  if (!handler.Set()) {
1947
-      cli_errmsg("[Bytecode JIT] *** FATAL error encountered during bytecode generation\n");
1948
-      return CL_EBYTECODE;
1949
-  }
1946
+  HANDLER_TRY(handler) {
1950 1947
   // LLVM itself never throws exceptions, but operator new may throw bad_alloc
1951 1948
   try {
1952 1949
     Module *M = new Module("ClamAV jit module", bcs->engine->Context);
... ...
@@ -2130,6 +2132,10 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
2130 2130
       cli_errmsg("[Bytecode JIT]: Unexpected unknown exception occured\n");
2131 2131
       return CL_EBYTECODE;
2132 2132
   }
2133
+  return 0;
2134
+  } HANDLER_END(handler);
2135
+  cli_errmsg("[Bytecode JIT] *** FATAL error encountered during bytecode generation\n");
2136
+  return CL_EBYTECODE;
2133 2137
 }
2134 2138
 
2135 2139
 int bytecode_init(void)