diff options
-rw-r--r-- | include/mupdf/fitz/context.h | 22 | ||||
-rw-r--r-- | source/fitz/error.c | 21 |
2 files changed, 16 insertions, 27 deletions
diff --git a/include/mupdf/fitz/context.h b/include/mupdf/fitz/context.h index 905a82ef..cb083f87 100644 --- a/include/mupdf/fitz/context.h +++ b/include/mupdf/fitz/context.h @@ -49,18 +49,9 @@ void fz_var_imp(void *); attention to the man behind the curtain. */ -/* - OK, so you looked behind the curtain, and you're wondering why we use - an inline function for fz_trying, rather than doing a bare assignment - and test. See bug 696115. Various versions of gcc (depressingly, - modern ones) cause problems under optimisation whereby the value - returned from setjmp is not written correctly. This causes the rest - of the try/catch to behave incorrectly. The use of a function call - here suffices to solve it. -*/ #define fz_try(ctx) \ - if (fz_push_try(ctx->error) && \ - fz_trying(ctx->error, fz_setjmp(ctx->error->stack[ctx->error->top].buffer)))\ + {{{ fz_push_try(ctx->error); \ + if (fz_setjmp(ctx->error->stack[ctx->error->top].buffer) == 0)\ { do { #define fz_always(ctx) \ @@ -73,15 +64,10 @@ void fz_var_imp(void *); #define fz_catch(ctx) \ } while(0); \ - } \ + } }}} \ if (ctx->error->stack[ctx->error->top--].code > 1) -int fz_push_try(fz_error_context *ex); -static inline int fz_trying(fz_error_context *error, int value) -{ - error->stack[error->top].code = value; - return value == 0; -} +void fz_push_try(fz_error_context *ex); FZ_NORETURN void fz_throw(fz_context *, int errcode, const char *, ...) __printflike(3, 4); FZ_NORETURN void fz_rethrow(fz_context *); FZ_NORETURN void fz_rethrow_message(fz_context *, const char *, ...) __printflike(2, 3); diff --git a/source/fitz/error.c b/source/fitz/error.c index 414b993f..6d0b831d 100644 --- a/source/fitz/error.c +++ b/source/fitz/error.c @@ -86,7 +86,8 @@ static void throw(fz_error_context *ex) { if (ex->top >= 0) { - fz_longjmp(ex->stack[ex->top].buffer, ex->stack[ex->top].code + 2); + ex->stack[ex->top].code += 2; + fz_longjmp(ex->stack[ex->top].buffer, ex->stack[ex->top].code); } else { @@ -101,23 +102,25 @@ static void throw(fz_error_context *ex) } } -int fz_push_try(fz_error_context *ex) +void fz_push_try(fz_error_context *ex) { - assert(ex); ex->top++; /* Normal case, get out of here quick */ if (ex->top < nelem(ex->stack)-1) - return 1; /* We exit here, and the setjmp sets the code to 0 */ + { + ex->stack[ex->top].code = 0; + return; + } /* We reserve the top slot on the exception stack purely to cope with * the case when we overflow. If we DO hit this, then we 'throw' - * immediately - returning 0 stops the setjmp happening and takes us - * direct to the always/catch clauses. */ - assert(ex->top == nelem(ex->stack)-1); + * immediately. */ + assert(ex->top == nelem(ex->stack)); + ex->top--; + ex->errcode = FZ_ERROR_GENERIC; strcpy(ex->message, "exception stack overflow!"); - ex->stack[ex->top].code = 2; fprintf(stderr, "error: %s\n", ex->message); LOGE("error: %s\n", ex->message); - return 0; + throw(ex); } int fz_caught(fz_context *ctx) |