// 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.h"
#include "src/builtins/builtins-constructor.h"
#include "src/builtins/builtins-utils.h"
#include "src/builtins/builtins.h"
#include "src/code-factory.h"
#include "src/code-stub-assembler.h"
#include "src/objects-inl.h"

namespace v8 {
namespace internal {

typedef compiler::Node Node;
typedef CodeStubAssembler::ParameterMode ParameterMode;
typedef compiler::CodeAssemblerState CodeAssemblerState;

Node* PromiseBuiltinsAssembler::AllocateJSPromise(Node* context) {
  Node* const native_context = LoadNativeContext(context);
  Node* const promise_fun =
      LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
  Node* const initial_map =
      LoadObjectField(promise_fun, JSFunction::kPrototypeOrInitialMapOffset);
  Node* const instance = AllocateJSObjectFromMap(initial_map);
  return instance;
}

void PromiseBuiltinsAssembler::PromiseInit(Node* promise) {
  StoreObjectField(promise, JSPromise::kStatusOffset,
                   SmiConstant(v8::Promise::kPending));
  StoreObjectField(promise, JSPromise::kFlagsOffset, SmiConstant(0));
}

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(IsPromiseHookEnabledOrDebugIsActive(), &out);
  CallRuntime(Runtime::kPromiseHookInit, context, instance, parent);
  Goto(&out);

  Bind(&out);
  return instance;
}

Node* PromiseBuiltinsAssembler::AllocateAndSetJSPromise(Node* context,
                                                        Node* status,
                                                        Node* result) {
  CSA_ASSERT(this, TaggedIsSmi(status));

  Node* const instance = AllocateJSPromise(context);

  StoreObjectFieldNoWriteBarrier(instance, JSPromise::kStatusOffset, status);
  StoreObjectFieldNoWriteBarrier(instance, JSPromise::kResultOffset, result);
  StoreObjectFieldNoWriteBarrier(instance, JSPromise::kFlagsOffset,
                                 SmiConstant(0));

  Label out(this);
  GotoIfNot(IsPromiseHookEnabledOrDebugIsActive(), &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_RESOLVE_SHARED_FUN);
  Node* const resolve =
      AllocateFunctionWithMapAndContext(map, resolve_info, promise_context);
  Node* const reject_info =
      LoadContextElement(native_context, Context::PROMISE_REJECT_SHARED_FUN);
  Node* const reject =
      AllocateFunctionWithMapAndContext(map, reject_info, promise_context);
  return std::make_pair(resolve, reject);
}

Node* PromiseBuiltinsAssembler::NewPromiseCapability(Node* context,
                                                     Node* constructor,
                                                     Node* debug_event) {
  if (debug_event == nullptr) {
    debug_event = TrueConstant();
  }

  Label if_not_constructor(this, Label::kDeferred);
  GotoIf(TaggedIsSmi(constructor), &if_not_constructor);
  GotoIfNot(IsConstructorMap(LoadMap(constructor)), &if_not_constructor);

  Node* native_context = LoadNativeContext(context);

  Node* map = LoadRoot(Heap::kJSPromiseCapabilityMapRootIndex);
  Node* capability = AllocateJSObjectFromMap(map);

  StoreObjectFieldNoWriteBarrier(
      capability, JSPromiseCapability::kPromiseOffset, UndefinedConstant());
  StoreObjectFieldNoWriteBarrier(
      capability, JSPromiseCapability::kResolveOffset, UndefinedConstant());
  StoreObjectFieldNoWriteBarrier(capability, JSPromiseCapability::kRejectOffset,
                                 UndefinedConstant());

  Variable var_result(this, MachineRepresentation::kTagged);
  var_result.Bind(capability);

  Label if_builtin_promise(this), if_custom_promise(this, Label::kDeferred),
      out(this);
  Branch(WordEqual(constructor,
                   LoadContextElement(native_context,
                                      Context::PROMISE_FUNCTION_INDEX)),
         &if_builtin_promise, &if_custom_promise);

  Bind(&if_builtin_promise);
  {
    Node* promise = AllocateJSPromise(context);
    PromiseInit(promise);
    StoreObjectFieldNoWriteBarrier(
        capability, JSPromiseCapability::kPromiseOffset, promise);

    Node* resolve = nullptr;
    Node* reject = nullptr;

    std::tie(resolve, reject) =
        CreatePromiseResolvingFunctions(promise, debug_event, native_context);
    StoreObjectField(capability, JSPromiseCapability::kResolveOffset, resolve);
    StoreObjectField(capability, JSPromiseCapability::kRejectOffset, reject);

    GotoIfNot(IsPromiseHookEnabledOrDebugIsActive(), &out);
    CallRuntime(Runtime::kPromiseHookInit, context, promise,
                UndefinedConstant());
    Goto(&out);
  }

  Bind(&if_custom_promise);
  {
    Label if_notcallable(this, Label::kDeferred);
    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);
    Node* executor = AllocateFunctionWithMapAndContext(
        function_map, executor_info, executor_context);

    Node* promise = ConstructJS(CodeFactory::Construct(isolate()), context,
                                constructor, executor);

    Node* resolve =
        LoadObjectField(capability, JSPromiseCapability::kResolveOffset);
    GotoIf(TaggedIsSmi(resolve), &if_notcallable);
    GotoIfNot(IsCallableMap(LoadMap(resolve)), &if_notcallable);

    Node* reject =
        LoadObjectField(capability, JSPromiseCapability::kRejectOffset);
    GotoIf(TaggedIsSmi(reject), &if_notcallable);
    GotoIfNot(IsCallableMap(LoadMap(reject)), &if_notcallable);

    StoreObjectField(capability, JSPromiseCapability::kPromiseOffset, promise);

    Goto(&out);

    Bind(&if_notcallable);
    Node* message = SmiConstant(MessageTemplate::kPromiseNonCallable);
    StoreObjectField(capability, JSPromiseCapability::kPromiseOffset,
                     UndefinedConstant());
    StoreObjectField(capability, JSPromiseCapability::kResolveOffset,
                     UndefinedConstant());
    StoreObjectField(capability, JSPromiseCapability::kRejectOffset,
                     UndefinedConstant());
    CallRuntime(Runtime::kThrowTypeError, context, message);
    Unreachable();
  }

  Bind(&if_not_constructor);
  {
    Node* const message_id = SmiConstant(MessageTemplate::kNotConstructor);
    CallRuntime(Runtime::kThrowTypeError, context, message_id, constructor);
    Unreachable();
  }

