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

#ifndef V8_OBJECTS_TEMPLATES_INL_H_
#define V8_OBJECTS_TEMPLATES_INL_H_

#include "src/objects/templates.h"

#include "src/heap/heap-inl.h"
#include "src/objects/oddball.h"
#include "src/objects/shared-function-info-inl.h"

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {

OBJECT_CONSTRUCTORS_IMPL(TemplateInfo, Struct)
OBJECT_CONSTRUCTORS_IMPL(FunctionTemplateInfo, TemplateInfo)
OBJECT_CONSTRUCTORS_IMPL(ObjectTemplateInfo, TemplateInfo)
OBJECT_CONSTRUCTORS_IMPL(FunctionTemplateRareData, Struct)

NEVER_READ_ONLY_SPACE_IMPL(TemplateInfo)

ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
ACCESSORS(TemplateInfo, serial_number, Object, kSerialNumberOffset)
SMI_ACCESSORS(TemplateInfo, number_of_properties, kNumberOfProperties)
ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
ACCESSORS(TemplateInfo, property_accessors, Object, kPropertyAccessorsOffset)

ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
ACCESSORS(FunctionTemplateInfo, shared_function_info, Object,
          kSharedFunctionInfoOffset)
ACCESSORS(FunctionTemplateInfo, rare_data, HeapObject,
          kFunctionTemplateRareDataOffset)
ACCESSORS(FunctionTemplateInfo, cached_property_name, Object,
          kCachedPropertyNameOffset)
SMI_ACCESSORS(FunctionTemplateInfo, length, kLengthOffset)
BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
               kHiddenPrototypeBit)
BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
               kNeedsAccessCheckBit)
BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
               kReadOnlyPrototypeBit)
BOOL_ACCESSORS(FunctionTemplateInfo, flag, remove_prototype,
               kRemovePrototypeBit)
BOOL_ACCESSORS(FunctionTemplateInfo, flag, do_not_cache, kDoNotCacheBit)
BOOL_ACCESSORS(FunctionTemplateInfo, flag, accept_any_receiver,
               kAcceptAnyReceiver)
SMI_ACCESSORS(FunctionTemplateInfo, flag, kFlagOffset)

// static
FunctionTemplateRareData FunctionTemplateInfo::EnsureFunctionTemplateRareData(
    Isolate* isolate, Handle<FunctionTemplateInfo> function_template_info) {
  HeapObject extra = function_template_info->rare_data();
  if (extra->IsUndefined(isolate)) {
    return AllocateFunctionTemplateRareData(isolate, function_template_info);
  } else {
    return FunctionTemplateRareData::cast(extra);
  }
}

#define RARE_ACCESSORS(Name, CamelName, Type)                                  \
  Type FunctionTemplateInfo::Get##CamelName() {                                \
    HeapObject extra = rare_data();                                            \
    HeapObject undefined = GetReadOnlyRoots().undefined_value();               \
    return extra == undefined ? undefined                                      \
                              : FunctionTemplateRareData::cast(extra)->Name(); \
  }                                                                            \
  inline void FunctionTemplateInfo::Set##CamelName(                            \
      Isolate* isolate, Handle<FunctionTemplateInfo> function_template_info,   \
      Handle<Type> Name) {                                                     \
    FunctionTemplateRareData rare_data =                                       \
        EnsureFunctionTemplateRareData(isolate, function_template_info);       \
    rare_data->set_##Name(*Name);                                              \
  }

RARE_ACCESSORS(prototype_template, PrototypeTemplate, Object)
RARE_ACCESSORS(prototype_provider_template, PrototypeProviderTemplate, Object)
RARE_ACCESSORS(parent_template, ParentTemplate, Object)
RARE_ACCESSORS(named_property_handler, NamedPropertyHandler, Object)
RARE_ACCESSORS(indexed_property_handler, IndexedPropertyHandler, Object)
RARE_ACCESSORS(instance_template, InstanceTemplate, Object)
RARE_ACCESSORS(instance_call_handler, InstanceCallHandler, Object)
RARE_ACCESSORS(access_check_info, AccessCheckInfo, Object)
#undef RARE_ACCESSORS

