// Copyright 2018 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.

namespace array {
macro LoadWithHoleCheck<Elements : type extends FixedArrayBase>(
    elements: FixedArrayBase, index: Smi): JSAny
    labels IfHole;

LoadWithHoleCheck<FixedArray>(implicit context: Context)(
    elements: FixedArrayBase, index: Smi): JSAny
    labels IfHole {
  const elements: FixedArray = UnsafeCast<FixedArray>(elements);
  const element: Object = elements.objects[index];
  if (element == TheHole) goto IfHole;
  return UnsafeCast<JSAny>(element);
}

LoadWithHoleCheck<FixedDoubleArray>(implicit context: Context)(
    elements: FixedArrayBase, index: Smi): JSAny
    labels IfHole {
  const elements: FixedDoubleArray = UnsafeCast<FixedDoubleArray>(elements);
  const element: float64 = elements.floats[index].Value() otherwise IfHole;
  return AllocateHeapNumberWithValue(element);
}

macro FastArrayLastIndexOf<Elements : type extends FixedArrayBase>(
    context: Context, array: JSArray, from: Smi, searchElement: JSAny): Smi {
  const elements: FixedArrayBase = array.elements;
  let k: Smi = from;

  // Bug(898785): Due to side-effects in the evaluation of `fromIndex`
  // the {from} can be out-of-bounds here, so we need to clamp {k} to
  // the {elements} length. We might be reading holes / hole NaNs still
  // due to that, but those will be ignored below.
  if (k >= elements.length) {
    k = elements.length - 1;
  }

  while (k >= 0) {
    try {
      const element: JSAny = LoadWithHoleCheck<Elements>(elements, k)
          otherwise Hole;

      const same: Boolean = StrictEqual(searchElement, element);
      if (same == True) {
        assert(Is<FastJSArray>(array));
        return k;
      }
    } label Hole {}  // Do nothing for holes.

    --k;
  }

  assert(Is<FastJSArray>(array));
  return -1;
}

transitioning macro
GetFromIndex(context: Context, length: Number, arguments: Arguments): Number {
  // 4. If fromIndex is present, let n be ? ToInteger(fromIndex);
  //    else let n be len - 1.
  const n: Number =
      arguments.length < 2 ? length - 1 : ToInteger_Inline(arguments[1]);

  // 5. If n >= 0, then.
  let k: Number = SmiConstant(0);
  if (n >= 0) {
    // a. If n is -0, let k be +0; else let k be min(n, len - 1).
    // If n was -0 it got truncated to 0.0, so taking the minimum is fine.
    k = Min(n, length - 1);
  } else {
    // a. Let k be len + n.
    k = length + n;
  }
  return k;
}

macro TryFastArrayLastIndexOf(
    context: Context, receiver: JSReceiver, searchElement: JSAny,
    from: Number): JSAny
    labels Slow {
  const array: FastJSArray = Cast<FastJSArray>(receiver) otherwise Slow;
  const length: Smi = array.length;
  if (length == 0) return SmiConstant(-1);

  const fromSmi: Smi = Cast<Smi>(from) otherwise Slow;
  const kind: ElementsKind = array.map.elements_kind;
  if (IsFastSmiOrTaggedElementsKind(kind)) {
    return FastArrayLastIndexOf<FixedArray>(
        context, array, fromSmi, searchElement);
  }
  assert(IsDoubleElementsKind(kind));
  return FastArrayLastIndexOf<FixedDoubleArray>(
      context, array, fromSmi, searchElement);
}

transitioning macro GenericArrayLastIndexOf(
    context: Context, object: JSReceiver, searchElement: JSAny,
    from: Number): JSAny {
  let k: Number = from;

  // 7. Repeat, while k >= 0.
  while (k >= 0) {
    // a. Let kPresent be ? HasProperty(O, ! ToString(k)).
    const kPresent: Boolean = HasProperty(object, k);

    // b. If kPresent is true, then.
    if (kPresent == True) {
      // i. Let elementK be ? Get(O, ! ToString(k)).
      const element: JSAny = GetProperty(object, k);

      // ii. Let same be the result of performing Strict Equality Comparison
      //     searchElement === elementK.
      const same: Boolean = StrictEqual(searchElement, element);

      // iii. If same is true, return k.
      if (same == True) return k;
    }

    // c. Decrease k by 1.
    --k;
  }

  // 8. Return -1.
  return SmiConstant(-1);
}

// https://tc39.github.io/ecma262/#sec-array.prototype.lastIndexOf
transitioning javascript builtin ArrayPrototypeLastIndexOf(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  // 1. Let O be ? ToObject(this value).
  const object: JSReceiver = ToObject_Inline(context, receiver);

  // 2. Let len be ? ToLength(? Get(O, "length")).
  const length: Number = GetLengthProperty(object);

  // 3. If len is 0, return -1.
  if (length == SmiConstant(0)) return SmiConstant(-1);

  // Step 4 - 6.
  const from: Number = GetFromIndex(context, length, arguments);

  const searchElement: JSAny = arguments[0];

  try {
    return TryFastArrayLastIndexOf(context, object, searchElement, from)
        otherwise Baseline;
  } label Baseline {
    return GenericArrayLastIndexOf(context, object, searchElement, from);
  }
}
}
