// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/builtins/builtins-promise-gen.h"

#include "src/builtins/builtins-constructor-gen.h"
#include "src/builtins/builtins-iterator-gen.h"
#include "src/builtins/builtins-utils-gen.h"
#include "src/builtins/builtins.h"
#include "src/code-factory.h"
#include "src/code-stub-assembler.h"
#include "src/objects-inl.h"
#include "src/objects/js-promise.h"
#include "src/objects/smi.h"

namespace v8 {
namespace internal {

using compiler::Node;
using IteratorRecord = BaseBuiltinsFromDSLAssembler::IteratorRecord;

Node* PromiseBuiltinsAssembler::AllocateJSPromise(Node* context) {
  Node* const native_context = LoadNativeContext(context);
  Node* const promise_fun =
      LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
  CSA_ASSERT(this, IsFunctionWithPrototypeSlotMap(LoadMap(promise_fun)));
  Node* const promise_map =
      LoadObjectField(promise_fun, JSFunction::kPrototypeOrInitialMapOffset);
  Node* const promise = Allocate(JSPromise::kSizeWithEmbedderFields);
  StoreMapNoWriteBarrier(promise, promise_map);
  StoreObjectFieldRoot(promise, JSPromise::kPropertiesOrHashOffset,
                       RootIndex::kEmptyFixedArray);
  StoreObjectFieldRoot(promise, JSPromise::kElementsOffset,
                       RootIndex::kEmptyFixedArray);
  return promise;
}

void PromiseBuiltinsAssembler::PromiseInit(Node* promise) {
  STATIC_ASSERT(v8::Promise::kPending == 0);
  StoreObjectFieldNoWriteBarrier(promise, JSPromise::kReactionsOrResultOffset,
                                 SmiConstant(Smi::zero()));
  StoreObjectFieldNoWriteBarrier(promise, JSPromise::kFlagsOffset,
                                 SmiConstant(Smi::zero()));
  for (int i = 0; i < v8::Promise::kEmbedderFieldCount; i++) {
    int offset = JSPromise::kSize + i * kPointerSize;
    StoreObjectFieldNoWriteBarrier(promise, offset, SmiConstant(Smi::zero()));
  }
}

Node* PromiseBuiltinsAssembler::AllocateAndInitJSPromise(Node* context) {
  return AllocateAndInitJSPromise(context, UndefinedConstant());
}

Node* PromiseBuiltinsAssembler::AllocateAndInitJSPromise(Node* context,
                                                         Node* parent) {
  Node* const instance = AllocateJSPromise(context);
  PromiseInit(instance);

  Label out(this);
  GotoIfNot(IsPromiseHookEnabledOrHasAsyncEventDelegate(), &out);
  CallRuntime(Runtime::kPromiseHookInit, context, instance, parent);
  Goto(&out);

  BIND(&out);
  return instance;
}

Node* PromiseBuiltinsAssembler::AllocateAndSetJSPromise(
    Node* context, v8::Promise::PromiseState status, Node* result) {
  DCHECK_NE(Promise::kPending, status);

  Node* const instance = AllocateJSPromise(context);
  StoreObjectFieldNoWriteBarrier(instance, JSPromise::kReactionsOrResultOffset,
                                 result);
  STATIC_ASSERT(JSPromise::kStatusShift == 0);
  StoreObjectFieldNoWriteBarrier(instance, JSPromise::kFlagsOffset,
                                 SmiConstant(status));
  for (int i = 0; i < v8::Promise::kEmbedderFieldCount; i++) {
    int offset = JSPromise::kSize + i * kPointerSize;
    StoreObjectFieldNoWriteBarrier(instance, offset, SmiConstant(0));
  }

  Label out(this);
  GotoIfNot(IsPromiseHookEnabledOrHasAsyncEventDelegate(), &out);
  CallRuntime(Runtime::kPromiseHookInit, context, instance,
              UndefinedConstant());
  Goto(&out);

  BIND(&out);
  return instance;
}

std::pair<Node*, Node*>
PromiseBuiltinsAssembler::CreatePromiseResolvingFunctions(
    Node* promise, Node* debug_event, Node* native_context) {
  Node* const promise_context = CreatePromiseResolvingFunctionsContext(
      promise, debug_event, native_context);
  Node* const map = LoadContextElement(
      native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
  Node* const resolve_info = LoadContextElement(
      native_context,
      Context::PROMISE_CAPABILITY_DEFAULT_RESOLVE_SHARED_FUN_INDEX);
  Node* const resolve =
      AllocateFunctionWithMapAndContext(map, resolve_info, promise_context);
  Node* const reject_info = LoadContextElement(
      native_context,
      Context::PROMISE_CAPABILITY_DEFAULT_REJECT_SHARED_FUN_INDEX);
  Node* const reject =
      AllocateFunctionWithMapAndContext(map, reject_info, promise_context);
  return std::make_pair(resolve, reject);
}

// ES #sec-newpromisecapability
TF_BUILTIN(NewPromiseCapability, PromiseBuiltinsAssembler) {
  Node* const context = Parameter(Descriptor::kContext);
  Node* const constructor = Parameter(Descriptor::kConstructor);
  Node* const debug_event = Parameter(Descriptor::kDebugEvent);
  TNode<Context> const native_context = LoadNativeContext(context);

  Label if_not_constructor(this, Label::kDeferred),
      if_notcallable(this, Label::kDeferred), if_fast_promise_capability(this),
      if_slow_promise_capability(this, Label::kDeferred);
  GotoIf(TaggedIsSmi(constructor), &if_not_constructor);
  GotoIfNot(IsConstructorMap(LoadMap(constructor)), &if_not_constructor);
  Branch(WordEqual(constructor,
                   LoadContextElement(native_context,
                                      Context::PROMISE_FUNCTION_INDEX)),
         &if_fast_promise_capability, &if_slow_promise_capability);

  BIND(&if_fast_promise_capability);
  {
    Node* promise =
        AllocateAndInitJSPromise(native_context, UndefinedConstant());

    Node* resolve = nullptr;
    Node* reject = nullptr;
    std::tie(resolve, reject) =
        CreatePromiseResolvingFunctions(promise, debug_event, native_context);

    Node* capability = Allocate(PromiseCapability::kSize);
    StoreMapNoWriteBarrier(capability, RootIndex::kPromiseCapabilityMap);
    StoreObjectFieldNoWriteBarrier(capability,
                                   PromiseCapability::kPromiseOffset, promise);
    StoreObjectFieldNoWriteBarrier(capability,
                                   PromiseCapability::kResolveOffset, resolve);
    StoreObjectFieldNoWriteBarrier(capability, PromiseCapability::kRejectOffset,
                                   reject);
    Return(capability);
  }

  BIND(&if_slow_promise_capability);
  {
    Node* capability = Allocate(PromiseCapability::kSize);
    StoreMapNoWriteBarrier(capability, RootIndex::kPromiseCapabilityMap);
    StoreObjectFieldRoot(capability, PromiseCapability::kPromiseOffset,
                         RootIndex::kUndefinedValue);
    StoreObjectFieldRoot(capability, PromiseCapability::kResolveOffset,
                         RootIndex::kUndefinedValue);
    StoreObjectFieldRoot(capability, PromiseCapability::kRejectOffset,
                         RootIndex::kUndefinedValue);

    Node* executor_context =
        CreatePromiseGetCapabilitiesExecutorContext(capability, native_context);
    Node* executor_info = LoadContextElement(
        native_context, Context::PROMISE_GET_CAPABILITIES_EXECUTOR_SHARED_FUN);
    Node* function_map = LoadContextElement(
        native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
    TNode<JSFunction> executor = CAST(AllocateFunctionWithMapAndContext(
        function_map, executor_info, executor_context));

    Node* promise = Construct(native_context, CAST(constructor), executor);
    StoreObjectField(capability, PromiseCapability::kPromiseOffset, promise);

    Node* resolve =
        LoadObjectField(capability, PromiseCapability::kResolveOffset);
    GotoIf(TaggedIsSmi(resolve), &if_notcallable);
    GotoIfNot(IsCallable(resolve), &if_notcallable);

    Node* reject =
        LoadObjectField(capability, PromiseCapability::kRejectOffset);
    GotoIf(TaggedIsSmi(reject), &if_notcallable);
    GotoIfNot(IsCallable(reject), &if_notcallable);
    Return(capability);
  }

  BIND(&if_not_constructor);
  ThrowTypeError(context, MessageTemplate::kNotConstructor, constructor);

  BIND(&if_notcallable);
  ThrowTypeError(context, MessageTemplate::kPromiseNonCallable);
}

Node* PromiseBuiltinsAssembler::CreatePromiseContext(Node* native_context,
                                                     int slots) {
  DCHECK_GE(slots, Context::MIN_CONTEXT_SLOTS);

  Node* const context = AllocateInNewSpace(FixedArray::SizeFor(slots));
  InitializeFunctionContext(native_context, context, slots);
  return context;
}

Node* PromiseBuiltinsAssembler::CreatePromiseAllResolveElementContext(
    Node* promise_capability, Node* native_context) {
  CSA_ASSERT(this, IsNativeContext(native_context));

  // TODO(bmeurer): Manually fold this into a single allocation.
  TNode<Map> array_map = CAST(LoadContextElement(
      native_context, Context::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX));
  TNode<JSArray> values_array = AllocateJSArray(
      PACKED_ELEMENTS, array_map, IntPtrConstant(0), SmiConstant(0));

  Node* const context =
      CreatePromiseContext(native_context, kPromiseAllResolveElementLength);
  StoreContextElementNoWriteBarrier(
      context, kPromiseAllResolveElementRemainingSlot, SmiConstant(1));
  StoreContextElementNoWriteBarrier(
      context, kPromiseAllResolveElementCapabilitySlot, promise_capability);
  StoreContextElementNoWriteBarrier(
      context, kPromiseAllResolveElementValuesArraySlot, values_array);

  return context;
}

Node* PromiseBuiltinsAssembler::CreatePromiseAllResolveElementFunction(
    Node* context, TNode<Smi> index, Node* native_context) {
  CSA_ASSERT(this, SmiGreaterThan(index, SmiConstant(0)));
  CSA_ASSERT(this, SmiLessThanOrEqual(
                       index, SmiConstant(PropertyArray::HashField::kMax)));
  CSA_ASSERT(this, IsNativeContext(native_context));

  Node* const map = LoadContextElement(
      native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
  Node* const resolve_info = LoadContextElement(
      native_context, Context::PROMISE_ALL_RESOLVE_ELEMENT_SHARED_FUN);
  Node* const resolve =
      AllocateFunctionWithMapAndContext(map, resolve_info, context);

  STATIC_ASSERT(PropertyArray::kNoHashSentinel == 0);
  StoreObjectFieldNoWriteBarrier(resolve, JSFunction::kPropertiesOrHashOffset,
                                 index);

  return resolve;
}

Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext(
    Node* promise, Node* debug_event, Node* native_context) {
  Node* const context =
      CreatePromiseContext(native_context, kPromiseContextLength);
  StoreContextElementNoWriteBarrier(context, kPromiseSlot, promise);
  StoreContextElementNoWriteBarrier(context, kAlreadyResolvedSlot,
                                    FalseConstant());
  StoreContextElementNoWriteBarrier(context, kDebugEventSlot, debug_event);
  return context;
}

Node* PromiseBuiltinsAssembler::CreatePromiseGetCapabilitiesExecutorContext(
    Node* promise_capability, Node* native_context) {
  int kContextLength = kCapabilitiesContextLength;
  Node* context = CreatePromiseContext(native_context, kContextLength);
  StoreContextElementNoWriteBarrier(context, kCapabilitySlot,
                                    promise_capability);
  return context;
}

Node* PromiseBuiltinsAssembler::PromiseHasHandler(Node* promise) {
  Node* const flags = LoadObjectField(promise, JSPromise::kFlagsOffset);
  return IsSetWord(SmiUntag(flags), 1 << JSPromise::kHasHandlerBit);
}

void PromiseBuiltinsAssembler::PromiseSetHasHandler(Node* promise) {
  TNode<Smi> const flags =
      CAST(LoadObjectField(promise, JSPromise::kFlagsOffset));
  TNode<Smi> const new_flags =
      SmiOr(flags, SmiConstant(1 << JSPromise::kHasHandlerBit));
  StoreObjectFieldNoWriteBarrier(promise, JSPromise::kFlagsOffset, new_flags);
}

Node* PromiseBuiltinsAssembler::IsPromiseStatus(
    Node* actual, v8::Promise::PromiseState expected) {
  return Word32Equal(actual, Int32Constant(expected));
}

Node* PromiseBuiltinsAssembler::PromiseStatus(Node* promise) {
  STATIC_ASSERT(JSPromise::kStatusShift == 0);
  TNode<Smi> const flags =
      CAST(LoadObjectField(promise, JSPromise::kFlagsOffset));
  return Word32And(SmiToInt32(flags), Int32Constant(JSPromise::kStatusMask));
}

void PromiseBuiltinsAssembler::PromiseSetStatus(
    Node* promise, v8::Promise::PromiseState const status) {
  CSA_ASSERT(this,
             IsPromiseStatus(PromiseStatus(promise), v8::Promise::kPending));
  CHECK_NE(status, v8::Promise::kPending);

  TNode<Smi> mask = SmiConstant(status);
  TNode<Smi> const flags =
      CAST(LoadObjectField(promise, JSPromise::kFlagsOffset));
  StoreObjectFieldNoWriteBarrier(promise, JSPromise::kFlagsOffset,
                                 SmiOr(flags, mask));
}

void PromiseBuiltinsAssembler::PromiseSetHandledHint(Node* promise) {
  TNode<Smi> const flags =
      CAST(LoadObjectField(promise, JSPromise::kFlagsOffset));
  TNode<Smi> const new_flags =
      SmiOr(flags, SmiConstant(1 << JSPromise::kHandledHintBit));
  StoreObjectFieldNoWriteBarrier(promise, JSPromise::kFlagsOffset, new_flags);
}

// ES #sec-performpromisethen
void PromiseBuiltinsAssembler::PerformPromiseThen(
    Node* context, Node* promise, Node* on_fulfilled, Node* on_rejected,
    Node* result_promise_or_capability) {
  CSA_ASSERT(this, TaggedIsNotSmi(promise));
  CSA_ASSERT(this, IsJSPromise(promise));
  CSA_ASSERT(this,
             Word32Or(IsCallable(on_fulfilled), IsUndefined(on_fulfilled)));
  CSA_ASSERT(this, Word32Or(IsCallable(on_rejected), IsUndefined(on_rejected)));
  CSA_ASSERT(this, TaggedIsNotSmi(result_promise_or_capability));
  CSA_ASSERT(
      this,
      Word32Or(Word32Or(IsJSPromise(result_promise_or_capability),
                        IsPromiseCapability(result_promise_or_capability)),
               IsUndefined(result_promise_or_capability)));

  Label if_pending(this), if_notpending(this), done(this);
  Node* const status = PromiseStatus(promise);
  Branch(IsPromiseStatus(status, v8::Promise::kPending), &if_pending,
         &if_notpending);

  BIND(&if_pending);
  {
    // The {promise} is still in "Pending" state, so we just record a new
    // PromiseReaction holding both the onFulfilled and onRejected callbacks.
    // Once the {promise} is resolved we decide on the concrete handler to
    // push onto the microtask queue.
    Node* const promise_reactions =
        LoadObjectField(promise, JSPromise::kReactionsOrResultOffset);
    Node* const reaction =
        AllocatePromiseReaction(promise_reactions, result_promise_or_capability,
                                on_fulfilled, on_rejected);
    StoreObjectField(promise, JSPromise::kReactionsOrResultOffset, reaction);
    Goto(&done);
  }

  BIND(&if_notpending);
  {
    VARIABLE(var_map, MachineRepresentation::kTagged);
    VARIABLE(var_handler, MachineRepresentation::kTagged);
    Label if_fulfilled(this), if_rejected(this, Label::kDeferred),
        enqueue(this);
    Branch(IsPromiseStatus(status, v8::Promise::kFulfilled), &if_fulfilled,
           &if_rejected);

    BIND(&if_fulfilled);
    {
      var_map.Bind(LoadRoot(RootIndex::kPromiseFulfillReactionJobTaskMap));
      var_handler.Bind(on_fulfilled);
      Goto(&enqueue);
    }

    BIND(&if_rejected);
    {
      CSA_ASSERT(this, IsPromiseStatus(status, v8::Promise::kRejected));
      var_map.Bind(LoadRoot(RootIndex::kPromiseRejectReactionJobTaskMap));
      var_handler.Bind(on_rejected);
      GotoIf(PromiseHasHandler(promise), &enqueue);
      CallRuntime(Runtime::kPromiseRevokeReject, context, promise);
      Goto(&enqueue);
    }

    BIND(&enqueue);
    Node* argument =
        LoadObjectField(promise, JSPromise::kReactionsOrResultOffset);
    Node* microtask = AllocatePromiseReactionJobTask(
        var_map.value(), context, argument, var_handler.value(),
        result_promise_or_capability);
    CallBuiltin(Builtins::kEnqueueMicrotask, NoContextConstant(), microtask);
    Goto(&done);
  }

  BIND(&done);
  PromiseSetHasHandler(promise);
}

// ES #sec-performpromisethen
TF_BUILTIN(PerformPromiseThen, PromiseBuiltinsAssembler) {
  Node* const context = Parameter(Descriptor::kContext);
  Node* const promise = Parameter(Descriptor::kPromise);
  Node* const on_fulfilled = Parameter(Descriptor::kOnFulfilled);
  Node* const on_rejected = Parameter(Descriptor::kOnRejected);
  Node* const result_promise = Parameter(Descriptor::kResultPromise);

  CSA_ASSERT(this, TaggedIsNotSmi(result_promise));
  CSA_ASSERT(
      this, Word32Or(IsJSPromise(result_promise), IsUndefined(result_promise)));

  PerformPromiseThen(context, promise, on_fulfilled, on_rejected,
                     result_promise);
  Return(result_promise);
}

Node* PromiseBuiltinsAssembler::AllocatePromiseReaction(
    Node* next, Node* promise_or_capability, Node* fulfill_handler,
    Node* reject_handler) {
  Node* const reaction = Allocate(PromiseReaction::kSize);
  StoreMapNoWriteBarrier(reaction, RootIndex::kPromiseReactionMap);
  StoreObjectFieldNoWriteBarrier(reaction, PromiseReaction::kNextOffset, next);
  StoreObjectFieldNoWriteBarrier(reaction,
                                 PromiseReaction::kPromiseOrCapabilityOffset,
                                 promise_or_capability);
  StoreObjectFieldNoWriteBarrier(
      reaction, PromiseReaction::kFulfillHandlerOffset, fulfill_handler);
  StoreObjectFieldNoWriteBarrier(
      reaction, PromiseReaction::kRejectHandlerOffset, reject_handler);
  return reaction;
}

Node* PromiseBuiltinsAssembler::AllocatePromiseReactionJobTask(
    Node* map, Node* context, Node* argument, Node* handler,
    Node* promise_or_capability) {
  Node* const microtask = Allocate(PromiseReactionJobTask::kSize);
  StoreMapNoWriteBarrier(microtask, map);
  StoreObjectFieldNoWriteBarrier(
      microtask, PromiseReactionJobTask::kArgumentOffset, argument);
  StoreObjectFieldNoWriteBarrier(
      microtask, PromiseReactionJobTask::kContextOffset, context);
  StoreObjectFieldNoWriteBarrier(
      microtask, PromiseReactionJobTask::kHandlerOffset, handler);
  StoreObjectFieldNoWriteBarrier(
      microtask, PromiseReactionJobTask::kPromiseOrCapabilityOffset,
      promise_or_capability);
  return microtask;
}

Node* PromiseBuiltinsAssembler::AllocatePromiseReactionJobTask(
    RootIndex map_root_index, Node* context, Node* argument, Node* handler,
    Node* promise_or_capability) {
  DCHECK(map_root_index == RootIndex::kPromiseFulfillReactionJobTaskMap ||
         map_root_index == RootIndex::kPromiseRejectReactionJobTaskMap);
  Node* const map = LoadRoot(map_root_index);
  return AllocatePromiseReactionJobTask(map, context, argument, handler,
                                        promise_or_capability);
}

Node* PromiseBuiltinsAssembler::AllocatePromiseResolveThenableJobTask(
    Node* promise_to_resolve, Node* then, Node* thenable, Node* context) {
  Node* const microtask = Allocate(PromiseResolveThenableJobTask::kSize);
  StoreMapNoWriteBarrier(microtask,
                         RootIndex::kPromiseResolveThenableJobTaskMap);
  StoreObjectFieldNoWriteBarrier(
      microtask, PromiseResolveThenableJobTask::kContextOffset, context);
  StoreObjectFieldNoWriteBarrier(
      microtask, PromiseResolveThenableJobTask::kPromiseToResolveOffset,
      promise_to_resolve);
  StoreObjectFieldNoWriteBarrier(
      microtask, PromiseResolveThenableJobTask::kThenOffset, then);
  StoreObjectFieldNoWriteBarrier(
      microtask, PromiseResolveThenableJobTask::kThenableOffset, thenable);
  return microtask;
}

// ES #sec-triggerpromisereactions
Node* PromiseBuiltinsAssembler::TriggerPromiseReactions(
    Node* context, Node* reactions, Node* argument,
    PromiseReaction::Type type) {
  // We need to reverse the {reactions} here, since we record them on the
  // JSPromise in the reverse order.
  {
    VARIABLE(var_current, MachineRepresentation::kTagged, reactions);
    VARIABLE(var_reversed, MachineRepresentation::kTagged,
             SmiConstant(Smi::zero()));

    Label loop(this, {&var_current, &var_reversed}), done_loop(this);
    Goto(&loop);
    BIND(&loop);
    {
      Node* current = var_current.value();
      GotoIf(TaggedIsSmi(current), &done_loop);
      var_current.Bind(LoadObjectField(current, PromiseReaction::kNextOffset));
      StoreObjectField(current, PromiseReaction::kNextOffset,
                       var_reversed.value());
      var_reversed.Bind(current);
      Goto(&loop);
    }
    BIND(&done_loop);
    reactions = var_reversed.value();
  }

  // Morph the {reactions} into PromiseReactionJobTasks and push them
  // onto the microtask queue.
  {
    VARIABLE(var_current, MachineRepresentation::kTagged, reactions);

    Label loop(this, {&var_current}), done_loop(this);
    Goto(&loop);
    BIND(&loop);
    {
      Node* current = var_current.value();
      GotoIf(TaggedIsSmi(current), &done_loop);
      var_current.Bind(LoadObjectField(current, PromiseReaction::kNextOffset));

      // Morph {current} from a PromiseReaction into a PromiseReactionJobTask
      // and schedule that on the microtask queue. We try to minimize the number
      // of stores here to avoid screwing up the store buffer.
      STATIC_ASSERT(PromiseReaction::kSize == PromiseReactionJobTask::kSize);
      if (type == PromiseReaction::kFulfill) {
        StoreMapNoWriteBarrier(current,
                               RootIndex::kPromiseFulfillReactionJobTaskMap);
        StoreObjectField(current, PromiseReactionJobTask::kArgumentOffset,
                         argument);
        StoreObjectField(current, PromiseReactionJobTask::kContextOffset,
                         context);
        STATIC_ASSERT(PromiseReaction::kFulfillHandlerOffset ==
                      PromiseReactionJobTask::kHandlerOffset);
        STATIC_ASSERT(PromiseReaction::kPromiseOrCapabilityOffset ==
                      PromiseReactionJobTask::kPromiseOrCapabilityOffset);
      } else {
        Node* handler =
            LoadObjectField(current, PromiseReaction::kRejectHandlerOffset);
        StoreMapNoWriteBarrier(current,
                               RootIndex::kPromiseRejectReactionJobTaskMap);
        StoreObjectField(current, PromiseReactionJobTask::kArgumentOffset,
                         argument);
        StoreObjectField(current, PromiseReactionJobTask::kContextOffset,
                         context);
        StoreObjectField(current, PromiseReactionJobTask::kHandlerOffset,
                         handler);
        STATIC_ASSERT(PromiseReaction::kPromiseOrCapabilityOffset ==
                      PromiseReactionJobTask::kPromiseOrCapabilityOffset);
      }
      CallBuiltin(Builtins::kEnqueueMicrotask, NoContextConstant(), current);
      Goto(&loop);
    }
    BIND(&done_loop);
  }

  return UndefinedConstant();
}

template <typename... TArgs>
Node* PromiseBuiltinsAssembler::InvokeThen(Node* native_context, Node* receiver,
                                           TArgs... args) {
  CSA_ASSERT(this, IsNativeContext(native_context));

  VARIABLE(var_result, MachineRepresentation::kTagged);
  Label if_fast(this), if_slow(this, Label::kDeferred), done(this, &var_result);
  GotoIf(TaggedIsSmi(receiver), &if_slow);
  Node* const receiver_map = LoadMap(receiver);
  // We can skip the "then" lookup on {receiver} if it's [[Prototype]]
  // is the (initial) Promise.prototype and the Promise#then protector
  // is intact, as that guards the lookup path for the "then" property
  // on JSPromise instances which have the (initial) %PromisePrototype%.
  BranchIfPromiseThenLookupChainIntact(native_context, receiver_map, &if_fast,
                                       &if_slow);

  BIND(&if_fast);
  {
    Node* const then =
        LoadContextElement(native_context, Context::PROMISE_THEN_INDEX);
    Node* const result =
        CallJS(CodeFactory::CallFunction(
                   isolate(), ConvertReceiverMode::kNotNullOrUndefined),
               native_context, then, receiver, args...);
    var_result.Bind(result);
    Goto(&done);
  }

  BIND(&if_slow);
  {
    Node* const then = GetProperty(native_context, receiver,
                                   isolate()->factory()->then_string());
    Node* const result = CallJS(
        CodeFactory::Call(isolate(), ConvertReceiverMode::kNotNullOrUndefined),
        native_context, then, receiver, args...);
    var_result.Bind(result);
    Goto(&done);
  }

  BIND(&done);
  return var_result.value();
}

Node* PromiseBuiltinsAssembler::InvokeResolve(Node* native_context,
                                              Node* constructor, Node* value,
                                              Label* if_exception,
                                              Variable* var_exception) {
  CSA_ASSERT(this, IsNativeContext(native_context));

  VARIABLE(var_result, MachineRepresentation::kTagged);
  Label if_fast(this), if_slow(this, Label::kDeferred), done(this, &var_result);
  // We can skip the "resolve" lookup on {constructor} if it's the
  // Promise constructor and the Promise.resolve protector is intact,
  // as that guards the lookup path for the "resolve" property on the
  // Promise constructor.
  BranchIfPromiseResolveLookupChainIntact(native_context, constructor, &if_fast,
                                          &if_slow);

  BIND(&if_fast);
  {
    Node* const result = CallBuiltin(Builtins::kPromiseResolve, native_context,
                                     constructor, value);
    GotoIfException(result, if_exception, var_exception);

    var_result.Bind(result);
    Goto(&done);
  }

  BIND(&if_slow);
  {
    Node* const resolve =
        GetProperty(native_context, constructor, factory()->resolve_string());
    GotoIfException(resolve, if_exception, var_exception);

    Node* const result = CallJS(
        CodeFactory::Call(isolate(), ConvertReceiverMode::kNotNullOrUndefined),
        native_context, resolve, constructor, value);
    GotoIfException(result, if_exception, var_exception);

    var_result.Bind(result);
    Goto(&done);
  }

  BIND(&done);
  return var_result.value();
}

void PromiseBuiltinsAssembler::BranchIfPromiseResolveLookupChainIntact(
    Node* native_context, Node* constructor, Label* if_fast, Label* if_slow) {
  CSA_ASSERT(this, IsNativeContext(native_context));

  GotoIfForceSlowPath(if_slow);
  Node* const promise_fun =
      LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
  GotoIfNot(WordEqual(promise_fun, constructor), if_slow);
  Branch(IsPromiseResolveProtectorCellInvalid(), if_slow, if_fast);
}

void PromiseBuiltinsAssembler::GotoIfNotPromiseResolveLookupChainIntact(
    Node* native_context, Node* constructor, Label* if_slow) {
  Label if_fast(this);
  BranchIfPromiseResolveLookupChainIntact(native_context, constructor, &if_fast,
                                          if_slow);
  BIND(&if_fast);
}

void PromiseBuiltinsAssembler::BranchIfPromiseSpeciesLookupChainIntact(
    Node* native_context, Node* promise_map, Label* if_fast, Label* if_slow) {
  CSA_ASSERT(this, IsNativeContext(native_context));
  CSA_ASSERT(this, IsJSPromiseMap(promise_map));

  Node* const promise_prototype =
      LoadContextElement(native_context, Context::PROMISE_PROTOTYPE_INDEX);
  GotoIfForceSlowPath(if_slow);
  GotoIfNot(WordEqual(LoadMapPrototype(promise_map), promise_prototype),
            if_slow);
  Branch(IsPromiseSpeciesProtectorCellInvalid(), if_slow, if_fast);
}

void PromiseBuiltinsAssembler::BranchIfPromiseThenLookupChainIntact(
    Node* native_context, Node* receiver_map, Label* if_fast, Label* if_slow) {
  CSA_ASSERT(this, IsMap(receiver_map));
  CSA_ASSERT(this, IsNativeContext(native_context));

  GotoIfForceSlowPath(if_slow);
  GotoIfNot(IsJSPromiseMap(receiver_map), if_slow);
  Node* const promise_prototype =
      LoadContextElement(native_context, Context::PROMISE_PROTOTYPE_INDEX);
  GotoIfNot(WordEqual(LoadMapPrototype(receiver_map), promise_prototype),
            if_slow);
  Branch(IsPromiseThenProtectorCellInvalid(), if_slow, if_fast);
}

void PromiseBuiltinsAssembler::BranchIfAccessCheckFailed(
    Node* context, Node* native_context, Node* promise_constructor,
    Node* executor, Label* if_noaccess) {
  VARIABLE(var_executor, MachineRepresentation::kTagged);
  var_executor.Bind(executor);
  Label has_access(this), call_runtime(this, Label::kDeferred);

  // If executor is a bound function, load the bound function until we've
  // reached an actual function.
  Label found_function(this), loop_over_bound_function(this, &var_executor);
  Goto(&loop_over_bound_function);
  BIND(&loop_over_bound_function);
  {
    Node* executor_type = LoadInstanceType(var_executor.value());
    GotoIf(InstanceTypeEqual(executor_type, JS_FUNCTION_TYPE), &found_function);
    GotoIfNot(InstanceTypeEqual(executor_type, JS_BOUND_FUNCTION_TYPE),
              &call_runtime);
    var_executor.Bind(LoadObjectField(
        var_executor.value(), JSBoundFunction::kBoundTargetFunctionOffset));
    Goto(&loop_over_bound_function);
  }

  // Load the context from the function and compare it to the Promise
  // constructor's context. If they match, everything is fine, otherwise, bail
  // out to the runtime.
  BIND(&found_function);
  {
    Node* function_context =
        LoadObjectField(var_executor.value(), JSFunction::kContextOffset);
    Node* native_function_context = LoadNativeContext(function_context);
    Branch(WordEqual(native_context, native_function_context), &has_access,
           &call_runtime);
  }

  BIND(&call_runtime);
  {
    Branch(WordEqual(CallRuntime(Runtime::kAllowDynamicFunction, context,
                                 promise_constructor),
                     TrueConstant()),
           &has_access, if_noaccess);
  }

  BIND(&has_access);
}

void PromiseBuiltinsAssembler::SetForwardingHandlerIfTrue(
    Node* context, Node* condition, const NodeGenerator& object) {
  Label done(this);
  GotoIfNot(condition, &done);
  SetPropertyStrict(
      CAST(context), CAST(object()),
      HeapConstant(factory()->promise_forwarding_handler_symbol()),
      TrueConstant());
  Goto(&done);
  BIND(&done);
}

void PromiseBuiltinsAssembler::SetPromiseHandledByIfTrue(
    Node* context, Node* condition, Node* promise,
    const NodeGenerator& handled_by) {
  Label done(this);
  GotoIfNot(condition, &done);
  GotoIf(TaggedIsSmi(promise), &done);
  GotoIfNot(HasInstanceType(promise, JS_PROMISE_TYPE), &done);
  SetPropertyStrict(CAST(context), CAST(promise),
                    HeapConstant(factory()->promise_handled_by_symbol()),
                    CAST(handled_by()));
  Goto(&done);
  BIND(&done);
}

// ES #sec-promise-reject-functions
TF_BUILTIN(PromiseCapabilityDefaultReject, PromiseBuiltinsAssembler) {
  Node* const reason = Parameter(Descriptor::kReason);
  Node* const context = Parameter(Descriptor::kContext);

  // 2. Let promise be F.[[Promise]].
  Node* const promise = LoadContextElement(context, kPromiseSlot);

  // 3. Let alreadyResolved be F.[[AlreadyResolved]].
  Label if_already_resolved(this, Label::kDeferred);
  Node* const already_resolved =
      LoadContextElement(context, kAlreadyResolvedSlot);

  // 4. If alreadyResolved.[[Value]] is true, return undefined.
  GotoIf(IsTrue(already_resolved), &if_already_resolved);

  // 5. Set alreadyResolved.[[Value]] to true.
  StoreContextElementNoWriteBarrier(context, kAlreadyResolvedSlot,
                                    TrueConstant());

  // 6. Return RejectPromise(promise, reason).
  Node* const debug_event = LoadContextElement(context, kDebugEventSlot);
  Return(CallBuiltin(Builtins::kRejectPromise, context, promise, reason,
                     debug_event));

  BIND(&if_already_resolved);
  {
    Return(CallRuntime(Runtime::kPromiseRejectAfterResolved, context, promise,
                       reason));
  }
}

// ES #sec-promise-resolve-functions
TF_BUILTIN(PromiseCapabilityDefaultResolve, PromiseBuiltinsAssembler) {
  Node* const resolution = Parameter(Descriptor::kResolution);
  Node* const context = Parameter(Descriptor::kContext);

  // 2. Let promise be F.[[Promise]].
  Node* const promise = LoadContextElement(context, kPromiseSlot);

  // 3. Let alreadyResolved be F.[[AlreadyResolved]].
  Label if_already_resolved(this, Label::kDeferred);
  Node* const already_resolved =
      LoadContextElement(context, kAlreadyResolvedSlot);

  // 4. If alreadyResolved.[[Value]] is true, return undefined.
  GotoIf(IsTrue(already_resolved), &if_already_resolved);

  // 5. Set alreadyResolved.[[Value]] to true.
  StoreContextElementNoWriteBarrier(context, kAlreadyResolvedSlot,
                                    TrueConstant());

  // The rest of the logic (and the catch prediction) is
  // encapsulated in the dedicated ResolvePromise builtin.
  Return(CallBuiltin(Builtins::kResolvePromise, context, promise, resolution));

  BIND(&if_already_resolved);
  {
    Return(CallRuntime(Runtime::kPromiseResolveAfterResolved, context, promise,
                       resolution));
  }
}

TF_BUILTIN(PromiseConstructorLazyDeoptContinuation, PromiseBuiltinsAssembler) {
  Node* promise = Parameter(Descriptor::kPromise);
  Node* reject = Parameter(Descriptor::kReject);
  Node* exception = Parameter(Descriptor::kException);
  Node* const context = Parameter(Descriptor::kContext);

  Label finally(this);

  GotoIf(IsTheHole(exception), &finally);
  CallJS(CodeFactory::Call(isolate(), ConvertReceiverMode::kNotNullOrUndefined),
         context, reject, UndefinedConstant(), exception);
  Goto(&finally);

  BIND(&finally);
  Return(promise);
}

// ES6 #sec-promise-executor
TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) {
  Node* const executor = Parameter(Descriptor::kExecutor);
  Node* const new_target = Parameter(Descriptor::kJSNewTarget);
  Node* const context = Parameter(Descriptor::kContext);
  Isolate* isolate = this->isolate();

  Label if_targetisundefined(this, Label::kDeferred);

  GotoIf(IsUndefined(new_target), &if_targetisundefined);

  Label if_notcallable(this, Label::kDeferred);

  GotoIf(TaggedIsSmi(executor), &if_notcallable);

  Node* const executor_map = LoadMap(executor);
  GotoIfNot(IsCallableMap(executor_map), &if_notcallable);

  Node* const native_context = LoadNativeContext(context);
  Node* const promise_fun =
      LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
  Node* const is_debug_active = IsDebugActive();
  Label if_targetisnotmodified(this),
      if_targetismodified(this, Label::kDeferred), run_executor(this),
      debug_push(this), if_noaccess(this, Label::kDeferred);

  BranchIfAccessCheckFailed(context, native_context, promise_fun, executor,
                            &if_noaccess);

  Branch(WordEqual(promise_fun, new_target), &if_targetisnotmodified,
         &if_targetismodified);

  VARIABLE(var_result, MachineRepresentation::kTagged);
  VARIABLE(var_reject_call, MachineRepresentation::kTagged);
  VARIABLE(var_reason, MachineRepresentation::kTagged);

  BIND(&if_targetisnotmodified);
  {
    Node* const instance = AllocateAndInitJSPromise(context);
    var_result.Bind(instance);
    Goto(&debug_push);
  }

  BIND(&if_targetismodified);
  {
    ConstructorBuiltinsAssembler constructor_assembler(this->state());
    Node* const instance = constructor_assembler.EmitFastNewObject(
        context, promise_fun, new_target);
    PromiseInit(instance);
    var_result.Bind(instance);

    GotoIfNot(IsPromiseHookEnabledOrHasAsyncEventDelegate(), &debug_push);
    CallRuntime(Runtime::kPromiseHookInit, context, instance,
                UndefinedConstant());
    Goto(&debug_push);
  }

  BIND(&debug_push);
  {
    GotoIfNot(is_debug_active, &run_executor);
    CallRuntime(Runtime::kDebugPushPromise, context, var_result.value());
    Goto(&run_executor);
  }

  BIND(&run_executor);
  {
    Label out(this), if_rejectpromise(this), debug_pop(this, Label::kDeferred);

    Node *resolve, *reject;
    std::tie(resolve, reject) = CreatePromiseResolvingFunctions(
        var_result.value(), TrueConstant(), native_context);

    Node* const maybe_exception = CallJS(
        CodeFactory::Call(isolate, ConvertReceiverMode::kNullOrUndefined),
        context, executor, UndefinedConstant(), resolve, reject);

    GotoIfException(maybe_exception, &if_rejectpromise, &var_reason);
    Branch(is_debug_active, &debug_pop, &out);

    BIND(&if_rejectpromise);
    {
      CallJS(CodeFactory::Call(isolate, ConvertReceiverMode::kNullOrUndefined),
             context, reject, UndefinedConstant(), var_reason.value());
      Branch(is_debug_active, &debug_pop, &out);
    }

    BIND(&debug_pop);
    {
      CallRuntime(Runtime::kDebugPopPromise, context);
      Goto(&out);
    }
    BIND(&out);
    Return(var_result.value());
  }

  // 1. If NewTarget is undefined, throw a TypeError exception.
  BIND(&if_targetisundefined);
  ThrowTypeError(context, MessageTemplate::kNotAPromise, new_target);

  // 2. If IsCallable(executor) is false, throw a TypeError exception.
  BIND(&if_notcallable);
  ThrowTypeError(context, MessageTemplate::kResolverNotAFunction, executor);

  // Silently fail if the stack looks fishy.
  BIND(&if_noaccess);
  {
    Node* const counter_id =
        SmiConstant(v8::Isolate::kPromiseConstructorReturnedUndefined);
    CallRuntime(Runtime::kIncrementUseCounter, context, counter_id);
    Return(UndefinedConstant());
  }
}

// V8 Extras: v8.createPromise(parent)
TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) {
  Node* const parent = Parameter(Descriptor::kParent);
  Node* const context = Parameter(Descriptor::kContext);
  Return(AllocateAndInitJSPromise(context, parent));
}

// V8 Extras: v8.rejectPromise(promise, reason)
TF_BUILTIN(PromiseInternalReject, PromiseBuiltinsAssembler) {
  Node* const promise = Parameter(Descriptor::kPromise);
  Node* const reason = Parameter(Descriptor::kReason);
  Node* const context = Parameter(Descriptor::kContext);
  // We pass true to trigger the debugger's on exception handler.
  Return(CallBuiltin(Builtins::kRejectPromise, context, promise, reason,
                     TrueConstant()));
}

// V8 Extras: v8.resolvePromise(promise, resolution)
TF_BUILTIN(PromiseInternalResolve, PromiseBuiltinsAssembler) {
  Node* const promise = Parameter(Descriptor::kPromise);
  Node* const resolution = Parameter(Descriptor::kResolution);
  Node* const context = Parameter(Descriptor::kContext);
  Return(CallBuiltin(Builtins::kResolvePromise, context, promise, resolution));
}

// ES#sec-promise.prototype.then
// Promise.prototype.then ( onFulfilled, onRejected )
TF_BUILTIN(PromisePrototypeThen, PromiseBuiltinsAssembler) {
  // 1. Let promise be the this value.
  Node* const promise = Parameter(Descriptor::kReceiver);
  Node* const on_fulfilled = Parameter(Descriptor::kOnFulfilled);
  Node* const on_rejected = Parameter(Descriptor::kOnRejected);
  Node* const context = Parameter(Descriptor::kContext);

  // 2. If IsPromise(promise) is false, throw a TypeError exception.
  ThrowIfNotInstanceType(context, promise, JS_PROMISE_TYPE,
                         "Promise.prototype.then");

  // 3. Let C be ? SpeciesConstructor(promise, %Promise%).
  Label fast_promise_capability(this), slow_constructor(this, Label::kDeferred),
      slow_promise_capability(this, Label::kDeferred);
  Node* const native_context = LoadNativeContext(context);
  Node* const promise_fun =
      LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
  Node* const promise_map = LoadMap(promise);
  BranchIfPromiseSpeciesLookupChainIntact(
      native_context, promise_map, &fast_promise_capability, &slow_constructor);

  BIND(&slow_constructor);
  Node* const constructor =
      SpeciesConstructor(native_context, promise, promise_fun);
  Branch(WordEqual(constructor, promise_fun), &fast_promise_capability,
         &slow_promise_capability);

  // 4. Let resultCapability be ? NewPromiseCapability(C).
  Label perform_promise_then(this);
  VARIABLE(var_result_promise, MachineRepresentation::kTagged);
  VARIABLE(var_result_promise_or_capability, MachineRepresentation::kTagged);

  BIND(&fast_promise_capability);
  {
    Node* const result_promise = AllocateAndInitJSPromise(context, promise);
    var_result_promise_or_capability.Bind(result_promise);
    var_result_promise.Bind(result_promise);
    Goto(&perform_promise_then);
  }

  BIND(&slow_promise_capability);
  {
    Node* const debug_event = TrueConstant();
    Node* const capability = CallBuiltin(Builtins::kNewPromiseCapability,
                                         context, constructor, debug_event);
    var_result_promise.Bind(
        LoadObjectField(capability, PromiseCapability::kPromiseOffset));
    var_result_promise_or_capability.Bind(capability);
    Goto(&perform_promise_then);
  }

  // 5. Return PerformPromiseThen(promise, onFulfilled, onRejected,
  //    resultCapability).
  BIND(&perform_promise_then);
  {
    // We do some work of the PerformPromiseThen operation here, in that
    // we check the handlers and turn non-callable handlers into undefined.
    // This is because this is the one and only callsite of PerformPromiseThen
    // that has to do this.

    // 3. If IsCallable(onFulfilled) is false, then
    //    a. Set onFulfilled to undefined.
    VARIABLE(var_on_fulfilled, MachineRepresentation::kTagged, on_fulfilled);
    Label if_fulfilled_done(this), if_fulfilled_notcallable(this);
    GotoIf(TaggedIsSmi(on_fulfilled), &if_fulfilled_notcallable);
    Branch(IsCallable(on_fulfilled), &if_fulfilled_done,
           &if_fulfilled_notcallable);
    BIND(&if_fulfilled_notcallable);
    var_on_fulfilled.Bind(UndefinedConstant());
    Goto(&if_fulfilled_done);
    BIND(&if_fulfilled_done);

    // 4. If IsCallable(onRejected) is false, then
    //    a. Set onRejected to undefined.
    VARIABLE(var_on_rejected, MachineRepresentation::kTagged, on_rejected);
    Label if_rejected_done(this), if_rejected_notcallable(this);
    GotoIf(TaggedIsSmi(on_rejected), &if_rejected_notcallable);
    Branch(IsCallable(on_rejected), &if_rejected_done,
           &if_rejected_notcallable);
    BIND(&if_rejected_notcallable);
    var_on_rejected.Bind(UndefinedConstant());
    Goto(&if_rejected_done);
    BIND(&if_rejected_done);

    PerformPromiseThen(context, promise, var_on_fulfilled.value(),
                       var_on_rejected.value(),
                       var_result_promise_or_capability.value());
    Return(var_result_promise.value());
  }
}

// ES#sec-promise.prototype.catch
// Promise.prototype.catch ( onRejected )
TF_BUILTIN(PromisePrototypeCatch, PromiseBuiltinsAssembler) {
  // 1. Let promise be the this value.
  Node* const receiver = Parameter(Descriptor::kReceiver);
  Node* const on_fulfilled = UndefinedConstant();
  Node* const on_rejected = Parameter(Descriptor::kOnRejected);
  Node* const context = Parameter(Descriptor::kContext);

  // 2. Return ? Invoke(promise, "then", « undefined, onRejected »).
  Node* const native_context = LoadNativeContext(context);
  Return(InvokeThen(native_context, receiver, on_fulfilled, on_rejected));
}

// ES #sec-promiseresolvethenablejob
TF_BUILTIN(PromiseResolveThenableJob, PromiseBuiltinsAssembler) {
  Node* const native_context = Parameter(Descriptor::kContext);
  Node* const promise_to_resolve = Parameter(Descriptor::kPromiseToResolve);
  Node* const thenable = Parameter(Descriptor::kThenable);
  Node* const then = Parameter(Descriptor::kThen);

  CSA_ASSERT(this, TaggedIsNotSmi(thenable));
  CSA_ASSERT(this, IsJSReceiver(thenable));
  CSA_ASSERT(this, IsJSPromise(promise_to_resolve));
  CSA_ASSERT(this, IsNativeContext(native_context));

  // 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.
  Label if_fast(this), if_slow(this, Label::kDeferred);
  Node* const promise_then =
      LoadContextElement(native_context, Context::PROMISE_THEN_INDEX);
  GotoIfNot(WordEqual(then, promise_then), &if_slow);
  Node* const thenable_map = LoadMap(thenable);
  GotoIfNot(IsJSPromiseMap(thenable_map), &if_slow);
  GotoIf(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(),
         &if_slow);
  BranchIfPromiseSpeciesLookupChainIntact(native_context, thenable_map,
                                          &if_fast, &if_slow);

  BIND(&if_fast);
  {
    // 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.
    TailCallBuiltin(Builtins::kPerformPromiseThen, native_context, thenable,
                    UndefinedConstant(), UndefinedConstant(),
                    promise_to_resolve);
  }

  BIND(&if_slow);
  {
    Node* resolve = nullptr;
    Node* reject = nullptr;
    std::tie(resolve, reject) = CreatePromiseResolvingFunctions(
        promise_to_resolve, FalseConstant(), native_context);

    Label if_exception(this, Label::kDeferred);
    VARIABLE(var_exception, MachineRepresentation::kTagged, TheHoleConstant());
    Node* const result = CallJS(
        CodeFactory::Call(isolate(), ConvertReceiverMode::kNotNullOrUndefined),
        native_context, then, thenable, resolve, reject);
    GotoIfException(result, &if_exception, &var_exception);
    Return(result);

    BIND(&if_exception);
    {
      // We need to reject the {thenable}.
      Node* const result = CallJS(
          CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
          native_context, reject, UndefinedConstant(), var_exception.value());
      Return(result);
    }
  }
}

// ES #sec-promisereactionjob
void PromiseBuiltinsAssembler::PromiseReactionJob(Node* context, Node* argument,
                                                  Node* handler,
                                                  Node* promise_or_capability,
                                                  PromiseReaction::Type type) {
  CSA_ASSERT(this, TaggedIsNotSmi(handler));
  CSA_ASSERT(this, Word32Or(IsUndefined(handler), IsCallable(handler)));
  CSA_ASSERT(this, TaggedIsNotSmi(promise_or_capability));
  CSA_ASSERT(this,
             Word32Or(Word32Or(IsJSPromise(promise_or_capability),
                               IsPromiseCapability(promise_or_capability)),
                      IsUndefined(promise_or_capability)));

  VARIABLE(var_handler_result, MachineRepresentation::kTagged, argument);
  Label if_handler_callable(this), if_fulfill(this), if_reject(this),
      if_internal(this);
  Branch(IsUndefined(handler),
         type == PromiseReaction::kFulfill ? &if_fulfill : &if_reject,
         &if_handler_callable);

  BIND(&if_handler_callable);
  {
    Node* const result = CallJS(
        CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
        context, handler, UndefinedConstant(), argument);
    GotoIfException(result, &if_reject, &var_handler_result);
    var_handler_result.Bind(result);
    Branch(IsUndefined(promise_or_capability), &if_internal, &if_fulfill);
  }

  BIND(&if_internal);
  {
    // There's no [[Capability]] for this promise reaction job, which
    // means that this is a specification-internal operation (aka await)
    // where the result does not matter (see the specification change in
    // https://github.com/tc39/ecma262/pull/1146 for details).
    Return(UndefinedConstant());
  }

  BIND(&if_fulfill);
  {
    Label if_promise(this), if_promise_capability(this, Label::kDeferred);
    Node* const value = var_handler_result.value();
    Branch(IsPromiseCapability(promise_or_capability), &if_promise_capability,
           &if_promise);

    BIND(&if_promise);
    {
      // For fast native promises we can skip the indirection
      // via the promiseCapability.[[Resolve]] function and
      // run the resolve logic directly from here.
      TailCallBuiltin(Builtins::kResolvePromise, context, promise_or_capability,
                      value);
    }

    BIND(&if_promise_capability);
    {
      // In the general case we need to call the (user provided)
      // promiseCapability.[[Resolve]] function.
      Node* const resolve = LoadObjectField(promise_or_capability,
                                            PromiseCapability::kResolveOffset);
      Node* const result = CallJS(
          CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
          context, resolve, UndefinedConstant(), value);
      GotoIfException(result, &if_reject, &var_handler_result);
      Return(result);
    }
  }

  BIND(&if_reject);
  if (type == PromiseReaction::kReject) {
    Label if_promise(this), if_promise_capability(this, Label::kDeferred);
    Node* const reason = var_handler_result.value();
    Branch(IsPromiseCapability(promise_or_capability), &if_promise_capability,
           &if_promise);

    BIND(&if_promise);
    {
      // For fast native promises we can skip the indirection
      // via the promiseCapability.[[Reject]] function and
      // run the resolve logic directly from here.
      TailCallBuiltin(Builtins::kRejectPromise, context, promise_or_capability,
                      reason, FalseConstant());
    }

    BIND(&if_promise_capability);
    {
      // In the general case we need to call the (user provided)
      // promiseCapability.[[Reject]] function.
      Label if_exception(this, Label::kDeferred);
      VARIABLE(var_exception, MachineRepresentation::kTagged,
               TheHoleConstant());
      Node* const reject = LoadObjectField(promise_or_capability,
                                           PromiseCapability::kRejectOffset);
      Node* const result = CallJS(
          CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
          context, reject, UndefinedConstant(), reason);
      GotoIfException(result, &if_exception, &var_exception);
      Return(result);

      // Swallow the exception here.
      BIND(&if_exception);
      TailCallRuntime(Runtime::kReportMessage, context, var_exception.value());
    }
  } else {
    // We have to call out to the dedicated PromiseRejectReactionJob builtin
    // here, instead of just doing the work inline, as otherwise the catch
    // predictions in the debugger will be wrong, which just walks the stack
    // and checks for certain builtins.
    TailCallBuiltin(Builtins::kPromiseRejectReactionJob, context,
                    var_handler_result.value(), UndefinedConstant(),
                    promise_or_capability);
  }
}

// ES #sec-promisereactionjob
TF_BUILTIN(PromiseFulfillReactionJob, PromiseBuiltinsAssembler) {
  Node* const context = Parameter(Descriptor::kContext);
  Node* const value = Parameter(Descriptor::kValue);
  Node* const handler = Parameter(Descriptor::kHandler);
  Node* const promise_or_capability =
      Parameter(Descriptor::kPromiseOrCapability);

  PromiseReactionJob(context, value, handler, promise_or_capability,
                     PromiseReaction::kFulfill);
}

// ES #sec-promisereactionjob
TF_BUILTIN(PromiseRejectReactionJob, PromiseBuiltinsAssembler) {
  Node* const context = Parameter(Descriptor::kContext);
  Node* const reason = Parameter(Descriptor::kReason);
  Node* const handler = Parameter(Descriptor::kHandler);
  Node* const promise_or_capability =
      Parameter(Descriptor::kPromiseOrCapability);

  PromiseReactionJob(context, reason, handler, promise_or_capability,
                     PromiseReaction::kReject);
}

TF_BUILTIN(PromiseResolveTrampoline, PromiseBuiltinsAssembler) {
  //  1. Let C be the this value.
  Node* receiver = Parameter(Descriptor::kReceiver);
  Node* value = Parameter(Descriptor::kValue);
  Node* context = Parameter(Descriptor::kContext);

  // 2. If Type(C) is not Object, throw a TypeError exception.
  ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject,
                       "PromiseResolve");

  // 3. Return ? PromiseResolve(C, x).
  Return(CallBuiltin(Builtins::kPromiseResolve, context, receiver, value));
}

TF_BUILTIN(PromiseResolve, PromiseBuiltinsAssembler) {
  Node* constructor = Parameter(Descriptor::kConstructor);
  Node* value = Parameter(Descriptor::kValue);
  Node* context = Parameter(Descriptor::kContext);

  CSA_ASSERT(this, IsJSReceiver(constructor));

  Node* const native_context = LoadNativeContext(context);
  Node* const promise_fun =
      LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);