  Bind(&out);
  return var_result.value();
}

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

  Node* const context = Allocate(FixedArray::SizeFor(slots));
  StoreMapNoWriteBarrier(context, Heap::kFunctionContextMapRootIndex);
  StoreObjectFieldNoWriteBarrier(context, FixedArray::kLengthOffset,
                                 SmiConstant(slots));

  Node* const empty_fn =
      LoadContextElement(native_context, Context::CLOSURE_INDEX);
  StoreContextElementNoWriteBarrier(context, Context::CLOSURE_INDEX, empty_fn);
  StoreContextElementNoWriteBarrier(context, Context::PREVIOUS_INDEX,
                                    UndefinedConstant());
  StoreContextElementNoWriteBarrier(context, Context::EXTENSION_INDEX,
                                    TheHoleConstant());
  StoreContextElementNoWriteBarrier(context, Context::NATIVE_CONTEXT_INDEX,
                                    native_context);
  return context;
}

Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext(
    Node* promise, Node* debug_event, Node* native_context) {
  Node* const context =
      CreatePromiseContext(native_context, kPromiseContextLength);
  StoreContextElementNoWriteBarrier(context, kAlreadyVisitedSlot,
                                    SmiConstant(0));
  StoreContextElementNoWriteBarrier(context, kPromiseSlot, promise);
  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::ThrowIfNotJSReceiver(
    Node* context, Node* value, MessageTemplate::Template msg_template,
    const char* method_name) {
  Label out(this), throw_exception(this, Label::kDeferred);
  Variable var_value_map(this, MachineRepresentation::kTagged);

  GotoIf(TaggedIsSmi(value), &throw_exception);

  // Load the instance type of the {value}.
  var_value_map.Bind(LoadMap(value));
  Node* const value_instance_type = LoadMapInstanceType(var_value_map.value());

  Branch(IsJSReceiverInstanceType(value_instance_type), &out, &throw_exception);

  // The {value} is not a compatible receiver for this method.
  Bind(&throw_exception);
  {
    Node* const method =
        method_name == nullptr
            ? UndefinedConstant()
            : HeapConstant(
                  isolate()->factory()->NewStringFromAsciiChecked(method_name));
    Node* const message_id = SmiConstant(msg_template);
    CallRuntime(Runtime::kThrowTypeError, context, message_id, method);
    Unreachable();
  }

  Bind(&out);
  return var_value_map.value();
}

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

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

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

Node* PromiseBuiltinsAssembler::SpeciesConstructor(Node* context, Node* object,
                                                   Node* default_constructor) {
  Isolate* isolate = this->isolate();
  Variable var_result(this, MachineRepresentation::kTagged);
  var_result.Bind(default_constructor);

  // 2. Let C be ? Get(O, "constructor").
  Node* const constructor_str =
      HeapConstant(isolate->factory()->constructor_string());
  Callable getproperty_callable = CodeFactory::GetProperty(isolate);
  Node* const constructor =
      CallStub(getproperty_callable, context, object, constructor_str);

  // 3. If C is undefined, return defaultConstructor.
  Label out(this);
  GotoIf(IsUndefined(constructor), &out);

  // 4. If Type(C) is not Object, throw a TypeError exception.
  ThrowIfNotJSReceiver(context, constructor,
                       MessageTemplate::kConstructorNotReceiver);

  // 5. Let S be ? Get(C, @@species).
  Node* const species_symbol =
      HeapConstant(isolate->factory()->species_symbol());
  Node* const species =
      CallStub(getproperty_callable, context, constructor, species_symbol);

  // 6. If S is either undefined or null, return defaultConstructor.
  GotoIf(IsUndefined(species), &out);
  GotoIf(WordEqual(species, NullConstant()), &out);

  // 7. If IsConstructor(S) is true, return S.
  Label throw_error(this);
  GotoIf(TaggedIsSmi(species), &throw_error);
  Node* species_bitfield = LoadMapBitField(LoadMap(species));
  GotoIfNot(Word32Equal(Word32And(species_bitfield,
                                  Int32Constant((1 << Map::kIsConstructor))),
                        Int32Constant(1 << Map::kIsConstructor)),
            &throw_error);
  var_result.Bind(species);
  Goto(&out);

  // 8. Throw a TypeError exception.
  Bind(&throw_error);
  {
    Node* const message_id =
        SmiConstant(MessageTemplate::kSpeciesNotConstructor);
    CallRuntime(Runtime::kThrowTypeError, context, message_id);
    Unreachable();
  }

  Bind(&out);
  return var_result.value();
}

void PromiseBuiltinsAssembler::AppendPromiseCallback(int offset, Node* promise,
                                                     Node* value) {
  Node* elements = LoadObjectField(promise, offset);
  Node* length = LoadFixedArrayBaseLength(elements);
  CodeStubAssembler::ParameterMode mode = OptimalParameterMode();
  length = TaggedToParameter(length, mode);

  Node* delta = IntPtrOrSmiConstant(1, mode);
  Node* new_capacity = IntPtrOrSmiAdd(length, delta, mode);

  const ElementsKind kind = FAST_ELEMENTS;
  const WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER;
  const CodeStubAssembler::AllocationFlags flags =
      CodeStubAssembler::kAllowLargeObjectAllocation;
  int additional_offset = 0;

  Node* new_elements = AllocateFixedArray(kind, new_capacity, mode, flags);

  CopyFixedArrayElements(kind, elements, new_elements, length, barrier_mode,
                         mode);
  StoreFixedArrayElement(new_elements, length, value, barrier_mode,
                         additional_offset, mode);

  StoreObjectField(promise, offset, new_elements);
}

Node* PromiseBuiltinsAssembler::InternalPromiseThen(Node* context,
                                                    Node* promise,
                                                    Node* on_resolve,
                                                    Node* on_reject) {
  Isolate* isolate = this->isolate();

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

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

  // 3. Let C be ? SpeciesConstructor(promise, %Promise%).
  Node* constructor = SpeciesConstructor(context, promise, promise_fun);

  // 4. Let resultCapability be ? NewPromiseCapability(C).
  Callable call_callable = CodeFactory::Call(isolate);
  Label fast_promise_capability(this), promise_capability(this),
      perform_promise_then(this);
  Variable var_deferred_promise(this, MachineRepresentation::kTagged),
      var_deferred_on_resolve(this, MachineRepresentation::kTagged),
      var_deferred_on_reject(this, MachineRepresentation::kTagged);

  Branch(WordEqual(promise_fun, constructor), &fast_promise_capability,
         &promise_capability);

  Bind(&fast_promise_capability);
  {
    Node* const deferred_promise = AllocateAndInitJSPromise(context, promise);
    var_deferred_promise.Bind(deferred_promise);
    var_deferred_on_resolve.Bind(UndefinedConstant());
    var_deferred_on_reject.Bind(UndefinedConstant());
    Goto(&perform_promise_then);
  }

  Bind(&promise_capability);
  {
    Node* const capability = NewPromiseCapability(context, constructor);
    var_deferred_promise.Bind(
        LoadObjectField(capability, JSPromiseCapability::kPromiseOffset));
    var_deferred_on_resolve.Bind(
        LoadObjectField(capability, JSPromiseCapability::kResolveOffset));
    var_deferred_on_reject.Bind(
        LoadObjectField(capability, JSPromiseCapability::kRejectOffset));
    Goto(&perform_promise_then);
  }

  // 5. Return PerformPromiseThen(promise, onFulfilled, onRejected,
  //    resultCapability).
  Bind(&perform_promise_then);
  Node* const result = InternalPerformPromiseThen(
      context, promise, on_resolve, on_reject, var_deferred_promise.value(),
      var_deferred_on_resolve.value(), var_deferred_on_reject.value());
  return result;
}

Node* PromiseBuiltinsAssembler::InternalPerformPromiseThen(
    Node* context, Node* promise, Node* on_resolve, Node* on_reject,
    Node* deferred_promise, Node* deferred_on_resolve,
    Node* deferred_on_reject) {

  Variable var_on_resolve(this, MachineRepresentation::kTagged),
      var_on_reject(this, MachineRepresentation::kTagged);

  var_on_resolve.Bind(on_resolve);
  var_on_reject.Bind(on_reject);

  Label out(this), if_onresolvenotcallable(this), onrejectcheck(this),
      append_callbacks(this);
  GotoIf(TaggedIsSmi(on_resolve), &if_onresolvenotcallable);

  Isolate* isolate = this->isolate();
  Node* const on_resolve_map = LoadMap(on_resolve);
  Branch(IsCallableMap(on_resolve_map), &onrejectcheck,
         &if_onresolvenotcallable);

  Bind(&if_onresolvenotcallable);
  {
    Node* const default_resolve_handler_symbol = HeapConstant(
        isolate->factory()->promise_default_resolve_handler_symbol());
    var_on_resolve.Bind(default_resolve_handler_symbol);
    Goto(&onrejectcheck);
  }

  Bind(&onrejectcheck);
  {
    Label if_onrejectnotcallable(this);
    GotoIf(TaggedIsSmi(on_reject), &if_onrejectnotcallable);

    Node* const on_reject_map = LoadMap(on_reject);
    Branch(IsCallableMap(on_reject_map), &append_callbacks,
           &if_onrejectnotcallable);

    Bind(&if_onrejectnotcallable);
    {
      Node* const default_reject_handler_symbol = HeapConstant(
          isolate->factory()->promise_default_reject_handler_symbol());
      var_on_reject.Bind(default_reject_handler_symbol);
      Goto(&append_callbacks);
    }
  }

  Bind(&append_callbacks);
  {
    Label fulfilled_check(this);
    Node* const status = LoadObjectField(promise, JSPromise::kStatusOffset);
    GotoIfNot(SmiEqual(status, SmiConstant(v8::Promise::kPending)),
              &fulfilled_check);

    Node* const existing_deferred_promise =
        LoadObjectField(promise, JSPromise::kDeferredPromiseOffset);

    Label if_noexistingcallbacks(this), if_existingcallbacks(this);
    Branch(IsUndefined(existing_deferred_promise), &if_noexistingcallbacks,
           &if_existingcallbacks);

    Bind(&if_noexistingcallbacks);
    {
      // Store callbacks directly in the slots.
      StoreObjectField(promise, JSPromise::kDeferredPromiseOffset,
                       deferred_promise);
      StoreObjectField(promise, JSPromise::kDeferredOnResolveOffset,
                       deferred_on_resolve);
      StoreObjectField(promise, JSPromise::kDeferredOnRejectOffset,
                       deferred_on_reject);
      StoreObjectField(promise, JSPromise::kFulfillReactionsOffset,
                       var_on_resolve.value());
      StoreObjectField(promise, JSPromise::kRejectReactionsOffset,
                       var_on_reject.value());
      Goto(&out);
    }

    Bind(&if_existingcallbacks);
    {
      Label if_singlecallback(this), if_multiplecallbacks(this);
      BranchIfJSObject(existing_deferred_promise, &if_singlecallback,
                       &if_multiplecallbacks);

      Bind(&if_singlecallback);
      {
        // Create new FixedArrays to store callbacks, and migrate
        // existing callbacks.
        Node* const deferred_promise_arr =
            AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
        StoreFixedArrayElement(deferred_promise_arr, 0,
                               existing_deferred_promise);
        StoreFixedArrayElement(deferred_promise_arr, 1, deferred_promise);

        Node* const deferred_on_resolve_arr =
            AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
        StoreFixedArrayElement(
            deferred_on_resolve_arr, 0,
            LoadObjectField(promise, JSPromise::kDeferredOnResolveOffset));
        StoreFixedArrayElement(deferred_on_resolve_arr, 1, deferred_on_resolve);

        Node* const deferred_on_reject_arr =
            AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
        StoreFixedArrayElement(
            deferred_on_reject_arr, 0,
            LoadObjectField(promise, JSPromise::kDeferredOnRejectOffset));
        StoreFixedArrayElement(deferred_on_reject_arr, 1, deferred_on_reject);

        Node* const fulfill_reactions =
            AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
        StoreFixedArrayElement(
            fulfill_reactions, 0,
            LoadObjectField(promise, JSPromise::kFulfillReactionsOffset));
        StoreFixedArrayElement(fulfill_reactions, 1, var_on_resolve.value());

        Node* const reject_reactions =
            AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
        StoreFixedArrayElement(
            reject_reactions, 0,
            LoadObjectField(promise, JSPromise::kRejectReactionsOffset));
        StoreFixedArrayElement(reject_reactions, 1, var_on_reject.value());

        // Store new FixedArrays in promise.
        StoreObjectField(promise, JSPromise::kDeferredPromiseOffset,
                         deferred_promise_arr);
        StoreObjectField(promise, JSPromise::kDeferredOnResolveOffset,
                         deferred_on_resolve_arr);
        StoreObjectField(promise, JSPromise::kDeferredOnRejectOffset,
                         deferred_on_reject_arr);
        StoreObjectField(promise, JSPromise::kFulfillReactionsOffset,
                         fulfill_reactions);
        StoreObjectField(promise, JSPromise::kRejectReactionsOffset,
                         reject_reactions);
        Goto(&out);
      }

      Bind(&if_multiplecallbacks);
      {
        AppendPromiseCallback(JSPromise::kDeferredPromiseOffset, promise,
                              deferred_promise);
        AppendPromiseCallback(JSPromise::kDeferredOnResolveOffset, promise,
                              deferred_on_resolve);
        AppendPromiseCallback(JSPromise::kDeferredOnRejectOffset, promise,
                              deferred_on_reject);
        AppendPromiseCallback(JSPromise::kFulfillReactionsOffset, promise,
                              var_on_resolve.value());
        AppendPromiseCallback(JSPromise::kRejectReactionsOffset, promise,
                              var_on_reject.value());
        Goto(&out);
      }
    }

    Bind(&fulfilled_check);
    {
      Label reject(this);
      Node* const result = LoadObjectField(promise, JSPromise::kResultOffset);
      GotoIfNot(WordEqual(status, SmiConstant(v8::Promise::kFulfilled)),
                &reject);

      Node* info = AllocatePromiseReactionJobInfo(
          result, var_on_resolve.value(), deferred_promise, deferred_on_resolve,
          deferred_on_reject, context);
      // TODO(gsathya): Move this to TF
      CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, info);
      Goto(&out);

      Bind(&reject);
      {
        Node* const has_handler = PromiseHasHandler(promise);
        Label enqueue(this);

        // TODO(gsathya): Fold these runtime calls and move to TF.
        GotoIf(has_handler, &enqueue);
        CallRuntime(Runtime::kPromiseRevokeReject, context, promise);
        Goto(&enqueue);

        Bind(&enqueue);
        {
          Node* info = AllocatePromiseReactionJobInfo(
              result, var_on_reject.value(), deferred_promise,
              deferred_on_resolve, deferred_on_reject, context);
          // TODO(gsathya): Move this to TF
          CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, info);
          Goto(&out);
        }
      }
    }
  }

  Bind(&out);
  PromiseSetHasHandler(promise);
  return deferred_promise;
}

