11cb0ef41Sopenharmony_ci// Copyright 2019 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include 'src/builtins/builtins-promise-gen.h' 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_cinamespace promise { 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_citransitioning 101cb0ef41Sopenharmony_cimacro RejectPromiseReactionJob( 111cb0ef41Sopenharmony_ci context: Context, 121cb0ef41Sopenharmony_ci promiseOrCapability: JSPromise|PromiseCapability|Undefined, reason: JSAny, 131cb0ef41Sopenharmony_ci reactionType: constexpr PromiseReactionType): JSAny { 141cb0ef41Sopenharmony_ci if constexpr (reactionType == kPromiseReactionReject) { 151cb0ef41Sopenharmony_ci typeswitch (promiseOrCapability) { 161cb0ef41Sopenharmony_ci case (promise: JSPromise): { 171cb0ef41Sopenharmony_ci // For fast native promises we can skip the indirection via the 181cb0ef41Sopenharmony_ci // promiseCapability.[[Reject]] function and run the resolve logic 191cb0ef41Sopenharmony_ci // directly from here. 201cb0ef41Sopenharmony_ci return RejectPromise(promise, reason, False); 211cb0ef41Sopenharmony_ci } 221cb0ef41Sopenharmony_ci case (Undefined): { 231cb0ef41Sopenharmony_ci return Undefined; 241cb0ef41Sopenharmony_ci } 251cb0ef41Sopenharmony_ci case (capability: PromiseCapability): { 261cb0ef41Sopenharmony_ci // In the general case we need to call the (user provided) 271cb0ef41Sopenharmony_ci // promiseCapability.[[Reject]] function. 281cb0ef41Sopenharmony_ci const reject = UnsafeCast<Callable>(capability.reject); 291cb0ef41Sopenharmony_ci return Call(context, reject, Undefined, reason); 301cb0ef41Sopenharmony_ci } 311cb0ef41Sopenharmony_ci } 321cb0ef41Sopenharmony_ci } else { 331cb0ef41Sopenharmony_ci static_assert(reactionType == kPromiseReactionFulfill); 341cb0ef41Sopenharmony_ci // We have to call out to the dedicated PromiseRejectReactionJob 351cb0ef41Sopenharmony_ci // builtin here, instead of just doing the work inline, as otherwise 361cb0ef41Sopenharmony_ci // the catch predictions in the debugger will be wrong, which just 371cb0ef41Sopenharmony_ci // walks the stack and checks for certain builtins. 381cb0ef41Sopenharmony_ci return PromiseRejectReactionJob(reason, Undefined, promiseOrCapability); 391cb0ef41Sopenharmony_ci } 401cb0ef41Sopenharmony_ci} 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_citransitioning 431cb0ef41Sopenharmony_cimacro FuflfillPromiseReactionJob( 441cb0ef41Sopenharmony_ci context: Context, 451cb0ef41Sopenharmony_ci promiseOrCapability: JSPromise|PromiseCapability|Undefined, result: JSAny, 461cb0ef41Sopenharmony_ci reactionType: constexpr PromiseReactionType): JSAny { 471cb0ef41Sopenharmony_ci typeswitch (promiseOrCapability) { 481cb0ef41Sopenharmony_ci case (promise: JSPromise): { 491cb0ef41Sopenharmony_ci // For fast native promises we can skip the indirection via the 501cb0ef41Sopenharmony_ci // promiseCapability.[[Resolve]] function and run the resolve logic 511cb0ef41Sopenharmony_ci // directly from here. 521cb0ef41Sopenharmony_ci return ResolvePromise(context, promise, result); 531cb0ef41Sopenharmony_ci } 541cb0ef41Sopenharmony_ci case (Undefined): { 551cb0ef41Sopenharmony_ci return Undefined; 561cb0ef41Sopenharmony_ci } 571cb0ef41Sopenharmony_ci case (capability: PromiseCapability): { 581cb0ef41Sopenharmony_ci // In the general case we need to call the (user provided) 591cb0ef41Sopenharmony_ci // promiseCapability.[[Resolve]] function. 601cb0ef41Sopenharmony_ci const resolve = UnsafeCast<Callable>(capability.resolve); 611cb0ef41Sopenharmony_ci try { 621cb0ef41Sopenharmony_ci return Call(context, resolve, Undefined, result); 631cb0ef41Sopenharmony_ci } catch (e, _message) { 641cb0ef41Sopenharmony_ci return RejectPromiseReactionJob( 651cb0ef41Sopenharmony_ci context, promiseOrCapability, e, reactionType); 661cb0ef41Sopenharmony_ci } 671cb0ef41Sopenharmony_ci } 681cb0ef41Sopenharmony_ci } 691cb0ef41Sopenharmony_ci} 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci// https://tc39.es/ecma262/#sec-promisereactionjob 721cb0ef41Sopenharmony_citransitioning 731cb0ef41Sopenharmony_cimacro PromiseReactionJob( 741cb0ef41Sopenharmony_ci context: Context, argument: JSAny, handler: Callable|Undefined, 751cb0ef41Sopenharmony_ci promiseOrCapability: JSPromise|PromiseCapability|Undefined, 761cb0ef41Sopenharmony_ci reactionType: constexpr PromiseReactionType): JSAny { 771cb0ef41Sopenharmony_ci if (handler == Undefined) { 781cb0ef41Sopenharmony_ci if constexpr (reactionType == kPromiseReactionFulfill) { 791cb0ef41Sopenharmony_ci return FuflfillPromiseReactionJob( 801cb0ef41Sopenharmony_ci context, promiseOrCapability, argument, reactionType); 811cb0ef41Sopenharmony_ci } else { 821cb0ef41Sopenharmony_ci static_assert(reactionType == kPromiseReactionReject); 831cb0ef41Sopenharmony_ci return RejectPromiseReactionJob( 841cb0ef41Sopenharmony_ci context, promiseOrCapability, argument, reactionType); 851cb0ef41Sopenharmony_ci } 861cb0ef41Sopenharmony_ci } else { 871cb0ef41Sopenharmony_ci try { 881cb0ef41Sopenharmony_ci const result = 891cb0ef41Sopenharmony_ci Call(context, UnsafeCast<Callable>(handler), Undefined, argument); 901cb0ef41Sopenharmony_ci if (promiseOrCapability == Undefined) { 911cb0ef41Sopenharmony_ci // There's no [[Capability]] for this promise reaction job, which 921cb0ef41Sopenharmony_ci // means that this is a specification-internal operation (aka 931cb0ef41Sopenharmony_ci // await) where the result does not matter (see the specification 941cb0ef41Sopenharmony_ci // change in https://github.com/tc39/ecma262/pull/1146 for 951cb0ef41Sopenharmony_ci // details). 961cb0ef41Sopenharmony_ci return Undefined; 971cb0ef41Sopenharmony_ci } else { 981cb0ef41Sopenharmony_ci return FuflfillPromiseReactionJob( 991cb0ef41Sopenharmony_ci context, promiseOrCapability, result, reactionType); 1001cb0ef41Sopenharmony_ci } 1011cb0ef41Sopenharmony_ci } catch (e, _message) { 1021cb0ef41Sopenharmony_ci return RejectPromiseReactionJob( 1031cb0ef41Sopenharmony_ci context, promiseOrCapability, e, reactionType); 1041cb0ef41Sopenharmony_ci } 1051cb0ef41Sopenharmony_ci } 1061cb0ef41Sopenharmony_ci} 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_citransitioning builtin 1091cb0ef41Sopenharmony_ciPromiseFulfillReactionJob(implicit context: Context)( 1101cb0ef41Sopenharmony_ci value: JSAny, handler: Callable|Undefined, 1111cb0ef41Sopenharmony_ci promiseOrCapability: JSPromise|PromiseCapability|Undefined): JSAny { 1121cb0ef41Sopenharmony_ci return PromiseReactionJob( 1131cb0ef41Sopenharmony_ci context, value, handler, promiseOrCapability, kPromiseReactionFulfill); 1141cb0ef41Sopenharmony_ci} 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_citransitioning builtin 1171cb0ef41Sopenharmony_ciPromiseRejectReactionJob(implicit context: Context)( 1181cb0ef41Sopenharmony_ci reason: JSAny, handler: Callable|Undefined, 1191cb0ef41Sopenharmony_ci promiseOrCapability: JSPromise|PromiseCapability|Undefined): JSAny { 1201cb0ef41Sopenharmony_ci return PromiseReactionJob( 1211cb0ef41Sopenharmony_ci context, reason, handler, promiseOrCapability, kPromiseReactionReject); 1221cb0ef41Sopenharmony_ci} 1231cb0ef41Sopenharmony_ci} 124