// Copyright 2019 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-promise-gen.h'

namespace runtime {
extern transitioning runtime
RejectPromise(implicit context: Context)(JSPromise, JSAny, Boolean): JSAny;

extern transitioning runtime
PromiseRevokeReject(implicit context: Context)(JSPromise): JSAny;

extern transitioning runtime
PromiseRejectAfterResolved(implicit context: Context)(JSPromise, JSAny): JSAny;

extern transitioning runtime
PromiseResolveAfterResolved(implicit context: Context)(JSPromise, JSAny): JSAny;

extern transitioning runtime
PromiseRejectEventFromStack(implicit context: Context)(JSPromise, JSAny): JSAny;
}

// https://tc39.es/ecma262/#sec-promise-abstract-operations
namespace promise {

extern macro PromiseForwardingHandlerSymbolConstant(): Symbol;
const kPromiseForwardingHandlerSymbol: Symbol =
    PromiseForwardingHandlerSymbolConstant();
extern macro PromiseHandledBySymbolConstant(): Symbol;
const kPromiseHandledBySymbol: Symbol = PromiseHandledBySymbolConstant();
extern macro ResolveStringConstant(): String;
const kResolveString: String = ResolveStringConstant();
extern macro IsPromiseResolveProtectorCellInvalid(): bool;

extern macro AllocateFunctionWithMapAndContext(
    Map, SharedFunctionInfo, FunctionContext): JSFunction;

extern macro PromiseReactionMapConstant(): Map;
extern macro PromiseFulfillReactionJobTaskMapConstant(): Map;
extern macro PromiseRejectReactionJobTaskMapConstant(): Map;
extern transitioning builtin
ResolvePromise(Context, JSPromise, JSAny): JSAny;

extern transitioning builtin
EnqueueMicrotask(Context, Microtask): Undefined;

macro
ExtractHandlerContextInternal(implicit context: Context)(
    handler: Callable|Undefined): Context labels NotFound {
  let iter: JSAny = handler;
  while (true) {
    typeswitch (iter) {
      case (b: JSBoundFunction): {
        iter = b.bound_target_function;
      }
      case (p: JSProxy): {
        iter = p.target;
      }
      case (f: JSFunction): {
        return f.context;
      }
      case (JSAny): {
        break;
      }
    }
  }
  goto NotFound;
}

macro
ExtractHandlerContext(implicit context: Context)(handler: Callable|
                                                 Undefined): Context {
  try {
    return ExtractHandlerContextInternal(handler) otherwise NotFound;
  } label NotFound deferred {
    return context;
  }
}

macro
ExtractHandlerContext(implicit context: Context)(
    primary: Callable|Undefined, secondary: Callable|Undefined): Context {
  try {
    return ExtractHandlerContextInternal(primary) otherwise NotFound;
  } label NotFound deferred {
    return ExtractHandlerContextInternal(secondary) otherwise Default;
  } label Default deferred {
    return context;
  }
}

transitioning macro MorphAndEnqueuePromiseReaction(implicit context: Context)(
    promiseReaction: PromiseReaction, argument: JSAny,
    reactionType: constexpr PromiseReactionType): void {
  let primaryHandler: Callable|Undefined;
  let secondaryHandler: Callable|Undefined;
  if constexpr (reactionType == kPromiseReactionFulfill) {
    primaryHandler = promiseReaction.fulfill_handler;
    secondaryHandler = promiseReaction.reject_handler;
  } else {
    static_assert(reactionType == kPromiseReactionReject);
    primaryHandler = promiseReaction.reject_handler;
    secondaryHandler = promiseReaction.fulfill_handler;
  }

  // According to HTML, we use the context of the appropriate handler as the
  // context of the microtask. See step 3 of HTML's EnqueueJob:
  // https://html.spec.whatwg.org/C/#enqueuejob(queuename,-job,-arguments)
  const handlerContext: Context =
      ExtractHandlerContext(primaryHandler, secondaryHandler);

  // 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(
      kPromiseReactionSize ==
      kPromiseReactionJobTaskSizeOfAllPromiseReactionJobTasks);
  if constexpr (reactionType == kPromiseReactionFulfill) {
    *UnsafeConstCast(&promiseReaction.map) =
        PromiseFulfillReactionJobTaskMapConstant();
    const promiseReactionJobTask =
        UnsafeCast<PromiseFulfillReactionJobTask>(promiseReaction);
    promiseReactionJobTask.argument = argument;
    promiseReactionJobTask.context = handlerContext;
    EnqueueMicrotask(handlerContext, promiseReactionJobTask);
    static_assert(
        kPromiseReactionFulfillHandlerOffset ==
        kPromiseReactionJobTaskHandlerOffset);
    static_assert(
        kPromiseReactionPromiseOrCapabilityOffset ==
        kPromiseReactionJobTaskPromiseOrCapabilityOffset);
  } else {
    static_assert(reactionType == kPromiseReactionReject);
    *UnsafeConstCast(&promiseReaction.map) =
        PromiseRejectReactionJobTaskMapConstant();
    const promiseReactionJobTask =
        UnsafeCast<PromiseRejectReactionJobTask>(promiseReaction);
    promiseReactionJobTask.argument = argument;
    promiseReactionJobTask.context = handlerContext;
    promiseReactionJobTask.handler = primaryHandler;
    EnqueueMicrotask(handlerContext, promiseReactionJobTask);
    static_assert(
        kPromiseReactionPromiseOrCapabilityOffset ==
        kPromiseReactionJobTaskPromiseOrCapabilityOffset);
  }
}