// Promise fast path implementations rely on unmodified JSPromise instances.
// We use a fairly coarse granularity for this and simply check whether both
// the promise itself is unmodified (i.e. its map has not changed) and its
// prototype is unmodified.
// TODO(gsathya): Refactor this out to prevent code dupe with builtins-regexp
void PromiseBuiltinsAssembler::BranchIfFastPath(Node* context, Node* promise,
                                                Label* if_isunmodified,
                                                Label* if_ismodified) {
  Node* const native_context = LoadNativeContext(context);
  Node* const promise_fun =
      LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
  BranchIfFastPath(native_context, promise_fun, promise, if_isunmodified,
                   if_ismodified);
}

void PromiseBuiltinsAssembler::BranchIfFastPath(Node* native_context,
                                                Node* promise_fun,
                                                Node* promise,
                                                Label* if_isunmodified,
                                                Label* if_ismodified) {
  CSA_ASSERT(this, IsNativeContext(native_context));
  CSA_ASSERT(this,
             WordEqual(promise_fun,
                       LoadContextElement(native_context,
                                          Context::PROMISE_FUNCTION_INDEX)));

  Node* const map = LoadMap(promise);
  Node* const initial_map =
      LoadObjectField(promise_fun, JSFunction::kPrototypeOrInitialMapOffset);
  Node* const has_initialmap = WordEqual(map, initial_map);

  GotoIfNot(has_initialmap, if_ismodified);

  Node* const initial_proto_initial_map =
      LoadContextElement(native_context, Context::PROMISE_PROTOTYPE_MAP_INDEX);
  Node* const proto_map = LoadMap(LoadMapPrototype(map));
  Node* const proto_has_initialmap =
      WordEqual(proto_map, initial_proto_initial_map);

  Branch(proto_has_initialmap, if_isunmodified, if_ismodified);
}