  Label if_slow_constructor(this, Label::kDeferred), if_need_to_allocate(this);

  // Check if {value} is a JSPromise.
  GotoIf(TaggedIsSmi(value), &if_need_to_allocate);
  Node* const value_map = LoadMap(value);
  GotoIfNot(IsJSPromiseMap(value_map), &if_need_to_allocate);

  // We can skip the "constructor" lookup on {value} if it's [[Prototype]]
  // is the (initial) Promise.prototype and the @@species protector is
  // intact, as that guards the lookup path for "constructor" on
  // JSPromise instances which have the (initial) Promise.prototype.
  Node* const promise_prototype =
      LoadContextElement(native_context, Context::PROMISE_PROTOTYPE_INDEX);
  GotoIfNot(WordEqual(LoadMapPrototype(value_map), promise_prototype),
            &if_slow_constructor);
  GotoIf(IsPromiseSpeciesProtectorCellInvalid(), &if_slow_constructor);

  // If the {constructor} is the Promise function, we just immediately
  // return the {value} here and don't bother wrapping it into a
  // native Promise.
  GotoIfNot(WordEqual(promise_fun, constructor), &if_slow_constructor);
  Return(value);

  // At this point, value or/and constructor are not native promises, but
  // they could be of the same subclass.
  BIND(&if_slow_constructor);
  {
    Node* const value_constructor =
        GetProperty(context, value, isolate()->factory()->constructor_string());
    GotoIfNot(WordEqual(value_constructor, constructor), &if_need_to_allocate);
    Return(value);
  }

