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/server-data.h"
11 #include "src/torque/type-inference.h"
12 #include "src/torque/type-oracle.h"
13 
14 namespace v8 {
15 namespace internal {
16 namespace torque {
17 
ComputeType(TypeDeclaration * decl,MaybeSpecializationKey specialized_from,Scope * specialization_requester)18 const Type* TypeVisitor::ComputeType(TypeDeclaration* decl,
19                                      MaybeSpecializationKey specialized_from,
20                                      Scope* specialization_requester) {
21   SourcePosition requester_position = CurrentSourcePosition::Get();
22   CurrentSourcePosition::Scope scope(decl->pos);
23   Scope* current_scope = CurrentScope::Get();
24   if (specialized_from) {
25     current_scope = TypeOracle::CreateGenericTypeInstantiationNamespace();
26     current_scope->SetSpecializationRequester(
27         {requester_position, specialization_requester,
28          Type::ComputeName(decl->name->value, specialized_from)});
29   }
30   CurrentScope::Scope new_current_scope_scope(current_scope);
31   if (specialized_from) {
32     auto& params = specialized_from->generic->generic_parameters();
33     auto arg_types_iterator = specialized_from->specialized_types.begin();
34     for (auto param : params) {
35       TypeAlias* alias =
36           Declarations::DeclareType(param.name, *arg_types_iterator);
37       alias->SetIsUserDefined(false);
38       arg_types_iterator++;
39     }
40   }
41 
42   switch (decl->kind) {
43 #define ENUM_ITEM(name)        \
44   case AstNode::Kind::k##name: \
45     return ComputeType(name::cast(decl), specialized_from);
46     AST_TYPE_DECLARATION_NODE_KIND_LIST(ENUM_ITEM)
47 #undef ENUM_ITEM
48     default:
49       UNIMPLEMENTED();
50   }
51 }
52 
ComputeType(TypeAliasDeclaration * decl,MaybeSpecializationKey specialized_from)53 const Type* TypeVisitor::ComputeType(TypeAliasDeclaration* decl,
54                                      MaybeSpecializationKey specialized_from) {
55   const Type* type = ComputeType(decl->type);
56   type->AddAlias(decl->name->value);
57   return type;
58 }
59 
60 namespace {
ComputeGeneratesType(base::Optional<std::string> opt_gen,bool enforce_tnode_type)61 std::string ComputeGeneratesType(base::Optional<std::string> opt_gen,
62                                  bool enforce_tnode_type) {
63   if (!opt_gen) return "";
64   const std::string& generates = *opt_gen;
65   if (enforce_tnode_type) {
66     if (generates.length() < 7 || generates.substr(0, 6) != "TNode<" ||
67         generates.substr(generates.length() - 1, 1) != ">") {
68       ReportError("generated type \"", generates,
69                   "\" should be of the form \"TNode<...>\"");
70     }
71     return generates.substr(6, generates.length() - 7);
72   }
73   return generates;
74 }
75 }  // namespace
76 
ComputeType(AbstractTypeDeclaration * decl,MaybeSpecializationKey specialized_from)77 const AbstractType* TypeVisitor::ComputeType(
78     AbstractTypeDeclaration* decl, MaybeSpecializationKey specialized_from) {
79   std::string generates =
80       ComputeGeneratesType(decl->generates, !decl->IsConstexpr());
81 
82   const Type* parent_type = nullptr;
83   if (decl->extends) {
84     parent_type = TypeVisitor::ComputeType(*decl->extends);
85     if (parent_type->IsUnionType()) {
86       // UnionType::IsSupertypeOf requires that types can only extend from non-
87       // union types in order to work correctly.
88       ReportError("type \"", decl->name->value,
89                   "\" cannot extend a type union");
90     }
91   }
92 
93   if (decl->IsConstexpr() && decl->IsTransient()) {
94     ReportError("cannot declare a transient type that is also constexpr");
95   }
96 
97   const Type* non_constexpr_version = nullptr;
98   if (decl->IsConstexpr()) {
99     QualifiedName non_constexpr_name{GetNonConstexprName(decl->name->value)};
100     if (auto type = Declarations::TryLookupType(non_constexpr_name)) {
101       non_constexpr_version = *type;
102     }
103   }
104 
105   return TypeOracle::GetAbstractType(parent_type, decl->name->value,
106                                      decl->flags, generates,
107                                      non_constexpr_version, specialized_from);
108 }
109 
DeclareMethods(AggregateType * container_type,const std::vector<Declaration * > & methods)110 void DeclareMethods(AggregateType* container_type,
111                     const std::vector<Declaration*>& methods) {
112   for (auto declaration : methods) {
113     CurrentSourcePosition::Scope pos_scope(declaration->pos);
114     TorqueMacroDeclaration* method =
115         TorqueMacroDeclaration::DynamicCast(declaration);
116     Signature signature = TypeVisitor::MakeSignature(method);
117     signature.parameter_names.insert(
118         signature.parameter_names.begin() + signature.implicit_count,
119         MakeNode<Identifier>(kThisParameterName));
120     Statement* body = *(method->body);
121     const std::string& method_name(method->name->value);
122     signature.parameter_types.types.insert(
123         signature.parameter_types.types.begin() + signature.implicit_count,
124         container_type);
125     Declarations::CreateMethod(container_type, method_name, signature, body);
126   }
127 }
128 
ComputeType(BitFieldStructDeclaration * decl,MaybeSpecializationKey specialized_from)129 const BitFieldStructType* TypeVisitor::ComputeType(
130     BitFieldStructDeclaration* decl, MaybeSpecializationKey specialized_from) {
131   CurrentSourcePosition::Scope position_scope(decl->pos);
132   if (specialized_from.has_value()) {
133     ReportError("Bitfield struct specialization is not supported");
134   }
135   const Type* parent = TypeVisitor::ComputeType(decl->parent);
136   if (!IsAnyUnsignedInteger(parent)) {
137     ReportError(
138         "Bitfield struct must extend from an unsigned integer type, not ",
139         parent->ToString());
140   }
141   auto opt_size = SizeOf(parent);
142   if (!opt_size.has_value()) {
143     ReportError("Cannot determine size of bitfield struct ", decl->name->value,
144                 " because of unsized parent type ", parent->ToString());
145   }
146   const size_t size = 8 * std::get<0>(*opt_size);  // Convert bytes to bits.
147   BitFieldStructType* type = TypeOracle::GetBitFieldStructType(parent, decl);
148 
149   // Iterate through all of the declared fields, checking their validity and
150   // registering them on the newly-constructed BitFieldStructType instance.
151   int offset = 0;
152   for (const auto& field : decl->fields) {
153     CurrentSourcePosition::Scope field_position_scope(
154         field.name_and_type.type->pos);
155     const Type* field_type = TypeVisitor::ComputeType(field.name_and_type.type);
156     if (!IsAllowedAsBitField(field_type)) {
157       ReportError("Type not allowed as bitfield: ",
158                   field.name_and_type.name->value);
159     }
160 
161     // Compute the maximum number of bits that could be used for a field of this
162     // type. Booleans are a special case, not included in SizeOf, because their
163     // runtime size is 32 bits but they should only occupy 1 bit as a bitfield.
164     size_t field_type_size = 0;
165     if (field_type->IsSubtypeOf(TypeOracle::GetBoolType())) {
166       field_type_size = 1;
167     } else {
168       auto opt_field_type_size = SizeOf(field_type);
169       if (!opt_field_type_size.has_value()) {
170         ReportError("Size unknown for type ", field_type->ToString());
171       }
172       field_type_size = 8 * std::get<0>(*opt_field_type_size);
173     }
174 
175     if (field.num_bits < 1 ||
176         static_cast<size_t>(field.num_bits) > field_type_size) {
177       ReportError("Invalid number of bits for ",
178                   field.name_and_type.name->value);
179     }
180     type->RegisterField({field.name_and_type.name->pos,
181                          {field.name_and_type.name->value, field_type},
182                          offset,
183                          field.num_bits});
184     offset += field.num_bits;
185     if (static_cast<size_t>(offset) > size) {
186       ReportError("Too many total bits in ", decl->name->value);
187     }
188   }
189 
190   return type;
191 }
192 
ComputeType(StructDeclaration * decl,MaybeSpecializationKey specialized_from)193 const StructType* TypeVisitor::ComputeType(
194     StructDeclaration* decl, MaybeSpecializationKey specialized_from) {
195   StructType* struct_type = TypeOracle::GetStructType(decl, specialized_from);
196   CurrentScope::Scope struct_namespace_scope(struct_type->nspace());
197   CurrentSourcePosition::Scope position_activator(decl->pos);
198 
199   ResidueClass offset = 0;
200   for (auto& field : decl->fields) {
201     CurrentSourcePosition::Scope position_activator(
202         field.name_and_type.type->pos);
203     const Type* field_type = TypeVisitor::ComputeType(field.name_and_type.type);
204     if (field_type->IsConstexpr()) {
205       ReportError("struct field \"", field.name_and_type.name->value,
206                   "\" carries constexpr type \"", *field_type, "\"");
207     }
208     Field f{field.name_and_type.name->pos,
209             struct_type,
210             base::nullopt,
211             {field.name_and_type.name->value, field_type},
212             offset.SingleValue(),
213             false,
214             field.const_qualified,
215             false};
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::kCustomCppClass) {
291     if (!(flags & ClassFlag::kExport)) {
292       Error("Only exported classes can have a custom C++ class.");
293     }
294     if (flags & ClassFlag::kExtern) {
295       Error("No need to specify ", ANNOTATION_CUSTOM_CPP_CLASS,
296             ", extern classes always have a custom C++ class.");
297     }
298   }
299   if (flags & ClassFlag::kExtern) {
300     if (decl->generates) {
301       bool enforce_tnode_type = true;
302       generates = ComputeGeneratesType(decl->generates, enforce_tnode_type);
303     }
304     if (flags & ClassFlag::kExport) {
305       Error("cannot export a class that is marked extern");
306     }
307   } else {
308     if (decl->generates) {
309       ReportError("Only extern classes can specify a generated type.");
310     }
311     if (super_type != TypeOracle::GetStrongTaggedType()) {
312       if (flags & ClassFlag::kUndefinedLayout) {
313         Error("non-external classes must have defined layouts");
314       }
315     }
316     flags = flags | ClassFlag::kGeneratePrint | ClassFlag::kGenerateVerify |
317             ClassFlag::kGenerateBodyDescriptor;
318   }
319   if (!(flags & ClassFlag::kExtern) &&
320       (flags & ClassFlag::kHasSameInstanceTypeAsParent)) {
321     Error("non-extern Torque-defined classes must have unique instance types");
322   }
323   if ((flags & ClassFlag::kHasSameInstanceTypeAsParent) &&
324       !(flags & ClassFlag::kDoNotGenerateCast || flags & ClassFlag::kIsShape)) {
325     Error(
326         "classes that inherit their instance type must be annotated with "
327         "@doNotGenerateCast");
328   }
329 
330   return TypeOracle::GetClassType(super_type, decl->name->value, flags,
331                                   generates, decl, alias);
332 }
333 
ComputeType(TypeExpression * type_expression)334 const Type* TypeVisitor::ComputeType(TypeExpression* type_expression) {
335   if (auto* basic = BasicTypeExpression::DynamicCast(type_expression)) {
336     QualifiedName qualified_name{basic->namespace_qualification, basic->name};
337     auto& args = basic->generic_arguments;
338     const Type* type;
339     SourcePosition pos = SourcePosition::Invalid();
340 
341     if (args.empty()) {
342       auto* alias = Declarations::LookupTypeAlias(qualified_name);
343       type = alias->type();
344       pos = alias->GetDeclarationPosition();
345     } else {
346       auto* generic_type =
347           Declarations::LookupUniqueGenericType(qualified_name);
348       type = TypeOracle::GetGenericTypeInstance(generic_type,
349                                                 ComputeTypeVector(args));
350       pos = generic_type->declaration()->name->pos;
351     }
352 
353     if (GlobalContext::collect_language_server_data()) {
354       LanguageServerData::AddDefinition(type_expression->pos, pos);
355     }
356     return type;
357 
358   } else if (auto* union_type =
359                  UnionTypeExpression::DynamicCast(type_expression)) {
360     return TypeOracle::GetUnionType(ComputeType(union_type->a),
361                                     ComputeType(union_type->b));
362   } else if (auto* function_type_exp =
363                  FunctionTypeExpression::DynamicCast(type_expression)) {
364     TypeVector argument_types;
365     for (TypeExpression* type_exp : function_type_exp->parameters) {
366       argument_types.push_back(ComputeType(type_exp));
367     }
368     return TypeOracle::GetBuiltinPointerType(
369         argument_types, ComputeType(function_type_exp->return_type));
370   } else {
371     auto* precomputed = PrecomputedTypeExpression::cast(type_expression);
372     return precomputed->type;
373   }
374 }
375 
MakeSignature(const CallableDeclaration * declaration)376 Signature TypeVisitor::MakeSignature(const CallableDeclaration* declaration) {
377   LabelDeclarationVector definition_vector;
378   for (const auto& label : declaration->labels) {
379     LabelDeclaration def = {label.name, ComputeTypeVector(label.types)};
380     definition_vector.push_back(def);
381   }
382   base::Optional<std::string> arguments_variable;
383   if (declaration->parameters.has_varargs)
384     arguments_variable = declaration->parameters.arguments_variable;
385   Signature result{declaration->parameters.names,
386                    arguments_variable,
387                    {ComputeTypeVector(declaration->parameters.types),
388                     declaration->parameters.has_varargs},
389                    declaration->parameters.implicit_count,
390                    ComputeType(declaration->return_type),
391                    definition_vector,
392                    declaration->transitioning};
393   return result;
394 }
395 
VisitClassFieldsAndMethods(ClassType * class_type,const ClassDeclaration * class_declaration)396 void TypeVisitor::VisitClassFieldsAndMethods(
397     ClassType* class_type, const ClassDeclaration* class_declaration) {
398   const ClassType* super_class = class_type->GetSuperClass();
399   ResidueClass class_offset = 0;
400   size_t header_size = 0;
401   if (super_class) {
402     class_offset = super_class->size();
403     header_size = super_class->header_size();
404   }
405 
406   for (const ClassFieldExpression& field_expression :
407        class_declaration->fields) {
408     CurrentSourcePosition::Scope position_activator(
409         field_expression.name_and_type.type->pos);
410     const Type* field_type = ComputeType(field_expression.name_and_type.type);
411     if (class_type->IsShape()) {
412       if (!field_type->IsSubtypeOf(TypeOracle::GetObjectType())) {
413         ReportError(
414             "in-object properties only support subtypes of Object, but "
415             "found type ",
416             *field_type);
417       }
418       if (field_expression.weak) {
419         ReportError("in-object properties cannot be weak");
420       }
421     }
422     base::Optional<Expression*> array_length = field_expression.index;
423     const Field& field = class_type->RegisterField(
424         {field_expression.name_and_type.name->pos,
425          class_type,
426          array_length,
427          {field_expression.name_and_type.name->value, field_type},
428          class_offset.SingleValue(),
429          field_expression.weak,
430          field_expression.const_qualified,
431          field_expression.generate_verify});
432     ResidueClass field_size = std::get<0>(field.GetFieldSizeInformation());
433     if (field.index) {
434       // Validate that a value at any index in a packed array is aligned
435       // correctly, since it is possible to define a struct whose size is not a
436       // multiple of its alignment.
437       field.ValidateAlignment(class_offset +
438                               field_size * ResidueClass::Unknown());
439 
440       if (auto literal = NumberLiteralExpression::DynamicCast(*field.index)) {
441         size_t value = static_cast<size_t>(literal->number);
442         if (value != literal->number) {
443           Error("non-integral array length").Position(field.pos);
444         }
445         field_size *= value;
446       } else {
447         field_size *= ResidueClass::Unknown();
448       }
449     }
450     field.ValidateAlignment(class_offset);
451     class_offset += field_size;
452     // In-object properties are not considered part of the header.
453     if (class_offset.SingleValue() && !class_type->IsShape()) {
454       header_size = *class_offset.SingleValue();
455     }
456     if (!field.index && !class_offset.SingleValue()) {
457       Error("Indexed fields have to be at the end of the object")
458           .Position(field.pos);
459     }
460   }
461   DCHECK_GT(header_size, 0);
462   class_type->header_size_ = header_size;
463   class_type->size_ = class_offset;
464   class_type->GenerateAccessors();
465   DeclareMethods(class_type, class_declaration->methods);
466 }
467 
VisitStructMethods(StructType * struct_type,const StructDeclaration * struct_declaration)468 void TypeVisitor::VisitStructMethods(
469     StructType* struct_type, const StructDeclaration* struct_declaration) {
470   DeclareMethods(struct_type, struct_declaration->methods);
471 }
472 
ComputeTypeForStructExpression(TypeExpression * type_expression,const std::vector<const Type * > & term_argument_types)473 const Type* TypeVisitor::ComputeTypeForStructExpression(
474     TypeExpression* type_expression,
475     const std::vector<const Type*>& term_argument_types) {
476   auto* basic = BasicTypeExpression::DynamicCast(type_expression);
477   if (!basic) {
478     ReportError("expected basic type expression referring to struct");
479   }
480 
481   QualifiedName qualified_name{basic->namespace_qualification, basic->name};
482   base::Optional<GenericType*> maybe_generic_type =
483       Declarations::TryLookupGenericType(qualified_name);
484 
485   StructDeclaration* decl =
486       maybe_generic_type
487           ? StructDeclaration::DynamicCast((*maybe_generic_type)->declaration())
488           : nullptr;
489 
490   // Compute types of non-generic structs as usual
491   if (!(maybe_generic_type && decl)) {
492     const Type* type = ComputeType(type_expression);
493     if (!type->IsStructType() && !type->IsBitFieldStructType()) {
494       ReportError(*type,
495                   " is not a struct or bitfield struct, but used like one");
496     }
497     return type;
498   }
499 
500   auto generic_type = *maybe_generic_type;
501   auto explicit_type_arguments = ComputeTypeVector(basic->generic_arguments);
502 
503   std::vector<TypeExpression*> term_parameters;
504   auto& fields = decl->fields;
505   term_parameters.reserve(fields.size());
506   for (auto& field : fields) {
507     term_parameters.push_back(field.name_and_type.type);
508   }
509 
510   CurrentScope::Scope generic_scope(generic_type->ParentScope());
511   TypeArgumentInference inference(
512       generic_type->generic_parameters(), explicit_type_arguments,
513       term_parameters,
514       TransformVector<base::Optional<const Type*>>(term_argument_types));
515 
516   if (inference.HasFailed()) {
517     ReportError("failed to infer type arguments for struct ", basic->name,
518                 " initialization: ", inference.GetFailureReason());
519   }
520   if (GlobalContext::collect_language_server_data()) {
521     LanguageServerData::AddDefinition(type_expression->pos,
522                                       generic_type->declaration()->name->pos);
523   }
524   return StructType::cast(
525       TypeOracle::GetGenericTypeInstance(generic_type, inference.GetResult()));
526 }
527 
528 }  // namespace torque
529 }  // namespace internal
530 }  // namespace v8
531