summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/fitz/context.h22
-rw-r--r--source/fitz/error.c21
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)