  BIND(&if_need_to_allocate);
  {
    Label if_nativepromise(this), if_notnativepromise(this, Label::kDeferred);
    Branch(WordEqual(promise_fun, constructor), &if_nativepromise,
           &if_notnativepromise);

    // This adds a fast path for native promises that don't need to
    // create NewPromiseCapability.
    BIND(&if_nativepromise);
    {
      Node* const result = AllocateAndInitJSPromise(context);
      CallBuiltin(Builtins::kResolvePromise, context, result, value);
      Return(result);
    }

    BIND(&if_notnativepromise);
    {
      Node* const debug_event = TrueConstant();
      Node* const capability = CallBuiltin(Builtins::kNewPromiseCapability,
                                           context, constructor, debug_event);

      Node* const resolve =
          LoadObjectField(capability, PromiseCapability::kResolveOffset);
      CallJS(
          CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
          context, resolve, UndefinedConstant(), value);

      Node* const result =
          LoadObjectField(capability, PromiseCapability::kPromiseOffset);
      Return(result);
    }
  }
}

// ES6 #sec-getcapabilitiesexecutor-functions
TF_BUILTIN(PromiseGetCapabilitiesExecutor, PromiseBuiltinsAssembler) {
  Node* const resolve = Parameter(Descriptor::kResolve);
  Node* const reject = Parameter(Descriptor::kReject);
  Node* const context = Parameter(Descriptor::kContext);

  Node* const capability = LoadContextElement(context, kCapabilitySlot);

  Label if_alreadyinvoked(this, Label::kDeferred);
  GotoIfNot(IsUndefined(
                LoadObjectField(capability, PromiseCapability::kResolveOffset)),
            &if_alreadyinvoked);
  GotoIfNot(IsUndefined(
                LoadObjectField(capability, PromiseCapability::kRejectOffset)),
            &if_alreadyinvoked);

  StoreObjectField(capability, PromiseCapability::kResolveOffset, resolve);
  StoreObjectField(capability, PromiseCapability::kRejectOffset, reject);

  Return(UndefinedConstant());

  BIND(&if_alreadyinvoked);
  ThrowTypeError(context, MessageTemplate::kPromiseExecutorAlreadyInvoked);
}

TF_BUILTIN(PromiseReject, PromiseBuiltinsAssembler) {
  // 1. Let C be the this value.
  Node* const receiver = Parameter(Descriptor::kReceiver);
  Node* const reason = Parameter(Descriptor::kReason);
  Node* const context = Parameter(Descriptor::kContext);

  // 2. If Type(C) is not Object, throw a TypeError exception.
  ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject,
                       "PromiseReject");

