// Copyright 2012 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/objects/elements-kind.h"

#include "src/base/lazy-instance.h"
#include "src/objects/elements.h"
#include "src/objects/objects-inl.h"
#include "src/objects/objects.h"

namespace v8 {
namespace internal {

int ElementsKindToShiftSize(ElementsKind elements_kind) {
  switch (elements_kind) {
    case UINT8_ELEMENTS:
    case INT8_ELEMENTS:
    case UINT8_CLAMPED_ELEMENTS:
      return 0;
    case UINT16_ELEMENTS:
    case INT16_ELEMENTS:
      return 1;
    case UINT32_ELEMENTS:
    case INT32_ELEMENTS:
    case FLOAT32_ELEMENTS:
      return 2;
    case PACKED_DOUBLE_ELEMENTS:
    case HOLEY_DOUBLE_ELEMENTS:
    case FLOAT64_ELEMENTS:
    case BIGINT64_ELEMENTS:
    case BIGUINT64_ELEMENTS:
      return 3;
    case PACKED_SMI_ELEMENTS:
    case PACKED_ELEMENTS:
    case PACKED_FROZEN_ELEMENTS:
    case PACKED_SEALED_ELEMENTS:
    case HOLEY_SMI_ELEMENTS:
    case HOLEY_ELEMENTS:
    case HOLEY_FROZEN_ELEMENTS:
    case HOLEY_SEALED_ELEMENTS:
    case DICTIONARY_ELEMENTS:
    case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
    case FAST_STRING_WRAPPER_ELEMENTS:
    case SLOW_STRING_WRAPPER_ELEMENTS:
      return kTaggedSizeLog2;
    case NO_ELEMENTS:
      UNREACHABLE();
  }
  UNREACHABLE();
}

int ElementsKindToByteSize(ElementsKind elements_kind) {
  return 1 << ElementsKindToShiftSize(elements_kind);
}

int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind) {
  STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize);

  if (IsTypedArrayElementsKind(elements_kind)) {
    return 0;
  } else {
    return FixedArray::kHeaderSize - kHeapObjectTag;
  }
}

const char* ElementsKindToString(ElementsKind kind) {
  switch (kind) {
    case PACKED_SMI_ELEMENTS:
      return "PACKED_SMI_ELEMENTS";
    case HOLEY_SMI_ELEMENTS:
      return "HOLEY_SMI_ELEMENTS";
    case PACKED_ELEMENTS:
      return "PACKED_ELEMENTS";
    case HOLEY_ELEMENTS:
      return "HOLEY_ELEMENTS";
    case PACKED_DOUBLE_ELEMENTS:
      return "PACKED_DOUBLE_ELEMENTS";
    case HOLEY_DOUBLE_ELEMENTS:
      return "HOLEY_DOUBLE_ELEMENTS";
    case PACKED_SEALED_ELEMENTS:
      return "PACKED_SEALED_ELEMENTS";
    case HOLEY_SEALED_ELEMENTS:
      return "HOLEY_SEALED_ELEMENTS";
    case PACKED_FROZEN_ELEMENTS:
      return "PACKED_FROZEN_ELEMENTS";
    case HOLEY_FROZEN_ELEMENTS:
      return "HOLEY_FROZEN_ELEMENTS";
    case DICTIONARY_ELEMENTS:
      return "DICTIONARY_ELEMENTS";
    case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
      return "FAST_SLOPPY_ARGUMENTS_ELEMENTS";
    case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
      return "SLOW_SLOPPY_ARGUMENTS_ELEMENTS";
    case FAST_STRING_WRAPPER_ELEMENTS:
      return "FAST_STRING_WRAPPER_ELEMENTS";
    case SLOW_STRING_WRAPPER_ELEMENTS:
      return "SLOW_STRING_WRAPPER_ELEMENTS";

#define PRINT_NAME(Type, type, TYPE, _) \
  case TYPE##_ELEMENTS:                 \
    return #TYPE "ELEMENTS";

      TYPED_ARRAYS(PRINT_NAME);
#undef PRINT_NAME
    case NO_ELEMENTS:
      return "NO_ELEMENTS";
  }
}

ElementsKind kFastElementsKindSequence[kFastElementsKindCount] = {
    PACKED_SMI_ELEMENTS,     // 0
    HOLEY_SMI_ELEMENTS,      // 1
    PACKED_DOUBLE_ELEMENTS,  // 2
    HOLEY_DOUBLE_ELEMENTS,   // 3
    PACKED_ELEMENTS,         // 4
    HOLEY_ELEMENTS           // 5
};
STATIC_ASSERT(PACKED_SMI_ELEMENTS == FIRST_FAST_ELEMENTS_KIND);
// Verify that kFastElementsKindPackedToHoley is correct.
STATIC_ASSERT(PACKED_SMI_ELEMENTS + kFastElementsKindPackedToHoley ==
              HOLEY_SMI_ELEMENTS);
STATIC_ASSERT(PACKED_DOUBLE_ELEMENTS + kFastElementsKindPackedToHoley ==
              HOLEY_DOUBLE_ELEMENTS);
