// 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_unshift {
  extern builtin ArrayUnshift(Context, JSFunction, Object, int32);

  macro TryFastArrayUnshift(
      context: Context, receiver: Object, arguments: Arguments): never
      labels Slow {
    const array: FastJSArray = Cast<FastJSArray>(receiver) otherwise Slow;
    array::EnsureWriteableFastElements(array);

    const map: Map = array.map;
    if (!IsExtensibleMap(map)) goto Slow;
    EnsureArrayLengthWritable(map) otherwise Slow;

    tail ArrayUnshift(
        context, LoadTargetFromFrame(), Undefined,
        Convert<int32>(arguments.length));
  }

  transitioning macro GenericArrayUnshift(
      context: Context, receiver: Object, arguments: Arguments): Number {
    // 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. Let argCount be the number of actual arguments.
    const argCount: Smi = Convert<Smi>(arguments.length);

    // 4. If argCount > 0, then.
    if (argCount > 0) {
      // a. If len + argCount > 2**53 - 1, throw a TypeError exception.
      if (length + argCount > kMaxSafeInteger) {
        ThrowTypeError(kInvalidArrayLength);
      }

      // b. Let k be len.
      let k: Number = length;

      // c. Repeat, while k > 0.
      while (k > 0) {
        // i. Let from be ! ToString(k - 1).
        const from: Number = k - 1;

        // ii. Let to be ! ToString(k + argCount - 1).
        const to: Number = k + argCount - 1;

        // iii. Let fromPresent be ? HasProperty(O, from).
        const fromPresent: Boolean = HasProperty(object, from);

        // iv. If fromPresent is true, then
        if (fromPresent == True) {
          // 1. Let fromValue be ? Get(O, from).
          const fromValue: Object = GetProperty(object, from);

          // 2. Perform ? Set(O, to, fromValue, true).
          SetProperty(object, to, fromValue);
        } else {
          // 1. Perform ? DeletePropertyOrThrow(O, to).
          DeleteProperty(object, to, kStrict);
        }

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

      // d. Let j be 0.
      let j: Smi = 0;

      // e. Let items be a List whose elements are, in left to right order,
      //    the arguments that were passed to this function invocation.
      // f. Repeat, while items is not empty
      while (j < argCount) {
        // ii .Perform ? Set(O, ! ToString(j), E, true).
        SetProperty(object, j, arguments[Convert<intptr>(j)]);

        // iii. Increase j by 1.
        ++j;
      }
    }

    // 5. Perform ? Set(O, "length", len + argCount, true).
    const newLength: Number = length + argCount;
    SetProperty(object, kLengthString, newLength);

    // 6. Return length + argCount.
    return newLength;
  }

  // https://tc39.github.io/ecma262/#sec-array.prototype.unshift
  transitioning javascript builtin ArrayPrototypeUnshift(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    try {
      TryFastArrayUnshift(context, receiver, arguments) otherwise Baseline;
    }
    label Baseline {
      return GenericArrayUnshift(context, receiver, arguments);
    }
  }
}
