deps/v8/src/js/promise.js
function ResolvePromise(promise, resolution) {
  if (resolution === promise) {
    return RejectPromise(promise, MakeTypeError(kPromiseCyclic, resolution));
  }
  if (IS_RECEIVER(resolution)) {
    // 25.4.1.3.2 steps 8-12
    try {
      var then = resolution.then;
    } catch (e) {
      return RejectPromise(promise, e);
    }

    // Resolution is a native promise and if it's already resolved or
    // rejected, shortcircuit the resolution procedure by directly
    // reusing the value from the promise.
    if (IsPromise(resolution) && then === PromiseThen) {
      var thenableState = GET_PRIVATE(resolution, promiseStateSymbol);
      if (thenableState === kFulfilled) {
        // This goes inside the if-else to save one symbol lookup in
        // the slow path.
        var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol);
        FulfillPromise(promise, kFulfilled, thenableValue,
                       promiseFulfillReactionsSymbol);
        SET_PRIVATE(promise, promiseHasHandlerSymbol, true);
        return;
      } else if (thenableState === kRejected) {
        var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol);
        if (!HAS_DEFINED_PRIVATE(resolution, promiseHasHandlerSymbol)) {
          // Promise has already been rejected, but had no handler.
          // Revoke previously triggered reject event.
          %PromiseRevokeReject(resolution);
        }
        RejectPromise(promise, thenableValue);
        SET_PRIVATE(resolution, promiseHasHandlerSymbol, true);
        return;
      }
    }

    if (IS_CALLABLE(then)) {
      // PromiseResolveThenableJob
      var id;
      var name = "PromiseResolveThenableJob";
      var instrumenting = DEBUG_IS_ACTIVE;
      %EnqueueMicrotask(function() {
        if (instrumenting) {
          %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });
        }
        var callbacks = CreateResolvingFunctions(promise);
        try {
          %_Call(then, resolution, callbacks.resolve, callbacks.reject);
        } catch (e) {
          %_Call(callbacks.reject, UNDEFINED, e);
        }
        if (instrumenting) {
          %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name });
        }
      });
      if (instrumenting) {
        id = ++lastMicrotaskId;
        %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
      }
      return;
    }
  }
  FulfillPromise(promise, kFulfilled, resolution, promiseFulfillReactionsSymbol);
}
function ResolvePromise(promise, resolution) {
  if (resolution === promise) {
    return RejectPromise(promise, MakeTypeError(kPromiseCyclic, resolution));
  }
  if (IS_RECEIVER(resolution)) {
    // 25.4.1.3.2 steps 8-12
    try {
      var then = resolution.then;
    } catch (e) {
      return RejectPromise(promise, e);
    }

    // Resolution is a native promise and if it's already resolved or
    // rejected, shortcircuit the resolution procedure by directly
    // reusing the value from the promise.
    if (IsPromise(resolution) && then === PromiseThen) {
      var thenableState = GET_PRIVATE(resolution, promiseStateSymbol);
      if (thenableState === kFulfilled) {
        // This goes inside the if-else to save one symbol lookup in
        // the slow path.
        var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol);
        FulfillPromise(promise, kFulfilled, thenableValue,
                       promiseFulfillReactionsSymbol);
        SET_PRIVATE(promise, promiseHasHandlerSymbol, true);
        return;
      } else if (thenableState === kRejected) {
        var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol);
        if (!HAS_DEFINED_PRIVATE(resolution, promiseHasHandlerSymbol)) {
          // Promise has already been rejected, but had no handler.
          // Revoke previously triggered reject event.
          %PromiseRevokeReject(resolution);
        }
        RejectPromise(promise, thenableValue);
        SET_PRIVATE(resolution, promiseHasHandlerSymbol, true);
        return;
      }
    }

    if (IS_CALLABLE(then)) {
      // PromiseResolveThenableJob
      var id;
      var name = "PromiseResolveThenableJob";
      var instrumenting = DEBUG_IS_ACTIVE;
      %EnqueueMicrotask(function() {
        if (instrumenting) {
          %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });
        }
        var callbacks = CreateResolvingFunctions(promise);
        try {
          %_Call(then, resolution, callbacks.resolve, callbacks.reject);
        } catch (e) {
          %_Call(callbacks.reject, UNDEFINED, e);
        }
        if (instrumenting) {
          %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name });
        }
      });
      if (instrumenting) {
        id = ++lastMicrotaskId;
        %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
      }
      return;
    }
  }
  FulfillPromise(promise, kFulfilled, resolution, promiseFulfillReactionsSymbol);
}
function ResolvePromise ( promise , resolution ) { if ( resolution === promise ) { return RejectPromise ( promise , MakeTypeError ( kPromiseCyclic , resolution ) ) ; } if ( IS_RECEIVER ( resolution ) ) { // 25.4.1.3.2 steps 8-12 try { var then = resolution . then ; } catch ( e ) { return RejectPromise ( promise , e ) ; } // Resolution is a native promise and if it's already resolved or // rejected, shortcircuit the resolution procedure by directly // reusing the value from the promise. if ( IsPromise ( resolution ) && then === PromiseThen ) { var thenableState = GET_PRIVATE ( resolution , promiseStateSymbol ) ; if ( thenableState === kFulfilled ) { // This goes inside the if-else to save one symbol lookup in // the slow path. var thenableValue = GET_PRIVATE ( resolution , promiseResultSymbol ) ; FulfillPromise ( promise , kFulfilled , thenableValue , promiseFulfillReactionsSymbol ) ; SET_PRIVATE ( promise , promiseHasHandlerSymbol , true ) ; return ; } else if ( thenableState === kRejected ) { var thenableValue = GET_PRIVATE ( resolution , promiseResultSymbol ) ; if ( ! HAS_DEFINED_PRIVATE ( resolution , promiseHasHandlerSymbol ) ) { // Promise has already been rejected, but had no handler. // Revoke previously triggered reject event. % PromiseRevokeReject ( resolution ) ; } RejectPromise ( promise , thenableValue ) ; SET_PRIVATE ( resolution , promiseHasHandlerSymbol , true ) ; return ; } } if ( IS_CALLABLE ( then ) ) { // PromiseResolveThenableJob var id ; var name = "PromiseResolveThenableJob" ; var instrumenting = DEBUG_IS_ACTIVE ; % EnqueueMicrotask ( function ( ) { if ( instrumenting ) { % DebugAsyncTaskEvent ( { type : "willHandle" , id : id , name : name } ) ; } var callbacks = CreateResolvingFunctions ( promise ) ; try { % _Call ( then , resolution , callbacks . resolve , callbacks . reject ) ; } catch ( e ) { % _Call ( callbacks . reject , UNDEFINED , e ) ; } if ( instrumenting ) { % DebugAsyncTaskEvent ( { type : "didHandle" , id : id , name : name } ) ; } } ) ; if ( instrumenting ) { id = ++ lastMicrotaskId ; % DebugAsyncTaskEvent ( { type : "enqueue" , id : id , name : name } ) ; } return ; } } FulfillPromise ( promise , kFulfilled , resolution , promiseFulfillReactionsSymbol ) ; }
ES#sec-promise-resolve-functions Promise Resolve Functions, steps 6-13
ES#sec - promise - resolve - functions Promise Resolve Functions steps 6 - 13