fix(node:async_hooks): createHook/AsyncResource validation + ALS arg forwarding#3520
Merged
Merged
Conversation
- createHook(options) now rejects nullish top-level options with Node's destructure TypeError (no code) and rejects present non-callable init/before/after/destroy/promiseResolve members with TypeError [ERR_ASYNC_CALLBACK] 'hook.<name> must be a function'. Missing/undefined members and non-nullish primitive options stay allowed. - AsyncLocalStorage#run(store, cb, ...args) and #exit(cb, ...args) now forward the trailing rest arguments to the callback via a new NA_VARARGS native-table slot + js_closure_call_array, preserving store push/pop and exit restoration semantics. - Add gap test test_gap_asynchooks_3089_3090_3091_3093.ts (byte-identical to node --experimental-strip-types).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3089
Closes #3093
Summary
Brings
node:async_hookscreateHookvalidation andAsyncLocalStorageargument forwarding to Node parity.async_hooks.createHook(options)now rejects a nullish top-level value with Node's plainTypeError(no error code) —Cannot destructure property 'init' of 'undefined' as it is undefined./... of 'object null' as it is null.— before any callback is read. A present (non-undefined)init/before/after/destroy/promiseResolvemember that is not callable now throwsTypeError [ERR_ASYNC_CALLBACK]withhook.<name> must be a function. Missing/undefinedmembers and non-nullish primitive top-level options (e.g.0) stay allowed, matching Node's destructuring semantics.AsyncLocalStorage#run(store, callback, ...args)and#exit(callback, ...args)now forward the trailing rest arguments to the callback. The native-table rows gained a trailingNA_VARARGSslot (already-existing codegen lowering packs...argsinto a JS array); the runtime helpers invoke the validated closure viajs_closure_call_arraywith the forwarded args while preserving store push/pop (run) and store save/clear/restore (exit) semantics.Implementation
crates/perry-runtime/src/async_hooks.rs:validate_create_hook_options(nullish guard) +validate_hook_member(present-non-callable guard), wired intojs_async_hooks_create_hook/callbacks_from_options.crates/perry-stdlib/src/async_local_storage.rs:js_async_local_storage_run/_exittake a trailingargs_array: i64and call the callback throughcall_with_forwarded_args(js_closure_call_array).crates/perry-codegen/src/lower_call/native_table/async_decimal.rs:run→&[NA_F64, NA_F64, NA_VARARGS],exit→&[NA_F64, NA_VARARGS].No new HIR variant; no new codegen-emitted
#[no_mangle](only signatures of existing emitted helpers changed).#3090/#3091were already closed onmain(AsyncResource constructor + callback validation present inasync_hooks.rs); this PR's gap test re-covers them as a regression net but does not re-close them.Validation
test-files/test_gap_asynchooks_3089_3090_3091_3093.ts(importsnode:async_hooks, printserr.name/code/messagefor throws and the forwarded args + return values for ALSrun/exit) is byte-identical tonode --experimental-strip-typesunder the DEFAULT auto-optimize compile.Guards:
./scripts/check_file_size.sh(exit 0),cargo fmt --all -- --check(clean),cargo test --release -p perry-hir(green),cargo test --release -p perry-runtime async_hooks(green single-threaded; thetest_async_hooks_promise_alloc_remains_malloc_trackedfailure under parallel--test-threadsis pre-existing global-HOOKS_ACTIVEcross-test contamination, passes isolated and is unrelated to this change).