Node* PromiseBuiltinsAssembler::AllocatePromiseResolveThenableJobInfo(
    Node* thenable, Node* then, Node* resolve, Node* reject, Node* context) {
  Node* const info = Allocate(PromiseResolveThenableJobInfo::kSize);
  StoreMapNoWriteBarrier(info,
                         Heap::kPromiseResolveThenableJobInfoMapRootIndex);
  StoreObjectFieldNoWriteBarrier(
      info, PromiseResolveThenableJobInfo::kThenableOffset, thenable);
  StoreObjectFieldNoWriteBarrier(
      info, PromiseResolveThenableJobInfo::kThenOffset, then);
  StoreObjectFieldNoWriteBarrier(
      info, PromiseResolveThenableJobInfo::kResolveOffset, resolve);
  StoreObjectFieldNoWriteBarrier(
      info, PromiseResolveThenableJobInfo::kRejectOffset, reject);
  StoreObjectFieldNoWriteBarrier(
      info, PromiseResolveThenableJobInfo::kContextOffset, context);
  return info;
}

void PromiseBuiltinsAssembler::InternalResolvePromise(Node* context,
                                                      Node* promise,
                                                      Node* result) {
  Isolate* isolate = this->isolate();

  Variable var_reason(this, MachineRepresentation::kTagged),
      var_then(this, MachineRepresentation::kTagged);

  Label do_enqueue(this), fulfill(this), if_cycle(this, Label::kDeferred),
      if_rejectpromise(this, Label::kDeferred), out(this);

  Label cycle_check(this);
  GotoIfNot(IsPromiseHookEnabledOrDebugIsActive(), &cycle_check);
  CallRuntime(Runtime::kPromiseHookResolve, context, promise);
  Goto(&cycle_check);

  Bind(&cycle_check);
  // 6. If SameValue(resolution, promise) is true, then
  GotoIf(SameValue(promise, result, context), &if_cycle);

  // 7. If Type(resolution) is not Object, then
  GotoIf(TaggedIsSmi(result), &fulfill);
  GotoIfNot(IsJSReceiver(result), &fulfill);

  Label if_nativepromise(this), if_notnativepromise(this, Label::kDeferred);
  Node* const native_context = LoadNativeContext(context);
  Node* const promise_fun =
      LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
  BranchIfFastPath(native_context, promise_fun, result, &if_nativepromise,
                   &if_notnativepromise);

  // Resolution is a native promise and if it's already resolved or
  // rejected, shortcircuit the resolution procedure by directly
  // reusing the value from the promise.
  Bind(&if_nativepromise);
  {
    Node* const thenable_status =
        LoadObjectField(result, JSPromise::kStatusOffset);
    Node* const thenable_value =
        LoadObjectField(result, JSPromise::kResultOffset);

    Label if_isnotpending(this);
    GotoIfNot(SmiEqual(SmiConstant(v8::Promise::kPending), thenable_status),
              &if_isnotpending);

    // TODO(gsathya): Use a marker here instead of the actual then
    // callback, and check for the marker in PromiseResolveThenableJob
    // and perform PromiseThen.
    Node* const then =
        LoadContextElement(native_context, Context::PROMISE_THEN_INDEX);
    var_then.Bind(then);
    Goto(&do_enqueue);

    Bind(&if_isnotpending);
    {
      Label if_fulfilled(this), if_rejected(this);
      Branch(SmiEqual(SmiConstant(v8::Promise::kFulfilled), thenable_status),
             &if_fulfilled, &if_rejected);

      Bind(&if_fulfilled);
      {
        PromiseFulfill(context, promise, thenable_value,
                       v8::Promise::kFulfilled);
        PromiseSetHasHandler(promise);
        Goto(&out);
      }

      Bind(&if_rejected);
      {
        Label reject(this);
        Node* const has_handler = PromiseHasHandler(result);

        // Promise has already been rejected, but had no handler.
        // Revoke previously triggered reject event.
        GotoIf(has_handler, &reject);
        CallRuntime(Runtime::kPromiseRevokeReject, context, result);
        Goto(&reject);

        Bind(&reject);
        // Don't cause a debug event as this case is forwarding a rejection
        InternalPromiseReject(context, promise, thenable_value, false);
        PromiseSetHasHandler(result);
        Goto(&out);
      }
    }
  }

  Bind(&if_notnativepromise);
  {
    // 8. Let then be Get(resolution, "then").
    Node* const then_str = HeapConstant(isolate->factory()->then_string());
    Callable getproperty_callable = CodeFactory::GetProperty(isolate);
    Node* const then =
        CallStub(getproperty_callable, context, result, then_str);

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

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

  Bind(&do_enqueue);
  {
    // TODO(gsathya): Add fast path for native promises with unmodified
    // PromiseThen (which don't need these resolving functions, but
    // instead can just call resolve/reject directly).
    Node* resolve = nullptr;
    Node* reject = nullptr;
    std::tie(resolve, reject) = CreatePromiseResolvingFunctions(
        promise, FalseConstant(), native_context);

    Node* const info = AllocatePromiseResolveThenableJobInfo(
        result, var_then.value(), resolve, reject, context);

    Label enqueue(this);
    GotoIfNot(IsDebugActive(), &enqueue);

    GotoIf(TaggedIsSmi(result), &enqueue);
    GotoIfNot(HasInstanceType(result, JS_PROMISE_TYPE), &enqueue);

    // Mark the dependency of the new promise on the resolution
    Node* const key =
        HeapConstant(isolate->factory()->promise_handled_by_symbol());
    CallRuntime(Runtime::kSetProperty, context, result, key, promise,
                SmiConstant(STRICT));
    Goto(&enqueue);

    // 12. Perform EnqueueJob("PromiseJobs",
    // PromiseResolveThenableJob, « promise, resolution, thenAction»).
    Bind(&enqueue);
    // TODO(gsathya): Move this to TF
    CallRuntime(Runtime::kEnqueuePromiseResolveThenableJob, context, info);
    Goto(&out);
  }

  // 7.b Return FulfillPromise(promise, resolution).
  Bind(&fulfill);
  {
    PromiseFulfill(context, promise, result, v8::Promise::kFulfilled);
    Goto(&out);
  }

  Bind(&if_cycle);
  {
    // 6.a Let selfResolutionError be a newly created TypeError object.
    Node* const message_id = SmiConstant(MessageTemplate::kPromiseCyclic);
    Node* const error =
        CallRuntime(Runtime::kNewTypeError, context, message_id, result);
    var_reason.Bind(error);

    // 6.b Return RejectPromise(promise, selfResolutionError).
    Goto(&if_rejectpromise);
  }

  // 9.a Return RejectPromise(promise, then.[[Value]]).
  Bind(&if_rejectpromise);
  {
    InternalPromiseReject(context, promise, var_reason.value(), true);
    Goto(&out);
  }

  Bind(&out);
}

void PromiseBuiltinsAssembler::PromiseFulfill(
    Node* context, Node* promise, Node* result,
    v8::Promise::PromiseState status) {
  Label do_promisereset(this), debug_async_event_enqueue_recurring(this);

  Node* const status_smi = SmiConstant(static_cast<int>(status));
  Node* const deferred_promise =
      LoadObjectField(promise, JSPromise::kDeferredPromiseOffset);

  GotoIf(IsUndefined(deferred_promise), &debug_async_event_enqueue_recurring);

  Node* const tasks =
      status == v8::Promise::kFulfilled
          ? LoadObjectField(promise, JSPromise::kFulfillReactionsOffset)
          : LoadObjectField(promise, JSPromise::kRejectReactionsOffset);

  Node* const deferred_on_resolve =
      LoadObjectField(promise, JSPromise::kDeferredOnResolveOffset);
  Node* const deferred_on_reject =
      LoadObjectField(promise, JSPromise::kDeferredOnRejectOffset);

  Node* const info = AllocatePromiseReactionJobInfo(
      result, tasks, deferred_promise, deferred_on_resolve, deferred_on_reject,
      context);

  CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, info);
  Goto(&debug_async_event_enqueue_recurring);

  Bind(&debug_async_event_enqueue_recurring);
  {
    GotoIfNot(IsDebugActive(), &do_promisereset);
    CallRuntime(Runtime::kDebugAsyncEventEnqueueRecurring, context, promise,
                status_smi);
    Goto(&do_promisereset);
  }

  Bind(&do_promisereset);
  {
    StoreObjectField(promise, JSPromise::kStatusOffset, status_smi);
    StoreObjectField(promise, JSPromise::kResultOffset, result);
    StoreObjectFieldRoot(promise, JSPromise::kDeferredPromiseOffset,
                         Heap::kUndefinedValueRootIndex);
    StoreObjectFieldRoot(promise, JSPromise::kDeferredOnResolveOffset,
                         Heap::kUndefinedValueRootIndex);
    StoreObjectFieldRoot(promise, JSPromise::kDeferredOnRejectOffset,
                         Heap::kUndefinedValueRootIndex);
    StoreObjectFieldRoot(promise, JSPromise::kFulfillReactionsOffset,
                         Heap::kUndefinedValueRootIndex);
    StoreObjectFieldRoot(promise, JSPromise::kRejectReactionsOffset,
                         Heap::kUndefinedValueRootIndex);
  }
}

