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

#ifndef V8_OBJECTS_LOOKUP_INL_H_
#define V8_OBJECTS_LOOKUP_INL_H_

#include "src/objects/lookup.h"

#include "src/handles/handles-inl.h"
#include "src/heap/factory-inl.h"
#include "src/objects/api-callbacks.h"
#include "src/objects/internal-index.h"
#include "src/objects/map-inl.h"
#include "src/objects/name-inl.h"
#include "src/objects/objects-inl.h"

namespace v8 {
namespace internal {

LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
                               Handle<Name> name, Configuration configuration)
    : LookupIterator(isolate, receiver, name, kInvalidIndex, receiver,
                     configuration) {}

LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
                               Handle<Name> name,
                               Handle<Object> lookup_start_object,
                               Configuration configuration)
    : LookupIterator(isolate, receiver, name, kInvalidIndex,
                     lookup_start_object, configuration) {}

LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
                               size_t index, Configuration configuration)
    : LookupIterator(isolate, receiver, Handle<Name>(), index, receiver,
                     configuration) {
  DCHECK_NE(index, kInvalidIndex);
}

LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
                               size_t index, Handle<Object> lookup_start_object,
                               Configuration configuration)
    : LookupIterator(isolate, receiver, Handle<Name>(), index,
                     lookup_start_object, configuration) {
  DCHECK_NE(index, kInvalidIndex);
}

LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
                               const Key& key, Configuration configuration)
    : LookupIterator(isolate, receiver, key.name(), key.index(), receiver,
                     configuration) {}

LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
                               const Key& key,
                               Handle<Object> lookup_start_object,
                               Configuration configuration)
    : LookupIterator(isolate, receiver, key.name(), key.index(),
                     lookup_start_object, configuration) {}

// This private constructor is the central bottleneck that all the other
// constructors use.
LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
                               Handle<Name> name, size_t index,
                               Handle<Object> lookup_start_object,
                               Configuration configuration)
    : configuration_(ComputeConfiguration(isolate, configuration, name)),
      isolate_(isolate),
      name_(name),
      receiver_(receiver),
      lookup_start_object_(lookup_start_object),
      index_(index) {
  if (IsElement()) {
    // If we're not looking at a TypedArray, we will need the key represented
    // as an internalized string.
    if (index_ > JSArray::kMaxArrayIndex &&
        !lookup_start_object->IsJSTypedArray()) {
      if (name_.is_null()) {
        name_ = isolate->factory()->SizeToString(index_);
      }
      name_ = isolate->factory()->InternalizeName(name_);
    } else if (!name_.is_null() && !name_->IsInternalizedString()) {
      // Maintain the invariant that if name_ is present, it is internalized.
      name_ = Handle<Name>();
    }
    Start<true>();
  } else {
    name_ = isolate->factory()->InternalizeName(name_);
#ifdef DEBUG
    // Assert that the name is not an index.
    // If we're not looking at the prototype chain and the lookup start object
    // is not a typed array, then this means "array index", otherwise we need to
    // ensure the full generality so that typed arrays are handled correctly.
    if (!check_prototype_chain() && !lookup_start_object->IsJSTypedArray()) {
      uint32_t index;
      DCHECK(!name_->AsArrayIndex(&index));
    } else {
      size_t index;
      DCHECK(!name_->AsIntegerIndex(&index));
    }
#endif  // DEBUG
    Start<false>();
  }
}

LookupIterator::Key::Key(Isolate* isolate, double index) {
  DCHECK_EQ(index, static_cast<uint64_t>(index));
#if V8_TARGET_ARCH_32_BIT
  if (index <= JSArray::kMaxArrayIndex) {
    index_ = static_cast<size_t>(index);
  } else {
    index_ = LookupIterator::kInvalidIndex;
    name_ = isolate->factory()->InternalizeString(
        isolate->factory()->HeapNumberToString(
            isolate->factory()->NewHeapNumber(index), index));
  }
#else
  index_ = static_cast<size_t>(index);
#endif
}

LookupIterator::Key::Key(Isolate* isolate, Handle<Name> name) {
  if (name->AsIntegerIndex(&index_)) {
    name_ = name;
  } else {
    index_ = LookupIterator::kInvalidIndex;
    name_ = isolate->factory()->InternalizeName(name);
  }
}

LookupIterator::Key::Key(Isolate* isolate, Handle<Object> valid_key) {
  DCHECK(valid_key->IsName() || valid_key->IsNumber());
  if (valid_key->ToIntegerIndex(&index_)) return;
  if (valid_key->IsNumber()) {
    // Negative or out of range -> treat as named property.
    valid_key = isolate->factory()->NumberToString(valid_key);
  }
  DCHECK(valid_key->IsName());
  name_ = Handle<Name>::cast(valid_key);
  if (!name_->AsIntegerIndex(&index_)) {
    index_ = LookupIterator::kInvalidIndex;
    name_ = isolate->factory()->InternalizeName(name_);
  }
}

Handle<Name> LookupIterator::Key::GetName(Isolate* isolate) {
  if (name_.is_null()) {
    DCHECK(is_element());
    name_ = isolate->factory()->SizeToString(index_);
  }
  return name_;
}

