types.cc 22.3 KB
Newer Older
1 2 3 4 5 6
// 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 <iostream>

7
#include "src/torque/ast.h"
8
#include "src/torque/declarable.h"
9
#include "src/torque/global-context.h"
10
#include "src/torque/type-oracle.h"
11
#include "src/torque/type-visitor.h"
12 13 14 15 16 17
#include "src/torque/types.h"

namespace v8 {
namespace internal {
namespace torque {

18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
std::string Type::ToString() const {
  if (aliases_.size() == 0) return ToExplicitString();
  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();
}

37
bool Type::IsSubtypeOf(const Type* supertype) const {
38
  if (supertype->IsTopType()) return true;
39
  if (IsNever()) return true;
40 41 42
  if (const UnionType* union_type = UnionType::DynamicCast(supertype)) {
    return union_type->IsSupertypeOf(this);
  }
43 44 45 46 47 48 49 50
  const Type* subtype = this;
  while (subtype != nullptr) {
    if (subtype == supertype) return true;
    subtype = subtype->parent();
  }
  return false;
}

51 52 53 54 55 56 57
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;
}

58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
// 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;
}

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

87 88
std::string Type::GetGeneratedTypeName() const {
  std::string result = GetGeneratedTypeNameImpl();
89
  if (result.empty() || result == "TNode<>") {
90 91 92 93 94 95 96 97
    ReportError("Generated type is required for type '", ToString(),
                "'. Use 'generates' clause in definition.");
  }
  return result;
}

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

std::string AbstractType::GetGeneratedTNodeTypeNameImpl() const {
106
  return generated_type_;
107 108
}

109
std::string BuiltinPointerType::ToExplicitString() const {
110 111
  std::stringstream result;
  result << "builtin (";
112 113
  PrintCommaSeparatedList(result, parameter_types_);
  result << ") => " << *return_type_;
114 115 116
  return result.str();
}

117
std::string BuiltinPointerType::MangledName() const {
118 119 120 121 122 123 124 125 126 127 128
  std::stringstream result;
  result << "FT";
  for (const Type* t : parameter_types_) {
    std::string arg_type_string = t->MangledName();
    result << arg_type_string.size() << arg_type_string;
  }
  std::string return_type_string = return_type_->MangledName();
  result << return_type_string.size() << return_type_string;
  return result.str();
}

129 130 131 132 133 134 135 136 137
std::string UnionType::ToExplicitString() const {
  std::stringstream result;
  result << "(";
  bool first = true;
  for (const Type* t : types_) {
    if (!first) {
      result << " | ";
    }
    first = false;
138
    result << *t;
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
  }
  result << ")";
  return result.str();
}

std::string UnionType::MangledName() const {
  std::stringstream result;
  result << "UT";
  for (const Type* t : types_) {
    std::string arg_type_string = t->MangledName();
    result << arg_type_string.size() << arg_type_string;
  }
  return result.str();
}

154
std::string UnionType::GetGeneratedTNodeTypeNameImpl() const {
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
  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();
}

170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
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);
}

200
void AggregateType::CheckForDuplicateFields() const {
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
  // 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;
    }
  }
}

229 230
std::vector<const AggregateType*> AggregateType::GetHierarchy() const {
  if (!is_finalized_) Finalize();
231 232 233 234 235 236 237 238 239 240 241 242 243
  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;
}

244
bool AggregateType::HasField(const std::string& name) const {
245
  if (!is_finalized_) Finalize();
246 247 248 249 250 251 252 253 254 255 256
  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;
}

257
const Field& AggregateType::LookupFieldInternal(const std::string& name) const {
258 259 260 261 262 263 264 265
  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);
    }
  }
266
  ReportError("no field ", name, " found in ", this->ToString());
267 268
}

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

274
std::string StructType::GetGeneratedTypeNameImpl() const {
275 276 277 278
  return "TorqueStruct" + MangledName();
}

