diff options
Diffstat (limited to 'deps/v8/src/builtins/promise-jobs.tq')
-rw-r--r-- | deps/v8/src/builtins/promise-jobs.tq | 120 |
1 files changed, 60 insertions, 60 deletions
diff --git a/deps/v8/src/builtins/promise-jobs.tq b/deps/v8/src/builtins/promise-jobs.tq index ee049605e1a..6c64baf22d1 100644 --- a/deps/v8/src/builtins/promise-jobs.tq +++ b/deps/v8/src/builtins/promise-jobs.tq @@ -6,68 +6,68 @@ // https://tc39.es/ecma262/#sec-promise-jobs namespace promise { - extern macro IsJSPromiseMap(Map): bool; +extern macro IsJSPromiseMap(Map): bool; - // https://tc39.es/ecma262/#sec-promiseresolvethenablejob - transitioning builtin - PromiseResolveThenableJob(implicit context: Context)( - promiseToResolve: JSPromise, thenable: JSReceiver, then: JSAny): JSAny { - // We can use a simple optimization here if we know that {then} is the - // initial Promise.prototype.then method, and {thenable} is a JSPromise - // whose - // @@species lookup chain is intact: We can connect {thenable} and - // {promise_to_resolve} directly in that case and avoid the allocation of a - // temporary JSPromise and the closures plus context. +// https://tc39.es/ecma262/#sec-promiseresolvethenablejob +transitioning builtin +PromiseResolveThenableJob(implicit context: Context)( + promiseToResolve: JSPromise, thenable: JSReceiver, then: JSAny): JSAny { + // We can use a simple optimization here if we know that {then} is the + // initial Promise.prototype.then method, and {thenable} is a JSPromise + // whose + // @@species lookup chain is intact: We can connect {thenable} and + // {promise_to_resolve} directly in that case and avoid the allocation of a + // temporary JSPromise and the closures plus context. + // + // We take the generic (slow-)path if a PromiseHook is enabled or the + // debugger is active, to make sure we expose spec compliant behavior. + const nativeContext = LoadNativeContext(context); + const promiseThen = nativeContext[NativeContextSlot::PROMISE_THEN_INDEX]; + const thenableMap = thenable.map; + if (TaggedEqual(then, promiseThen) && IsJSPromiseMap(thenableMap) && + !IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate() && + IsPromiseSpeciesLookupChainIntact(nativeContext, thenableMap)) { + // We know that the {thenable} is a JSPromise, which doesn't require + // any special treatment and that {then} corresponds to the initial + // Promise.prototype.then method. So instead of allocating a temporary + // JSPromise to connect the {thenable} with the {promise_to_resolve}, + // we can directly schedule the {promise_to_resolve} with default + // handlers onto the {thenable} promise. This does not only save the + // JSPromise allocation, but also avoids the allocation of the two + // resolving closures and the shared context. // - // We take the generic (slow-)path if a PromiseHook is enabled or the - // debugger is active, to make sure we expose spec compliant behavior. - const nativeContext = LoadNativeContext(context); - const promiseThen = nativeContext[NativeContextSlot::PROMISE_THEN_INDEX]; - const thenableMap = thenable.map; - if (TaggedEqual(then, promiseThen) && IsJSPromiseMap(thenableMap) && - !IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate() && - IsPromiseSpeciesLookupChainIntact(nativeContext, thenableMap)) { - // We know that the {thenable} is a JSPromise, which doesn't require - // any special treatment and that {then} corresponds to the initial - // Promise.prototype.then method. So instead of allocating a temporary - // JSPromise to connect the {thenable} with the {promise_to_resolve}, - // we can directly schedule the {promise_to_resolve} with default - // handlers onto the {thenable} promise. This does not only save the - // JSPromise allocation, but also avoids the allocation of the two - // resolving closures and the shared context. - // - // What happens normally in this case is - // - // resolve, reject = CreateResolvingFunctions(promise_to_resolve) - // result_capability = NewPromiseCapability(%Promise%) - // PerformPromiseThen(thenable, resolve, reject, result_capability) - // - // which means that PerformPromiseThen will either schedule a new - // PromiseReaction with resolve and reject or a PromiseReactionJob - // with resolve or reject based on the state of {thenable}. And - // resolve or reject will just invoke the default [[Resolve]] or - // [[Reject]] functions on the {promise_to_resolve}. - // - // This is the same as just doing - // - // PerformPromiseThen(thenable, undefined, undefined, - // promise_to_resolve) - // - // which performs exactly the same (observable) steps. - return PerformPromiseThen( - UnsafeCast<JSPromise>(thenable), UndefinedConstant(), - UndefinedConstant(), promiseToResolve); - } else { - const funcs = CreatePromiseResolvingFunctions( - promiseToResolve, False, nativeContext); - const resolve = funcs.resolve; - const reject = funcs.reject; - try { - return Call( - context, UnsafeCast<Callable>(then), thenable, resolve, reject); - } catch (e) { - return Call(context, UnsafeCast<Callable>(reject), Undefined, e); - } + // What happens normally in this case is + // + // resolve, reject = CreateResolvingFunctions(promise_to_resolve) + // result_capability = NewPromiseCapability(%Promise%) + // PerformPromiseThen(thenable, resolve, reject, result_capability) + // + // which means that PerformPromiseThen will either schedule a new + // PromiseReaction with resolve and reject or a PromiseReactionJob + // with resolve or reject based on the state of {thenable}. And + // resolve or reject will just invoke the default [[Resolve]] or + // [[Reject]] functions on the {promise_to_resolve}. + // + // This is the same as just doing + // + // PerformPromiseThen(thenable, undefined, undefined, + // promise_to_resolve) + // + // which performs exactly the same (observable) steps. + return PerformPromiseThen( + UnsafeCast<JSPromise>(thenable), UndefinedConstant(), + UndefinedConstant(), promiseToResolve); + } else { + const funcs = + CreatePromiseResolvingFunctions(promiseToResolve, False, nativeContext); + const resolve = funcs.resolve; + const reject = funcs.reject; + try { + return Call( + context, UnsafeCast<Callable>(then), thenable, resolve, reject); + } catch (e) { + return Call(context, UnsafeCast<Callable>(reject), Undefined, e); } } } +} |