// https://tc39.es/ecma262/#sec-triggerpromisereactions
transitioning macro TriggerPromiseReactions(implicit context: Context)(
    reactions: Zero|PromiseReaction, argument: JSAny,
    reactionType: constexpr PromiseReactionType): void {
  // We need to reverse the {reactions} here, since we record them on the
  // JSPromise in the reverse order.
  let current = reactions;
  let reversed: Zero|PromiseReaction = kZero;

  // As an additional safety net against misuse of the V8 Extras API, we
  // sanity check the {reactions} to make sure that they are actually
  // PromiseReaction instances and not actual JavaScript values (which
  // would indicate that we're rejecting or resolving an already settled
  // promise), see https://crbug.com/931640 for details on this.
  while (true) {
    typeswitch (current) {
      case (Zero): {
        break;
      }
      case (currentReaction: PromiseReaction): {
        current = currentReaction.next;
        currentReaction.next = reversed;
        reversed = currentReaction;
      }
    }
  }
  // Morph the {reactions} into PromiseReactionJobTasks and push them
  // onto the microtask queue.
  current = reversed;
  while (true) {
    typeswitch (current) {
      case (Zero): {
        break;
      }
      case (currentReaction: PromiseReaction): {
        current = currentReaction.next;
        MorphAndEnqueuePromiseReaction(currentReaction, argument, reactionType);
      }
    }
  }
}

// https://tc39.es/ecma262/#sec-fulfillpromise
transitioning builtin
FulfillPromise(implicit context: Context)(
    promise: JSPromise, value: JSAny): Undefined {
  // Assert: The value of promise.[[PromiseState]] is "pending".
  assert(promise.Status() == PromiseState::kPending);

  // 2. Let reactions be promise.[[PromiseFulfillReactions]].
  const reactions =
      UnsafeCast<(Zero | PromiseReaction)>(promise.reactions_or_result);

  // 3. Set promise.[[PromiseResult]] to value.
  // 4. Set promise.[[PromiseFulfillReactions]] to undefined.
  // 5. Set promise.[[PromiseRejectReactions]] to undefined.
  promise.reactions_or_result = value;

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

  // 7. Return TriggerPromiseReactions(reactions, value).
  TriggerPromiseReactions(reactions, value, kPromiseReactionFulfill);
  return Undefined;
}

