From 4c923fc7c5d52030859ef7729f6c2aa57c99e4ee Mon Sep 17 00:00:00 2001 From: Sam Hellawell Date: Fri, 1 Sep 2023 06:31:04 +0100 Subject: [PATCH 1/2] Add JS_SetHostUnhandledPromiseRejectionTracker Signed-off-by: Sam Hellawell --- include/quickjs/quickjs.h | 2 ++ src/core/builtins/js-promise.c | 16 ++++++++++++++++ src/core/types.h | 3 +++ 3 files changed, 21 insertions(+) diff --git a/include/quickjs/quickjs.h b/include/quickjs/quickjs.h index c28c48cf4..2cf6a970e 100644 --- a/include/quickjs/quickjs.h +++ b/include/quickjs/quickjs.h @@ -503,6 +503,7 @@ typedef struct JSClassDef { } JSClassDef; JSClassID JS_NewClassID(JSClassID *pclass_id); + int JS_NewClass(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def); int JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id); @@ -795,6 +796,7 @@ JSValue JS_NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs); /* is_handled = TRUE means that the rejection is handled */ typedef void JSHostPromiseRejectionTracker(JSContext* ctx, JSValueConst promise, JSValueConst reason, JS_BOOL is_handled, void* opaque); void JS_SetHostPromiseRejectionTracker(JSRuntime *rt, JSHostPromiseRejectionTracker *cb, void *opaque); +void JS_SetHostUnhandledPromiseRejectionTracker(JSRuntime *rt, JSHostPromiseRejectionTracker *cb, void *opaque); /* return != 0 if the JS code needs to be interrupted */ typedef int JSInterruptHandler(JSRuntime *rt, void *opaque); diff --git a/src/core/builtins/js-promise.c b/src/core/builtins/js-promise.c index 324530ecc..a6dcab1d7 100644 --- a/src/core/builtins/js-promise.c +++ b/src/core/builtins/js-promise.c @@ -131,6 +131,14 @@ void JS_SetHostPromiseRejectionTracker(JSRuntime *rt, rt->host_promise_rejection_tracker_opaque = opaque; } +void JS_SetHostUnhandledPromiseRejectionTracker(JSRuntime *rt, + JSHostPromiseRejectionTracker *cb, + void *opaque) +{ + rt->host_unhandled_promise_rejection_tracker = cb; + rt->host_unhandled_promise_rejection_tracker_opaque = opaque; +} + void fulfill_or_reject_promise(JSContext *ctx, JSValueConst promise, JSValueConst value, BOOL is_reject) { @@ -335,6 +343,14 @@ void js_promise_finalizer(JSRuntime *rt, JSValue val) if (!s) return; + + if (s->promise_state == JS_PROMISE_REJECTED && !s->is_handled) { + if (rt->host_unhandled_promise_rejection_tracker) { + rt->host_unhandled_promise_rejection_tracker(s->ctx, val, s->promise_result, FALSE, + rt->host_unhandled_promise_rejection_tracker_opaque); + } + } + for(i = 0; i < 2; i++) { list_for_each_safe(el, el1, &s->promise_reactions[i]) { JSPromiseReactionData *rd = diff --git a/src/core/types.h b/src/core/types.h index 1532d39f7..af18a2abc 100644 --- a/src/core/types.h +++ b/src/core/types.h @@ -209,6 +209,9 @@ struct JSRuntime { JSHostPromiseRejectionTracker *host_promise_rejection_tracker; void *host_promise_rejection_tracker_opaque; + JSHostPromiseRejectionTracker *host_unhandled_promise_rejection_tracker; + void *host_unhandled_promise_rejection_tracker_opaque; + struct list_head job_list; /* list of JSJobEntry.link */ JSModuleNormalizeFunc *module_normalize_func; From 09e13edbe3452612b6127488ef78f5183d647cce Mon Sep 17 00:00:00 2001 From: Sam Hellawell Date: Fri, 1 Sep 2023 06:31:39 +0100 Subject: [PATCH 2/2] Add JS_GetClassID Signed-off-by: Sam Hellawell --- include/quickjs/quickjs.h | 1 + src/core/builtins/js-promise.c | 2 +- src/core/runtime.c | 10 ++++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/quickjs/quickjs.h b/include/quickjs/quickjs.h index 2cf6a970e..290bb8e82 100644 --- a/include/quickjs/quickjs.h +++ b/include/quickjs/quickjs.h @@ -503,6 +503,7 @@ typedef struct JSClassDef { } JSClassDef; JSClassID JS_NewClassID(JSClassID *pclass_id); +JSClassID JS_GetClassID(JSValueConst v); int JS_NewClass(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def); int JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id); diff --git a/src/core/builtins/js-promise.c b/src/core/builtins/js-promise.c index a6dcab1d7..a0b001d20 100644 --- a/src/core/builtins/js-promise.c +++ b/src/core/builtins/js-promise.c @@ -346,7 +346,7 @@ void js_promise_finalizer(JSRuntime *rt, JSValue val) if (s->promise_state == JS_PROMISE_REJECTED && !s->is_handled) { if (rt->host_unhandled_promise_rejection_tracker) { - rt->host_unhandled_promise_rejection_tracker(s->ctx, val, s->promise_result, FALSE, + rt->host_unhandled_promise_rejection_tracker(rt, val, s->promise_result, FALSE, rt->host_unhandled_promise_rejection_tracker_opaque); } } diff --git a/src/core/runtime.c b/src/core/runtime.c index a6f99f4b5..ff83c3f13 100644 --- a/src/core/runtime.c +++ b/src/core/runtime.c @@ -230,6 +230,16 @@ JSClassID JS_NewClassID(JSClassID* pclass_id) { return class_id; } +JSClassID JS_GetClassID(JSValueConst v) { + JSObject *p; + + if (JS_VALUE_GET_TAG(v) != JS_TAG_OBJECT) + return 0; + p = JS_VALUE_GET_OBJ(v); + assert(p != 0); + return p->class_id; +} + BOOL JS_IsRegisteredClass(JSRuntime* rt, JSClassID class_id) { return (class_id < rt->class_count && rt->class_array[class_id].class_id != 0); }