  Label if_nativepromise(this), if_custompromise(this, Label::kDeferred);
  Node* const native_context = LoadNativeContext(context);

  Node* const promise_fun =
      LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
  Branch(WordEqual(promise_fun, receiver), &if_nativepromise,
         &if_custompromise);

  BIND(&if_nativepromise);
  {
    Node* const promise =
        AllocateAndSetJSPromise(context, v8::Promise::kRejected, reason);
    CallRuntime(Runtime::kPromiseRejectEventFromStack, context, promise,
                reason);
    Return(promise);
  }

  BIND(&if_custompromise);
  {
    // 3. Let promiseCapability be ? NewPromiseCapability(C).
    Node* const debug_event = TrueConstant();
    Node* const capability = CallBuiltin(Builtins::kNewPromiseCapability,
                                         context, receiver, debug_event);

    // 4. Perform ? Call(promiseCapability.[[Reject]], undefined, « r »).
    Node* const reject =
        LoadObjectField(capability, PromiseCapability::kRejectOffset);
    CallJS(CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
           context, reject, UndefinedConstant(), reason);

    // 5. Return promiseCapability.[[Promise]].
    Node* const promise =
        LoadObjectField(capability, PromiseCapability::kPromiseOffset);
    Return(promise);
  }
}

std::pair<Node*, Node*> PromiseBuiltinsAssembler::CreatePromiseFinallyFunctions(
    Node* on_finally, Node* constructor, Node* native_context) {
  Node* const promise_context =
      CreatePromiseContext(native_context, kPromiseFinallyContextLength);
  StoreContextElementNoWriteBarrier(promise_context, kOnFinallySlot,
                                    on_finally);
  StoreContextElementNoWriteBarrier(promise_context, kConstructorSlot,
                                    constructor);
  Node* const map = LoadContextElement(
      native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
  Node* const then_finally_info = LoadContextElement(
      native_context, Context::PROMISE_THEN_FINALLY_SHARED_FUN);
  Node* const then_finally = AllocateFunctionWithMapAndContext(
      map, then_finally_info, promise_context);
  Node* const catch_finally_info = LoadContextElement(
      native_context, Context::PROMISE_CATCH_FINALLY_SHARED_FUN);
  Node* const catch_finally = AllocateFunctionWithMapAndContext(
      map, catch_finally_info, promise_context);
  return std::make_pair(then_finally, catch_finally);
}

TF_BUILTIN(PromiseValueThunkFinally, PromiseBuiltinsAssembler) {
  Node* const context = Parameter(Descriptor::kContext);

  Node* const value = LoadContextElement(context, kValueSlot);
  Return(value);
}

Node* PromiseBuiltinsAssembler::CreateValueThunkFunction(Node* value,
                                                         Node* native_context) {
  Node* const value_thunk_context = CreatePromiseContext(
      native_context, kPromiseValueThunkOrReasonContextLength);
  StoreContextElementNoWriteBarrier(value_thunk_context, kValueSlot, value);
  Node* const map = LoadContextElement(
      native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
  Node* const value_thunk_info = LoadContextElement(
      native_context, Context::PROMISE_VALUE_THUNK_FINALLY_SHARED_FUN);
  Node* const value_thunk = AllocateFunctionWithMapAndContext(
      map, value_thunk_info, value_thunk_context);
  return value_thunk;
}

TF_BUILTIN(PromiseThenFinally, PromiseBuiltinsAssembler) {
  CSA_ASSERT_JS_ARGC_EQ(this, 1);

  Node* const value = Parameter(Descriptor::kValue);
  Node* const context = Parameter(Descriptor::kContext);

  // 1. Let onFinally be F.[[OnFinally]].
  Node* const on_finally = LoadContextElement(context, kOnFinallySlot);

  // 2.  Assert: IsCallable(onFinally) is true.
  CSA_ASSERT(this, IsCallable(on_finally));

  // 3. Let result be ?  Call(onFinally).
  Node* const result = CallJS(
      CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
      context, on_finally, UndefinedConstant());

  // 4. Let C be F.[[Constructor]].
  Node* const constructor = LoadContextElement(context, kConstructorSlot);

  // 5. Assert: IsConstructor(C) is true.
  CSA_ASSERT(this, IsConstructor(constructor));

  // 6. Let promise be ? PromiseResolve(C, result).
  Node* const promise =
    CallBuiltin(Builtins::kPromiseResolve, context, constructor, result);

  // 7. Let valueThunk be equivalent to a function that returns value.
  Node* const native_context = LoadNativeContext(context);
  Node* const value_thunk = CreateValueThunkFunction(value, native_context);

  // 8. Return ? Invoke(promise, "then", « valueThunk »).
  Return(InvokeThen(native_context, promise, value_thunk));
}

TF_BUILTIN(PromiseThrowerFinally, PromiseBuiltinsAssembler) {
  Node* const context = Parameter(Descriptor::kContext);

  Node* const reason = LoadContextElement(context, kValueSlot);
  CallRuntime(Runtime::kThrow, context, reason);
  Unreachable();
}

Node* PromiseBuiltinsAssembler::CreateThrowerFunction(Node* reason,
                                                      Node* native_context) {
  Node* const thrower_context = CreatePromiseContext(
      native_context, kPromiseValueThunkOrReasonContextLength);
  StoreContextElementNoWriteBarrier(thrower_context, kValueSlot, reason);
  Node* const map = LoadContextElement(
      native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
  Node* const thrower_info = LoadContextElement(
      native_context, Context::PROMISE_THROWER_FINALLY_SHARED_FUN);
  Node* const thrower =
      AllocateFunctionWithMapAndContext(map, thrower_info, thrower_context);
  return thrower;
}

TF_BUILTIN(PromiseCatchFinally, PromiseBuiltinsAssembler) {
  CSA_ASSERT_JS_ARGC_EQ(this, 1);

  Node* const reason = Parameter(Descriptor::kReason);
  Node* const context = Parameter(Descriptor::kContext);

  // 1. Let onFinally be F.[[OnFinally]].
  Node* const on_finally = LoadContextElement(context, kOnFinallySlot);

  // 2. Assert: IsCallable(onFinally) is true.
  CSA_ASSERT(this, IsCallable(on_finally));

  // 3. Let result be ? Call(onFinally).
  Node* result = CallJS(
      CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
      context, on_finally, UndefinedConstant());

  // 4. Let C be F.[[Constructor]].
  Node* const constructor = LoadContextElement(context, kConstructorSlot);

  // 5. Assert: IsConstructor(C) is true.
  CSA_ASSERT(this, IsConstructor(constructor));

  // 6. Let promise be ? PromiseResolve(C, result).
  Node* const promise =
    CallBuiltin(Builtins::kPromiseResolve, context, constructor, result);

  // 7. Let thrower be equivalent to a function that throws reason.
  Node* const native_context = LoadNativeContext(context);
  Node* const thrower = CreateThrowerFunction(reason, native_context);

  // 8. Return ? Invoke(promise, "then", « thrower »).
  Return(InvokeThen(native_context, promise, thrower));
}

TF_BUILTIN(PromisePrototypeFinally, PromiseBuiltinsAssembler) {
  CSA_ASSERT_JS_ARGC_EQ(this, 1);

  // 1.  Let promise be the this value.
  Node* const receiver = Parameter(Descriptor::kReceiver);
  Node* const on_finally = Parameter(Descriptor::kOnFinally);
  Node* const context = Parameter(Descriptor::kContext);

  // 2. If Type(promise) is not Object, throw a TypeError exception.
  ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject,
                       "Promise.prototype.finally");

  // 3. Let C be ? SpeciesConstructor(promise, %Promise%).
  Node* const native_context = LoadNativeContext(context);
  Node* const promise_fun =
      LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
  VARIABLE(var_constructor, MachineRepresentation::kTagged, promise_fun);
  Label slow_constructor(this, Label::kDeferred), done_constructor(this);
  Node* const receiver_map = LoadMap(receiver);
  GotoIfNot(IsJSPromiseMap(receiver_map), &slow_constructor);
  BranchIfPromiseSpeciesLookupChainIntact(native_context, receiver_map,
                                          &done_constructor, &slow_constructor);
  BIND(&slow_constructor);
  {
    Node* const constructor =
        SpeciesConstructor(context, receiver, promise_fun);
    var_constructor.Bind(constructor);
    Goto(&done_constructor);
  }
  BIND(&done_constructor);
  Node* const constructor = var_constructor.value();

  // 4. Assert: IsConstructor(C) is true.
  CSA_ASSERT(this, IsConstructor(constructor));

  VARIABLE(var_then_finally, MachineRepresentation::kTagged);
  VARIABLE(var_catch_finally, MachineRepresentation::kTagged);

  Label if_notcallable(this, Label::kDeferred), perform_finally(this);

  GotoIf(TaggedIsSmi(on_finally), &if_notcallable);
  GotoIfNot(IsCallable(on_finally), &if_notcallable);

  // 6. Else,
  //   a. Let thenFinally be a new built-in function object as defined
  //   in ThenFinally Function.
  //   b. Let catchFinally be a new built-in function object as
  //   defined in CatchFinally Function.
  //   c. Set thenFinally and catchFinally's [[Constructor]] internal
  //   slots to C.
  //   d. Set thenFinally and catchFinally's [[OnFinally]] internal
  //   slots to onFinally.
  Node* then_finally = nullptr;
  Node* catch_finally = nullptr;
  std::tie(then_finally, catch_finally) =
    CreatePromiseFinallyFunctions(on_finally, constructor, native_context);
  var_then_finally.Bind(then_finally);
  var_catch_finally.Bind(catch_finally);
  Goto(&perform_finally);

  // 5. If IsCallable(onFinally) is not true,
  //    a. Let thenFinally be onFinally.
  //    b. Let catchFinally be onFinally.
  BIND(&if_notcallable);
  {
    var_then_finally.Bind(on_finally);
    var_catch_finally.Bind(on_finally);
    Goto(&perform_finally);
  }

  // 7. Return ? Invoke(promise, "then", « thenFinally, catchFinally »).
  BIND(&perform_finally);
  Return(InvokeThen(native_context, receiver, var_then_finally.value(),
                    var_catch_finally.value()));
}

// ES #sec-fulfillpromise
TF_BUILTIN(FulfillPromise, PromiseBuiltinsAssembler) {
  Node* const promise = Parameter(Descriptor::kPromise);
  Node* const value = Parameter(Descriptor::kValue);
  Node* const context = Parameter(Descriptor::kContext);

  CSA_ASSERT(this, TaggedIsNotSmi(promise));
  CSA_ASSERT(this, IsJSPromise(promise));

  // 2. Let reactions be promise.[[PromiseFulfillReactions]].
  Node* const reactions =
      LoadObjectField(promise, JSPromise::kReactionsOrResultOffset);

  // 3. Set promise.[[PromiseResult]] to value.
  // 4. Set promise.[[PromiseFulfillReactions]] to undefined.
  // 5. Set promise.[[PromiseRejectReactions]] to undefined.
  StoreObjectField(promise, JSPromise::kReactionsOrResultOffset, value);

  // 6. Set promise.[[PromiseState]] to "fulfilled".
  PromiseSetStatus(promise, Promise::kFulfilled);

  // 7. Return TriggerPromiseReactions(reactions, value).
  Return(TriggerPromiseReactions(context, reactions, value,
                                 PromiseReaction::kFulfill));
}

// ES #sec-rejectpromise
TF_BUILTIN(RejectPromise, PromiseBuiltinsAssembler) {
  Node* const promise = Parameter(Descriptor::kPromise);
  Node* const reason = Parameter(Descriptor::kReason);
  Node* const debug_event = Parameter(Descriptor::kDebugEvent);
  Node* const context = Parameter(Descriptor::kContext);

  CSA_ASSERT(this, TaggedIsNotSmi(promise));
  CSA_ASSERT(this, IsJSPromise(promise));
  CSA_ASSERT(this, IsBoolean(debug_event));
  Label if_runtime(this, Label::kDeferred);

  // If promise hook is enabled or the debugger is active, let
  // the runtime handle this operation, which greatly reduces
  // the complexity here and also avoids a couple of back and
  // forth between JavaScript and C++ land.
  GotoIf(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(),
         &if_runtime);

  // 7. If promise.[[PromiseIsHandled]] is false, perform
  //    HostPromiseRejectionTracker(promise, "reject").
  // We don't try to handle rejecting {promise} without handler
  // here, but we let the C++ code take care of this completely.
  GotoIfNot(PromiseHasHandler(promise), &if_runtime);

  // 2. Let reactions be promise.[[PromiseRejectReactions]].
  Node* reactions =
      LoadObjectField(promise, JSPromise::kReactionsOrResultOffset);

  // 3. Set promise.[[PromiseResult]] to reason.
  // 4. Set promise.[[PromiseFulfillReactions]] to undefined.
  // 5. Set promise.[[PromiseRejectReactions]] to undefined.
  StoreObjectField(promise, JSPromise::kReactionsOrResultOffset, reason);

  // 6. Set promise.[[PromiseState]] to "rejected".
  PromiseSetStatus(promise, Promise::kRejected);

  // 7. Return TriggerPromiseReactions(reactions, reason).
  Return(TriggerPromiseReactions(context, reactions, reason,
                                 PromiseReaction::kReject));

  BIND(&if_runtime);
  TailCallRuntime(Runtime::kRejectPromise, context, promise, reason,
                  debug_event);
}

// ES #sec-promise-resolve-functions
TF_BUILTIN(ResolvePromise, PromiseBuiltinsAssembler) {
  Node* const promise = Parameter(Descriptor::kPromise);
  Node* const resolution = Parameter(Descriptor::kResolution);
  Node* const context = Parameter(Descriptor::kContext);

  CSA_ASSERT(this, TaggedIsNotSmi(promise));
  CSA_ASSERT(this, IsJSPromise(promise));

  Label do_enqueue(this), if_fulfill(this), if_reject(this, Label::kDeferred),
      if_runtime(this, Label::kDeferred);
  VARIABLE(var_reason, MachineRepresentation::kTagged);
  VARIABLE(var_then, MachineRepresentation::kTagged);

  // If promise hook is enabled or the debugger is active, let
  // the runtime handle this operation, which greatly reduces
  // the complexity here and also avoids a couple of back and
  // forth between JavaScript and C++ land.
  GotoIf(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(),
         &if_runtime);

  // 6. If SameValue(resolution, promise) is true, then
  // We can use pointer comparison here, since the {promise} is guaranteed
  // to be a JSPromise inside this function and thus is reference comparable.
  GotoIf(WordEqual(promise, resolution), &if_runtime);

  // 7. If Type(resolution) is not Object, then
  GotoIf(TaggedIsSmi(resolution), &if_fulfill);
  Node* const resolution_map = LoadMap(resolution);
  GotoIfNot(IsJSReceiverMap(resolution_map), &if_fulfill);

  // We can skip the "then" lookup on {resolution} if its [[Prototype]]
  // is the (initial) Promise.prototype and the Promise#then protector
  // is intact, as that guards the lookup path for the "then" property
  // on JSPromise instances which have the (initial) %PromisePrototype%.
  Label if_fast(this), if_receiver(this), if_slow(this, Label::kDeferred);
  Node* const native_context = LoadNativeContext(context);
  GotoIfForceSlowPath(&if_slow);
  GotoIf(IsPromiseThenProtectorCellInvalid(), &if_slow);
  GotoIfNot(IsJSPromiseMap(resolution_map), &if_receiver);
  Node* const promise_prototype =
      LoadContextElement(native_context, Context::PROMISE_PROTOTYPE_INDEX);
  Branch(WordEqual(LoadMapPrototype(resolution_map), promise_prototype),
         &if_fast, &if_slow);

  BIND(&if_fast);
  {
    // The {resolution} is a native Promise in this case.
    Node* const then =
        LoadContextElement(native_context, Context::PROMISE_THEN_INDEX);
    var_then.Bind(then);
    Goto(&do_enqueue);
  }

  BIND(&if_receiver);
  {
    // We can skip the lookup of "then" if the {resolution} is a (newly
    // created) IterResultObject, as the Promise#then() protector also
    // ensures that the intrinsic %ObjectPrototype% doesn't contain any
    // "then" property. This helps to avoid negative lookups on iterator
    // results from async generators.
    CSA_ASSERT(this, IsJSReceiverMap(resolution_map));
    CSA_ASSERT(this, Word32BinaryNot(IsPromiseThenProtectorCellInvalid()));
    Node* const iterator_result_map =
        LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX);
    Branch(WordEqual(resolution_map, iterator_result_map), &if_fulfill,
           &if_slow);
  }

  BIND(&if_slow);
  {
    // 8. Let then be Get(resolution, "then").
    Node* const then =
        GetProperty(context, resolution, isolate()->factory()->then_string());

    // 9. If then is an abrupt completion, then
    GotoIfException(then, &if_reject, &var_reason);

    // 11. If IsCallable(thenAction) is false, then
    GotoIf(TaggedIsSmi(then), &if_fulfill);
    Node* const then_map = LoadMap(then);
    GotoIfNot(IsCallableMap(then_map), &if_fulfill);
    var_then.Bind(then);
    Goto(&do_enqueue);
  }

  BIND(&do_enqueue);
  {
    // 12. Perform EnqueueJob("PromiseJobs", PromiseResolveThenableJob,
    //                        «promise, resolution, thenAction»).
    Node* const task = AllocatePromiseResolveThenableJobTask(
        promise, var_then.value(), resolution, native_context);
    TailCallBuiltin(Builtins::kEnqueueMicrotask, native_context, task);
  }

  BIND(&if_fulfill);
  {
    // 7.b Return FulfillPromise(promise, resolution).
    TailCallBuiltin(Builtins::kFulfillPromise, context, promise, resolution);
  }

  BIND(&if_runtime);
  Return(CallRuntime(Runtime::kResolvePromise, context, promise, resolution));

  BIND(&if_reject);
  {
    // 9.a Return RejectPromise(promise, then.[[Value]]).
    TailCallBuiltin(Builtins::kRejectPromise, context, promise,
                    var_reason.value(), FalseConstant());
  }
}

Node* PromiseBuiltinsAssembler::PerformPromiseAll(
    Node* context, Node* constructor, Node* capability,
    const IteratorRecord& iterator, Label* if_exception,
    Variable* var_exception) {
  IteratorBuiltinsAssembler iter_assembler(state());

  Node* const native_context = LoadNativeContext(context);

  // For catch prediction, don't treat the .then calls as handling it;
  // instead, recurse outwards.
  SetForwardingHandlerIfTrue(
      native_context, IsDebugActive(),
      LoadObjectField(capability, PromiseCapability::kRejectOffset));

  Node* const resolve_element_context =
      CreatePromiseAllResolveElementContext(capability, native_context);

  TVARIABLE(Smi, var_index, SmiConstant(1));
  Label loop(this, &var_index), done_loop(this),
      too_many_elements(this, Label::kDeferred),
      close_iterator(this, Label::kDeferred);
  Goto(&loop);
  BIND(&loop);
  {
    // Let next be IteratorStep(iteratorRecord.[[Iterator]]).
    // If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
    // ReturnIfAbrupt(next).
    Node* const fast_iterator_result_map =
        LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX);
    Node* const next = iter_assembler.IteratorStep(
        native_context, iterator, &done_loop, fast_iterator_result_map,
        if_exception, var_exception);

    // Let nextValue be IteratorValue(next).
    // If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to
    //     true.
    // ReturnIfAbrupt(nextValue).
    Node* const next_value = iter_assembler.IteratorValue(
        native_context, next, fast_iterator_result_map, if_exception,
        var_exception);

    // Check if we reached the limit.
    TNode<Smi> const index = var_index.value();
    GotoIf(SmiEqual(index, SmiConstant(PropertyArray::HashField::kMax)),
           &too_many_elements);

    // Set index to index + 1.
    var_index = SmiAdd(index, SmiConstant(1));

    // Set remainingElementsCount.[[Value]] to
    //     remainingElementsCount.[[Value]] + 1.
    TNode<Smi> const remaining_elements_count = CAST(LoadContextElement(
        resolve_element_context, kPromiseAllResolveElementRemainingSlot));
    StoreContextElementNoWriteBarrier(
        resolve_element_context, kPromiseAllResolveElementRemainingSlot,
        SmiAdd(remaining_elements_count, SmiConstant(1)));

    // Let resolveElement be CreateBuiltinFunction(steps,
    //                                             « [[AlreadyCalled]],
    //                                               [[Index]],
    //                                               [[Values]],
    //                                               [[Capability]],
    //                                               [[RemainingElements]] »).
    // Set resolveElement.[[AlreadyCalled]] to a Record { [[Value]]: false }.
    // Set resolveElement.[[Index]] to index.
    // Set resolveElement.[[Values]] to values.
    // Set resolveElement.[[Capability]] to resultCapability.
    // Set resolveElement.[[RemainingElements]] to remainingElementsCount.
    Node* const resolve_element_fun = CreatePromiseAllResolveElementFunction(
        resolve_element_context, index, native_context);

    // We can skip the "resolve" lookup on the {constructor} as well as the
    // "then" lookup on the result of the "resolve" call, and immediately
    // chain continuation onto the {next_value} if:
    //
    //   (a) The {constructor} is the intrinsic %Promise% function, and
    //       looking up "resolve" on {constructor} yields the initial
    //       Promise.resolve() builtin, and
    //   (b) the {next_value} is a JSPromise whose [[Prototype]] field
    //       contains the intrinsic %PromisePrototype%, and
    //   (c) we're not running with async_hooks or DevTools enabled.
    //
    // In that case we also don't need to allocate a chained promise for
    // the PromiseReaction (aka we can pass undefined to PerformPromiseThen),
    // since this is only necessary for DevTools and PromiseHooks.
    Label if_fast(this), if_slow(this);
    GotoIfNotPromiseResolveLookupChainIntact(native_context, constructor,
                                             &if_slow);
    GotoIf(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(),
           &if_slow);
    GotoIf(TaggedIsSmi(next_value), &if_slow);
    Node* const next_value_map = LoadMap(next_value);
    BranchIfPromiseThenLookupChainIntact(native_context, next_value_map,
                                         &if_fast, &if_slow);

    BIND(&if_fast);
    {
      // Register the PromiseReaction immediately on the {next_value}, not
      // passing any chained promise since neither async_hooks nor DevTools
      // are enabled, so there's no use of the resulting promise.
      PerformPromiseThen(
          native_context, next_value, resolve_element_fun,
          LoadObjectField(capability, PromiseCapability::kRejectOffset),
          UndefinedConstant());
      Goto(&loop);
    }

    BIND(&if_slow);
    {
      // Let nextPromise be ? Invoke(constructor, "resolve", « nextValue »).
      Node* const next_promise =
          InvokeResolve(native_context, constructor, next_value,
                        &close_iterator, var_exception);

      // Perform ? Invoke(nextPromise, "then", « resolveElement,
      //                  resultCapability.[[Reject]] »).
      Node* const then =
          GetProperty(native_context, next_promise, factory()->then_string());
      GotoIfException(then, &close_iterator, var_exception);

      Node* const then_call =
          CallJS(CodeFactory::Call(isolate(),
                                   ConvertReceiverMode::kNotNullOrUndefined),
                 native_context, then, next_promise, resolve_element_fun,
                 LoadObjectField(capability, PromiseCapability::kRejectOffset));
      GotoIfException(then_call, &close_iterator, var_exception);

      // For catch prediction, mark that rejections here are semantically
      // handled by the combined Promise.
      SetPromiseHandledByIfTrue(
          native_context, IsDebugActive(), then_call, [=]() {
            // Load promiseCapability.[[Promise]]
            return LoadObjectField(capability,
                                   PromiseCapability::kPromiseOffset);
          });

      Goto(&loop);
    }
  }

  BIND(&too_many_elements);
  {
    // If there are too many elements (currently more than 2**21-1), raise a
    // RangeError here (which is caught directly and turned into a rejection)
    // of the resulting promise. We could gracefully handle this case as well
    // and support more than this number of elements by going to a separate
    // function and pass the larger indices via a separate context, but it
    // doesn't seem likely that we need this, and it's unclear how the rest
    // of the system deals with 2**21 live Promises anyways.
    Node* const result =
        CallRuntime(Runtime::kThrowRangeError, native_context,
                    SmiConstant(MessageTemplate::kTooManyElementsInPromiseAll));
    GotoIfException(result, &close_iterator, var_exception);
    Unreachable();
  }

  BIND(&close_iterator);
  {
    // Exception must be bound to a JS value.
    CSA_ASSERT(this, IsNotTheHole(var_exception->value()));
    iter_assembler.IteratorCloseOnException(native_context, iterator,
                                            if_exception, var_exception);
  }

  BIND(&done_loop);
  {
    Label resolve_promise(this, Label::kDeferred), return_promise(this);
    // Set iteratorRecord.[[Done]] to true.
    // Set remainingElementsCount.[[Value]] to
    //    remainingElementsCount.[[Value]] - 1.
    TNode<Smi> remaining_elements_count = CAST(LoadContextElement(
        resolve_element_context, kPromiseAllResolveElementRemainingSlot));
    remaining_elements_count = SmiSub(remaining_elements_count, SmiConstant(1));
    StoreContextElementNoWriteBarrier(resolve_element_context,
                                      kPromiseAllResolveElementRemainingSlot,
                                      remaining_elements_count);
    GotoIf(SmiEqual(remaining_elements_count, SmiConstant(0)),
           &resolve_promise);

    // Pre-allocate the backing store for the {values_array} to the desired
    // capacity here. We may already have elements here in case of some
    // fancy Thenable that calls the resolve callback immediately, so we need
    // to handle that correctly here.
    Node* const values_array = LoadContextElement(
        resolve_element_context, kPromiseAllResolveElementValuesArraySlot);
    Node* const old_elements = LoadElements(values_array);
    TNode<Smi> const old_capacity = LoadFixedArrayBaseLength(old_elements);
    TNode<Smi> const new_capacity = var_index.value();
    GotoIf(SmiGreaterThanOrEqual(old_capacity, new_capacity), &return_promise);
    Node* const new_elements =
        AllocateFixedArray(PACKED_ELEMENTS, new_capacity, SMI_PARAMETERS,
                           AllocationFlag::kAllowLargeObjectAllocation);
    CopyFixedArrayElements(PACKED_ELEMENTS, old_elements, PACKED_ELEMENTS,
                           new_elements, SmiConstant(0), old_capacity,
                           new_capacity, UPDATE_WRITE_BARRIER, SMI_PARAMETERS);
    StoreObjectField(values_array, JSArray::kElementsOffset, new_elements);
    Goto(&return_promise);

    // If remainingElementsCount.[[Value]] is 0, then
    //     Let valuesArray be CreateArrayFromList(values).
    //     Perform ? Call(resultCapability.[[Resolve]], undefined,
    //                    « valuesArray »).
    BIND(&resolve_promise);
    {
      Node* const resolve =
          LoadObjectField(capability, PromiseCapability::kResolveOffset);
      Node* const values_array = LoadContextElement(
          resolve_element_context, kPromiseAllResolveElementValuesArraySlot);
      Node* const resolve_call = CallJS(
          CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
          native_context, resolve, UndefinedConstant(), values_array);
      GotoIfException(resolve_call, if_exception, var_exception);
      Goto(&return_promise);
    }

    // Return resultCapability.[[Promise]].
    BIND(&return_promise);
  }

  Node* const promise =
      LoadObjectField(capability, PromiseCapability::kPromiseOffset);
  return promise;
}