extern macro PromiseBuiltinsAssembler::
    IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(): bool;

// https://tc39.es/ecma262/#sec-rejectpromise
transitioning builtin
RejectPromise(implicit context: Context)(
    promise: JSPromise, reason: JSAny, debugEvent: Boolean): JSAny {
  // 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.
  if (IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate() ||
      !promise.HasHandler()) {
    // 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.
    return runtime::RejectPromise(promise, reason, debugEvent);
  }

  // 2. Let reactions be promise.[[PromiseRejectReactions]].
  const reactions =
      UnsafeCast<(Zero | PromiseReaction)>(promise.reactions_or_result);

  // 3. Set promise.[[PromiseResult]] to reason.
  // 4. Set promise.[[PromiseFulfillReactions]] to undefined.
  // 5. Set promise.[[PromiseRejectReactions]] to undefined.
  promise.reactions_or_result = reason;

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

  // 8. Return TriggerPromiseReactions(reactions, reason).
  TriggerPromiseReactions(reactions, reason, kPromiseReactionReject);
  return Undefined;
}

const kPromiseCapabilitySize:
    constexpr int31 generates 'PromiseCapability::kSize';

type PromiseResolvingFunctionContext extends FunctionContext;
extern enum PromiseResolvingFunctionContextSlot extends intptr
constexpr 'PromiseBuiltins::PromiseResolvingFunctionContextSlot' {
  kPromiseSlot: Slot<PromiseResolvingFunctionContext, JSPromise>,
  kAlreadyResolvedSlot: Slot<PromiseResolvingFunctionContext, Boolean>,
  kDebugEventSlot: Slot<PromiseResolvingFunctionContext, Boolean>,
  kPromiseContextLength
}

type PromiseCapabilitiesExecutorContext extends FunctionContext;
extern enum FunctionContextSlot extends intptr
constexpr 'PromiseBuiltins::FunctionContextSlot' {
  kCapabilitySlot: Slot<PromiseCapabilitiesExecutorContext, PromiseCapability>,
  kCapabilitiesContextLength
}

@export
macro CreatePromiseCapabilitiesExecutorContext(
    nativeContext: NativeContext, capability: PromiseCapability):
    PromiseCapabilitiesExecutorContext {
  const executorContext = %RawDownCast<PromiseCapabilitiesExecutorContext>(
      AllocateSyntheticFunctionContext(
          nativeContext, FunctionContextSlot::kCapabilitiesContextLength));

  InitContextSlot(
      executorContext, FunctionContextSlot::kCapabilitySlot, capability);
  return executorContext;
}

@export
macro CreatePromiseCapability(
    promise: JSReceiver|Undefined, resolve: JSFunction|Undefined,
    reject: JSFunction|Undefined): PromiseCapability {
  return new PromiseCapability{
    map: kPromiseCapabilityMap,
    promise: promise,
    resolve: resolve,
    reject: reject
  };
}

@export
struct PromiseResolvingFunctions {
  resolve: JSFunction;
  reject: JSFunction;
}

