// Copyright 2017 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/torque/types.h"

#include <cmath>
#include <iostream>

#include "src/base/bits.h"
#include "src/base/optional.h"
#include "src/torque/ast.h"
#include "src/torque/declarable.h"
#include "src/torque/global-context.h"
#include "src/torque/source-positions.h"
#include "src/torque/type-oracle.h"
#include "src/torque/type-visitor.h"

namespace v8 {
namespace internal {
namespace torque {

// This custom copy constructor doesn't copy aliases_ and id_ because they
// should be distinct for each type.
Type::Type(const Type& other) V8_NOEXCEPT
    : TypeBase(other),
      parent_(other.parent_),
      aliases_(),
      id_(TypeOracle::FreshTypeId()),
      constexpr_version_(other.constexpr_version_) {}
Type::Type(TypeBase::Kind kind, const Type* parent,
           MaybeSpecializationKey specialized_from)
    : TypeBase(kind),
      parent_(parent),
      id_(TypeOracle::FreshTypeId()),
      specialized_from_(specialized_from),
      constexpr_version_(nullptr) {}

std::string Type::ToString() const {
  if (aliases_.size() == 0)
    return ComputeName(ToExplicitString(), GetSpecializedFrom());
  if (aliases_.size() == 1) return *aliases_.begin();
  std::stringstream result;
  int i = 0;
  for (const std::string& alias : aliases_) {
    if (i == 0) {
      result << alias << " (aka. ";
    } else if (i == 1) {
      result << alias;
    } else {
      result << ", " << alias;
    }
    ++i;
  }
  result << ")";
  return result.str();
}

std::string Type::SimpleName() const {
  if (aliases_.empty()) {
    std::stringstream result;
    result << SimpleNameImpl();
    if (GetSpecializedFrom()) {
      for (const Type* t : GetSpecializedFrom()->specialized_types) {
        result << "_" << t->SimpleName();
      }
    }
    return result.str();
  }
  return *aliases_.begin();
}

// TODO(danno): HandlifiedCppTypeName should be used universally in Torque
// where the C++ type of a Torque object is required.
std::string Type::HandlifiedCppTypeName() const {
  if (IsSubtypeOf(TypeOracle::GetSmiType())) return "int";
  if (IsSubtypeOf(TypeOracle::GetTaggedType())) {
    return "Handle<" + UnhandlifiedCppTypeName() + ">";
  } else {
    return UnhandlifiedCppTypeName();
  }
}

std::string Type::UnhandlifiedCppTypeName() const {
  if (IsSubtypeOf(TypeOracle::GetSmiType())) return "int";
  if (this == TypeOracle::GetObjectType()) return "Object";
  return GetConstexprGeneratedTypeName();
}

bool Type::IsSubtypeOf(const Type* supertype) const {
  if (supertype->IsTopType()) return true;
  if (IsNever()) return true;
  if (const UnionType* union_type = UnionType::DynamicCast(supertype)) {
    return union_type->IsSupertypeOf(this);
  }
  const Type* subtype = this;
  while (subtype != nullptr) {
    if (subtype == supertype) return true;
    subtype = subtype->parent();
  }
  return false;
}

std::string Type::GetConstexprGeneratedTypeName() const {
  const Type* constexpr_version = ConstexprVersion();
  if (constexpr_version == nullptr) {
    Error("Type '", ToString(), "' requires a constexpr representation");
    return "";
  }
  return constexpr_version->GetGeneratedTypeName();
}

base::Optional<const ClassType*> Type::ClassSupertype() const {
  for (const Type* t = this; t != nullptr; t = t->parent()) {
    if (auto* class_type = ClassType::DynamicCast(t)) {
      return class_type;
    }
  }
  return base::nullopt;
}

base::Optional<const StructType*> Type::StructSupertype() const {
  for (const Type* t = this; t != nullptr; t = t->parent()) {
    if (auto* struct_type = StructType::DynamicCast(t)) {
      return struct_type;
    }
  }
  return base::nullopt;
}

// static
const Type* Type::CommonSupertype(const Type* a, const Type* b) {
  int diff = a->Depth() - b->Depth();
  const Type* a_supertype = a;
  const Type* b_supertype = b;
  for (; diff > 0; --diff) a_supertype = a_supertype->parent();
  for (; diff < 0; ++diff) b_supertype = b_supertype->parent();
  while (a_supertype && b_supertype) {
    if (a_supertype == b_supertype) return a_supertype;
    a_supertype = a_supertype->parent();
    b_supertype = b_supertype->parent();
  }
  ReportError("types " + a->ToString() + " and " + b->ToString() +
              " have no common supertype");
}

int Type::Depth() const {
  int result = 0;
  for (const Type* current = parent_; current; current = current->parent_) {
    ++result;
  }
  return result;
}

bool Type::IsAbstractName(const std::string& name) const {
  if (!IsAbstractType()) return false;
  return AbstractType::cast(this)->name() == name;
}

std::string Type::GetGeneratedTypeName() const {
  std::string result = GetGeneratedTypeNameImpl();
  if (result.empty() || result == "TNode<>") {
    ReportError("Generated type is required for type '", ToString(),
                "'. Use 'generates' clause in definition.");
  }
  return result;
}

std::string Type::GetGeneratedTNodeTypeName() const {
  std::string result = GetGeneratedTNodeTypeNameImpl();
  if (result.empty() || IsConstexpr()) {
    ReportError("Generated TNode type is required for type '", ToString(),
                "'. Use 'generates' clause in definition.");
  }
  return result;
}

std::string AbstractType::GetGeneratedTNodeTypeNameImpl() const {
  if (generated_type_.empty()) return parent()->GetGeneratedTNodeTypeName();
  return generated_type_;
}

std::vector<TypeChecker> AbstractType::GetTypeCheckers() const {
  if (UseParentTypeChecker()) return parent()->GetTypeCheckers();
  std::string type_name = name();
  if (auto strong_type =
          Type::MatchUnaryGeneric(this, TypeOracle::GetWeakGeneric())) {
    auto strong_runtime_types = (*strong_type)->GetTypeCheckers();
    std::vector<TypeChecker> result;
    for (const TypeChecker& type : strong_runtime_types) {
      // Generic parameter in Weak<T> should have already been checked to
      // extend HeapObject, so it couldn't itself be another weak type.
      DCHECK(type.weak_ref_to.empty());
      result.push_back({type_name, type.type});
    }
    return result;
  }
  return {{type_name, ""}};
}

std::string BuiltinPointerType::ToExplicitString() const {
  std::stringstream result;
  result << "builtin (";
  PrintCommaSeparatedList(result, parameter_types_);
  result << ") => " << *return_type_;
  return result.str();
}

std::string BuiltinPointerType::SimpleNameImpl() const {
  std::stringstream result;
  result << "BuiltinPointer";
  for (const Type* t : parameter_types_) {
    result << "_" << t->SimpleName();
  }
  result << "_" << return_type_->SimpleName();
  return result.str();
}

std::string UnionType::ToExplicitString() const {
  std::stringstream result;
  result << "(";
  bool first = true;
  for (const Type* t : types_) {
    if (!first) {
      result << " | ";
    }
    first = false;
    result << *t;
  }
  result << ")";
  return result.str();
}

std::string UnionType::SimpleNameImpl() const {
  std::stringstream result;
  bool first = true;
  for (const Type* t : types_) {
    if (!first) {
      result << "_OR_";
    }
    first = false;
    result << t->SimpleName();
  }
  return result.str();
}

std::string UnionType::GetGeneratedTNodeTypeNameImpl() const {
  if (types_.size() <= 3) {
    std::set<std::string> members;
    for (const Type* t : types_) {
      members.insert(t->GetGeneratedTNodeTypeName());
    }
    if (members == std::set<std::string>{"Smi", "HeapNumber"}) {
      return "Number";
    }
    if (members == std::set<std::string>{"Smi", "HeapNumber", "BigInt"}) {
      return "Numeric";
    }
  }
  return parent()->GetGeneratedTNodeTypeName();
}

void UnionType::RecomputeParent() {
  const Type* parent = nullptr;
  for (const Type* t : types_) {
    if (parent == nullptr) {
      parent = t;
    } else {
      parent = CommonSupertype(parent, t);
    }
  }
  set_parent(parent);
}

void UnionType::Subtract(const Type* t) {
  for (auto it = types_.begin(); it != types_.end();) {
    if ((*it)->IsSubtypeOf(t)) {
      it = types_.erase(it);
    } else {
      ++it;
    }
  }
  if (types_.size() == 0) types_.insert(TypeOracle::GetNeverType());
  RecomputeParent();
}

const Type* SubtractType(const Type* a, const Type* b) {
  UnionType result = UnionType::FromType(a);
  result.Subtract(b);
  return TypeOracle::GetUnionType(result);
}

std::string BitFieldStructType::ToExplicitString() const {
  return "bitfield struct " + name();
}

const BitField& BitFieldStructType::LookupField(const std::string& name) const {
  for (const BitField& field : fields_) {
    if (field.name_and_type.name == name) {
      return field;
    }
  }
  ReportError("Couldn't find bitfield ", name);
}

void AggregateType::CheckForDuplicateFields() const {
  // Check the aggregate hierarchy and currently defined class for duplicate
  // field declarations.
  auto hierarchy = GetHierarchy();
  std::map<std::string, const AggregateType*> field_names;
  for (const AggregateType* aggregate_type : hierarchy) {
    for (const Field& field : aggregate_type->fields()) {
      const std::string& field_name = field.name_and_type.name;
      auto i = field_names.find(field_name);
      if (i != field_names.end()) {
        CurrentSourcePosition::Scope current_source_position(field.pos);
        std::string aggregate_type_name =
            aggregate_type->IsClassType() ? "class" : "struct";
        if (i->second == this) {
          ReportError(aggregate_type_name, " '", name(),
                      "' declares a field with the name '", field_name,
                      "' more than once");
        } else {
          ReportError(aggregate_type_name, " '", name(),
                      "' declares a field with the name '", field_name,
                      "' that masks an inherited field from class '",
                      i->second->name(), "'");
        }
      }
      field_names[field_name] = aggregate_type;
    }
  }
}

std::vector<const AggregateType*> AggregateType::GetHierarchy() const {
  if (!is_finalized_) Finalize();
  std::vector<const AggregateType*> hierarchy;
  const AggregateType* current_container_type = this;
  while (current_container_type != nullptr) {
    hierarchy.push_back(current_container_type);
    current_container_type =
        current_container_type->IsClassType()
            ? ClassType::cast(current_container_type)->GetSuperClass()
            : nullptr;
  }
  std::reverse(hierarchy.begin(), hierarchy.end());
  return hierarchy;
}

bool AggregateType::HasField(const std::string& name) const {
  if (!is_finalized_) Finalize();
  for (auto& field : fields_) {
    if (field.name_and_type.name == name) return true;
  }
  if (parent() != nullptr) {
    if (auto parent_class = ClassType::DynamicCast(parent())) {
      return parent_class->HasField(name);
    }
  }
  return false;
}

const Field& AggregateType::LookupFieldInternal(const std::string& name) const {
  for (auto& field : fields_) {
    if (field.name_and_type.name == name) return field;
  }
  if (parent() != nullptr) {
    if (auto parent_class = ClassType::DynamicCast(parent())) {
      return parent_class->LookupField(name);
    }
  }
  ReportError("no field ", name, " found in ", this->ToString());
}

const Field& AggregateType::LookupField(const std::string& name) const {
  if (!is_finalized_) Finalize();
  return LookupFieldInternal(name);
}

StructType::StructType(Namespace* nspace, const StructDeclaration* decl,
                       MaybeSpecializationKey specialized_from)
    : AggregateType(Kind::kStructType, nullptr, nspace, decl->name->value,
                    specialized_from),
      decl_(decl) {
  if (decl->flags & StructFlag::kExport) {
    generated_type_name_ = "TorqueStruct" + name();
  } else {
    generated_type_name_ =
        GlobalContext::MakeUniqueName("TorqueStruct" + SimpleName());
  }
}

std::string StructType::GetGeneratedTypeNameImpl() const {
  return generated_type_name_;
}

size_t StructType::PackedSize() const {
  size_t result = 0;
  for (const Field& field : fields()) {
    result += std::get<0>(field.GetFieldSizeInformation());
  }
  return result;
}

StructType::Classification StructType::ClassifyContents() const {
  Classification result = ClassificationFlag::kEmpty;
  for (const Field& struct_field : fields()) {
    const Type* field_type = struct_field.name_and_type.type;
    if (field_type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
      result |= ClassificationFlag::kTagged;
    } else if (auto field_as_struct = field_type->StructSupertype()) {
      result |= (*field_as_struct)->ClassifyContents();
    } else {
      result |= ClassificationFlag::kUntagged;
    }
  }
  return result;
}

// static
std::string Type::ComputeName(const std::string& basename,
                              MaybeSpecializationKey specialized_from) {
  if (!specialized_from) return basename;
  if (specialized_from->generic == TypeOracle::GetConstReferenceGeneric()) {
    return torque::ToString("const &", *specialized_from->specialized_types[0]);
  }
  if (specialized_from->generic == TypeOracle::GetMutableReferenceGeneric()) {
    return torque::ToString("&", *specialized_from->specialized_types[0]);
  }
  std::stringstream s;
  s << basename << "<";
  bool first = true;
  for (auto t : specialized_from->specialized_types) {
    if (!first) {
      s << ", ";
    }
    s << t->ToString();
    first = false;
  }
  s << ">";
  return s.str();
}

std::string StructType::SimpleNameImpl() const { return decl_->name->value; }

// static
base::Optional<const Type*> Type::MatchUnaryGeneric(const Type* type,
                                                    GenericType* generic) {
  DCHECK_EQ(generic->generic_parameters().size(), 1);
  if (!type->GetSpecializedFrom()) {
    return base::nullopt;
  }
  auto& key = type->GetSpecializedFrom().value();
  if (key.generic != generic || key.specialized_types.size() != 1) {
    return base::nullopt;
  }
  return {key.specialized_types[0]};
}

std::vector<Method*> AggregateType::Methods(const std::string& name) const {
  if (!is_finalized_) Finalize();
  std::vector<Method*> result;
  std::copy_if(methods_.begin(), methods_.end(), std::back_inserter(result),
               [name](Macro* macro) { return macro->ReadableName() == name; });
  return result;
}

std::string StructType::ToExplicitString() const { return "struct " + name(); }

void StructType::Finalize() const {
  if (is_finalized_) return;
  {
    CurrentScope::Scope scope_activator(nspace());
    CurrentSourcePosition::Scope position_activator(decl_->pos);
    TypeVisitor::VisitStructMethods(const_cast<StructType*>(this), decl_);
  }
  is_finalized_ = true;
  CheckForDuplicateFields();
}

ClassType::ClassType(const Type* parent, Namespace* nspace,
                     const std::string& name, ClassFlags flags,
                     const std::string& generates, const ClassDeclaration* decl,
                     const TypeAlias* alias)
    : AggregateType(Kind::kClassType, parent, nspace, name),
      size_(ResidueClass::Unknown()),
      flags_(flags),
      generates_(generates),
      decl_(decl),
      alias_(alias) {}

std::string ClassType::GetGeneratedTNodeTypeNameImpl() const {
  return generates_;
}

std::string ClassType::GetGeneratedTypeNameImpl() const {
  return IsConstexpr() ? GetGeneratedTNodeTypeName()
                       : "TNode<" + GetGeneratedTNodeTypeName() + ">";
}

std::string ClassType::ToExplicitString() const { return "class " + name(); }

bool ClassType::AllowInstantiation() const {
  return (!IsExtern() || nspace()->IsDefaultNamespace()) && !IsAbstract();
}

void ClassType::Finalize() const {
  if (is_finalized_) return;
  CurrentScope::Scope scope_activator(alias_->ParentScope());
  CurrentSourcePosition::Scope position_activator(decl_->pos);
  TypeVisitor::VisitClassFieldsAndMethods(const_cast<ClassType*>(this),
                                          this->decl_);
  is_finalized_ = true;
  if (GenerateCppClassDefinitions() || !IsExtern()) {
    for (const Field& f : fields()) {
      if (f.is_weak) {
        Error("Generation of C++ class for Torque class ", name(),
              " is not supported yet, because field ", f.name_and_type.name,
              ": ", *f.name_and_type.type, " is a weak field.")
            .Position(f.pos);
      }
    }
  }
  CheckForDuplicateFields();
}

std::vector<Field> ClassType::ComputeAllFields() const {
  std::vector<Field> all_fields;
  const ClassType* super_class = this->GetSuperClass();
  if (super_class) {
    all_fields = super_class->ComputeAllFields();
  }
  const std::vector<Field>& fields = this->fields();
  all_fields.insert(all_fields.end(), fields.begin(), fields.end());
  return all_fields;
}

std::vector<Field> ClassType::ComputeHeaderFields() const {
  std::vector<Field> result;
  for (Field& field : ComputeAllFields()) {
    if (field.index) break;
    DCHECK(*field.offset < header_size());
    result.push_back(std::move(field));
  }
  return result;
}

std::vector<Field> ClassType::ComputeArrayFields() const {
  std::vector<Field> result;
  for (Field& field : ComputeAllFields()) {
    if (!field.index) {
      DCHECK(*field.offset < header_size());
      continue;
    }
    result.push_back(std::move(field));
  }
  return result;
}

void ClassType::InitializeInstanceTypes(
    base::Optional<int> own, base::Optional<std::pair<int, int>> range) const {
  DCHECK(!own_instance_type_.has_value());
  DCHECK(!instance_type_range_.has_value());
  own_instance_type_ = own;
  instance_type_range_ = range;
}

base::Optional<int> ClassType::OwnInstanceType() const {
  DCHECK(GlobalContext::IsInstanceTypesInitialized());
  return own_instance_type_;
}

base::Optional<std::pair<int, int>> ClassType::InstanceTypeRange() const {
  DCHECK(GlobalContext::IsInstanceTypesInitialized());
  return instance_type_range_;
}

namespace {
void ComputeSlotKindsHelper(std::vector<ObjectSlotKind>* slots,
                            size_t start_offset,
                            const std::vector<Field>& fields) {
  size_t offset = start_offset;
  for (const Field& field : fields) {
    size_t field_size = std::get<0>(field.GetFieldSizeInformation());
    size_t slot_index = offset / TargetArchitecture::TaggedSize();
    // Rounding-up division to find the number of slots occupied by all the
    // fields up to and including the current one.
    size_t used_slots =
        (offset + field_size + TargetArchitecture::TaggedSize() - 1) /
        TargetArchitecture::TaggedSize();
    while (used_slots > slots->size()) {
      slots->push_back(ObjectSlotKind::kNoPointer);
    }
    const Type* type = field.name_and_type.type;
    if (auto struct_type = type->StructSupertype()) {
      ComputeSlotKindsHelper(slots, offset, (*struct_type)->fields());
    } else {
      ObjectSlotKind kind;
      if (type->IsSubtypeOf(TypeOracle::GetObjectType())) {
        if (field.is_weak) {
          kind = ObjectSlotKind::kCustomWeakPointer;
        } else {
          kind = ObjectSlotKind::kStrongPointer;
        }
      } else if (type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
        DCHECK(!field.is_weak);
        kind = ObjectSlotKind::kMaybeObjectPointer;
      } else {
        kind = ObjectSlotKind::kNoPointer;
      }
      DCHECK(slots->at(slot_index) == ObjectSlotKind::kNoPointer);
      slots->at(slot_index) = kind;
    }

    offset += field_size;
  }
}
}  // namespace

std::vector<ObjectSlotKind> ClassType::ComputeHeaderSlotKinds() const {
  std::vector<ObjectSlotKind> result;
  std::vector<Field> header_fields = ComputeHeaderFields();
  ComputeSlotKindsHelper(&result, 0, header_fields);
  DCHECK_EQ(std::ceil(static_cast<double>(header_size()) /
                      TargetArchitecture::TaggedSize()),
            result.size());
  return result;
}

base::Optional<ObjectSlotKind> ClassType::ComputeArraySlotKind() const {
  std::vector<ObjectSlotKind> kinds;
  ComputeSlotKindsHelper(&kinds, 0, ComputeArrayFields());
  if (kinds.empty()) return base::nullopt;
  std::sort(kinds.begin(), kinds.end());
  if (kinds.front() == kinds.back()) return {kinds.front()};
  if (kinds.front() == ObjectSlotKind::kStrongPointer &&
      kinds.back() == ObjectSlotKind::kMaybeObjectPointer) {
    return ObjectSlotKind::kMaybeObjectPointer;
  }
  Error("Array fields mix types with different GC visitation requirements.")
      .Throw();
}

bool ClassType::HasNoPointerSlots() const {
  for (ObjectSlotKind slot : ComputeHeaderSlotKinds()) {
    if (slot != ObjectSlotKind::kNoPointer) return false;
  }
  if (auto slot = ComputeArraySlotKind()) {
    if (*slot != ObjectSlotKind::kNoPointer) return false;
  }
  return true;
}

bool ClassType::HasIndexedFieldsIncludingInParents() const {
  for (const auto& field : fields_) {
    if (field.index.has_value()) return true;
  }
  if (const ClassType* parent = GetSuperClass()) {
    return parent->HasIndexedFieldsIncludingInParents();
  }
  return false;
}

const Field* ClassType::GetFieldPreceding(size_t field_index) const {
  if (field_index > 0) {
    return &fields_[field_index - 1];
  }
  if (const ClassType* parent = GetSuperClass()) {
    return parent->GetFieldPreceding(parent->fields_.size());
  }
  return nullptr;
}

const ClassType* ClassType::GetClassDeclaringField(const Field& f) const {
  for (const Field& field : fields_) {
    if (f.name_and_type.name == field.name_and_type.name) return this;
  }
  return GetSuperClass()->GetClassDeclaringField(f);
}

std::string ClassType::GetSliceMacroName(const Field& field) const {
  const ClassType* declarer = GetClassDeclaringField(field);
  return "FieldSlice" + declarer->name() +
         CamelifyString(field.name_and_type.name);
}

void ClassType::GenerateAccessors() {
  bool at_or_after_indexed_field = false;
  if (const ClassType* parent = GetSuperClass()) {
    at_or_after_indexed_field = parent->HasIndexedFieldsIncludingInParents();
  }
  // For each field, construct AST snippets that implement a CSA accessor
  // function. The implementation iterator will turn the snippets into code.
  for (size_t field_index = 0; field_index < fields_.size(); ++field_index) {
    Field& field = fields_[field_index];
    if (field.name_and_type.type == TypeOracle::GetVoidType()) {
      continue;
    }
    at_or_after_indexed_field =
        at_or_after_indexed_field || field.index.has_value();
    CurrentSourcePosition::Scope position_activator(field.pos);

    IdentifierExpression* parameter = MakeIdentifierExpression("o");
    IdentifierExpression* index = MakeIdentifierExpression("i");

    std::string camel_field_name = CamelifyString(field.name_and_type.name);

    if (at_or_after_indexed_field) {
      if (!field.index.has_value()) {
        // There's no fundamental reason we couldn't generate functions to get
        // references instead of slices, but it's not yet implemented.
        ReportError(
            "Torque doesn't yet support non-indexed fields after indexed "
            "fields");
      }

      GenerateSliceAccessor(field_index);
    }

    // For now, only generate indexed accessors for simple types
    if (field.index.has_value() && field.name_and_type.type->IsStructType()) {
      continue;
    }

    // Load accessor
    std::string load_macro_name = "Load" + this->name() + camel_field_name;
    Signature load_signature;
    load_signature.parameter_names.push_back(MakeNode<Identifier>("o"));
    load_signature.parameter_types.types.push_back(this);
    if (field.index) {
      load_signature.parameter_names.push_back(MakeNode<Identifier>("i"));
      load_signature.parameter_types.types.push_back(
          TypeOracle::GetIntPtrType());
    }
    load_signature.parameter_types.var_args = false;
    load_signature.return_type = field.name_and_type.type;

    Expression* load_expression =
        MakeFieldAccessExpression(parameter, field.name_and_type.name);
    if (field.index) {
      load_expression =
          MakeNode<ElementAccessExpression>(load_expression, index);
    }
    Statement* load_body = MakeNode<ReturnStatement>(load_expression);
    Declarations::DeclareMacro(load_macro_name, true, base::nullopt,
                               load_signature, load_body, base::nullopt);

    // Store accessor
    if (!field.const_qualified) {
      IdentifierExpression* value = MakeIdentifierExpression("v");
      std::string store_macro_name = "Store" + this->name() + camel_field_name;
      Signature store_signature;
      store_signature.parameter_names.push_back(MakeNode<Identifier>("o"));
      store_signature.parameter_types.types.push_back(this);
      if (field.index) {
        store_signature.parameter_names.push_back(MakeNode<Identifier>("i"));
        store_signature.parameter_types.types.push_back(
            TypeOracle::GetIntPtrType());
      }
      store_signature.parameter_names.push_back(MakeNode<Identifier>("v"));
      store_signature.parameter_types.types.push_back(field.name_and_type.type);
      store_signature.parameter_types.var_args = false;
      // TODO(danno): Store macros probably should return their value argument
      store_signature.return_type = TypeOracle::GetVoidType();
      Expression* store_expression =
          MakeFieldAccessExpression(parameter, field.name_and_type.name);
      if (field.index) {
        store_expression =
            MakeNode<ElementAccessExpression>(store_expression, index);
      }
      Statement* store_body = MakeNode<ExpressionStatement>(
          MakeNode<AssignmentExpression>(store_expression, value));
      Declarations::DeclareMacro(store_macro_name, true, base::nullopt,
                                 store_signature, store_body, base::nullopt,
                                 false);
    }
  }
}

void ClassType::GenerateSliceAccessor(size_t field_index) {
  // Generate a Torque macro for getting a Slice to this field. This macro can
  // be called by the dot operator for this field. In Torque, this function for
  // class "ClassName" and field "field_name" and field type "FieldType" would
  // be written as one of the following:
  //
  // If the field has a known offset (in this example, 16):
  // FieldSliceClassNameFieldName(o: ClassName) {
  //   return torque_internal::Slice<FieldType> {
  //     object: o,
  //     offset: 16,
  //     length: torque_internal::%IndexedFieldLength<ClassName>(
  //                 o, "field_name")),
  //     unsafeMarker: torque_internal::Unsafe {}
  //   };
  // }
  //
  // If the field has an unknown offset, and the previous field is named p, and
  // an item in the previous field has size 4:
  // FieldSliceClassNameFieldName(o: ClassName) {
  //   const previous = &o.p;
  //   return torque_internal::Slice<FieldType> {
  //     object: o,
  //     offset: previous.offset + 4 * previous.length,
  //     length: torque_internal::%IndexedFieldLength<ClassName>(
  //                 o, "field_name")),
  //     unsafeMarker: torque_internal::Unsafe {}
  //   };
  // }
  const Field& field = fields_[field_index];
  std::string macro_name = GetSliceMacroName(field);
  Signature signature;
  Identifier* parameter_identifier = MakeNode<Identifier>("o");
  signature.parameter_names.push_back(parameter_identifier);
  signature.parameter_types.types.push_back(this);
  signature.parameter_types.var_args = false;
  signature.return_type = TypeOracle::GetSliceType(field.name_and_type.type);

  std::vector<Statement*> statements;
  Expression* offset_expression = nullptr;
  IdentifierExpression* parameter =
      MakeNode<IdentifierExpression>(parameter_identifier);

  if (field.offset.has_value()) {
    offset_expression =
        MakeNode<NumberLiteralExpression>(static_cast<double>(*field.offset));
  } else {
    const Field* previous = GetFieldPreceding(field_index);
    DCHECK_NOT_NULL(previous);

    // o.p
    Expression* previous_expression =
        MakeFieldAccessExpression(parameter, previous->name_and_type.name);

    // &o.p
    previous_expression = MakeCallExpression("&", {previous_expression});

    // const previous = &o.p;
    Statement* define_previous =
        MakeConstDeclarationStatement("previous", previous_expression);
    statements.push_back(define_previous);

    // 4
    size_t previous_element_size;
    std::tie(previous_element_size, std::ignore) =
        *SizeOf(previous->name_and_type.type);
    Expression* previous_element_size_expression =
        MakeNode<NumberLiteralExpression>(
            static_cast<double>(previous_element_size));

    // previous.length
    Expression* previous_length_expression = MakeFieldAccessExpression(
        MakeIdentifierExpression("previous"), "length");

    // previous.offset
    Expression* previous_offset_expression = MakeFieldAccessExpression(
        MakeIdentifierExpression("previous"), "offset");

    // 4 * previous.length
    // In contrast to the code used for allocation, we don't need overflow
    // checks here because we already know all the offsets fit into memory.
    offset_expression = MakeCallExpression(
        "*", {previous_element_size_expression, previous_length_expression});

    // previous.offset + 4 * previous.length
    offset_expression = MakeCallExpression(
        "+", {previous_offset_expression, offset_expression});
  }

  // torque_internal::%IndexedFieldLength<ClassName>(o, "field_name")
  Expression* length_expression = MakeCallExpression(
      MakeIdentifierExpression({"torque_internal"}, "%IndexedFieldLength",
                               {MakeNode<PrecomputedTypeExpression>(this)}),
      {parameter, MakeNode<StringLiteralExpression>(
                      StringLiteralQuote(field.name_and_type.name))});

  // torque_internal::Unsafe {}
  Expression* unsafe_expression = MakeStructExpression(
      MakeBasicTypeExpression({"torque_internal"}, "Unsafe"), {});

  // torque_internal::Slice<FieldType> {
  //   object: o,
  //   offset: <<offset_expression>>,
  //   length: torque_internal::%IndexedFieldLength<ClassName>(
  //               o, "field_name")),
  //   unsafeMarker: torque_internal::Unsafe {}
  // }
  Expression* slice_expression = MakeStructExpression(
      MakeBasicTypeExpression(
          {"torque_internal"}, "Slice",
          {MakeNode<PrecomputedTypeExpression>(field.name_and_type.type)}),
      {{MakeNode<Identifier>("object"), parameter},
       {MakeNode<Identifier>("offset"), offset_expression},
       {MakeNode<Identifier>("length"), length_expression},
       {MakeNode<Identifier>("unsafeMarker"), unsafe_expression}});

  statements.push_back(MakeNode<ReturnStatement>(slice_expression));
  Statement* block =
      MakeNode<BlockStatement>(/*deferred=*/false, std::move(statements));

  Macro* macro = Declarations::DeclareMacro(macro_name, true, base::nullopt,
                                            signature, block, base::nullopt);
  GlobalContext::EnsureInCCOutputList(TorqueMacro::cast(macro));
}

bool ClassType::HasStaticSize() const {
  // Abstract classes don't have instances directly, so asking this question
  // doesn't make sense.
  DCHECK(!IsAbstract());
  if (IsSubtypeOf(TypeOracle::GetJSObjectType()) && !IsShape()) return false;
  return size().SingleValue().has_value();
}

SourceId ClassType::AttributedToFile() const {
  bool in_test_directory = StringStartsWith(
      SourceFileMap::PathFromV8Root(GetPosition().source).substr(), "test/");
  if (!in_test_directory && (IsExtern() || ShouldExport())) {
    return GetPosition().source;
  }
  return SourceFileMap::GetSourceId("src/objects/torque-defined-classes.tq");
}

void PrintSignature(std::ostream& os, const Signature& sig, bool with_names) {
  os << "(";
  for (size_t i = 0; i < sig.parameter_types.types.size(); ++i) {
    if (i == 0 && sig.implicit_count != 0) os << "implicit ";
    if (sig.implicit_count > 0 && sig.implicit_count == i) {
      os << ")(";
    } else {
      if (i > 0) os << ", ";
    }
    if (with_names && !sig.parameter_names.empty()) {
      if (i < sig.parameter_names.size()) {
        os << sig.parameter_names[i] << ": ";
      }
    }
    os << *sig.parameter_types.types[i];
  }
  if (sig.parameter_types.var_args) {
    if (sig.parameter_names.size()) os << ", ";
    os << "...";
  }
  os << ")";
  os << ": " << *sig.return_type;

  if (sig.labels.empty()) return;

  os << " labels ";
  for (size_t i = 0; i < sig.labels.size(); ++i) {
    if (i > 0) os << ", ";
    os << sig.labels[i].name;
    if (sig.labels[i].types.size() > 0) os << "(" << sig.labels[i].types << ")";
  }
}

std::ostream& operator<<(std::ostream& os, const NameAndType& name_and_type) {
  os << name_and_type.name;
  os << ": ";
  os << *name_and_type.type;
  return os;
}

std::ostream& operator<<(std::ostream& os, const Field& field) {
  os << field.name_and_type;
  if (field.is_weak) {
    os << " (weak)";
  }
  return os;
}

std::ostream& operator<<(std::ostream& os, const Signature& sig) {
  PrintSignature(os, sig, true);
  return os;
}

std::ostream& operator<<(std::ostream& os, const TypeVector& types) {
  PrintCommaSeparatedList(os, types);
  return os;
}

std::ostream& operator<<(std::ostream& os, const ParameterTypes& p) {
  PrintCommaSeparatedList(os, p.types);
  if (p.var_args) {
    if (p.types.size() > 0) os << ", ";
    os << "...";
  }
  return os;
}

bool Signature::HasSameTypesAs(const Signature& other,
                               ParameterMode mode) const {
  auto compare_types = types();
  auto other_compare_types = other.types();
  if (mode == ParameterMode::kIgnoreImplicit) {
    compare_types = GetExplicitTypes();
    other_compare_types = other.GetExplicitTypes();
  }
  if (!(compare_types == other_compare_types &&
        parameter_types.var_args == other.parameter_types.var_args &&
        return_type == other.return_type)) {
    return false;
  }
  if (labels.size() != other.labels.size()) {
    return false;
  }
  size_t i = 0;
  for (const auto& l : labels) {
    if (l.types != other.labels[i++].types) {
      return false;
    }
  }
  return true;
}

namespace {
bool FirstTypeIsContext(const std::vector<const Type*> parameter_types) {
  return !parameter_types.empty() &&
         parameter_types[0] == TypeOracle::GetContextType();
}
}  // namespace

bool Signature::HasContextParameter() const {
  return FirstTypeIsContext(types());
}

bool BuiltinPointerType::HasContextParameter() const {
  return FirstTypeIsContext(parameter_types());
}

bool IsAssignableFrom(const Type* to, const Type* from) {
  if (to == from) return true;
  if (from->IsSubtypeOf(to)) return true;
  return TypeOracle::ImplicitlyConvertableFrom(to, from).has_value();
}

bool operator<(const Type& a, const Type& b) { return a.id() < b.id(); }

VisitResult ProjectStructField(VisitResult structure,
                               const std::string& fieldname) {
  BottomOffset begin = structure.stack_range().begin();

  // Check constructor this super classes for fields.
  const StructType* type = *structure.type()->StructSupertype();
  auto& fields = type->fields();
  for (auto& field : fields) {
    BottomOffset end = begin + LoweredSlotCount(field.name_and_type.type);
    if (field.name_and_type.name == fieldname) {
      return VisitResult(field.name_and_type.type, StackRange{begin, end});
    }
    begin = end;
  }

  ReportError("struct '", type->name(), "' doesn't contain a field '",
              fieldname, "'");
}

namespace {
void AppendLoweredTypes(const Type* type, std::vector<const Type*>* result) {
  DCHECK_NE(type, TypeOracle::GetNeverType());
  if (type->IsConstexpr()) return;
  if (type == TypeOracle::GetVoidType()) return;
  if (base::Optional<const StructType*> s = type->StructSupertype()) {
    for (const Field& field : (*s)->fields()) {
      AppendLoweredTypes(field.name_and_type.type, result);
    }
  } else {
    result->push_back(type);
  }
}
}  // namespace

TypeVector LowerType(const Type* type) {
  TypeVector result;
  AppendLoweredTypes(type, &result);
  return result;
}

size_t LoweredSlotCount(const Type* type) { return LowerType(type).size(); }

TypeVector LowerParameterTypes(const TypeVector& parameters) {
  std::vector<const Type*> result;
  for (const Type* t : parameters) {
    AppendLoweredTypes(t, &result);
  }
  return result;
}

TypeVector LowerParameterTypes(const ParameterTypes& parameter_types,
                               size_t arg_count) {
  std::vector<const Type*> result = LowerParameterTypes(parameter_types.types);
  for (size_t i = parameter_types.types.size(); i < arg_count; ++i) {
    DCHECK(parameter_types.var_args);
    AppendLoweredTypes(TypeOracle::GetObjectType(), &result);
  }
  return result;
}

VisitResult VisitResult::NeverResult() {
  VisitResult result;
  result.type_ = TypeOracle::GetNeverType();
  return result;
}

VisitResult VisitResult::TopTypeResult(std::string top_reason,
                                       const Type* from_type) {
  VisitResult result;
  result.type_ = TypeOracle::GetTopType(std::move(top_reason), from_type);
  return result;
}

std::tuple<size_t, std::string> Field::GetFieldSizeInformation() const {
  auto optional = SizeOf(this->name_and_type.type);
  if (optional.has_value()) {
    return *optional;
  }
  Error("fields of type ", *name_and_type.type, " are not (yet) supported")
      .Position(pos);
  return std::make_tuple(0, "#no size");
}

size_t Type::AlignmentLog2() const {
  if (parent()) return parent()->AlignmentLog2();
  return TargetArchitecture::TaggedSize();
}

size_t AbstractType::AlignmentLog2() const {
  size_t alignment;
  if (this == TypeOracle::GetTaggedType()) {
    alignment = TargetArchitecture::TaggedSize();
  } else if (this == TypeOracle::GetRawPtrType()) {
    alignment = TargetArchitecture::RawPtrSize();
  } else if (this == TypeOracle::GetExternalPointerType()) {
    alignment = TargetArchitecture::ExternalPointerSize();
  } else if (this == TypeOracle::GetVoidType()) {
    alignment = 1;
  } else if (this == TypeOracle::GetInt8Type()) {
    alignment = kUInt8Size;
  } else if (this == TypeOracle::GetUint8Type()) {
    alignment = kUInt8Size;
  } else if (this == TypeOracle::GetInt16Type()) {
    alignment = kUInt16Size;
  } else if (this == TypeOracle::GetUint16Type()) {
    alignment = kUInt16Size;
  } else if (this == TypeOracle::GetInt32Type()) {
    alignment = kInt32Size;
  } else if (this == TypeOracle::GetUint32Type()) {
    alignment = kInt32Size;
  } else if (this == TypeOracle::GetFloat64Type()) {
    alignment = kDoubleSize;
  } else if (this == TypeOracle::GetIntPtrType()) {
    alignment = TargetArchitecture::RawPtrSize();
  } else if (this == TypeOracle::GetUIntPtrType()) {
    alignment = TargetArchitecture::RawPtrSize();
  } else {
    return Type::AlignmentLog2();
  }
  alignment = std::min(alignment, TargetArchitecture::TaggedSize());
  return base::bits::WhichPowerOfTwo(alignment);
}

size_t StructType::AlignmentLog2() const {
  if (this == TypeOracle::GetFloat64OrHoleType()) {
    return TypeOracle::GetFloat64Type()->AlignmentLog2();
  }
  size_t alignment_log_2 = 0;
  for (const Field& field : fields()) {
    alignment_log_2 =
        std::max(alignment_log_2, field.name_and_type.type->AlignmentLog2());
  }
  return alignment_log_2;
}

void Field::ValidateAlignment(ResidueClass at_offset) const {
  const Type* type = name_and_type.type;
  base::Optional<const StructType*> struct_type = type->StructSupertype();
  if (struct_type && struct_type != TypeOracle::GetFloat64OrHoleType()) {
    for (const Field& field : (*struct_type)->fields()) {
      field.ValidateAlignment(at_offset);
      size_t field_size = std::get<0>(field.GetFieldSizeInformation());
      at_offset += field_size;
    }
  } else {
    size_t alignment_log_2 = name_and_type.type->AlignmentLog2();
    if (at_offset.AlignmentLog2() < alignment_log_2) {
      Error("field ", name_and_type.name, " at offset ", at_offset, " is not ",
            size_t{1} << alignment_log_2, "-byte aligned.")
          .Position(pos);
    }
  }
}

base::Optional<std::tuple<size_t, std::string>> SizeOf(const Type* type) {
  std::string size_string;
  size_t size;
  if (type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
    size = TargetArchitecture::TaggedSize();
    size_string = "kTaggedSize";
  } else if (type->IsSubtypeOf(TypeOracle::GetRawPtrType())) {
    size = TargetArchitecture::RawPtrSize();
    size_string = "kSystemPointerSize";
  } else if (type->IsSubtypeOf(TypeOracle::GetExternalPointerType())) {
    size = TargetArchitecture::ExternalPointerSize();
    size_string = "kExternalPointerSize";
  } else if (type->IsSubtypeOf(TypeOracle::GetVoidType())) {
    size = 0;
    size_string = "0";
  } else if (type->IsSubtypeOf(TypeOracle::GetInt8Type())) {
    size = kUInt8Size;
    size_string = "kUInt8Size";
  } else if (type->IsSubtypeOf(TypeOracle::GetUint8Type())) {
    size = kUInt8Size;
    size_string = "kUInt8Size";
  } else if (type->IsSubtypeOf(TypeOracle::GetInt16Type())) {
    size = kUInt16Size;
    size_string = "kUInt16Size";
  } else if (type->IsSubtypeOf(TypeOracle::GetUint16Type())) {
    size = kUInt16Size;
    size_string = "kUInt16Size";
  } else if (type->IsSubtypeOf(TypeOracle::GetInt32Type())) {
    size = kInt32Size;
    size_string = "kInt32Size";
  } else if (type->IsSubtypeOf(TypeOracle::GetUint32Type())) {
    size = kInt32Size;
    size_string = "kInt32Size";
  } else if (type->IsSubtypeOf(TypeOracle::GetFloat64Type())) {
    size = kDoubleSize;
    size_string = "kDoubleSize";
  } else if (type->IsSubtypeOf(TypeOracle::GetIntPtrType())) {
    size = TargetArchitecture::RawPtrSize();
    size_string = "kIntptrSize";
  } else if (type->IsSubtypeOf(TypeOracle::GetUIntPtrType())) {
    size = TargetArchitecture::RawPtrSize();
    size_string = "kIntptrSize";
  } else if (auto struct_type = type->StructSupertype()) {
    if (type == TypeOracle::GetFloat64OrHoleType()) {
      size = kDoubleSize;
      size_string = "kDoubleSize";
    } else {
      size = (*struct_type)->PackedSize();
      size_string = std::to_string(size);
    }
  } else {
    return {};
  }
  return std::make_tuple(size, size_string);
}

bool IsAnyUnsignedInteger(const Type* type) {
  return type == TypeOracle::GetUint32Type() ||
         type == TypeOracle::GetUint31Type() ||
         type == TypeOracle::GetUint16Type() ||
         type == TypeOracle::GetUint8Type() ||
         type == TypeOracle::GetUIntPtrType();
}

bool IsAllowedAsBitField(const Type* type) {
  if (type->IsBitFieldStructType()) {
    // No nested bitfield structs for now. We could reconsider if there's a
    // compelling use case.
    return false;
  }
  // Any integer-ish type, including bools and enums which inherit from integer
  // types, are allowed. Note, however, that we always zero-extend during
  // decoding regardless of signedness.
  return IsPointerSizeIntegralType(type) || Is32BitIntegralType(type);
}

bool IsPointerSizeIntegralType(const Type* type) {
  return type->IsSubtypeOf(TypeOracle::GetUIntPtrType()) ||
         type->IsSubtypeOf(TypeOracle::GetIntPtrType());
}

bool Is32BitIntegralType(const Type* type) {
  return type->IsSubtypeOf(TypeOracle::GetUint32Type()) ||
         type->IsSubtypeOf(TypeOracle::GetInt32Type()) ||
         type->IsSubtypeOf(TypeOracle::GetBoolType());
}

base::Optional<NameAndType> ExtractSimpleFieldArraySize(
    const ClassType& class_type, Expression* array_size) {
  IdentifierExpression* identifier =
      IdentifierExpression::DynamicCast(array_size);
  if (!identifier || !identifier->generic_arguments.empty() ||
      !identifier->namespace_qualification.empty())
    return {};
  if (!class_type.HasField(identifier->name->value)) return {};
  return class_type.LookupField(identifier->name->value).name_and_type;
}

std::string Type::GetRuntimeType() const {
  if (IsSubtypeOf(TypeOracle::GetSmiType())) return "Smi";
  if (IsSubtypeOf(TypeOracle::GetTaggedType())) {
    return GetGeneratedTNodeTypeName();
  }
  if (base::Optional<const StructType*> struct_type = StructSupertype()) {
    std::stringstream result;
    result << "std::tuple<";
    bool first = true;
    for (const Type* field_type : LowerType(*struct_type)) {
      if (!first) result << ", ";
      first = false;
      result << field_type->GetRuntimeType();
    }
    result << ">";
    return result.str();
  }
  return ConstexprVersion()->GetGeneratedTypeName();
}

}  // namespace torque
}  // namespace internal
}  // namespace v8