// static
279 280 281 282
std::string StructType::ComputeName(
    const std::string& basename,
    StructType::MaybeSpecializationKey specialized_from) {
  if (!specialized_from) return basename;
283 284 285
  std::stringstream s;
  s << basename << "<";
  bool first = true;
286
  for (auto t : specialized_from->specialized_types) {
287 288 289 290 291 292 293 294
    if (!first) {
      s << ", ";
    }
    s << t->ToString();
    first = false;
  }
  s << ">";
  return s.str();
295 296
}

297 298 299 300
std::string StructType::MangledName() const {
  std::stringstream result;
  // TODO(gsps): Add 'ST' as a prefix once we can control the generated type
  // name from Torque code
301
  result << decl_->name->value;
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
  if (specialized_from_) {
    for (const Type* t : specialized_from_->specialized_types) {
      std::string arg_type_string = t->MangledName();
      result << arg_type_string.size() << arg_type_string;
    }
  }
  return result.str();
}

// static
base::Optional<const Type*> StructType::MatchUnaryGeneric(
    const Type* type, GenericStructType* generic) {
  if (auto* struct_type = StructType::DynamicCast(type)) {
    return MatchUnaryGeneric(struct_type, generic);
  }
  return base::nullopt;
}

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

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

342 343
std::string StructType::ToExplicitString() const {
  std::stringstream result;
344
  result << "struct " << name();
345 346 347
  return result.str();
}

348 349 350 351 352 353 354 355 356 357 358
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();
}

359 360
constexpr ClassFlags ClassType::kInternalFlags;

361
ClassType::ClassType(const Type* parent, Namespace* nspace,
362
                     const std::string& name, ClassFlags flags,
363 364
                     const std::string& generates, const ClassDeclaration* decl,
                     const TypeAlias* alias)
365 366
    : AggregateType(Kind::kClassType, parent, nspace, name),
      size_(0),
367
      flags_(flags & ~(kInternalFlags)),
368 369
      generates_(generates),
      decl_(decl),
370 371 372
      alias_(alias) {
  DCHECK_EQ(flags & kInternalFlags, 0);
}
373 374

bool ClassType::HasIndexedField() const {
375
  if (!is_finalized_) Finalize();
376
  return flags_ & ClassFlag::kHasIndexedField;
377 378
}

379
std::string ClassType::GetGeneratedTNodeTypeNameImpl() const {
380
  return generates_;
381 382
}

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

388 389
std::string ClassType::ToExplicitString() const {
  std::stringstream result;
390
  result << "class " << name();
391
  return result.str();
392 393
}

394
bool ClassType::AllowInstantiation() const {
395 396
  return (!IsExtern() || nspace()->IsDefaultNamespace()) &&
         (!IsAbstract() || IsInstantiatedAbstractClass());
397 398
}

399 400 401 402 403 404
void ClassType::Finalize() const {
  if (is_finalized_) return;
  CurrentScope::Scope scope_activator(alias_->ParentScope());
  CurrentSourcePosition::Scope position_activator(decl_->pos);
  if (parent()) {
    if (const ClassType* super_class = ClassType::DynamicCast(parent())) {
405
      if (super_class->HasIndexedField()) flags_ |= ClassFlag::kHasIndexedField;
406
      if (!super_class->IsAbstract() && !HasSameInstanceTypeAsParent()) {
407
        Error(
408 409 410
            "Super class must either be abstract (annotate super class with "
            "@abstract) "
            "or this class must have the same instance type as the super class "
411 412
            "(annotate this class with @hasSameInstanceTypeAsParent).")
            .Position(this->decl_->name->pos);
413
      }
414 415 416 417 418
    }
  }
  TypeVisitor::VisitClassFieldsAndMethods(const_cast<ClassType*>(this),
                                          this->decl_);
  is_finalized_ = true;
419
  if (GenerateCppClassDefinitions() || !IsExtern()) {
420
    for (const Field& f : fields()) {
421 422 423 424
      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.")
425
            .Position(f.pos);
426 427 428
      }
    }
  }
429 430 431
  CheckForDuplicateFields();
}

432 433 434 435 436 437 438 439 440 441 442
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;
}