// ES#sec-promise.all
// Promise.all ( iterable )
TF_BUILTIN(PromiseAll, PromiseBuiltinsAssembler) {
  IteratorBuiltinsAssembler iter_assembler(state());

  // Let C be the this value.
  // If Type(C) is not Object, throw a TypeError exception.
  Node* const receiver = Parameter(Descriptor::kReceiver);
  Node* const context = Parameter(Descriptor::kContext);
  ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject,
                       "Promise.all");

  // Let promiseCapability be ? NewPromiseCapability(C).
  // Don't fire debugEvent so that forwarding the rejection through all does not
  // trigger redundant ExceptionEvents
  Node* const debug_event = FalseConstant();
  Node* const capability = CallBuiltin(Builtins::kNewPromiseCapability, context,
                                       receiver, debug_event);

  VARIABLE(var_exception, MachineRepresentation::kTagged, TheHoleConstant());
  Label reject_promise(this, &var_exception, Label::kDeferred);

  // Let iterator be GetIterator(iterable).
  // IfAbruptRejectPromise(iterator, promiseCapability).
  Node* const iterable = Parameter(Descriptor::kIterable);
  IteratorRecord iterator = iter_assembler.GetIterator(
      context, iterable, &reject_promise, &var_exception);

  // Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
  // If result is an abrupt completion, then
  //   If iteratorRecord.[[Done]] is false, let result be
  //       IteratorClose(iterator, result).
  //    IfAbruptRejectPromise(result, promiseCapability).
  Node* const result = PerformPromiseAll(
      context, receiver, capability, iterator, &reject_promise, &var_exception);

  Return(result);

  BIND(&reject_promise);
  {
    // Exception must be bound to a JS value.
    CSA_SLOW_ASSERT(this, IsNotTheHole(var_exception.value()));
    Node* const reject =
        LoadObjectField(capability, PromiseCapability::kRejectOffset);
    CallJS(CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
           context, reject, UndefinedConstant(), var_exception.value());

    Node* const promise =
        LoadObjectField(capability, PromiseCapability::kPromiseOffset);
    Return(promise);
  }
}

