• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/torque/type-visitor.h"
6 
7 #include "src/common/globals.h"
8 #include "src/torque/declarable.h"
9 #include "src/torque/global-context.h"
10 #include "src/torque/kythe-data.h"
11 #include "src/torque/server-data.h"
12 #include "src/torque/type-inference.h"
13 #include "src/torque/type-oracle.h"
14 
15 namespace v8 {
16 namespace internal {
17 namespace torque {
18 
ComputeType(TypeDeclaration * decl,MaybeSpecializationKey specialized_from,Scope * specialization_requester)19 const Type* TypeVisitor::ComputeType(TypeDeclaration* decl,
20                                      MaybeSpecializationKey specialized_from,
21                                      Scope* specialization_requester) {
22   SourcePosition requester_position = CurrentSourcePosition::Get();
23   CurrentSourcePosition::Scope scope(decl->pos);
24   Scope* current_scope = CurrentScope::Get();
25   if (specialized_from) {
26     current_scope = TypeOracle::CreateGenericTypeInstantiationNamespace();
27     current_scope->SetSpecializationRequester(
28         {requester_position, specialization_requester,
29          Type::ComputeName(decl->name->value, specialized_from)});
30   }
31   CurrentScope::Scope new_current_scope_scope(current_scope);
32   if (specialized_from) {
33     auto& params = specialized_from->generic->generic_parameters();
34     auto arg_types_iterator = specialized_from->specialized_types.begin();
35     for (auto param : params) {
36       TypeAlias* alias =
37           Declarations::DeclareType(param.name, *arg_types_iterator);
38       alias->SetIsUserDefined(false);
39       arg_types_iterator++;
40     }
41   }
42 
43   switch (decl->kind) {
44 #define ENUM_ITEM(name)        \
45   case AstNode::Kind::k##name: \
46     return ComputeType(name::cast(decl), specialized_from);
47     AST_TYPE_DECLARATION_NODE_KIND_LIST(ENUM_ITEM)
48 #undef ENUM_ITEM
49     default:
50       UNIMPLEMENTED();
51   }
52 }
53 
ComputeType(TypeAliasDeclaration * decl,MaybeSpecializationKey specialized_from)54 const Type* TypeVisitor::ComputeType(TypeAliasDeclaration* decl,
55                                      MaybeSpecializationKey specialized_from) {
56   const Type* type = ComputeType(decl->type);
57   type->AddAlias(decl->name->value);
58   return type;
59 }
60 
61 namespace {
ComputeGeneratesType(base::Optional<std::string> opt_gen,bool enforce_tnode_type)62 std::string ComputeGeneratesType(base::Optional<std::string> opt_gen,
63                                  bool enforce_tnode_type) {
64   if (!opt_gen) return "";
65   const std::string& generates = *opt_gen;
66   if (enforce_tnode_type) {
67     return UnwrapTNodeTypeName(generates);
68   }
69   return generates;
70 }
71 }  // namespace
72 
ComputeType(AbstractTypeDeclaration * decl,MaybeSpecializationKey specialized_from)73 const AbstractType* TypeVisitor::ComputeType(
74     AbstractTypeDeclaration* decl, MaybeSpecializationKey specialized_from) {
75   std::string generates =
76       ComputeGeneratesType(decl->generates, !decl->IsConstexpr());
77 
78   const Type* parent_type = nullptr;
79   if (decl->extends) {
80     parent_type = TypeVisitor::ComputeType(*decl->extends);
81     if (parent_type->IsUnionType()) {
82       // UnionType::IsSupertypeOf requires that types can only extend from non-
83       // union types in order to work correctly.
84       ReportError("type \"", decl->name->value,
85                   "\" cannot extend a type union");
86     }
87   }
88 
89   if (decl->IsConstexpr() && decl->IsTransient()) {
90     ReportError("cannot declare a transient type that is also constexpr");
91   }
92 
93   const Type* non_constexpr_version = nullptr;
94   if (decl->IsConstexpr()) {
95     QualifiedName non_constexpr_name{GetNonConstexprName(decl->name->value)};
96     if (auto type = Declarations::TryLookupType(non_constexpr_name)) {
97       non_constexpr_version = *type;
98     }
99   }
100 
101   return TypeOracle::GetAbstractType(parent_type, decl->name->value,
102                                      decl->flags, generates,
103                                      non_constexpr_version, specialized_from);
104 }
105 
DeclareMethods(AggregateType * container_type,const std::vector<Declaration * > & methods)106 void DeclareMethods(AggregateType* container_type,
107                     const std::vector<Declaration*>& methods) {
108   for (auto declaration : methods) {
109     CurrentSourcePosition::Scope pos_scope(declaration->pos);
110     TorqueMacroDeclaration* method =
111         TorqueMacroDeclaration::DynamicCast(declaration);
112     Signature signature = TypeVisitor::MakeSignature(method);
113     signature.parameter_names.insert(
114         signature.parameter_names.begin() + signature.implicit_count,
115         MakeNode<Identifier>(kThisParameterName));
116     Statement* body = *(method->body);
117     const std::string& method_name(method->name->value);
118     signature.parameter_types.types.insert(
119         signature.parameter_types.types.begin() + signature.implicit_count,
120         container_type);
121     Method* m = Declarations::CreateMethod(container_type, method_name,
122                                            signature, body);
123     m->SetPosition(method->pos);
124     m->SetIdentifierPosition(method->name->pos);
125   }
126 }
127 
ComputeType(BitFieldStructDeclaration * decl,MaybeSpecializationKey specialized_from)128 const BitFieldStructType* TypeVisitor::ComputeType(
129     BitFieldStructDeclaration* decl, MaybeSpecializationKey specialized_from) {
130   CurrentSourcePosition::Scope position_scope(decl->pos);
131   if (specialized_from.has_value()) {
132     ReportError("Bitfield struct specialization is not supported");
133   }
134   const Type* parent = TypeVisitor::ComputeType(decl->parent);
135   if (!IsAnyUnsignedInteger(parent)) {
136     ReportError(
137         "Bitfield struct must extend from an unsigned integer type, not ",
138         parent->ToString());
139   }
140   auto opt_size = SizeOf(parent);
141   if (!opt_size.has_value()) {
142     ReportError("Cannot determine size of bitfield struct ", decl->name->value,
143                 " because of unsized parent type ", parent->ToString());
144   }
145   const size_t size = 8 * std::get<0>(*opt_size);  // Convert bytes to bits.
146   BitFieldStructType* type = TypeOracle::GetBitFieldStructType(parent, decl);
147 
148   // Iterate through all of the declared fields, checking their validity and
149   // registering them on the newly-constructed BitFieldStructType instance.
150   int offset = 0;
151   for (const auto& field : decl->fields) {
152     CurrentSourcePosition::Scope field_position_scope(
153         field.name_and_type.type->pos);
154     const Type* field_type = TypeVisitor::ComputeType(field.name_and_type.type);
155     if (!IsAllowedAsBitField(field_type)) {
156       ReportError("Type not allowed as bitfield: ",
157                   field.name_and_type.name->value);
158     }
159 
160     // Compute the maximum number of bits that could be used for a field of this
161     // type. Booleans are a special case, not included in SizeOf, because their
162     // runtime size is 32 bits but they should only occupy 1 bit as a bitfield.
163     size_t field_type_size = 0;
164     if (field_type->IsSubtypeOf(TypeOracle::GetBoolType())) {
165       field_type_size = 1;
166     } else {
167       auto opt_field_type_size = SizeOf(field_type);
168       if (!opt_field_type_size.has_value()) {
169         ReportError("Size unknown for type ", field_type->ToString());
170       }
171       field_type_size = 8 * std::get<0>(*opt_field_type_size);
172     }
173 
174     if (field.num_bits < 1 ||
175         static_cast<size_t>(field.num_bits) > field_type_size) {
176       ReportError("Invalid number of bits for ",
177                   field.name_and_type.name->value);
178     }
179     type->RegisterField({field.name_and_type.name->pos,
180                          {field.name_and_type.name->value, field_type},
181                          offset,
182                          field.num_bits});
183     offset += field.num_bits;
184     if (static_cast<size_t>(offset) > size) {
185       ReportError("Too many total bits in ", decl->name->value);
186     }
187   }
188 
189   return type;
190 }
191 
ComputeType(StructDeclaration * decl,MaybeSpecializationKey specialized_from)192 const StructType* TypeVisitor::ComputeType(
193     StructDeclaration* decl, MaybeSpecializationKey specialized_from) {
194   StructType* struct_type = TypeOracle::GetStructType(decl, specialized_from);
195   CurrentScope::Scope struct_namespace_scope(struct_type->nspace());
196   CurrentSourcePosition::Scope decl_position_activator(decl->pos);
197 
198   ResidueClass offset = 0;
199   for (auto& field : decl->fields) {
200     CurrentSourcePosition::Scope position_activator(
201         field.name_and_type.type->pos);
202     const Type* field_type = TypeVisitor::ComputeType(field.name_and_type.type);
203     if (field_type->IsConstexpr()) {
204       ReportError("struct field \"", field.name_and_type.name->value,
205                   "\" carries constexpr type \"", *field_type, "\"");
206     }
207     Field f{field.name_and_type.name->pos,
208             struct_type,
209             base::nullopt,
210             {field.name_and_type.name->value, field_type},
211             offset.SingleValue(),
212             false,
213             field.const_qualified,
214             FieldSynchronization::kNone,
215             FieldSynchronization::kNone};
216     auto optional_size = SizeOf(f.name_and_type.type);
217     struct_type->RegisterField(f);
218     // Offsets are assigned based on an assumption of no space between members.
219     // This might lead to invalid alignment in some cases, but most structs are
220     // never actually packed in memory together (they just represent a batch of
221     // CSA TNode values that should be passed around together). For any struct
222     // that is used as a class field, we verify its offsets when setting up the
223     // class type.
224     if (optional_size.has_value()) {
225       size_t field_size = 0;
226       std::tie(field_size, std::ignore) = *optional_size;
227       offset += field_size;
228     } else {
229       // Structs may contain fields that aren't representable in packed form. If
230       // so, the offset of subsequent fields are marked as invalid.
231       offset = ResidueClass::Unknown();
232     }
233   }
234   return struct_type;
235 }
236 
ComputeType(ClassDeclaration * decl,MaybeSpecializationKey specialized_from)237 const ClassType* TypeVisitor::ComputeType(
238     ClassDeclaration* decl, MaybeSpecializationKey specialized_from) {
239   // TODO(sigurds): Remove this hack by introducing a declarable for classes.
240   const TypeAlias* alias =
241       Declarations::LookupTypeAlias(QualifiedName(decl->name->value));
242   DCHECK_EQ(*alias->delayed_, decl);
243   ClassFlags flags = decl->flags;
244   bool is_shape = flags & ClassFlag::kIsShape;
245   std::string generates = decl->name->value;
246   const Type* super_type = TypeVisitor::ComputeType(decl->super);
247   if (is_shape) {
248     if (!(flags & ClassFlag::kExtern)) {
249       ReportError("Shapes must be extern, add \"extern\" to the declaration.");
250     }
251     if (flags & ClassFlag::kUndefinedLayout) {
252       ReportError("Shapes need to define their layout.");
253     }
254     const ClassType* super_class = ClassType::DynamicCast(super_type);
255     if (!super_class ||
256         !super_class->IsSubtypeOf(TypeOracle::GetJSObjectType())) {
257       Error("Shapes need to extend a subclass of ",
258             *TypeOracle::GetJSObjectType())
259           .Throw();
260     }
261     // Shapes use their super class in CSA code since they have incomplete
262     // support for type-checks on the C++ side.
263     generates = super_class->name();
264   }
265   if (super_type != TypeOracle::GetStrongTaggedType()) {
266     const ClassType* super_class = ClassType::DynamicCast(super_type);
267     if (!super_class) {
268       ReportError(
269           "class \"", decl->name->value,
270           "\" must extend either StrongTagged or an already declared class");
271     }
272     if (super_class->HasUndefinedLayout() &&
273         !(flags & ClassFlag::kUndefinedLayout)) {
274       Error("Class \"", decl->name->value,
275             "\" defines its layout but extends a class which does not")
276           .Position(decl->pos);
277     }
278     if ((flags & ClassFlag::kExport) &&
279         !(super_class->ShouldExport() || super_class->IsExtern())) {
280       Error("cannot export class ", decl->name,
281             " because superclass is neither @export or extern");
282     }
283   }
284   if ((flags & ClassFlag::kGenerateBodyDescriptor ||
285        flags & ClassFlag::kExport) &&
286       flags & ClassFlag::kUndefinedLayout) {
287     Error("Class \"", decl->name->value,
288           "\" requires a layout but doesn't have one");
289   }
290   if (flags & ClassFlag::kGenerateUniqueMap) {
291     if (!(flags & ClassFlag::kExtern)) {
292       Error("No need to specify ", ANNOTATION_GENERATE_UNIQUE_MAP,
293             ", non-extern classes always have a unique map.");
294     }
295     if (flags & ClassFlag::kAbstract) {
296       Error(ANNOTATION_ABSTRACT, " and ", ANNOTATION_GENERATE_UNIQUE_MAP,
297             " shouldn't be used together, because abstract classes are never "
298             "instantiated.");
299     }
300   }
301   if ((flags & ClassFlag::kGenerateFactoryFunction) &&
302       (flags & ClassFlag::kAbstract)) {
303     Error(ANNOTATION_ABSTRACT, " and ", ANNOTATION_GENERATE_FACTORY_FUNCTION,
304           " shouldn't be used together, because abstract classes are never "
305           "instantiated.");
306   }
307   if (flags & ClassFlag::kExtern) {
308     if (decl->generates) {
309       bool enforce_tnode_type = true;
310       std::string explicit_generates =
311           ComputeGeneratesType(decl->generates, enforce_tnode_type);
312       if (explicit_generates == generates) {
313         Lint("Unnecessary 'generates' clause for class ", decl->name->value);
314       }
315       generates = explicit_generates;
316     }
317     if (flags & ClassFlag::kExport) {
318       Error("cannot export a class that is marked extern");
319     }
320   } else {
321     if (decl->generates) {
322       ReportError("Only extern classes can specify a generated type.");
323     }
324     if (super_type != TypeOracle::GetStrongTaggedType()) {
325       if (flags & ClassFlag::kUndefinedLayout) {
326         Error("non-external classes must have defined layouts");
327       }
328     }
329   }
330   if (!(flags & ClassFlag::kExtern) &&
331       (flags & ClassFlag::kHasSameInstanceTypeAsParent)) {
332     Error("non-extern Torque-defined classes must have unique instance types");
333   }
334   if ((flags & ClassFlag::kHasSameInstanceTypeAsParent) &&
335       !(flags & ClassFlag::kDoNotGenerateCast || flags & ClassFlag::kIsShape)) {
336     Error(
337         "classes that inherit their instance type must be annotated with "
338         "@doNotGenerateCast");
339   }
340 
341   return TypeOracle::GetClassType(super_type, decl->name->value, flags,
342                                   generates, decl, alias);
343 }
344 
ComputeType(TypeExpression * type_expression)345 const Type* TypeVisitor::ComputeType(TypeExpression* type_expression) {
346   if (auto* basic = BasicTypeExpression::DynamicCast(type_expression)) {
347     QualifiedName qualified_name{basic->namespace_qualification,
348                                  basic->name->value};
349     auto& args = basic->generic_arguments;
350     const Type* type;
351     SourcePosition pos = SourcePosition::Invalid();
352 
353     if (args.empty()) {
354       auto* alias = Declarations::LookupTypeAlias(qualified_name);
355       type = alias->type();
356       pos = alias->GetDeclarationPosition();
357       if (GlobalContext::collect_kythe_data()) {
358         if (alias->IsUserDefined()) {
359           KytheData::AddTypeUse(basic->name->pos, alias);
360         }
361       }
362     } else {
363       auto* generic_type =
364           Declarations::LookupUniqueGenericType(qualified_name);
365       type = TypeOracle::GetGenericTypeInstance(generic_type,
366                                                 ComputeTypeVector(args));
367       pos = generic_type->declaration()->name->pos;
368       if (GlobalContext::collect_kythe_data()) {
369         KytheData::AddTypeUse(basic->name->pos, generic_type);
370       }
371     }
372 
373     if (GlobalContext::collect_language_server_data()) {
374       LanguageServerData::AddDefinition(type_expression->pos, pos);
375     }
376     return type;
377 
378   } else if (auto* union_type =
379                  UnionTypeExpression::DynamicCast(type_expression)) {
380     return TypeOracle::GetUnionType(ComputeType(union_type->a),
381                                     ComputeType(union_type->b));
382   } else if (auto* function_type_exp =
383                  FunctionTypeExpression::DynamicCast(type_expression)) {
384     TypeVector argument_types;
385     for (TypeExpression* type_exp : function_type_exp->parameters) {
386       argument_types.push_back(ComputeType(type_exp));
387     }
388     return TypeOracle::GetBuiltinPointerType(
389         argument_types, ComputeType(function_type_exp->return_type));
390   } else {
391     auto* precomputed = PrecomputedTypeExpression::cast(type_expression);
392     return precomputed->type;
393   }
394 }
395 
MakeSignature(const CallableDeclaration * declaration)396 Signature TypeVisitor::MakeSignature(const CallableDeclaration* declaration) {
397   LabelDeclarationVector definition_vector;
398   for (const auto& label : declaration->labels) {
399     LabelDeclaration def = {label.name, ComputeTypeVector(label.types)};
400     definition_vector.push_back(def);
401   }
402   base::Optional<std::string> arguments_variable;
403   if (declaration->parameters.has_varargs)
404     arguments_variable = declaration->parameters.arguments_variable;
405   Signature result{declaration->parameters.names,
406                    arguments_variable,
407                    {ComputeTypeVector(declaration->parameters.types),
408                     declaration->parameters.has_varargs},
409                    declaration->parameters.implicit_count,
410                    ComputeType(declaration->return_type),
411                    definition_vector,
412                    declaration->transitioning};
413   return result;
414 }
415 
VisitClassFieldsAndMethods(ClassType * class_type,const ClassDeclaration * class_declaration)416 void TypeVisitor::VisitClassFieldsAndMethods(
417     ClassType* class_type, const ClassDeclaration* class_declaration) {
418   const ClassType* super_class = class_type->GetSuperClass();
419   ResidueClass class_offset = 0;
420   size_t header_size = 0;
421   if (super_class) {
422     class_offset = super_class->size();
423     header_size = super_class->header_size();
424   }
425 
426   for (const ClassFieldExpression& field_expression :
427        class_declaration->fields) {
428     CurrentSourcePosition::Scope position_activator(
429         field_expression.name_and_type.type->pos);
430     const Type* field_type = ComputeType(field_expression.name_and_type.type);
431     if (class_type->IsShape()) {
432       if (!field_type->IsSubtypeOf(TypeOracle::GetObjectType())) {
433         ReportError(
434             "in-object properties only support subtypes of Object, but "
435             "found type ",
436             *field_type);
437       }
438       if (field_expression.custom_weak_marking) {
439         ReportError("in-object properties cannot use @customWeakMarking");
440       }
441     }
442     base::Optional<ClassFieldIndexInfo> array_length = field_expression.index;
443     const Field& field = class_type->RegisterField(
444         {field_expression.name_and_type.name->pos,
445          class_type,
446          array_length,
447          {field_expression.name_and_type.name->value, field_type},
448          class_offset.SingleValue(),
449          field_expression.custom_weak_marking,
450          field_expression.const_qualified,
451          field_expression.read_synchronization,
452          field_expression.write_synchronization});
453     ResidueClass field_size = std::get<0>(field.GetFieldSizeInformation());
454     if (field.index) {
455       // Validate that a value at any index in a packed array is aligned
456       // correctly, since it is possible to define a struct whose size is not a
457       // multiple of its alignment.
458       field.ValidateAlignment(class_offset +
459                               field_size * ResidueClass::Unknown());
460 
461       if (auto literal =
462               IntegerLiteralExpression::DynamicCast(field.index->expr)) {
463         if (auto value = literal->value.TryTo<size_t>()) {
464           field_size *= *value;
465         } else {
466           Error("Not a valid field index").Position(field.pos);
467         }
468       } else {
469         field_size *= ResidueClass::Unknown();
470       }
471     }
472     field.ValidateAlignment(class_offset);
473     class_offset += field_size;
474     // In-object properties are not considered part of the header.
475     if (class_offset.SingleValue() && !class_type->IsShape()) {
476       header_size = *class_offset.SingleValue();
477     }
478     if (!field.index && !class_offset.SingleValue()) {
479       Error("Indexed fields have to be at the end of the object")
480           .Position(field.pos);
481     }
482   }
483   DCHECK_GT(header_size, 0);
484   class_type->header_size_ = header_size;
485   class_type->size_ = class_offset;
486   class_type->GenerateAccessors();
487   DeclareMethods(class_type, class_declaration->methods);
488 }
489 
VisitStructMethods(StructType * struct_type,const StructDeclaration * struct_declaration)490 void TypeVisitor::VisitStructMethods(
491     StructType* struct_type, const StructDeclaration* struct_declaration) {
492   DeclareMethods(struct_type, struct_declaration->methods);
493 }
494 
ComputeTypeForStructExpression(TypeExpression * type_expression,const std::vector<const Type * > & term_argument_types)495 const Type* TypeVisitor::ComputeTypeForStructExpression(
496     TypeExpression* type_expression,
497     const std::vector<const Type*>& term_argument_types) {
498   auto* basic = BasicTypeExpression::DynamicCast(type_expression);
499   if (!basic) {
500     ReportError("expected basic type expression referring to struct");
501   }
502 
503   QualifiedName qualified_name{basic->namespace_qualification,
504                                basic->name->value};
505   base::Optional<GenericType*> maybe_generic_type =
506       Declarations::TryLookupGenericType(qualified_name);
507 
508   StructDeclaration* decl =
509       maybe_generic_type
510           ? StructDeclaration::DynamicCast((*maybe_generic_type)->declaration())
511           : nullptr;
512 
513   // Compute types of non-generic structs as usual
514   if (!(maybe_generic_type && decl)) {
515     const Type* type = ComputeType(type_expression);
516     if (!type->IsStructType() && !type->IsBitFieldStructType()) {
517       ReportError(*type,
518                   " is not a struct or bitfield struct, but used like one");
519     }
520     return type;
521   }
522 
523   auto generic_type = *maybe_generic_type;
524   auto explicit_type_arguments = ComputeTypeVector(basic->generic_arguments);
525 
526   std::vector<TypeExpression*> term_parameters;
527   auto& fields = decl->fields;
528   term_parameters.reserve(fields.size());
529   for (auto& field : fields) {
530     term_parameters.push_back(field.name_and_type.type);
531   }
532 
533   CurrentScope::Scope generic_scope(generic_type->ParentScope());
534   TypeArgumentInference inference(
535       generic_type->generic_parameters(), explicit_type_arguments,
536       term_parameters,
537       TransformVector<base::Optional<const Type*>>(term_argument_types));
538 
539   if (inference.HasFailed()) {
540     ReportError("failed to infer type arguments for struct ", basic->name,
541                 " initialization: ", inference.GetFailureReason());
542   }
543   if (GlobalContext::collect_language_server_data()) {
544     LanguageServerData::AddDefinition(type_expression->pos,
545                                       generic_type->declaration()->name->pos);
546   }
547   return StructType::cast(
548       TypeOracle::GetGenericTypeInstance(generic_type, inference.GetResult()));
549 }
550 
551 }  // namespace torque
552 }  // namespace internal
553 }  // namespace v8
554