443 444 445 446 447
void ClassType::GenerateAccessors() {
  // For each field, construct AST snippets that implement a CSA accessor
  // function and define a corresponding '.field' operator. The
  // implementation iterator will turn the snippets into code.
  for (auto& field : fields_) {
448 449 450
    if (field.index || field.name_and_type.type == TypeOracle::GetVoidType()) {
      continue;
    }
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465
    CurrentSourcePosition::Scope position_activator(field.pos);
    IdentifierExpression* parameter =
        MakeNode<IdentifierExpression>(MakeNode<Identifier>(std::string{"o"}));

    // Load accessor
    std::string camel_field_name = CamelifyString(field.name_and_type.name);
    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);
    load_signature.parameter_types.var_args = false;
    load_signature.return_type = field.name_and_type.type;
    Statement* load_body =
        MakeNode<ReturnStatement>(MakeNode<FieldAccessExpression>(
            parameter, MakeNode<Identifier>(field.name_and_type.name)));
466
    Declarations::DeclareMacro(load_macro_name, true, base::nullopt,
467
                               load_signature, load_body, base::nullopt);
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485

    // Store accessor
    IdentifierExpression* value = MakeNode<IdentifierExpression>(
        std::vector<std::string>{}, MakeNode<Identifier>(std::string{"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_names.push_back(MakeNode<Identifier>("v"));
    store_signature.parameter_types.types.push_back(this);
    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();
    Statement* store_body =
        MakeNode<ExpressionStatement>(MakeNode<AssignmentExpression>(
            MakeNode<FieldAccessExpression>(
                parameter, MakeNode<Identifier>(field.name_and_type.name)),
            value));
486
    Declarations::DeclareMacro(store_macro_name, true, base::nullopt,
487 488
                               store_signature, store_body, base::nullopt,
                               false);
489 490 491
  }
}

492
void PrintSignature(std::ostream& os, const Signature& sig, bool with_names) {
493
  os << "(";
494
  for (size_t i = 0; i < sig.parameter_types.types.size(); ++i) {
495 496 497 498 499 500
    if (i == 0 && sig.implicit_count != 0) os << "implicit ";
    if (sig.implicit_count > 0 && sig.implicit_count == i) {
      os << ")(";
    } else {
      if (i > 0) os << ", ";
    }
501
    if (with_names && !sig.parameter_names.empty()) {
502 503 504
      if (i < sig.parameter_names.size()) {
        os << sig.parameter_names[i] << ": ";
      }
505 506
    }
    os << *sig.parameter_types.types[i];
507 508 509 510 511 512
  }
  if (sig.parameter_types.var_args) {
    if (sig.parameter_names.size()) os << ", ";
    os << "...";
  }
  os << ")";
513
  os << ": " << *sig.return_type;
514

515
  if (sig.labels.empty()) return;
516 517 518 519

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

525 526 527 528 529 530 531
std::ostream& operator<<(std::ostream& os, const NameAndType& name_and_type) {
  os << name_and_type.name;
  os << ": ";
  os << *name_and_type.type;
  return os;
}

532 533 534 535 536 537 538 539
std::ostream& operator<<(std::ostream& os, const Field& field) {
  os << field.name_and_type;
  if (field.is_weak) {
    os << " (weak)";
  }
  return os;
}

540 541
std::ostream& operator<<(std::ostream& os, const Signature& sig) {
  PrintSignature(os, sig, true);
542 543 544 545
  return os;
}

std::ostream& operator<<(std::ostream& os, const TypeVector& types) {
546
  PrintCommaSeparatedList(os, types);
547 548 549 550
  return os;
}

std::ostream& operator<<(std::ostream& os, const ParameterTypes& p) {
551
  PrintCommaSeparatedList(os, p.types);
552 553 554 555 556 557 558
  if (p.var_args) {
    if (p.types.size() > 0) os << ", ";
    os << "...";
  }
  return os;
}

559 560
bool Signature::HasSameTypesAs(const Signature& other,
                               ParameterMode mode) const {
561 562
  auto compare_types = types();
  auto other_compare_types = other.types();
563 564 565 566
  if (mode == ParameterMode::kIgnoreImplicit) {
    compare_types = GetExplicitTypes();
    other_compare_types = other.GetExplicitTypes();
  }
567
  if (!(compare_types == other_compare_types &&
568 569 570 571 572 573 574 575
        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;
576
  for (const auto& l : labels) {
577 578 579 580 581 582 583
    if (l.types != other.labels[i++].types) {
      return false;
    }
  }
  return true;
}

584 585
bool IsAssignableFrom(const Type* to, const Type* from) {
  if (to == from) return true;
586 587
  if (from->IsSubtypeOf(to)) return true;
  return TypeOracle::IsImplicitlyConvertableFrom(to, from);
588 589
}

590 591 592 593
bool operator<(const Type& a, const Type& b) {
  return a.MangledName() < b.MangledName();
}

594
VisitResult ProjectStructField(VisitResult structure,
595 596
                               const std::string& fieldname) {
  BottomOffset begin = structure.stack_range().begin();
597 598

  // Check constructor this super classes for fields.
599
  const StructType* type = StructType::cast(structure.type());
600 601
  auto& fields = type->fields();
  for (auto& field : fields) {
602 603 604
    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});
605 606 607
    }
    begin = end;
  }
608

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

613 614 615 616 617 618
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 (auto* s = StructType::DynamicCast(type)) {
619 620
    for (const Field& field : s->fields()) {
      AppendLoweredTypes(field.name_and_type.type, result);
621 622
    }
  } else {
623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649
    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);
650
  }
651 652 653 654 655 656 657
  return result;
}

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

660
std::tuple<size_t, std::string> Field::GetFieldSizeInformation() const {
661 662 663 664
  std::string size_string = "#no size";
  const Type* field_type = this->name_and_type.type;
  size_t field_size = 0;
  if (field_type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
665
    field_size = TargetArchitecture::TaggedSize();
666 667
    size_string = "kTaggedSize";
  } else if (field_type->IsSubtypeOf(TypeOracle::GetRawPtrType())) {
668
    field_size = TargetArchitecture::RawPtrSize();
669
    size_string = "kSystemPointerSize";
670 671 672 673
  } else if (field_type->IsSubtypeOf(TypeOracle::GetVoidType())) {
    field_size = 0;
    size_string = "0";
  } else if (field_type->IsSubtypeOf(TypeOracle::GetInt8Type())) {
674 675
    field_size = kUInt8Size;
    size_string = "kUInt8Size";
676
  } else if (field_type->IsSubtypeOf(TypeOracle::GetUint8Type())) {
677 678
    field_size = kUInt8Size;
    size_string = "kUInt8Size";
679 680 681 682 683 684 685 686 687 688 689 690 691
  } else if (field_type->IsSubtypeOf(TypeOracle::GetInt16Type())) {
    field_size = kUInt16Size;
    size_string = "kUInt16Size";
  } else if (field_type->IsSubtypeOf(TypeOracle::GetUint16Type())) {
    field_size = kUInt16Size;
    size_string = "kUInt16Size";
  } else if (field_type->IsSubtypeOf(TypeOracle::GetInt32Type())) {
    field_size = kInt32Size;
    size_string = "kInt32Size";
  } else if (field_type->IsSubtypeOf(TypeOracle::GetUint32Type())) {
    field_size = kInt32Size;
    size_string = "kInt32Size";
  } else if (field_type->IsSubtypeOf(TypeOracle::GetFloat64Type())) {
692 693
    field_size = kDoubleSize;
    size_string = "kDoubleSize";
694
  } else if (field_type->IsSubtypeOf(TypeOracle::GetIntPtrType())) {
695
    field_size = TargetArchitecture::RawPtrSize();
696
    size_string = "kIntptrSize";
697
  } else if (field_type->IsSubtypeOf(TypeOracle::GetUIntPtrType())) {
698
    field_size = TargetArchitecture::RawPtrSize();
699 700 701 702
    size_string = "kIntptrSize";
  } else {
    ReportError("fields of type ", *field_type, " are not (yet) supported");
  }
703
  return std::make_tuple(field_size, size_string);
704 705
}

706 707 708
}  // namespace torque
}  // namespace internal
}  // namespace v8