void PromiseBuiltinsAssembler::BranchIfAccessCheckFailed(
    Node* context, Node* native_context, Node* promise_constructor,
    Node* executor, Label* if_noaccess) {
  Variable var_executor(this, 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),
                     BooleanConstant(true)),
           &has_access, if_noaccess);
  }

  Bind(&has_access);
}

void PromiseBuiltinsAssembler::InternalPromiseReject(Node* context,
                                                     Node* promise, Node* value,
                                                     Node* debug_event) {
  Label out(this);
  GotoIfNot(IsDebugActive(), &out);
  GotoIfNot(WordEqual(TrueConstant(), debug_event), &out);
  CallRuntime(Runtime::kDebugPromiseReject, context, promise, value);
  Goto(&out);

  Bind(&out);
  InternalPromiseReject(context, promise, value, false);
}

// This duplicates a lot of logic from PromiseRejectEvent in
// runtime-promise.cc
void PromiseBuiltinsAssembler::InternalPromiseReject(Node* context,
                                                     Node* promise, Node* value,
                                                     bool debug_event) {
  Label fulfill(this), report_unhandledpromise(this), run_promise_hook(this);

  if (debug_event) {
    GotoIfNot(IsDebugActive(), &run_promise_hook);
    CallRuntime(Runtime::kDebugPromiseReject, context, promise, value);
    Goto(&run_promise_hook);
  } else {
    Goto(&run_promise_hook);
  }

  Bind(&run_promise_hook);
  {
    GotoIfNot(IsPromiseHookEnabledOrDebugIsActive(), &report_unhandledpromise);
    CallRuntime(Runtime::kPromiseHookResolve, context, promise);
    Goto(&report_unhandledpromise);
  }

  Bind(&report_unhandledpromise);
  {
    GotoIf(PromiseHasHandler(promise), &fulfill);
    CallRuntime(Runtime::kReportPromiseReject, context, promise, value);
    Goto(&fulfill);
  }

  Bind(&fulfill);
  PromiseFulfill(context, promise, value, v8::Promise::kRejected);
}

// ES#sec-promise-reject-functions
// Promise Reject Functions
TF_BUILTIN(PromiseRejectClosure, PromiseBuiltinsAssembler) {
  Node* const value = Parameter(1);
  Node* const context = Parameter(4);

  Label out(this);

  // 3. Let alreadyResolved be F.[[AlreadyResolved]].
  int has_already_visited_slot = kAlreadyVisitedSlot;

  Node* const has_already_visited =
      LoadContextElement(context, has_already_visited_slot);

  // 4. If alreadyResolved.[[Value]] is true, return undefined.
  GotoIf(SmiEqual(has_already_visited, SmiConstant(1)), &out);

  // 5.Set alreadyResolved.[[Value]] to true.
  StoreContextElementNoWriteBarrier(context, has_already_visited_slot,
                                    SmiConstant(1));

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

  InternalPromiseReject(context, promise, value, debug_event);
  Return(UndefinedConstant());

  Bind(&out);
  Return(UndefinedConstant());
}

TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) {
  Node* const executor = Parameter(1);
  Node* const new_target = Parameter(2);
  Node* const context = Parameter(4);
  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(this, MachineRepresentation::kTagged),
      var_reject_call(this, MachineRepresentation::kTagged),
      var_reason(this, 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(IsPromiseHookEnabledOrDebugIsActive(), &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);
    Callable call_callable = CodeFactory::Call(isolate);

    Node* const maybe_exception = CallJS(call_callable, context, executor,
                                         UndefinedConstant(), resolve, reject);

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

    Bind(&if_rejectpromise);
    {
      Callable call_callable = CodeFactory::Call(isolate);
      CallJS(call_callable, 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);
  {
    Node* const message_id = SmiConstant(MessageTemplate::kNotAPromise);
    CallRuntime(Runtime::kThrowTypeError, context, message_id, new_target);
    Unreachable();
  }

  // 2. If IsCallable(executor) is false, throw a TypeError exception.
  Bind(&if_notcallable);
  {
    Node* const message_id =
        SmiConstant(MessageTemplate::kResolverNotAFunction);
    CallRuntime(Runtime::kThrowTypeError, context, message_id, executor);
    Unreachable();
  }

  // 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());
  }
}

TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) {
  Node* const parent = Parameter(1);
  Node* const context = Parameter(4);
  Return(AllocateAndInitJSPromise(context, parent));
}

TF_BUILTIN(IsPromise, PromiseBuiltinsAssembler) {
  Node* const maybe_promise = Parameter(1);
  Label if_notpromise(this, Label::kDeferred);

  GotoIf(TaggedIsSmi(maybe_promise), &if_notpromise);

  Node* const result =
      SelectBooleanConstant(HasInstanceType(maybe_promise, JS_PROMISE_TYPE));
  Return(result);

  Bind(&if_notpromise);
  Return(FalseConstant());
}

// ES#sec-promise.prototype.then
// Promise.prototype.catch ( onFulfilled, onRejected )
TF_BUILTIN(PromiseThen, PromiseBuiltinsAssembler) {
  // 1. Let promise be the this value.
  Node* const promise = Parameter(0);
  Node* const on_resolve = Parameter(1);
  Node* const on_reject = Parameter(2);
  Node* const context = Parameter(5);

  Node* const result =
      InternalPromiseThen(context, promise, on_resolve, on_reject);
  Return(result);
}

// ES#sec-promise-resolve-functions
// Promise Resolve Functions
TF_BUILTIN(PromiseResolveClosure, PromiseBuiltinsAssembler) {
  Node* const value = Parameter(1);
  Node* const context = Parameter(4);

  Label out(this);

  // 3. Let alreadyResolved be F.[[AlreadyResolved]].
  int has_already_visited_slot = kAlreadyVisitedSlot;

  Node* const has_already_visited =
      LoadContextElement(context, has_already_visited_slot);

  // 4. If alreadyResolved.[[Value]] is true, return undefined.
  GotoIf(SmiEqual(has_already_visited, SmiConstant(1)), &out);

  // 5.Set alreadyResolved.[[Value]] to true.
  StoreContextElementNoWriteBarrier(context, has_already_visited_slot,
                                    SmiConstant(1));

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

  InternalResolvePromise(context, promise, value);
  Return(UndefinedConstant());

  Bind(&out);
  Return(UndefinedConstant());
}

TF_BUILTIN(ResolvePromise, PromiseBuiltinsAssembler) {
  Node* const promise = Parameter(1);
  Node* const result = Parameter(2);
  Node* const context = Parameter(5);

  InternalResolvePromise(context, promise, result);
  Return(UndefinedConstant());
}

TF_BUILTIN(PromiseHandleReject, PromiseBuiltinsAssembler) {
  typedef PromiseHandleRejectDescriptor Descriptor;

  Node* const promise = Parameter(Descriptor::kPromise);
  Node* const on_reject = Parameter(Descriptor::kOnReject);
  Node* const exception = Parameter(Descriptor::kException);
  Node* const context = Parameter(Descriptor::kContext);

  Callable call_callable = CodeFactory::Call(isolate());
  Variable var_unused(this, MachineRepresentation::kTagged);

  Label if_internalhandler(this), if_customhandler(this, Label::kDeferred);
  Branch(IsUndefined(on_reject), &if_internalhandler, &if_customhandler);

  Bind(&if_internalhandler);
  {
    InternalPromiseReject(context, promise, exception, false);
    Return(UndefinedConstant());
  }

  Bind(&if_customhandler);
  {
    CallJS(call_callable, context, on_reject, UndefinedConstant(), exception);
    Return(UndefinedConstant());
  }
}

TF_BUILTIN(PromiseHandle, PromiseBuiltinsAssembler) {
  Node* const value = Parameter(1);
  Node* const handler = Parameter(2);
  Node* const deferred_promise = Parameter(3);
  Node* const deferred_on_resolve = Parameter(4);
  Node* const deferred_on_reject = Parameter(5);
  Node* const context = Parameter(8);
  Isolate* isolate = this->isolate();

  Variable var_reason(this, MachineRepresentation::kTagged);

  Node* const is_debug_active = IsDebugActive();
  Label run_handler(this), if_rejectpromise(this), promisehook_before(this),
      promisehook_after(this), debug_pop(this);

  GotoIfNot(is_debug_active, &promisehook_before);
  CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise);
  Goto(&promisehook_before);

  Bind(&promisehook_before);
  {
    GotoIfNot(IsPromiseHookEnabledOrDebugIsActive(), &run_handler);
    CallRuntime(Runtime::kPromiseHookBefore, context, deferred_promise);
    Goto(&run_handler);
  }

  Bind(&run_handler);
  {
    Label if_defaulthandler(this), if_callablehandler(this),
        if_internalhandler(this), if_customhandler(this, Label::kDeferred);
    Variable var_result(this, MachineRepresentation::kTagged);

    Branch(IsSymbol(handler), &if_defaulthandler, &if_callablehandler);

    Bind(&if_defaulthandler);
    {
      Label if_resolve(this), if_reject(this);
      Node* const default_resolve_handler_symbol = HeapConstant(
          isolate->factory()->promise_default_resolve_handler_symbol());
      Branch(WordEqual(default_resolve_handler_symbol, handler), &if_resolve,
             &if_reject);

      Bind(&if_resolve);
      {
        var_result.Bind(value);
        Branch(IsUndefined(deferred_on_resolve), &if_internalhandler,
               &if_customhandler);
      }

      Bind(&if_reject);
      {
        var_reason.Bind(value);
        Goto(&if_rejectpromise);
      }
    }

    Bind(&if_callablehandler);
    {
      Callable call_callable = CodeFactory::Call(isolate);
      Node* const result =
          CallJS(call_callable, context, handler, UndefinedConstant(), value);
      var_result.Bind(result);
      GotoIfException(result, &if_rejectpromise, &var_reason);
      Branch(IsUndefined(deferred_on_resolve), &if_internalhandler,
             &if_customhandler);
    }

    Bind(&if_internalhandler);
    InternalResolvePromise(context, deferred_promise, var_result.value());
    Goto(&promisehook_after);

    Bind(&if_customhandler);
    {
      Callable call_callable = CodeFactory::Call(isolate);
      Node* const maybe_exception =
          CallJS(call_callable, context, deferred_on_resolve,
                 UndefinedConstant(), var_result.value());
      GotoIfException(maybe_exception, &if_rejectpromise, &var_reason);
      Goto(&promisehook_after);
    }
  }

  Bind(&if_rejectpromise);
  {
    Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate);
    CallStub(promise_handle_reject, context, deferred_promise,
             deferred_on_reject, var_reason.value());
    Goto(&promisehook_after);
  }

  Bind(&promisehook_after);
  {
    GotoIfNot(IsPromiseHookEnabledOrDebugIsActive(), &debug_pop);
    CallRuntime(Runtime::kPromiseHookAfter, context, deferred_promise);
    Goto(&debug_pop);
  }

  Bind(&debug_pop);
  {
    Label out(this);

    GotoIfNot(is_debug_active, &out);
    CallRuntime(Runtime::kDebugPopPromise, context);
    Goto(&out);

    Bind(&out);
    Return(UndefinedConstant());
  }
}

