[njs] Fixed catching of exception thrown in try block of async function.
Dmitry Volyntsev
xeioex at nginx.com
Tue Nov 30 16:36:14 UTC 2021
details: https://hg.nginx.org/njs/rev/748eca39acb3
branches:
changeset: 1755:748eca39acb3
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Tue Nov 30 14:55:57 2021 +0000
description:
Fixed catching of exception thrown in try block of async function.
The bug was introduced in 92d10cd761e2 (0.7.0).
diffstat:
src/njs_async.c | 11 ++++++-----
src/njs_async.h | 2 +-
src/njs_function.c | 10 +++++++---
src/njs_function.h | 2 +-
src/njs_vmcode.c | 4 ++--
test/js/async_throw_in_try_after_await.t.js | 25 +++++++++++++++++++++++++
6 files changed, 42 insertions(+), 12 deletions(-)
diffs (149 lines):
diff -r 6aaf1c14c1e7 -r 748eca39acb3 src/njs_async.c
--- a/src/njs_async.c Mon Nov 29 18:14:25 2021 +0000
+++ b/src/njs_async.c Tue Nov 30 14:55:57 2021 +0000
@@ -59,7 +59,7 @@ njs_await_fulfilled(njs_vm_t *vm, njs_va
{
njs_int_t ret;
njs_value_t **cur_local, **cur_closures, **cur_temp, *value;
- njs_frame_t *frame;
+ njs_frame_t *frame, *async_frame;
njs_function_t *function;
njs_async_ctx_t *ctx;
njs_native_frame_t *top, *async;
@@ -71,7 +71,8 @@ njs_await_fulfilled(njs_vm_t *vm, njs_va
goto failed;
}
- async = ctx->await;
+ async_frame = ctx->await;
+ async = &async_frame->native;
async->previous = vm->top_frame;
function = async->function;
@@ -87,7 +88,7 @@ njs_await_fulfilled(njs_vm_t *vm, njs_va
vm->levels[NJS_LEVEL_TEMP] = async->temp;
vm->top_frame = async;
- vm->active_frame = (njs_frame_t *) async;
+ vm->active_frame = async_frame;
*njs_scope_value(vm, ctx->index) = *value;
vm->retval = *value;
@@ -149,7 +150,7 @@ njs_await_rejected(njs_vm_t *vm, njs_val
value = njs_arg(args, nargs, 1);
- if (ctx->await->pc == ctx->pc) {
+ if (ctx->await->native.pc == ctx->pc) {
(void) njs_function_call(vm, njs_function(&ctx->capability->reject),
&njs_value_undefined, value, 1, &vm->retval);
@@ -158,7 +159,7 @@ njs_await_rejected(njs_vm_t *vm, njs_val
return NJS_ERROR;
}
- ctx->pc = ctx->await->pc;
+ ctx->pc = ctx->await->native.pc;
return njs_await_fulfilled(vm, args, nargs, unused);
}
diff -r 6aaf1c14c1e7 -r 748eca39acb3 src/njs_async.h
--- a/src/njs_async.h Mon Nov 29 18:14:25 2021 +0000
+++ b/src/njs_async.h Tue Nov 30 14:55:57 2021 +0000
@@ -10,7 +10,7 @@
typedef struct {
njs_promise_capability_t *capability;
- njs_native_frame_t *await;
+ njs_frame_t *await;
uintptr_t index;
u_char *pc;
} njs_async_ctx_t;
diff -r 6aaf1c14c1e7 -r 748eca39acb3 src/njs_function.c
--- a/src/njs_function.c Mon Nov 29 18:14:25 2021 +0000
+++ b/src/njs_function.c Tue Nov 30 14:55:57 2021 +0000
@@ -800,12 +800,17 @@ njs_function_frame_free(njs_vm_t *vm, nj
njs_int_t
-njs_function_frame_save(njs_vm_t *vm, njs_native_frame_t *native, u_char *pc)
+njs_function_frame_save(njs_vm_t *vm, njs_frame_t *frame, u_char *pc)
{
size_t value_count, n;
njs_value_t *start, *end, *p, **new, *value, **local;
njs_function_t *function;
- njs_native_frame_t *active;
+ njs_native_frame_t *active, *native;
+
+ *frame = *vm->active_frame;
+ frame->previous_active_frame = NULL;
+
+ native = &frame->native;
active = &vm->active_frame->native;
value_count = njs_function_frame_value_count(active);
@@ -816,7 +821,6 @@ njs_function_frame_save(njs_vm_t *vm, nj
value = (njs_value_t *) (new + value_count
+ function->u.lambda->temp);
- *native = *active;
native->arguments = value;
native->arguments_offset = value + (function->args_offset - 1);
diff -r 6aaf1c14c1e7 -r 748eca39acb3 src/njs_function.h
--- a/src/njs_function.h Mon Nov 29 18:14:25 2021 +0000
+++ b/src/njs_function.h Tue Nov 30 14:55:57 2021 +0000
@@ -116,7 +116,7 @@ njs_int_t njs_function_lambda_call(njs_v
njs_int_t njs_function_native_call(njs_vm_t *vm);
njs_native_frame_t *njs_function_frame_alloc(njs_vm_t *vm, size_t size);
void njs_function_frame_free(njs_vm_t *vm, njs_native_frame_t *frame);
-njs_int_t njs_function_frame_save(njs_vm_t *vm, njs_native_frame_t *native,
+njs_int_t njs_function_frame_save(njs_vm_t *vm, njs_frame_t *native,
u_char *pc);
njs_object_type_t njs_function_object_type(njs_vm_t *vm,
njs_function_t *function);
diff -r 6aaf1c14c1e7 -r 748eca39acb3 src/njs_vmcode.c
--- a/src/njs_vmcode.c Mon Nov 29 18:14:25 2021 +0000
+++ b/src/njs_vmcode.c Tue Nov 30 14:55:57 2021 +0000
@@ -1875,10 +1875,10 @@ njs_vmcode_await(njs_vm_t *vm, njs_vmcod
frame = (njs_frame_t *) active;
if (frame->exception.catch != NULL) {
- ctx->await->pc = frame->exception.catch;
+ ctx->await->native.pc = frame->exception.catch;
} else {
- ctx->await->pc = ctx->pc;
+ ctx->await->native.pc = ctx->pc;
}
fulfilled->context = ctx;
diff -r 6aaf1c14c1e7 -r 748eca39acb3 test/js/async_throw_in_try_after_await.t.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/js/async_throw_in_try_after_await.t.js Tue Nov 30 14:55:57 2021 +0000
@@ -0,0 +1,25 @@
+/*---
+includes: []
+flags: [async]
+---*/
+
+function pr(x) {
+ return new Promise(resolve => {resolve(x)});
+}
+
+async function add(x) {
+ try {
+ const a = await pr(x);
+ throw 'Oops';
+ return a + b;
+
+ } catch (e) {
+ return `catch: ${e.toString()}`;
+ }
+}
+
+add(50)
+.then(
+ v => assert.sameValue(v, 'catch: Oops'),
+ v => $DONOTEVALUATE(),
+).then($DONE, $DONE);
More information about the nginx-devel
mailing list