diff --git a/Source/JavaScriptCore/builtins/BuiltinNames.h b/Source/JavaScriptCore/builtins/BuiltinNames.h index f8277fd8c5f57..03beaf0b856a3 100644 --- a/Source/JavaScriptCore/builtins/BuiltinNames.h +++ b/Source/JavaScriptCore/builtins/BuiltinNames.h @@ -212,6 +212,9 @@ namespace JSC { macro(hasOwn) \ macro(indexOf) \ macro(pop) \ + macro(pushAsyncContextFrame) \ + macro(popAsyncContextFrame) \ + macro(getAsyncContextFrame) \ namespace Symbols { diff --git a/Source/JavaScriptCore/builtins/PromiseOperations.js b/Source/JavaScriptCore/builtins/PromiseOperations.js index 72906b4524134..623dfa6471ec3 100644 --- a/Source/JavaScriptCore/builtins/PromiseOperations.js +++ b/Source/JavaScriptCore/builtins/PromiseOperations.js @@ -36,7 +36,7 @@ function pushNewPromiseReaction(thenable, existingReactions, promiseOrCapability @promiseOrCapability: promiseOrCapability, @onFulfilled: onFulfilled, @onRejected: onRejected, - @context: context, + @context: @getAsyncContextFrame ? @getAsyncContextFrame(context) : context, // This is 4x the number of out of line reactions (promise, fulfill callback, reject callback, context). @outOfLineReactionCounts: 0, }; @@ -46,7 +46,7 @@ function pushNewPromiseReaction(thenable, existingReactions, promiseOrCapability @putByValDirect(existingReactions, outOfLineReactionCounts++, promiseOrCapability); @putByValDirect(existingReactions, outOfLineReactionCounts++, onFulfilled); @putByValDirect(existingReactions, outOfLineReactionCounts++, onRejected); - @putByValDirect(existingReactions, outOfLineReactionCounts++, context); + @putByValDirect(existingReactions, outOfLineReactionCounts++, @getAsyncContextFrame ? @getAsyncContextFrame(context) : context); existingReactions.@outOfLineReactionCounts = outOfLineReactionCounts; } } @@ -318,6 +318,10 @@ function createResolvingFunctions(promise) function promiseReactionJobWithoutPromise(handler, argument, context) { "use strict"; + var pushed; + if (@pushAsyncContextFrame) { + pushed = @pushAsyncContextFrame(context); + } try { if (context) @@ -326,6 +330,10 @@ function promiseReactionJobWithoutPromise(handler, argument, context) handler(argument); } catch { // This is user-uncatchable promise. We just ignore the error here. + } finally { + if (@popAsyncContextFrame) { + @popAsyncContextFrame(pushed); + } } } @@ -457,6 +465,11 @@ function promiseReactionJob(promiseOrCapability, handler, argument, contextOrSta return; } + var pushed; + if (@pushAsyncContextFrame) { + pushed = @pushAsyncContextFrame(contextOrState); + } + // Case (1), or (2). try { var result = (contextOrState) ? handler(argument, contextOrState) : handler(argument); @@ -466,14 +479,23 @@ function promiseReactionJob(promiseOrCapability, handler, argument, contextOrSta return; } promiseOrCapability.@reject.@call(@undefined, error); + if (@popAsyncContextFrame) { + @popAsyncContextFrame(pushed); + } return; } if (@isPromise(promiseOrCapability)) { @resolvePromise(promiseOrCapability, result); + if (@popAsyncContextFrame) { + @popAsyncContextFrame(pushed); + } return; } promiseOrCapability.@resolve.@call(@undefined, result); + if (@popAsyncContextFrame) { + @popAsyncContextFrame(pushed); + } } @linkTimeConstant diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp index ad0ecac28221d..5a6f31294d7a6 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp +++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp @@ -1669,6 +1669,10 @@ capitalName ## Constructor* lowerName ## Constructor = featureFlag ? capitalName putDirectWithoutTransition(vm, Identifier::fromString(vm, "__signpostStop"_s), JSFunction::create(vm, this, 1, "signpostStop"_s, signpostStop, ImplementationVisibility::Public), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); } + putDirectWithoutTransition(vm, vm.propertyNames->builtinNames().pushAsyncContextFramePrivateName(), jsUndefined(), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | 0); + putDirectWithoutTransition(vm, vm.propertyNames->builtinNames().popAsyncContextFramePrivateName(), jsUndefined(), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | 0); + putDirectWithoutTransition(vm, vm.propertyNames->builtinNames().getAsyncContextFramePrivateName(), jsUndefined(), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | 0); + initStaticGlobals(vm); if (UNLIKELY(Options::useDollarVM()))