Handle<Name> LookupIterator::name() const {
  DCHECK(!IsElement(*holder_));
  return name_;
}

Handle<Name> LookupIterator::GetName() {
  if (name_.is_null()) {
    DCHECK(IsElement());
    name_ = factory()->SizeToString(index_);
  }
  return name_;
}

bool LookupIterator::IsElement(JSReceiver object) const {
  return index_ <= JSArray::kMaxArrayIndex ||
         (index_ != kInvalidIndex && object.map().has_typed_array_elements());
}

bool LookupIterator::is_dictionary_holder() const {
  return !holder_->HasFastProperties(isolate_);
}

Handle<Map> LookupIterator::transition_map() const {
  DCHECK_EQ(TRANSITION, state_);
  return Handle<Map>::cast(transition_);
}

Handle<PropertyCell> LookupIterator::transition_cell() const {
  DCHECK_EQ(TRANSITION, state_);
  return Handle<PropertyCell>::cast(transition_);
}

template <class T>
Handle<T> LookupIterator::GetHolder() const {
  DCHECK(IsFound());
  return Handle<T>::cast(holder_);
}

bool LookupIterator::ExtendingNonExtensible(Handle<JSReceiver> receiver) {
  DCHECK(receiver.is_identical_to(GetStoreTarget<JSReceiver>()));
  return !receiver->map(isolate_).is_extensible() &&
         (IsElement() || !name_->IsPrivate(isolate_));
}

bool LookupIterator::IsCacheableTransition() {
  DCHECK_EQ(TRANSITION, state_);
  return transition_->IsPropertyCell(isolate_) ||
         (transition_map()->is_dictionary_map() &&
          !GetStoreTarget<JSReceiver>()->HasFastProperties(isolate_)) ||
         transition_map()->GetBackPointer(isolate_).IsMap(isolate_);
}

// static
void LookupIterator::UpdateProtector(Isolate* isolate, Handle<Object> receiver,
                                     Handle<Name> name) {
  // This list must be kept in sync with
  // CodeStubAssembler::CheckForAssociatedProtector!
  ReadOnlyRoots roots(isolate);
  if (*name == roots.is_concat_spreadable_symbol() ||
      *name == roots.constructor_string() || *name == roots.next_string() ||
      *name == roots.species_symbol() || *name == roots.iterator_symbol() ||
      *name == roots.resolve_string() || *name == roots.then_string()) {
    InternalUpdateProtector(isolate, receiver, name);
  }
}

void LookupIterator::UpdateProtector() {
  if (IsElement()) return;
  UpdateProtector(isolate_, receiver_, name_);
}

InternalIndex LookupIterator::descriptor_number() const {
  DCHECK(!IsElement(*holder_));
  DCHECK(has_property_);
  DCHECK(holder_->HasFastProperties(isolate_));
  return number_;
}

InternalIndex LookupIterator::dictionary_entry() const {
  DCHECK(!IsElement(*holder_));
  DCHECK(has_property_);
  DCHECK(!holder_->HasFastProperties(isolate_));
  return number_;
}

// static
LookupIterator::Configuration LookupIterator::ComputeConfiguration(
    Isolate* isolate, Configuration configuration, Handle<Name> name) {
  return (!name.is_null() && name->IsPrivate(isolate)) ? OWN_SKIP_INTERCEPTOR
                                                       : configuration;
}

// static
Handle<JSReceiver> LookupIterator::GetRoot(Isolate* isolate,
                                           Handle<Object> lookup_start_object,
                                           size_t index) {
  if (lookup_start_object->IsJSReceiver(isolate)) {
    return Handle<JSReceiver>::cast(lookup_start_object);
  }
  return GetRootForNonJSReceiver(isolate, lookup_start_object, index);
}

template <class T>
Handle<T> LookupIterator::GetStoreTarget() const {
  DCHECK(receiver_->IsJSReceiver(isolate_));
  if (receiver_->IsJSGlobalProxy(isolate_)) {
    HeapObject prototype =
        JSGlobalProxy::cast(*receiver_).map(isolate_).prototype(isolate_);
    if (prototype.IsJSGlobalObject(isolate_)) {
      return handle(JSGlobalObject::cast(prototype), isolate_);
    }
  }
  return Handle<T>::cast(receiver_);
}

template <bool is_element>
InterceptorInfo LookupIterator::GetInterceptor(JSObject holder) const {
  if (is_element && index_ <= JSArray::kMaxArrayIndex) {
    return holder.GetIndexedInterceptor(isolate_);
  } else {
    return holder.GetNamedInterceptor(isolate_);
  }
}

inline Handle<InterceptorInfo> LookupIterator::GetInterceptor() const {
  DCHECK_EQ(INTERCEPTOR, state_);
  JSObject holder = JSObject::cast(*holder_);
  InterceptorInfo result = IsElement(holder) ? GetInterceptor<true>(holder)
                                             : GetInterceptor<false>(holder);
  return handle(result, isolate_);
}

}  // namespace internal
}  // namespace v8

#endif  // V8_OBJECTS_LOOKUP_INL_H_
