[JSC] Promise jobs must not run with the realm of a cross-realm settle site
// JSTests/stress/cross-realm-await-thenable-resolve-realm.js
const other = createGlobalObject();
other.MainFunction = Function;
other.subject = promise; // cross-realm pending promise
new other.Function(`
(async () => {
await subject;
await { then(f) {
// Before patch: f.constructor === MainFunction (foreign realm leaked)
// After patch: f.constructor === Function (own realm)
f(0);
} };
})();
`)();
In multi-realm environments (iframes, ShadowRealm, workers), each realm has its own built-in constructors. The ECMAScript spec requires each microtask job's realm to be fixed at creation time — for Await this is step 4 of the Await algorithm, not the settle site. JSC optimizes the common same-realm case with fast paths in resolveWithInternalMicrotaskForAsyncAwait that skip the intermediate promise normally required by PromiseResolve.
This commit fixes two defects. The await fast paths now require realm match before adopting vanilla promises directly; cross-realm cases take the thenable path (+1 microtask, V8-compatible) so the own realm is preserved. Internal microtask handlers in runInternalMicrotask now derive their realm from the driven object (generator, result promise, or module) rather than the settle site's globalObject.
Significance
Cross-realm realm leakage means resolving functions passed to a subsequently-awaited thenable's then(f,j) could carry constructors from an unexpected foreign realm — an observable spec violation detectable from JavaScript and a primitive that could be leveraged in cross-realm exploitation scenarios.