Previously, njs_engine_qjs_unhandled_rejection() kept a pointer to
the rejected promise list while converting the first rejection reason
to a string. The conversion may call user JavaScript code, which can
reject more promises and cause the list to be reallocated. After that,
the old pointer was used together with the new item count to free the
promise and reason values, which caused out-of-bounds reads and invalid
frees.
The fix is to take a reference to the first reason and free the list
before conversion, so that rejections created during conversion are
tracked in a new list.
The test/js/promise_rejection_tracker_recursive.t.js test is no longer
skipped for the QuickJS engine.