TF_BUILTIN(PromiseAllResolveElementClosure, PromiseBuiltinsAssembler) {
  TNode<Object> value = CAST(Parameter(Descriptor::kValue));
  TNode<Context> context = CAST(Parameter(Descriptor::kContext));
  TNode<JSFunction> function = CAST(Parameter(Descriptor::kJSTarget));

  Label already_called(this, Label::kDeferred), resolve_promise(this);

  // We use the {function}s context as the marker to remember whether this
  // resolve element closure was already called. It points to the resolve
  // element context (which is a FunctionContext) until it was called the
  // first time, in which case we make it point to the native context here
  // to mark this resolve element closure as done.
  GotoIf(IsNativeContext(context), &already_called);
  CSA_ASSERT(this, SmiEqual(LoadFixedArrayBaseLength(context),
                            SmiConstant(kPromiseAllResolveElementLength)));
  TNode<Context> native_context = LoadNativeContext(context);
  StoreObjectField(function, JSFunction::kContextOffset, native_context);

  // Determine the index from the {function}.
  Label unreachable(this, Label::kDeferred);
  STATIC_ASSERT(PropertyArray::kNoHashSentinel == 0);
  TNode<IntPtrT> identity_hash =
      LoadJSReceiverIdentityHash(function, &unreachable);
  CSA_ASSERT(this, IntPtrGreaterThan(identity_hash, IntPtrConstant(0)));
  TNode<IntPtrT> index = IntPtrSub(identity_hash, IntPtrConstant(1));

  // Check if we need to grow the [[ValuesArray]] to store {value} at {index}.
  TNode<JSArray> values_array = CAST(
      LoadContextElement(context, kPromiseAllResolveElementValuesArraySlot));
  TNode<FixedArray> elements = CAST(LoadElements(values_array));
  TNode<IntPtrT> values_length =
      LoadAndUntagObjectField(values_array, JSArray::kLengthOffset);
  Label if_inbounds(this), if_outofbounds(this), done(this);
  Branch(IntPtrLessThan(index, values_length), &if_inbounds, &if_outofbounds);

  BIND(&if_outofbounds);
  {
    // Check if we need to grow the backing store.
    TNode<IntPtrT> new_length = IntPtrAdd(index, IntPtrConstant(1));
    TNode<IntPtrT> elements_length =
        LoadAndUntagObjectField(elements, FixedArray::kLengthOffset);
    Label if_grow(this, Label::kDeferred), if_nogrow(this);
    Branch(IntPtrLessThan(index, elements_length), &if_nogrow, &if_grow);

    BIND(&if_grow);
    {
      // We need to grow the backing store to fit the {index} as well.
      TNode<IntPtrT> new_elements_length =
          IntPtrMin(CalculateNewElementsCapacity(new_length),
                    IntPtrConstant(PropertyArray::HashField::kMax + 1));
      CSA_ASSERT(this, IntPtrLessThan(index, new_elements_length));
      CSA_ASSERT(this, IntPtrLessThan(elements_length, new_elements_length));
      TNode<FixedArray> new_elements =
          CAST(AllocateFixedArray(PACKED_ELEMENTS, new_elements_length,
                                  AllocationFlag::kAllowLargeObjectAllocation));
      CopyFixedArrayElements(PACKED_ELEMENTS, elements, PACKED_ELEMENTS,
                             new_elements, elements_length,
                             new_elements_length);
      StoreFixedArrayElement(new_elements, index, value);

      // Update backing store and "length" on {values_array}.
      StoreObjectField(values_array, JSArray::kElementsOffset, new_elements);
      StoreObjectFieldNoWriteBarrier(values_array, JSArray::kLengthOffset,
                                     SmiTag(new_length));
      Goto(&done);
    }

    BIND(&if_nogrow);
    {
      // The {index} is within bounds of the {elements} backing store, so
      // just store the {value} and update the "length" of the {values_array}.
      StoreObjectFieldNoWriteBarrier(values_array, JSArray::kLengthOffset,
                                     SmiTag(new_length));
      StoreFixedArrayElement(elements, index, value);
      Goto(&done);
    }
  }

  BIND(&if_inbounds);
  {
    // The {index} is in bounds of the {values_array},
    // just store the {value} and continue.
    StoreFixedArrayElement(elements, index, value);
    Goto(&done);
  }

  BIND(&done);
  TNode<Smi> remaining_elements_count =
      CAST(LoadContextElement(context, kPromiseAllResolveElementRemainingSlot));
  remaining_elements_count = SmiSub(remaining_elements_count, SmiConstant(1));
  StoreContextElement(context, kPromiseAllResolveElementRemainingSlot,
                      remaining_elements_count);
  GotoIf(SmiEqual(remaining_elements_count, SmiConstant(0)), &resolve_promise);
  Return(UndefinedConstant());

  BIND(&resolve_promise);
  TNode<PromiseCapability> capability = CAST(
      LoadContextElement(context, kPromiseAllResolveElementCapabilitySlot));
  TNode<Object> resolve =
      LoadObjectField(capability, PromiseCapability::kResolveOffset);
  CallJS(CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
         context, resolve, UndefinedConstant(), values_array);
  Return(UndefinedConstant());

  BIND(&already_called);
  Return(UndefinedConstant());

  BIND(&unreachable);
  Unreachable();
}