ACCESSORS(FunctionTemplateRareData, prototype_template, Object,
          kPrototypeTemplateOffset)
ACCESSORS(FunctionTemplateRareData, prototype_provider_template, Object,
          kPrototypeProviderTemplateOffset)
ACCESSORS(FunctionTemplateRareData, parent_template, Object,
          kParentTemplateOffset)
ACCESSORS(FunctionTemplateRareData, named_property_handler, Object,
          kNamedPropertyHandlerOffset)
ACCESSORS(FunctionTemplateRareData, indexed_property_handler, Object,
          kIndexedPropertyHandlerOffset)
ACCESSORS(FunctionTemplateRareData, instance_template, Object,
          kInstanceTemplateOffset)
ACCESSORS(FunctionTemplateRareData, instance_call_handler, Object,
          kInstanceCallHandlerOffset)
ACCESSORS(FunctionTemplateRareData, access_check_info, Object,
          kAccessCheckInfoOffset)

ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
ACCESSORS(ObjectTemplateInfo, data, Object, kDataOffset)

CAST_ACCESSOR(TemplateInfo)
CAST_ACCESSOR(FunctionTemplateInfo)
CAST_ACCESSOR(FunctionTemplateRareData)
CAST_ACCESSOR(ObjectTemplateInfo)

bool FunctionTemplateInfo::instantiated() {
  return shared_function_info()->IsSharedFunctionInfo();
}

bool FunctionTemplateInfo::BreakAtEntry() {
  Object maybe_shared = shared_function_info();
  if (maybe_shared->IsSharedFunctionInfo()) {
    SharedFunctionInfo shared = SharedFunctionInfo::cast(maybe_shared);
    return shared->BreakAtEntry();
  }
  return false;
}

FunctionTemplateInfo FunctionTemplateInfo::GetParent(Isolate* isolate) {
  Object parent = GetParentTemplate();
  return parent->IsUndefined(isolate) ? FunctionTemplateInfo()
                                      : FunctionTemplateInfo::cast(parent);
}

ObjectTemplateInfo ObjectTemplateInfo::GetParent(Isolate* isolate) {
  Object maybe_ctor = constructor();
  if (maybe_ctor->IsUndefined(isolate)) return ObjectTemplateInfo();
  FunctionTemplateInfo constructor = FunctionTemplateInfo::cast(maybe_ctor);
  while (true) {
    constructor = constructor->GetParent(isolate);
    if (constructor.is_null()) return ObjectTemplateInfo();
    Object maybe_obj = constructor->GetInstanceTemplate();
    if (!maybe_obj->IsUndefined(isolate)) {
      return ObjectTemplateInfo::cast(maybe_obj);
    }
  }
  return ObjectTemplateInfo();
}

int ObjectTemplateInfo::embedder_field_count() const {
  Object value = data();
  DCHECK(value->IsSmi());
  return EmbedderFieldCount::decode(Smi::ToInt(value));
}

void ObjectTemplateInfo::set_embedder_field_count(int count) {
  DCHECK_LE(count, JSObject::kMaxEmbedderFields);
  return set_data(
      Smi::FromInt(EmbedderFieldCount::update(Smi::ToInt(data()), count)));
}

bool ObjectTemplateInfo::immutable_proto() const {
  Object value = data();
  DCHECK(value->IsSmi());
  return IsImmutablePrototype::decode(Smi::ToInt(value));
}

void ObjectTemplateInfo::set_immutable_proto(bool immutable) {
  return set_data(Smi::FromInt(
      IsImmutablePrototype::update(Smi::ToInt(data()), immutable)));
}

bool FunctionTemplateInfo::IsTemplateFor(JSObject object) {
  return IsTemplateFor(object->map());
}

}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_TEMPLATES_INL_H_
