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

module array {
  // Naming convention from elements.cc. We have a similar intent but implement
  // fastpaths using generics instead of using a class hierarchy for elements
  // kinds specific implementations.
  type GenericElementsAccessor;
  type FastPackedSmiElements;
  type FastPackedObjectElements;
  type FastPackedDoubleElements;
  type FastSmiOrObjectElements;
  type FastDoubleElements;
  type DictionaryElements;

  macro GetLengthProperty(context: Context, o: Object): Number {
    if (BranchIfFastJSArray(o, context)) {
      let a: JSArray = unsafe_cast<JSArray>(o);
      return a.length_fast;
    } else
      deferred {
        return ToLength_Inline(context, GetProperty(context, o, kLengthString));
      }
  }

  macro EnsureWriteableFastElements(array: JSArray) {
    assert(IsFastElementsKind(array.map.elements_kind));

    const elements: FixedArrayBase = array.elements;
    if (elements.map != kCOWMap) return;

    // There are no COW *_DOUBLE_ELEMENTS arrays, so we are allowed to always
    // extract FixedArrays and don't have to worry about FixedDoubleArrays.
    assert(IsFastSmiOrTaggedElementsKind(array.map.elements_kind));

    const length: Smi = array.length_fast;
    array.elements = ExtractFixedArray(
        elements, 0, length, length, kFixedArrays);
    assert(array.elements.map != kCOWMap);
  }

  macro IsJSArray(o: Object): bool {
    try {
      let array: JSArray = cast<JSArray>(o) otherwise NotArray;
      return true;
    }
    label NotArray {
      return false;
    }
  }

  macro StoreArrayHole(elements: FixedDoubleArray, k: Smi): void {
    StoreFixedDoubleArrayHoleSmi(elements, k);
  }

  macro StoreArrayHole(elements: FixedArray, k: Smi): void {
    elements[k] = Hole;
  }

  macro CopyArrayElement(
      elements: FixedArray, newElements: FixedArray, from: Smi, to: Smi): void {
    let e: Object = elements[from];
    newElements[to] = e;
  }

  macro CopyArrayElement(
      elements: FixedDoubleArray, newElements: FixedDoubleArray, from: Smi,
      to: Smi): void {
    try {
      let floatValue: float64 = LoadDoubleWithHoleCheck(elements, from)
      otherwise FoundHole;
      newElements[to] = floatValue;
    }
    label FoundHole {
      StoreArrayHole(newElements, to);
    }
  }
}
