From: Dmitry Volyntsev Date: Tue, 30 Nov 2021 14:55:57 +0000 (+0000) Subject: Fixed catching of exception thrown in try block of async function. X-Git-Tag: 0.7.1~35 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=3d44059ce047569f310da43b35d5071b41b2e396;p=njs.git Fixed catching of exception thrown in try block of async function. The bug was introduced in 92d10cd761e2 (0.7.0). --- diff --git a/src/njs_async.c b/src/njs_async.c index 6a93cfd0..d92d377a 100644 --- a/src/njs_async.c +++ b/src/njs_async.c @@ -59,7 +59,7 @@ njs_await_fulfilled(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, { 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_value_t *args, njs_uint_t nargs, 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_value_t *args, njs_uint_t nargs, 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_value_t *args, njs_uint_t nargs, 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_value_t *args, njs_uint_t nargs, return NJS_ERROR; } - ctx->pc = ctx->await->pc; + ctx->pc = ctx->await->native.pc; return njs_await_fulfilled(vm, args, nargs, unused); } diff --git a/src/njs_async.h b/src/njs_async.h index 598abfbc..28533cbd 100644 --- a/src/njs_async.h +++ b/src/njs_async.h @@ -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 --git a/src/njs_function.c b/src/njs_function.c index b166ef20..e889c19d 100644 --- a/src/njs_function.c +++ b/src/njs_function.c @@ -800,12 +800,17 @@ njs_function_frame_free(njs_vm_t *vm, njs_native_frame_t *native) 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, njs_native_frame_t *native, u_char *pc) 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 --git a/src/njs_function.h b/src/njs_function.h index f936547c..b47e7dc6 100644 --- a/src/njs_function.h +++ b/src/njs_function.h @@ -116,7 +116,7 @@ njs_int_t njs_function_lambda_call(njs_vm_t *vm); 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 --git a/src/njs_vmcode.c b/src/njs_vmcode.c index 6f7639dd..5facef58 100644 --- a/src/njs_vmcode.c +++ b/src/njs_vmcode.c @@ -1875,10 +1875,10 @@ njs_vmcode_await(njs_vm_t *vm, njs_vmcode_await_t *await) 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 --git a/test/js/async_throw_in_try_after_await.t.js b/test/js/async_throw_in_try_after_await.t.js new file mode 100644 index 00000000..a00b2e9a --- /dev/null +++ b/test/js/async_throw_in_try_after_await.t.js @@ -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);