Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 51cc3feb729804866ae63510d837f4df674bbc59
      
https://github.com/WebKit/WebKit/commit/51cc3feb729804866ae63510d837f4df674bbc59
  Author: Sosuke Suzuki <[email protected]>
  Date:   2026-06-04 (Thu, 04 Jun 2026)

  Changed paths:
    A JSTests/stress/cross-realm-await-thenable-resolve-realm.js
    A JSTests/stress/cross-realm-promise-internal-reaction-realm.js
    A JSTests/stress/cross-realm-promise-microtask-ordering.js
    M Source/JavaScriptCore/API/JSAPIGlobalObject.mm
    M Source/JavaScriptCore/dfg/DFGOperations.cpp
    M Source/JavaScriptCore/jsc.cpp
    M Source/JavaScriptCore/runtime/Completion.cpp
    M Source/JavaScriptCore/runtime/CyclicModuleRecord.cpp
    M Source/JavaScriptCore/runtime/JSGlobalObject.cpp
    M Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
    M Source/JavaScriptCore/runtime/JSMicrotask.cpp
    M Source/JavaScriptCore/runtime/JSModuleLoader.cpp
    M Source/JavaScriptCore/runtime/JSModuleRecord.cpp
    M Source/JavaScriptCore/runtime/JSPromise.cpp
    M Source/JavaScriptCore/runtime/JSPromise.h
    M Source/JavaScriptCore/runtime/JSPromiseConstructor.cpp
    M Source/JavaScriptCore/runtime/JSPromisePrototype.cpp
    M Source/JavaScriptCore/runtime/ModuleRegistryEntry.cpp
    M Source/JavaScriptCore/runtime/PinballCompletion.cpp
    M Source/JavaScriptCore/runtime/ShadowRealmPrototype.cpp
    M Source/JavaScriptCore/tools/JSDollarVM.cpp
    M Source/JavaScriptCore/wasm/WasmStreamingCompiler.cpp
    M Source/JavaScriptCore/wasm/js/JSWebAssembly.cpp
    M Source/JavaScriptCore/wasm/js/WebAssemblyPromising.cpp
    M Source/WebCore/bindings/js/JSDOMGlobalObject.cpp
    M Source/WebCore/bindings/js/JSDOMPromiseDeferred.cpp
    M Source/WebCore/bindings/js/ScriptModuleLoader.cpp
    M Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
    M Source/WebCore/bindings/scripts/test/JS/JSTestCallbackInterface.cpp

  Log Message:
  -----------
  [JSC] Promise jobs must not run with the realm of a cross-realm settle site
https://bugs.webkit.org/show_bug.cgi?id=316187

Reviewed by Yusuke Suzuki.

In a VM with multiple JSGlobalObjects, two defects let a foreign realm leak
into observable objects (e.g. the resolving functions passed to an awaited
thenable's then(f, j)):

1. The await fast paths in resolveWithInternalMicrotaskForAsyncAwait and
   resolveWithInternalMicrotask adopted cross-realm vanilla promises directly,
   skipping the intermediate promise that PromiseResolve[1] requires for them.
   Now they require the promise's realm to match the current globalObject, so
   cross-realm promises take the thenable path, whose resolving functions
   re-anchor the realm; cross-realm await now costs one extra microtask,
   matching V8. resolvePromise has no such check in the spec and keeps its
   fast path, but enqueues the thenable job with the promise's realm.

2. Internal microtask handlers used the queue entry's globalObject, which is
   the settle site's realm and can be foreign (e.g. then/catch/finally called
   on a cross-realm promise). Per spec, each job's realm is fixed at creation
   (e.g. Await[2] step 4), so runInternalMicrotask now derives the realm from
   the object each job drives (the generator, the result promise, or the
   module) and passes it to the handlers, following the precedent of
   JSPromise::pipeFrom. fulfillPromise, rejectPromise, and
   performPromiseThenWithInternalMicrotask now anchor on the promise's realm
   instead of taking a globalObject.

V8 behaves correctly in all of these cases. Same-realm fast paths only pay
one extra pointer comparison; same-realm microtask ordering is unchanged and
async/promise microbenchmarks are neutral.

    const other = createGlobalObject();
    other.MainFunction = Function;
    other.subject = somePendingMainRealmPromise;
    new other.Function(`
        (async () => {
            await subject;
            await { then(f) {
                // f.constructor must be this realm's Function,
                // but was MainFunction before this patch.
            } };
        })();
    `)();

[1]: https://tc39.es/ecma262/#sec-promise-resolve
[2]: https://tc39.es/ecma262/#await

Tests: JSTests/stress/cross-realm-await-thenable-resolve-realm.js
       JSTests/stress/cross-realm-promise-internal-reaction-realm.js

* JSTests/stress/cross-realm-await-thenable-resolve-realm.js: Added.
(shouldBe):
(async return):
* JSTests/stress/cross-realm-promise-internal-reaction-realm.js: Added.
(shouldBe):
(makePending):
(makePendingRejection):
(async settles):
(async return):
* Source/JavaScriptCore/runtime/JSMicrotask.cpp:
(JSC::asyncFromSyncIteratorContinueOrDone):
(JSC::promiseFinallyReactionJob):
(JSC::asyncModuleExecutionDone):
(JSC::asyncModuleExecutionResume):
(JSC::promiseResolveWithoutHandlerJob):
(JSC::runInternalMicrotask):
* Source/JavaScriptCore/runtime/JSPromise.cpp:
(JSC::JSPromise::resolvePromise):
(JSC::JSPromise::resolveWithInternalMicrotaskForAsyncAwait):
(JSC::JSPromise::resolveWithInternalMicrotask):

Canonical link: https://commits.webkit.org/314528@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to