STATIC_ASSERT(PACKED_ELEMENTS + kFastElementsKindPackedToHoley ==
              HOLEY_ELEMENTS);

ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number) {
  DCHECK(sequence_number >= 0 && sequence_number < kFastElementsKindCount);
  return kFastElementsKindSequence[sequence_number];
}

int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind) {
  for (int i = 0; i < kFastElementsKindCount; ++i) {
    if (kFastElementsKindSequence[i] == elements_kind) {
      return i;
    }
  }
  UNREACHABLE();
}

ElementsKind GetNextTransitionElementsKind(ElementsKind kind) {
  int index = GetSequenceIndexFromFastElementsKind(kind);
  return GetFastElementsKindFromSequenceIndex(index + 1);
}

static inline bool IsFastTransitionTarget(ElementsKind elements_kind) {
  return IsFastElementsKind(elements_kind) ||
         elements_kind == DICTIONARY_ELEMENTS;
}

bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
                                         ElementsKind to_kind) {
  if (!IsFastElementsKind(from_kind)) return false;
  if (!IsFastTransitionTarget(to_kind)) return false;
  DCHECK(!IsTypedArrayElementsKind(from_kind));
  DCHECK(!IsTypedArrayElementsKind(to_kind));
  switch (from_kind) {
    case PACKED_SMI_ELEMENTS:
      return to_kind != PACKED_SMI_ELEMENTS;
    case HOLEY_SMI_ELEMENTS:
      return to_kind != PACKED_SMI_ELEMENTS && to_kind != HOLEY_SMI_ELEMENTS;
    case PACKED_DOUBLE_ELEMENTS:
      return to_kind != PACKED_SMI_ELEMENTS && to_kind != HOLEY_SMI_ELEMENTS &&
             to_kind != PACKED_DOUBLE_ELEMENTS;
    case HOLEY_DOUBLE_ELEMENTS:
      return to_kind == PACKED_ELEMENTS || to_kind == HOLEY_ELEMENTS;
    case PACKED_ELEMENTS:
      return to_kind == HOLEY_ELEMENTS;
    case HOLEY_ELEMENTS:
      return false;
    default:
      return false;
  }
}

bool UnionElementsKindUptoSize(ElementsKind* a_out, ElementsKind b) {
  // Assert that the union of two ElementKinds can be computed via std::max.
  static_assert(PACKED_SMI_ELEMENTS < HOLEY_SMI_ELEMENTS,
                "ElementsKind union not computable via std::max.");
  static_assert(HOLEY_SMI_ELEMENTS < PACKED_ELEMENTS,
                "ElementsKind union not computable via std::max.");
  static_assert(PACKED_ELEMENTS < HOLEY_ELEMENTS,
                "ElementsKind union not computable via std::max.");
  static_assert(PACKED_DOUBLE_ELEMENTS < HOLEY_DOUBLE_ELEMENTS,
                "ElementsKind union not computable via std::max.");
  ElementsKind a = *a_out;
  switch (a) {
    case PACKED_SMI_ELEMENTS:
      switch (b) {
        case PACKED_SMI_ELEMENTS:
        case HOLEY_SMI_ELEMENTS:
        case PACKED_ELEMENTS:
        case HOLEY_ELEMENTS:
          *a_out = b;
          return true;
        default:
          return false;
      }
    case HOLEY_SMI_ELEMENTS:
      switch (b) {
        case PACKED_SMI_ELEMENTS:
        case HOLEY_SMI_ELEMENTS:
          *a_out = HOLEY_SMI_ELEMENTS;
          return true;
        case PACKED_ELEMENTS:
        case HOLEY_ELEMENTS:
          *a_out = HOLEY_ELEMENTS;
          return true;
        default:
          return false;
      }
    case PACKED_ELEMENTS:
      switch (b) {
        case PACKED_SMI_ELEMENTS:
        case PACKED_ELEMENTS:
          *a_out = PACKED_ELEMENTS;
          return true;
        case HOLEY_SMI_ELEMENTS:
        case HOLEY_ELEMENTS:
          *a_out = HOLEY_ELEMENTS;
          return true;
        default:
          return false;
      }
    case HOLEY_ELEMENTS:
      switch (b) {
        case PACKED_SMI_ELEMENTS:
        case HOLEY_SMI_ELEMENTS:
        case PACKED_ELEMENTS:
        case HOLEY_ELEMENTS:
          *a_out = HOLEY_ELEMENTS;
          return true;
        default:
          return false;
      }
      break;
    case PACKED_DOUBLE_ELEMENTS:
      switch (b) {
        case PACKED_DOUBLE_ELEMENTS:
        case HOLEY_DOUBLE_ELEMENTS:
          *a_out = b;
          return true;
        default:
          return false;
      }
    case HOLEY_DOUBLE_ELEMENTS:
      switch (b) {
        case PACKED_DOUBLE_ELEMENTS:
        case HOLEY_DOUBLE_ELEMENTS:
          *a_out = HOLEY_DOUBLE_ELEMENTS;
          return true;
        default:
          return false;
      }

      break;
    default:
      break;
  }
  return false;
}

}  // namespace internal
}  // namespace v8