// ES#sec-promise.prototype.catch
// Promise.prototype.catch ( onRejected )
TF_BUILTIN(PromiseCatch, PromiseBuiltinsAssembler) {
  // 1. Let promise be the this value.
  Node* const promise = Parameter(0);
  Node* const on_resolve = UndefinedConstant();
  Node* const on_reject = Parameter(1);
  Node* const context = Parameter(4);

  Label if_internalthen(this), if_customthen(this, Label::kDeferred);
  GotoIf(TaggedIsSmi(promise), &if_customthen);
  BranchIfFastPath(context, promise, &if_internalthen, &if_customthen);

  Bind(&if_internalthen);
  {
    Node* const result =
        InternalPromiseThen(context, promise, on_resolve, on_reject);
    Return(result);
  }

  Bind(&if_customthen);
  {
    Isolate* isolate = this->isolate();
    Node* const then_str = HeapConstant(isolate->factory()->then_string());
    Callable getproperty_callable = CodeFactory::GetProperty(isolate);
    Node* const then =
        CallStub(getproperty_callable, context, promise, then_str);
    Callable call_callable = CodeFactory::Call(isolate);
    Node* const result =
        CallJS(call_callable, context, then, promise, on_resolve, on_reject);
    Return(result);
  }
}

TF_BUILTIN(PromiseResolve, PromiseBuiltinsAssembler) {
  //  1. Let C be the this value.
  Node* receiver = Parameter(0);
  Node* value = Parameter(1);
  Node* context = Parameter(4);
  Isolate* isolate = this->isolate();

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

  Label if_valueisnativepromise(this), if_valueisnotnativepromise(this),
      if_valueisnotpromise(this);

  // 3.If IsPromise(x) is true, then
  GotoIf(TaggedIsSmi(value), &if_valueisnotpromise);

  // This shortcircuits the constructor lookups.
  GotoIfNot(HasInstanceType(value, JS_PROMISE_TYPE), &if_valueisnotpromise);

  // This adds a fast path as non-subclassed native promises don't have
  // an observable constructor lookup.
  Node* const native_context = LoadNativeContext(context);
  Node* const promise_fun =
      LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
  BranchIfFastPath(native_context, promise_fun, value, &if_valueisnativepromise,
                   &if_valueisnotnativepromise);

  Bind(&if_valueisnativepromise);
  {
    GotoIfNot(WordEqual(promise_fun, receiver), &if_valueisnotnativepromise);
    Return(value);
  }

  // At this point, value or/and receiver are not native promises, but
  // they could be of the same subclass.
  Bind(&if_valueisnotnativepromise);
  {
    // 3.a Let xConstructor be ? Get(x, "constructor").
    // The constructor lookup is observable.
    Node* const constructor_str =
        HeapConstant(isolate->factory()->constructor_string());
    Callable getproperty_callable = CodeFactory::GetProperty(isolate);
    Node* const constructor =
        CallStub(getproperty_callable, context, value, constructor_str);

    // 3.b If SameValue(xConstructor, C) is true, return x.
    GotoIfNot(SameValue(constructor, receiver, context), &if_valueisnotpromise);

    Return(value);
  }

  Bind(&if_valueisnotpromise);
  {
    Label if_nativepromise(this), if_notnativepromise(this);
    BranchIfFastPath(context, receiver, &if_nativepromise,
                     &if_notnativepromise);

    // This adds a fast path for native promises that don't need to
    // create NewPromiseCapability.
    Bind(&if_nativepromise);
    {
      Label do_resolve(this);

      Node* const result = AllocateAndInitJSPromise(context);
      InternalResolvePromise(context, result, value);
      Return(result);
    }

    Bind(&if_notnativepromise);
    {
      // 4. Let promiseCapability be ? NewPromiseCapability(C).
      Node* const capability = NewPromiseCapability(context, receiver);

      // 5. Perform ? Call(promiseCapability.[[Resolve]], undefined, « x »).
      Callable call_callable = CodeFactory::Call(isolate);
      Node* const resolve =
          LoadObjectField(capability, JSPromiseCapability::kResolveOffset);
      CallJS(call_callable, context, resolve, UndefinedConstant(), value);

      // 6. Return promiseCapability.[[Promise]].
      Node* const result =
          LoadObjectField(capability, JSPromiseCapability::kPromiseOffset);
      Return(result);
    }
  }
}

TF_BUILTIN(PromiseGetCapabilitiesExecutor, PromiseBuiltinsAssembler) {
  Node* const resolve = Parameter(1);
  Node* const reject = Parameter(2);
  Node* const context = Parameter(5);

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

  Label if_alreadyinvoked(this, Label::kDeferred);
  GotoIf(WordNotEqual(
             LoadObjectField(capability, JSPromiseCapability::kResolveOffset),
             UndefinedConstant()),
         &if_alreadyinvoked);
  GotoIf(WordNotEqual(
             LoadObjectField(capability, JSPromiseCapability::kRejectOffset),
             UndefinedConstant()),
         &if_alreadyinvoked);

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

  Return(UndefinedConstant());

  Bind(&if_alreadyinvoked);
  Node* message = SmiConstant(MessageTemplate::kPromiseExecutorAlreadyInvoked);
  CallRuntime(Runtime::kThrowTypeError, context, message);
  Unreachable();
}

TF_BUILTIN(NewPromiseCapability, PromiseBuiltinsAssembler) {
  Node* constructor = Parameter(1);
  Node* debug_event = Parameter(2);
  Node* context = Parameter(5);

  CSA_ASSERT_JS_ARGC_EQ(this, 2);

  Return(NewPromiseCapability(context, constructor, debug_event));
}

