Commit 5d1fd76
QuickJS: skip newTarget self-dup for non-constructor functions
ExternalCallback::newTarget is only consulted when the function is
invoked as a constructor (Callback(), isConstructCall-gated). For
regular functions created via napi_create_function (i.e. magic=0 —
all Napi::Function::New() lambdas, polyfill callbacks, etc.) the
newTarget self-dup creates a useless cycle:
func -> func_data[callbackData] -> opaque ExternalCallback -> newTarget -> func
NapiCallback's gc_mark exposes the newTarget to QuickJS's cycle
collector, so this is technically safe — but in practice many of
these cycles end up externally pinned (e.g. via bytecode closures
or refs captured by polyfills) and survive teardown, contributing
to the gc_obj_list residents that trip the assert in JS_FreeRuntime.
Skipping the dup for magic=0 eliminates the cycle entirely for the
common case (all Napi::Function::New lambdas).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent 4502c2c commit 5d1fd76
1 file changed
Lines changed: 11 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
954 | 954 | | |
955 | 955 | | |
956 | 956 | | |
957 | | - | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
958 | 960 | | |
959 | | - | |
960 | | - | |
961 | | - | |
| 961 | + | |
| 962 | + | |
| 963 | + | |
| 964 | + | |
| 965 | + | |
| 966 | + | |
| 967 | + | |
| 968 | + | |
962 | 969 | | |
963 | 970 | | |
964 | 971 | | |
| |||
0 commit comments