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