TF_BUILTIN(PromiseReject, PromiseBuiltinsAssembler) {
  // 1. Let C be the this value.
  Node* const receiver = Parameter(0);
  Node* const reason = Parameter(1);
  Node* const context = Parameter(4);

  // 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, SmiConstant(v8::Promise::kRejected), reason);
    CallRuntime(Runtime::kPromiseRejectEventFromStack, context, promise,
                reason);
    Return(promise);
  }

  Bind(&if_custompromise);
  {
    // 3. Let promiseCapability be ? NewPromiseCapability(C).
    Node* const capability = NewPromiseCapability(context, receiver);

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

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

TF_BUILTIN(InternalPromiseReject, PromiseBuiltinsAssembler) {
  Node* const promise = Parameter(1);
  Node* const reason = Parameter(2);
  Node* const debug_event = Parameter(3);
  Node* const context = Parameter(6);

  InternalPromiseReject(context, promise, reason, debug_event);
  Return(UndefinedConstant());
}

Node* PromiseBuiltinsAssembler::CreatePromiseFinallyContext(
    Node* on_finally, Node* native_context) {
  Node* const context =
      CreatePromiseContext(native_context, kOnFinallyContextLength);
  StoreContextElementNoWriteBarrier(context, kOnFinallySlot, on_finally);
  return context;
}

std::pair<Node*, Node*> PromiseBuiltinsAssembler::CreatePromiseFinallyFunctions(
    Node* on_finally, Node* native_context) {
  Node* const promise_context =
      CreatePromiseFinallyContext(on_finally, native_context);
  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(3);

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

Node* PromiseBuiltinsAssembler::CreateValueThunkFunctionContext(
    Node* value, Node* native_context) {
  Node* const context =
      CreatePromiseContext(native_context, kOnFinallyContextLength);
  StoreContextElementNoWriteBarrier(context, kOnFinallySlot, value);
  return context;
}

Node* PromiseBuiltinsAssembler::CreateValueThunkFunction(Node* value,
                                                         Node* native_context) {
  Node* const value_thunk_context =
      CreateValueThunkFunctionContext(value, native_context);
  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(1);
  Node* const context = Parameter(4);

  Node* const on_finally = LoadContextElement(context, kOnFinallySlot);

  // 2.a Let result be ?  Call(onFinally, undefined).
  Callable call_callable = CodeFactory::Call(isolate());
  Node* result =
      CallJS(call_callable, context, on_finally, UndefinedConstant());

  // 2.b Let promise be !  PromiseResolve( %Promise%, result).
  Node* const promise = AllocateAndInitJSPromise(context);
  InternalResolvePromise(context, promise, result);

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

  // 2.d Let promiseCapability be !  NewPromiseCapability( %Promise%).
  Node* const promise_capability = AllocateAndInitJSPromise(context, promise);

  // 2.e Return PerformPromiseThen(promise, valueThunk, undefined,
  // promiseCapability).
  InternalPerformPromiseThen(context, promise, value_thunk, UndefinedConstant(),
                             promise_capability, UndefinedConstant(),
                             UndefinedConstant());
  Return(promise_capability);
}

TF_BUILTIN(PromiseThrowerFinally, PromiseBuiltinsAssembler) {
  Node* const context = Parameter(3);

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

Node* PromiseBuiltinsAssembler::CreateThrowerFunctionContext(
    Node* reason, Node* native_context) {
  Node* const context =
      CreatePromiseContext(native_context, kOnFinallyContextLength);
  StoreContextElementNoWriteBarrier(context, kOnFinallySlot, reason);
  return context;
}

Node* PromiseBuiltinsAssembler::CreateThrowerFunction(Node* reason,
                                                      Node* native_context) {
  Node* const thrower_context =
      CreateThrowerFunctionContext(reason, native_context);
  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(1);
  Node* const context = Parameter(4);

  Node* const on_finally = LoadContextElement(context, kOnFinallySlot);

  // 2.a Let result be ?  Call(onFinally, undefined).
  Callable call_callable = CodeFactory::Call(isolate());
  Node* result =
      CallJS(call_callable, context, on_finally, UndefinedConstant());

  // 2.b Let promise be !  PromiseResolve( %Promise%, result).
  Node* const promise = AllocateAndInitJSPromise(context);
  InternalResolvePromise(context, promise, result);

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

  // 2.d Let promiseCapability be !  NewPromiseCapability( %Promise%).
  Node* const promise_capability = AllocateAndInitJSPromise(context, promise);

  // 2.e Return PerformPromiseThen(promise, thrower, undefined,
  // promiseCapability).
  InternalPerformPromiseThen(context, promise, thrower, UndefinedConstant(),
                             promise_capability, UndefinedConstant(),
                             UndefinedConstant());
  Return(promise_capability);
}

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

  // 1.  Let promise be the this value.
  Node* const promise = Parameter(0);
  Node* const on_finally = Parameter(1);
  Node* const context = Parameter(4);

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

  Variable var_then_finally(this, MachineRepresentation::kTagged),
      var_catch_finally(this, MachineRepresentation::kTagged);

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

  // 3. Let thenFinally be !  CreateThenFinally(onFinally).
  // 4. Let catchFinally be !  CreateCatchFinally(onFinally).
  GotoIf(TaggedIsSmi(on_finally), &if_notcallable);
  Node* const on_finally_map = LoadMap(on_finally);
  GotoIfNot(IsCallableMap(on_finally_map), &if_notcallable);

  Node* const native_context = LoadNativeContext(context);
  Node* then_finally = nullptr;
  Node* catch_finally = nullptr;
  std::tie(then_finally, catch_finally) =
      CreatePromiseFinallyFunctions(on_finally, native_context);
  var_then_finally.Bind(then_finally);
  var_catch_finally.Bind(catch_finally);
  Goto(&perform_finally);

  Bind(&if_notcallable);
  {
    var_then_finally.Bind(on_finally);
    var_catch_finally.Bind(on_finally);
    Goto(&perform_finally);
  }

  // 5. Return PerformPromiseThen(promise, valueThunk, undefined,
  // promiseCapability).
  Bind(&perform_finally);
  Label if_nativepromise(this), if_custompromise(this, Label::kDeferred);
  BranchIfFastPath(context, promise, &if_nativepromise, &if_custompromise);

  Bind(&if_nativepromise);
  {
    Node* deferred_promise = AllocateAndInitJSPromise(context, promise);
    InternalPerformPromiseThen(context, promise, var_then_finally.value(),
                               var_catch_finally.value(), deferred_promise,
                               UndefinedConstant(), UndefinedConstant());
    Return(deferred_promise);
  }

  Bind(&if_custompromise);
  {
    Isolate* isolate = this->isolate();
    Node* const then_str = HeapConstant(isolate->factory()->then_string());
    Callable getproperty_callable = CodeFactory::GetProperty(isolate);
    Node* const then =
        CallStub(getproperty_callable, context, promise, then_str);
    Callable call_callable = CodeFactory::Call(isolate);
    // 5. Return ?  Invoke(promise, "then", « thenFinally, catchFinally »).
    Node* const result =
        CallJS(call_callable, context, then, promise, var_then_finally.value(),
               var_catch_finally.value());
    Return(result);
  }
}

}  // namespace internal
}  // namespace v8