// ES#sec-promise.race
// Promise.race ( iterable )
TF_BUILTIN(PromiseRace, PromiseBuiltinsAssembler) {
  IteratorBuiltinsAssembler iter_assembler(state());
  VARIABLE(var_exception, MachineRepresentation::kTagged, TheHoleConstant());

  Node* const receiver = Parameter(Descriptor::kReceiver);
  Node* const context = Parameter(Descriptor::kContext);
  ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject,
                       "Promise.race");

  // Let promiseCapability be ? NewPromiseCapability(C).
  // Don't fire debugEvent so that forwarding the rejection through all does not
  // trigger redundant ExceptionEvents
  Node* const debug_event = FalseConstant();
  Node* const capability = CallBuiltin(Builtins::kNewPromiseCapability, context,
                                       receiver, debug_event);

  Node* const resolve =
      LoadObjectField(capability, PromiseCapability::kResolveOffset);
  Node* const reject =
      LoadObjectField(capability, PromiseCapability::kRejectOffset);

  Label close_iterator(this, Label::kDeferred);
  Label reject_promise(this, Label::kDeferred);

  // For catch prediction, don't treat the .then calls as handling it;
  // instead, recurse outwards.
  SetForwardingHandlerIfTrue(context, IsDebugActive(), reject);

  // Let iterator be GetIterator(iterable).
  // IfAbruptRejectPromise(iterator, promiseCapability).
  Node* const iterable = Parameter(Descriptor::kIterable);
  IteratorRecord iterator = iter_assembler.GetIterator(
      context, iterable, &reject_promise, &var_exception);

  // Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
  {
    Label loop(this), break_loop(this);
    Goto(&loop);
    BIND(&loop);
    {
      Node* const native_context = LoadNativeContext(context);
      Node* const fast_iterator_result_map = LoadContextElement(
          native_context, Context::ITERATOR_RESULT_MAP_INDEX);

      // Let next be IteratorStep(iteratorRecord.[[Iterator]]).
      // If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
      // ReturnIfAbrupt(next).
      Node* const next = iter_assembler.IteratorStep(
          context, iterator, &break_loop, fast_iterator_result_map,
          &reject_promise, &var_exception);

      // Let nextValue be IteratorValue(next).
      // If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to
      //     true.
      // ReturnIfAbrupt(nextValue).
      Node* const next_value =
          iter_assembler.IteratorValue(context, next, fast_iterator_result_map,
                                       &reject_promise, &var_exception);

      // Let nextPromise be ? Invoke(constructor, "resolve", « nextValue »).
      Node* const next_promise =
          InvokeResolve(native_context, receiver, next_value, &close_iterator,
                        &var_exception);

      // Perform ? Invoke(nextPromise, "then", « resolveElement,
      //                  resultCapability.[[Reject]] »).
      Node* const then =
          GetProperty(context, next_promise, factory()->then_string());
      GotoIfException(then, &close_iterator, &var_exception);

      Node* const then_call =
          CallJS(CodeFactory::Call(isolate(),
                                   ConvertReceiverMode::kNotNullOrUndefined),
                 context, then, next_promise, resolve, reject);
      GotoIfException(then_call, &close_iterator, &var_exception);

      // For catch prediction, mark that rejections here are semantically
      // handled by the combined Promise.
      SetPromiseHandledByIfTrue(context, IsDebugActive(), then_call, [=]() {
        // Load promiseCapability.[[Promise]]
        return LoadObjectField(capability, PromiseCapability::kPromiseOffset);
      });
      Goto(&loop);
    }

    BIND(&break_loop);
    Return(LoadObjectField(capability, PromiseCapability::kPromiseOffset));
  }

  BIND(&close_iterator);
  {
    CSA_ASSERT(this, IsNotTheHole(var_exception.value()));
    iter_assembler.IteratorCloseOnException(context, iterator, &reject_promise,
                                            &var_exception);
  }

  BIND(&reject_promise);
  {
    Node* const reject =
        LoadObjectField(capability, PromiseCapability::kRejectOffset);
    CallJS(CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
           context, reject, UndefinedConstant(), var_exception.value());

    Node* const promise =
        LoadObjectField(capability, PromiseCapability::kPromiseOffset);
    Return(promise);
  }
}

}  // namespace internal
}  // namespace v8
