// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "elements-kind.h"

#include "api.h"
#include "elements.h"
#include "objects.h"

namespace v8 {
namespace internal {


int ElementsKindToShiftSize(ElementsKind elements_kind) {
  switch (elements_kind) {
    case EXTERNAL_BYTE_ELEMENTS:
    case EXTERNAL_PIXEL_ELEMENTS:
    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
      return 0;
    case EXTERNAL_SHORT_ELEMENTS:
    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
      return 1;
    case EXTERNAL_INT_ELEMENTS:
    case EXTERNAL_UNSIGNED_INT_ELEMENTS:
    case EXTERNAL_FLOAT_ELEMENTS:
      return 2;
    case EXTERNAL_DOUBLE_ELEMENTS:
    case FAST_DOUBLE_ELEMENTS:
    case FAST_HOLEY_DOUBLE_ELEMENTS:
      return 3;
    case FAST_SMI_ELEMENTS:
    case FAST_ELEMENTS:
    case FAST_HOLEY_SMI_ELEMENTS:
    case FAST_HOLEY_ELEMENTS:
    case DICTIONARY_ELEMENTS:
    case NON_STRICT_ARGUMENTS_ELEMENTS:
      return kPointerSizeLog2;
  }
  UNREACHABLE();
  return 0;
}


void PrintElementsKind(FILE* out, ElementsKind kind) {
  ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
  PrintF(out, "%s", accessor->name());
}


ElementsKind GetInitialFastElementsKind() {
  if (FLAG_packed_arrays) {
    return FAST_SMI_ELEMENTS;
  } else {
    return FAST_HOLEY_SMI_ELEMENTS;
  }
}


struct InitializeFastElementsKindSequence {
  static void Construct(
      ElementsKind** fast_elements_kind_sequence_ptr) {
    ElementsKind* fast_elements_kind_sequence =
        new ElementsKind[kFastElementsKindCount];
    *fast_elements_kind_sequence_ptr = fast_elements_kind_sequence;
    STATIC_ASSERT(FAST_SMI_ELEMENTS == FIRST_FAST_ELEMENTS_KIND);
    fast_elements_kind_sequence[0] = FAST_SMI_ELEMENTS;
    fast_elements_kind_sequence[1] = FAST_HOLEY_SMI_ELEMENTS;
    fast_elements_kind_sequence[2] = FAST_DOUBLE_ELEMENTS;
    fast_elements_kind_sequence[3] = FAST_HOLEY_DOUBLE_ELEMENTS;
    fast_elements_kind_sequence[4] = FAST_ELEMENTS;
    fast_elements_kind_sequence[5] = FAST_HOLEY_ELEMENTS;
  }
};


static LazyInstance<ElementsKind*,
                    InitializeFastElementsKindSequence>::type
    fast_elements_kind_sequence = LAZY_INSTANCE_INITIALIZER;


ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number) {
  ASSERT(sequence_number >= 0 &&
         sequence_number < kFastElementsKindCount);
  return fast_elements_kind_sequence.Get()[sequence_number];
}

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


ElementsKind GetNextMoreGeneralFastElementsKind(ElementsKind elements_kind,
                                                bool allow_only_packed) {
  ASSERT(IsFastElementsKind(elements_kind));
  ASSERT(elements_kind != TERMINAL_FAST_ELEMENTS_KIND);
  while (true) {
    int index =
        GetSequenceIndexFromFastElementsKind(elements_kind) + 1;
    elements_kind = GetFastElementsKindFromSequenceIndex(index);
    if (!IsFastHoleyElementsKind(elements_kind) || !allow_only_packed) {
      return elements_kind;
    }
  }
  UNREACHABLE();
  return TERMINAL_FAST_ELEMENTS_KIND;
}


bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
                                         ElementsKind to_kind) {
  switch (from_kind) {
    case FAST_SMI_ELEMENTS:
      return to_kind != FAST_SMI_ELEMENTS;
    case FAST_HOLEY_SMI_ELEMENTS:
      return to_kind != FAST_SMI_ELEMENTS &&
          to_kind != FAST_HOLEY_SMI_ELEMENTS;
    case FAST_DOUBLE_ELEMENTS:
      return to_kind != FAST_SMI_ELEMENTS &&
          to_kind != FAST_HOLEY_SMI_ELEMENTS &&
          to_kind != FAST_DOUBLE_ELEMENTS;
    case FAST_HOLEY_DOUBLE_ELEMENTS:
      return to_kind == FAST_ELEMENTS ||
          to_kind == FAST_HOLEY_ELEMENTS;
    case FAST_ELEMENTS:
      return to_kind == FAST_HOLEY_ELEMENTS;
    case FAST_HOLEY_ELEMENTS:
      return false;
    default:
      return false;
  }
}


} }  // namespace v8::internal
