diff --git a/quickjs-libc.c b/quickjs-libc.c index 04684b9..091fd42 100644 --- a/quickjs-libc.c +++ b/quickjs-libc.c @@ -804,7 +804,7 @@ static JSValue js_evalScript(JSContext *ctx, JSValueConst this_val, /* convert the uncatchable "interrupted" error into a normal error so that it can be caught by the REPL */ if (JS_IsException(ret)) - JS_ResetUncatchableError(ctx); + JS_SetUncatchableException(ctx, FALSE); } return ret; } diff --git a/quickjs.c b/quickjs.c index 7f61596..9979dc4 100644 --- a/quickjs.c +++ b/quickjs.c @@ -263,6 +263,8 @@ struct JSRuntime { uintptr_t stack_limit; /* lower stack limit */ JSValue current_exception; + /* true if the current exception cannot be catched */ + BOOL current_exception_is_uncatchable : 8; /* true if inside an out of memory error, to avoid recursing */ BOOL in_out_of_memory : 8; @@ -912,7 +914,6 @@ struct JSObject { uint8_t is_exotic : 1; /* TRUE if object has exotic property handlers */ uint8_t fast_array : 1; /* TRUE if u.array is used for get/put (for JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS and typed arrays) */ uint8_t is_constructor : 1; /* TRUE if object is a constructor function */ - uint8_t is_uncatchable_error : 1; /* if TRUE, error is not catchable */ uint8_t tmp_mark : 1; /* used in JS_WriteObjectRec() */ uint8_t is_HTMLDDA : 1; /* specific annex B IsHtmlDDA behavior */ uint16_t class_id; /* see JS_CLASS_x */ @@ -5052,7 +5053,6 @@ static JSValue JS_NewObjectFromShape(JSContext *ctx, JSShape *sh, JSClassID clas p->is_exotic = 0; p->fast_array = 0; p->is_constructor = 0; - p->is_uncatchable_error = 0; p->tmp_mark = 0; p->is_HTMLDDA = 0; p->weakref_count = 0; @@ -6699,6 +6699,7 @@ JSValue JS_Throw(JSContext *ctx, JSValue obj) JSRuntime *rt = ctx->rt; JS_FreeValue(ctx, rt->current_exception); rt->current_exception = obj; + rt->current_exception_is_uncatchable = FALSE; return JS_EXCEPTION; } @@ -7166,7 +7167,7 @@ static JSValue JS_ThrowTypeErrorInvalidClass(JSContext *ctx, int class_id) static void JS_ThrowInterrupted(JSContext *ctx) { JS_ThrowInternalError(ctx, "interrupted"); - JS_SetUncatchableError(ctx, ctx->rt->current_exception, TRUE); + JS_SetUncatchableException(ctx, TRUE); } static no_inline __exception int __js_poll_interrupts(JSContext *ctx) @@ -10221,29 +10222,10 @@ BOOL JS_IsError(JSContext *ctx, JSValueConst val) return (p->class_id == JS_CLASS_ERROR); } -/* used to avoid catching interrupt exceptions */ -BOOL JS_IsUncatchableError(JSContext *ctx, JSValueConst val) +/* must be called after JS_Throw() */ +void JS_SetUncatchableException(JSContext *ctx, BOOL flag) { - JSObject *p; - if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) - return FALSE; - p = JS_VALUE_GET_OBJ(val); - return p->class_id == JS_CLASS_ERROR && p->is_uncatchable_error; -} - -void JS_SetUncatchableError(JSContext *ctx, JSValueConst val, BOOL flag) -{ - JSObject *p; - if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) - return; - p = JS_VALUE_GET_OBJ(val); - if (p->class_id == JS_CLASS_ERROR) - p->is_uncatchable_error = flag; -} - -void JS_ResetUncatchableError(JSContext *ctx) -{ - JS_SetUncatchableError(ctx, ctx->rt->current_exception, FALSE); + ctx->rt->current_exception_is_uncatchable = flag; } void JS_SetOpaque(JSValue obj, void *opaque) @@ -18762,7 +18744,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, sf->cur_pc = pc; build_backtrace(ctx, rt->current_exception, NULL, 0, 0, 0); } - if (!JS_IsUncatchableError(ctx, rt->current_exception)) { + if (!rt->current_exception_is_uncatchable) { while (sp > stack_buf) { JSValue val = *--sp; JS_FreeValue(ctx, val); diff --git a/quickjs.h b/quickjs.h index 8814222..adc8620 100644 --- a/quickjs.h +++ b/quickjs.h @@ -659,11 +659,10 @@ static inline JS_BOOL JS_IsObject(JSValueConst v) } JSValue JS_Throw(JSContext *ctx, JSValue obj); +void JS_SetUncatchableException(JSContext *ctx, JS_BOOL flag); JSValue JS_GetException(JSContext *ctx); JS_BOOL JS_HasException(JSContext *ctx); JS_BOOL JS_IsError(JSContext *ctx, JSValueConst val); -void JS_SetUncatchableError(JSContext *ctx, JSValueConst val, JS_BOOL flag); -void JS_ResetUncatchableError(JSContext *ctx); JSValue JS_NewError(JSContext *ctx); JSValue __js_printf_like(2, 3) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...); JSValue __js_printf_like(2, 3) JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...);