// 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 {
transitioning javascript builtin
ArraySomeLoopEagerDeoptContinuation(
    js-implicit context: NativeContext, receiver: JSAny)(
    callback: JSAny, thisArg: JSAny, initialK: JSAny, length: JSAny): JSAny {
  // All continuation points in the optimized some implementation are
  // after the ToObject(O) call that ensures we are dealing with a
  // JSReceiver.
  //
  // Also, this great mass of casts is necessary because the signature
  // of Torque javascript builtins requires JSAny type for all parameters
  // other than {context}.
  const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable;
  const callbackfn = Cast<Callable>(callback) otherwise unreachable;
  const numberK = Cast<Number>(initialK) otherwise unreachable;
  const numberLength = Cast<Number>(length) otherwise unreachable;

  return ArraySomeLoopContinuation(
      jsreceiver, callbackfn, thisArg, Undefined, jsreceiver, numberK,
      numberLength, Undefined);
}

transitioning javascript builtin
ArraySomeLoopLazyDeoptContinuation(
    js-implicit context: NativeContext, receiver: JSAny)(
    callback: JSAny, thisArg: JSAny, initialK: JSAny, length: JSAny,
    result: JSAny): JSAny {
  // All continuation points in the optimized some implementation are
  // after the ToObject(O) call that ensures we are dealing with a
  // JSReceiver.
  const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable;
  const callbackfn = Cast<Callable>(callback) otherwise unreachable;
  let numberK = Cast<Number>(initialK) otherwise unreachable;
  const numberLength = Cast<Number>(length) otherwise unreachable;

  // This custom lazy deopt point is right after the callback. some() needs
  // to pick up at the next step: if the result is true, then return,
  // otherwise, keep going through the array starting from k + 1.
  if (ToBoolean(result)) {
    return True;
  }

  numberK = numberK + 1;

  return ArraySomeLoopContinuation(
      jsreceiver, callbackfn, thisArg, Undefined, jsreceiver, numberK,
      numberLength, Undefined);
}

transitioning builtin ArraySomeLoopContinuation(implicit context: Context)(
    _receiver: JSReceiver, callbackfn: Callable, thisArg: JSAny, _array: JSAny,
    o: JSReceiver, initialK: Number, length: Number, _initialTo: JSAny): JSAny {
  // 5. Let k be 0.
  // 6. Repeat, while k < len
  for (let k: Number = initialK; k < length; k++) {
    // 6a. Let Pk be ! ToString(k).
    // k is guaranteed to be a positive integer, hence ToString is
    // side-effect free and HasProperty/GetProperty do the conversion inline.

    // 6b. Let kPresent be ? HasProperty(O, Pk).
    const kPresent: Boolean = HasProperty_Inline(o, k);

    // 6c. If kPresent is true, then
    if (kPresent == True) {
      // 6c. i. Let kValue be ? Get(O, Pk).
      const kValue: JSAny = GetProperty(o, k);

      // 6c. ii. Perform ? Call(callbackfn, T, <kValue, k, O>).
      const result: JSAny = Call(context, callbackfn, thisArg, kValue, k, o);

      // iii. If selected is true, then...
      if (ToBoolean(result)) {
        return True;
      }
    }

    // 6d. Increase k by 1. (done by the loop).
  }
  return False;
}

transitioning macro FastArraySome(implicit context: Context)(
    o: JSReceiver, len: Number, callbackfn: Callable, thisArg: JSAny): JSAny
    labels Bailout(Smi) {
  let k: Smi = 0;
  const smiLen = Cast<Smi>(len) otherwise goto Bailout(k);
  const fastO = Cast<FastJSArray>(o) otherwise goto Bailout(k);
  let fastOW = NewFastJSArrayWitness(fastO);

  // Build a fast loop over the smi array.
  for (; k < smiLen; k++) {
    fastOW.Recheck() otherwise goto Bailout(k);

    // Ensure that we haven't walked beyond a possibly updated length.
    if (k >= fastOW.Get().length) goto Bailout(k);
    const value: JSAny = fastOW.LoadElementNoHole(k) otherwise continue;
    const result: JSAny =
        Call(context, callbackfn, thisArg, value, k, fastOW.Get());
    if (ToBoolean(result)) {
      return True;
    }
  }
  return False;
}

// https://tc39.github.io/ecma262/#sec-array.prototype.some
transitioning javascript builtin
ArraySome(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  try {
    RequireObjectCoercible(receiver, 'Array.prototype.some');

    // 1. Let O be ? ToObject(this value).
    const o: JSReceiver = ToObject_Inline(context, receiver);

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

    // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
    if (arguments.length == 0) {
      goto TypeError;
    }
    const callbackfn = Cast<Callable>(arguments[0]) otherwise TypeError;

    // 4. If thisArg is present, let T be thisArg; else let T be undefined.
    const thisArg: JSAny = arguments[1];

    // Special cases.
    try {
      return FastArraySome(o, len, callbackfn, thisArg)
          otherwise Bailout;
    } label Bailout(kValue: Smi) deferred {
      return ArraySomeLoopContinuation(
          o, callbackfn, thisArg, Undefined, o, kValue, len, Undefined);
    }
  } label TypeError deferred {
    ThrowTypeError(MessageTemplate::kCalledNonCallable, arguments[0]);
  }
}
}