@export
macro CreatePromiseResolvingFunctions(implicit context: Context)(
    promise: JSPromise, debugEvent: Boolean, nativeContext: NativeContext):
    PromiseResolvingFunctions {
  const promiseContext = CreatePromiseResolvingFunctionsContext(
      promise, debugEvent, nativeContext);
  const map = *NativeContextSlot(
      nativeContext, ContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
  const resolveInfo = PromiseCapabilityDefaultResolveSharedFunConstant();

  const resolve: JSFunction =
      AllocateFunctionWithMapAndContext(map, resolveInfo, promiseContext);
  const rejectInfo = PromiseCapabilityDefaultRejectSharedFunConstant();
  const reject: JSFunction =
      AllocateFunctionWithMapAndContext(map, rejectInfo, promiseContext);
  return PromiseResolvingFunctions{resolve: resolve, reject: reject};
}

transitioning macro
InnerNewPromiseCapability(implicit context: Context)(
    constructor: HeapObject, debugEvent: Boolean): PromiseCapability {
  const nativeContext = LoadNativeContext(context);
  if (constructor ==
      *NativeContextSlot(nativeContext, ContextSlot::PROMISE_FUNCTION_INDEX)) {
    const promise = NewJSPromise();

    const pair =
        CreatePromiseResolvingFunctions(promise, debugEvent, nativeContext);

    return CreatePromiseCapability(promise, pair.resolve, pair.reject);
  } else {
    // We have to create the capability before the associated promise
    // because the builtin PromiseConstructor uses the executor.
    const capability = CreatePromiseCapability(Undefined, Undefined, Undefined);
    const executorContext =
        CreatePromiseCapabilitiesExecutorContext(nativeContext, capability);

    const executorInfo = PromiseGetCapabilitiesExecutorSharedFunConstant();
    const functionMap =
        *NativeContextSlot(
        nativeContext,
        ContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
    const executor = AllocateFunctionWithMapAndContext(
        functionMap, executorInfo, executorContext);

    const promiseConstructor = UnsafeCast<Constructor>(constructor);
    const promise = Construct(promiseConstructor, executor);
    capability.promise = promise;

    if (!Is<Callable>(capability.resolve) || !Is<Callable>(capability.reject)) {
      ThrowTypeError(MessageTemplate::kPromiseNonCallable);
    }
    return capability;
  }
}

// https://tc39.es/ecma262/#sec-newpromisecapability
transitioning builtin
NewPromiseCapability(implicit context: Context)(
    maybeConstructor: Object, debugEvent: Boolean): PromiseCapability {
  typeswitch (maybeConstructor) {
    case (Smi): {
      ThrowTypeError(MessageTemplate::kNotConstructor, maybeConstructor);
    }
    case (constructor: HeapObject): {
      if (!IsConstructor(constructor)) {
        ThrowTypeError(MessageTemplate::kNotConstructor, maybeConstructor);
      }
      return InnerNewPromiseCapability(constructor, debugEvent);
    }
  }
}

// https://tc39.es/ecma262/#sec-promise-reject-functions
transitioning javascript builtin
PromiseCapabilityDefaultReject(
    js-implicit context: Context, receiver: JSAny)(reason: JSAny): JSAny {
  const context = %RawDownCast<PromiseResolvingFunctionContext>(context);
  // 2. Let promise be F.[[Promise]].
  const promise =
      *ContextSlot(context, PromiseResolvingFunctionContextSlot::kPromiseSlot);

  // 3. Let alreadyResolved be F.[[AlreadyResolved]].
  const alreadyResolved = *ContextSlot(
      context, PromiseResolvingFunctionContextSlot::kAlreadyResolvedSlot);

  // 4. If alreadyResolved.[[Value]] is true, return undefined.
  if (alreadyResolved == True) {
    return runtime::PromiseRejectAfterResolved(promise, reason);
  }

  // 5. Set alreadyResolved.[[Value]] to true.
  *ContextSlot(
      context, PromiseResolvingFunctionContextSlot::kAlreadyResolvedSlot) =
      True;

  // 6. Return RejectPromise(promise, reason).
  const debugEvent = *ContextSlot(
      context, PromiseResolvingFunctionContextSlot::kDebugEventSlot);
  return RejectPromise(promise, reason, debugEvent);
}

// https://tc39.es/ecma262/#sec-promise-resolve-functions
transitioning javascript builtin
PromiseCapabilityDefaultResolve(
    js-implicit context: Context, receiver: JSAny)(resolution: JSAny): JSAny {
  const context = %RawDownCast<PromiseResolvingFunctionContext>(context);
  // 2. Let promise be F.[[Promise]].
  const promise: JSPromise =
      *ContextSlot(context, PromiseResolvingFunctionContextSlot::kPromiseSlot);

  // 3. Let alreadyResolved be F.[[AlreadyResolved]].
  const alreadyResolved: Boolean = *ContextSlot(
      context, PromiseResolvingFunctionContextSlot::kAlreadyResolvedSlot);

  // 4. If alreadyResolved.[[Value]] is true, return undefined.
  if (alreadyResolved == True) {
    return runtime::PromiseResolveAfterResolved(promise, resolution);
  }

  // 5. Set alreadyResolved.[[Value]] to true.
  *ContextSlot(
      context, PromiseResolvingFunctionContextSlot::kAlreadyResolvedSlot) =
      True;

  // The rest of the logic (and the catch prediction) is
  // encapsulated in the dedicated ResolvePromise builtin.
  return ResolvePromise(context, promise, resolution);
}

@export
transitioning macro PerformPromiseThenImpl(implicit context: Context)(
    promise: JSPromise, onFulfilled: Callable|Undefined,
    onRejected: Callable|Undefined,
    resultPromiseOrCapability: JSPromise|PromiseCapability|Undefined): void {
  if (promise.Status() == PromiseState::kPending) {
    // 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.
    const handlerContext = ExtractHandlerContext(onFulfilled, onRejected);
    const promiseReactions =
        UnsafeCast<(Zero | PromiseReaction)>(promise.reactions_or_result);
    const reaction = NewPromiseReaction(
        handlerContext, promiseReactions, resultPromiseOrCapability,
        onFulfilled, onRejected);
    promise.reactions_or_result = reaction;
  } else {
    const reactionsOrResult = promise.reactions_or_result;
    let microtask: PromiseReactionJobTask;
    let handlerContext: Context;
    if (promise.Status() == PromiseState::kFulfilled) {
      handlerContext = ExtractHandlerContext(onFulfilled, onRejected);
      microtask = NewPromiseFulfillReactionJobTask(
          handlerContext, reactionsOrResult, onFulfilled,
          resultPromiseOrCapability);
    } else
      deferred {
        assert(promise.Status() == PromiseState::kRejected);
        handlerContext = ExtractHandlerContext(onRejected, onFulfilled);
        microtask = NewPromiseRejectReactionJobTask(
            handlerContext, reactionsOrResult, onRejected,
            resultPromiseOrCapability);
        if (!promise.HasHandler()) {
          runtime::PromiseRevokeReject(promise);
        }
      }
    EnqueueMicrotask(handlerContext, microtask);
  }
  promise.SetHasHandler();
}

// https://tc39.es/ecma262/#sec-performpromisethen
transitioning builtin
PerformPromiseThen(implicit context: Context)(
    promise: JSPromise, onFulfilled: Callable|Undefined,
    onRejected: Callable|Undefined, resultPromise: JSPromise|Undefined): JSAny {
  PerformPromiseThenImpl(promise, onFulfilled, onRejected, resultPromise);
  return resultPromise;
}

// https://tc39.es/ecma262/#sec-promise-reject-functions
transitioning javascript builtin
PromiseReject(
    js-implicit context: NativeContext, receiver: JSAny)(reason: JSAny): JSAny {
  // 1. Let C be the this value.
  // 2. If Type(C) is not Object, throw a TypeError exception.
  const receiver = Cast<JSReceiver>(receiver) otherwise
  ThrowTypeError(MessageTemplate::kCalledOnNonObject, 'PromiseReject');

  const promiseFun = *NativeContextSlot(ContextSlot::PROMISE_FUNCTION_INDEX);
  if (promiseFun == receiver) {
    const promise = NewJSPromise(PromiseState::kRejected, reason);
    runtime::PromiseRejectEventFromStack(promise, reason);
    return promise;
  } else {
    // 3. Let promiseCapability be ? NewPromiseCapability(C).
    const capability = NewPromiseCapability(receiver, True);

    // 4. Perform ? Call(promiseCapability.[[Reject]], undefined, « r »).
    const reject = UnsafeCast<Callable>(capability.reject);
    Call(context, reject, Undefined, reason);

    // 5. Return promiseCapability.[[Promise]].
    return capability.promise;
  }
}

const kPromiseExecutorAlreadyInvoked: constexpr MessageTemplate
    generates 'MessageTemplate::kPromiseExecutorAlreadyInvoked';

// https://tc39.es/ecma262/#sec-getcapabilitiesexecutor-functions
transitioning javascript builtin
PromiseGetCapabilitiesExecutor(js-implicit context: Context, receiver: JSAny)(
    resolve: JSAny, reject: JSAny): JSAny {
  const context = %RawDownCast<PromiseCapabilitiesExecutorContext>(context);
  const capability: PromiseCapability =
      *ContextSlot(context, FunctionContextSlot::kCapabilitySlot);
  if (capability.resolve != Undefined || capability.reject != Undefined)
    deferred {
      ThrowTypeError(kPromiseExecutorAlreadyInvoked);
    }

  capability.resolve = resolve;
  capability.reject = reject;
  return Undefined;
}

macro IsPromiseResolveLookupChainIntact(implicit context: Context)(
    nativeContext: NativeContext, constructor: JSReceiver): bool {
  if (IsForceSlowPath()) return false;
  const promiseFun =
      *NativeContextSlot(nativeContext, ContextSlot::PROMISE_FUNCTION_INDEX);
  return promiseFun == constructor && !IsPromiseResolveProtectorCellInvalid();
}

// https://tc39.es/ecma262/#sec-getpromiseresolve
transitioning macro GetPromiseResolve(implicit context: Context)(
    nativeContext: NativeContext, constructor: Constructor): JSAny {
  // 1. Assert: IsConstructor(constructor) is true.

  // 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. In this case, promiseResolveFunction is undefined,
  // and when CallResolve is called with it later, it will call Promise.resolve.
  let promiseResolveFunction: JSAny = Undefined;

  if (!IsPromiseResolveLookupChainIntact(nativeContext, constructor)) {
    let promiseResolve: JSAny;

    // 2. Let promiseResolve be ? Get(constructor, "resolve").
    promiseResolve = GetProperty(constructor, kResolveString);

    // 3. If IsCallable(promiseResolve) is false, throw a TypeError exception.
    promiseResolveFunction =
        Cast<Callable>(promiseResolve) otherwise ThrowTypeError(
            MessageTemplate::kCalledNonCallable, 'resolve');
  }
  // 4. return promiseResolve.
  return promiseResolveFunction;
}

transitioning macro CallResolve(implicit context: Context)(
    constructor: Constructor, resolve: JSAny, value: JSAny): JSAny {
  // Undefined can never be a valid value for the resolve function,
  // instead it is used as a special marker for the fast path.
  if (resolve == Undefined) {
    return PromiseResolve(constructor, value);
  } else
    deferred {
      return Call(context, UnsafeCast<Callable>(resolve), constructor, value);
    }
}

transitioning javascript builtin
PromiseConstructorLazyDeoptContinuation(
    js-implicit context: NativeContext, receiver: JSAny)(
    promise: JSAny, reject: JSAny, exception: JSAny|TheHole,
    _result: JSAny): JSAny {
  typeswitch (exception) {
    case (TheHole): {
    }
    case (e: JSAny): {
      Call(context, reject, Undefined, e);
    }
  }
  return promise;
}

extern macro PromiseCapabilityDefaultRejectSharedFunConstant():
    SharedFunctionInfo;
extern macro PromiseCapabilityDefaultResolveSharedFunConstant():
    SharedFunctionInfo;
extern macro PromiseGetCapabilitiesExecutorSharedFunConstant():
    SharedFunctionInfo;
}
