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 | #ifndef V8_TORQUE_TYPES_H_ |
6 | #define V8_TORQUE_TYPES_H_ |
7 | |
8 | #include <algorithm> |
9 | #include <map> |
10 | #include <set> |
11 | #include <string> |
12 | #include <vector> |
13 | |
14 | #include "src/base/optional.h" |
15 | #include "src/torque/source-positions.h" |
16 | #include "src/torque/utils.h" |
17 | |
18 | namespace v8 { |
19 | namespace internal { |
20 | namespace torque { |
21 | |
22 | static const char* const CONSTEXPR_TYPE_PREFIX = "constexpr " ; |
23 | static const char* const NEVER_TYPE_STRING = "never" ; |
24 | static const char* const CONSTEXPR_BOOL_TYPE_STRING = "constexpr bool" ; |
25 | static const char* const CONSTEXPR_INTPTR_TYPE_STRING = "constexpr intptr" ; |
26 | static const char* const BOOL_TYPE_STRING = "bool" ; |
27 | static const char* const VOID_TYPE_STRING = "void" ; |
28 | static const char* const ARGUMENTS_TYPE_STRING = "Arguments" ; |
29 | static const char* const CONTEXT_TYPE_STRING = "Context" ; |
30 | static const char* const MAP_TYPE_STRING = "Map" ; |
31 | static const char* const OBJECT_TYPE_STRING = "Object" ; |
32 | static const char* const HEAP_OBJECT_TYPE_STRING = "HeapObject" ; |
33 | static const char* const JSOBJECT_TYPE_STRING = "JSObject" ; |
34 | static const char* const SMI_TYPE_STRING = "Smi" ; |
35 | static const char* const TAGGED_TYPE_STRING = "Tagged" ; |
36 | static const char* const RAWPTR_TYPE_STRING = "RawPtr" ; |
37 | static const char* const CONST_STRING_TYPE_STRING = "constexpr string" ; |
38 | static const char* const STRING_TYPE_STRING = "String" ; |
39 | static const char* const NUMBER_TYPE_STRING = "Number" ; |
40 | static const char* const BUILTIN_POINTER_TYPE_STRING = "BuiltinPtr" ; |
41 | static const char* const INTPTR_TYPE_STRING = "intptr" ; |
42 | static const char* const UINTPTR_TYPE_STRING = "uintptr" ; |
43 | static const char* const INT32_TYPE_STRING = "int32" ; |
44 | static const char* const UINT32_TYPE_STRING = "uint32" ; |
45 | static const char* const INT16_TYPE_STRING = "int16" ; |
46 | static const char* const UINT16_TYPE_STRING = "uint16" ; |
47 | static const char* const INT8_TYPE_STRING = "int8" ; |
48 | static const char* const UINT8_TYPE_STRING = "uint8" ; |
49 | static const char* const FLOAT64_TYPE_STRING = "float64" ; |
50 | static const char* const CONST_INT31_TYPE_STRING = "constexpr int31" ; |
51 | static const char* const CONST_INT32_TYPE_STRING = "constexpr int32" ; |
52 | static const char* const CONST_FLOAT64_TYPE_STRING = "constexpr float64" ; |
53 | |
54 | class AggregateType; |
55 | struct Identifier; |
56 | class Macro; |
57 | class Method; |
58 | class StructType; |
59 | class ClassType; |
60 | class Value; |
61 | class Namespace; |
62 | |
63 | class TypeBase { |
64 | public: |
65 | enum class Kind { |
66 | kTopType, |
67 | kAbstractType, |
68 | kBuiltinPointerType, |
69 | kReferenceType, |
70 | kUnionType, |
71 | kStructType, |
72 | kClassType |
73 | }; |
74 | virtual ~TypeBase() = default; |
75 | bool IsTopType() const { return kind() == Kind::kTopType; } |
76 | bool IsAbstractType() const { return kind() == Kind::kAbstractType; } |
77 | bool IsBuiltinPointerType() const { |
78 | return kind() == Kind::kBuiltinPointerType; |
79 | } |
80 | bool IsReferenceType() const { return kind() == Kind::kReferenceType; } |
81 | bool IsUnionType() const { return kind() == Kind::kUnionType; } |
82 | bool IsStructType() const { return kind() == Kind::kStructType; } |
83 | bool IsClassType() const { return kind() == Kind::kClassType; } |
84 | bool IsAggregateType() const { return IsStructType() || IsClassType(); } |
85 | |
86 | protected: |
87 | explicit TypeBase(Kind kind) : kind_(kind) {} |
88 | Kind kind() const { return kind_; } |
89 | |
90 | private: |
91 | const Kind kind_; |
92 | }; |
93 | |
94 | #define DECLARE_TYPE_BOILERPLATE(x) \ |
95 | static x* cast(TypeBase* declarable) { \ |
96 | DCHECK(declarable->Is##x()); \ |
97 | return static_cast<x*>(declarable); \ |
98 | } \ |
99 | static const x* cast(const TypeBase* declarable) { \ |
100 | DCHECK(declarable->Is##x()); \ |
101 | return static_cast<const x*>(declarable); \ |
102 | } \ |
103 | static x* DynamicCast(TypeBase* declarable) { \ |
104 | if (!declarable) return nullptr; \ |
105 | if (!declarable->Is##x()) return nullptr; \ |
106 | return static_cast<x*>(declarable); \ |
107 | } \ |
108 | static const x* DynamicCast(const TypeBase* declarable) { \ |
109 | if (!declarable) return nullptr; \ |
110 | if (!declarable->Is##x()) return nullptr; \ |
111 | return static_cast<const x*>(declarable); \ |
112 | } |
113 | |
114 | class Type : public TypeBase { |
115 | public: |
116 | virtual bool IsSubtypeOf(const Type* supertype) const; |
117 | |
118 | std::string ToString() const; |
119 | virtual std::string MangledName() const = 0; |
120 | bool IsVoid() const { return IsAbstractName(VOID_TYPE_STRING); } |
121 | bool IsNever() const { return IsAbstractName(NEVER_TYPE_STRING); } |
122 | bool IsBool() const { return IsAbstractName(BOOL_TYPE_STRING); } |
123 | bool IsConstexprBool() const { |
124 | return IsAbstractName(CONSTEXPR_BOOL_TYPE_STRING); |
125 | } |
126 | bool IsVoidOrNever() const { return IsVoid() || IsNever(); } |
127 | std::string GetGeneratedTypeName() const; |
128 | std::string GetGeneratedTNodeTypeName() const; |
129 | virtual bool IsConstexpr() const { |
130 | if (parent()) DCHECK(!parent()->IsConstexpr()); |
131 | return false; |
132 | } |
133 | virtual bool IsTransient() const { return false; } |
134 | virtual const Type* NonConstexprVersion() const { return this; } |
135 | base::Optional<const ClassType*> ClassSupertype() const; |
136 | static const Type* CommonSupertype(const Type* a, const Type* b); |
137 | void AddAlias(std::string alias) const { aliases_.insert(std::move(alias)); } |
138 | |
139 | protected: |
140 | Type(TypeBase::Kind kind, const Type* parent) |
141 | : TypeBase(kind), parent_(parent) {} |
142 | const Type* parent() const { return parent_; } |
143 | void set_parent(const Type* t) { parent_ = t; } |
144 | int Depth() const; |
145 | virtual std::string ToExplicitString() const = 0; |
146 | virtual std::string GetGeneratedTypeNameImpl() const = 0; |
147 | virtual std::string GetGeneratedTNodeTypeNameImpl() const = 0; |
148 | |
149 | private: |
150 | bool IsAbstractName(const std::string& name) const; |
151 | |
152 | // If {parent_} is not nullptr, then this type is a subtype of {parent_}. |
153 | const Type* parent_; |
154 | mutable std::set<std::string> aliases_; |
155 | }; |
156 | |
157 | using TypeVector = std::vector<const Type*>; |
158 | |
159 | inline size_t hash_value(const TypeVector& types) { |
160 | size_t hash = 0; |
161 | for (const Type* t : types) { |
162 | hash = base::hash_combine(hash, t); |
163 | } |
164 | return hash; |
165 | } |
166 | |
167 | struct NameAndType { |
168 | std::string name; |
169 | const Type* type; |
170 | }; |
171 | |
172 | std::ostream& operator<<(std::ostream& os, const NameAndType& name_and_type); |
173 | |
174 | struct Field { |
175 | // TODO(danno): This likely should be refactored, the handling of the types |
176 | // using the universal grab-bag utility with std::tie, as well as the |
177 | // reliance of string types is quite clunky. |
178 | std::tuple<size_t, std::string, std::string> GetFieldSizeInformation() const; |
179 | |
180 | SourcePosition pos; |
181 | const AggregateType* aggregate; |
182 | base::Optional<const Field*> index; |
183 | NameAndType name_and_type; |
184 | size_t offset; |
185 | bool is_weak; |
186 | bool const_qualified; |
187 | }; |
188 | |
189 | std::ostream& operator<<(std::ostream& os, const Field& name_and_type); |
190 | |
191 | class TopType final : public Type { |
192 | public: |
193 | DECLARE_TYPE_BOILERPLATE(TopType) |
194 | std::string MangledName() const override { return "top" ; } |
195 | std::string GetGeneratedTypeNameImpl() const override { UNREACHABLE(); } |
196 | std::string GetGeneratedTNodeTypeNameImpl() const override { |
197 | return source_type_->GetGeneratedTNodeTypeName(); |
198 | } |
199 | std::string ToExplicitString() const override { |
200 | std::stringstream s; |
201 | s << "inaccessible " + source_type_->ToString(); |
202 | return s.str(); |
203 | } |
204 | |
205 | const Type* source_type() const { return source_type_; } |
206 | const std::string reason() const { return reason_; } |
207 | |
208 | private: |
209 | friend class TypeOracle; |
210 | explicit TopType(std::string reason, const Type* source_type) |
211 | : Type(Kind::kTopType, nullptr), |
212 | reason_(std::move(reason)), |
213 | source_type_(source_type) {} |
214 | std::string reason_; |
215 | const Type* source_type_; |
216 | }; |
217 | |
218 | class AbstractType final : public Type { |
219 | public: |
220 | DECLARE_TYPE_BOILERPLATE(AbstractType) |
221 | const std::string& name() const { return name_; } |
222 | std::string ToExplicitString() const override { return name(); } |
223 | std::string MangledName() const override { |
224 | std::string str(name()); |
225 | std::replace(str.begin(), str.end(), ' ', '_'); |
226 | return "AT" + str; |
227 | } |
228 | std::string GetGeneratedTypeNameImpl() const override { |
229 | return IsConstexpr() ? generated_type_ |
230 | : "compiler::TNode<" + generated_type_ + ">" ; |
231 | } |
232 | std::string GetGeneratedTNodeTypeNameImpl() const override; |
233 | bool IsConstexpr() const override { |
234 | return name().substr(0, strlen(CONSTEXPR_TYPE_PREFIX)) == |
235 | CONSTEXPR_TYPE_PREFIX; |
236 | } |
237 | const Type* NonConstexprVersion() const override { |
238 | if (IsConstexpr()) return *non_constexpr_version_; |
239 | return this; |
240 | } |
241 | |
242 | private: |
243 | friend class TypeOracle; |
244 | AbstractType(const Type* parent, bool transient, const std::string& name, |
245 | const std::string& generated_type, |
246 | base::Optional<const AbstractType*> non_constexpr_version) |
247 | : Type(Kind::kAbstractType, parent), |
248 | transient_(transient), |
249 | name_(name), |
250 | generated_type_(generated_type), |
251 | non_constexpr_version_(non_constexpr_version) { |
252 | DCHECK_EQ(non_constexpr_version_.has_value(), IsConstexpr()); |
253 | if (parent) DCHECK(parent->IsConstexpr() == IsConstexpr()); |
254 | } |
255 | |
256 | bool IsTransient() const override { return transient_; } |
257 | |
258 | bool transient_; |
259 | const std::string name_; |
260 | const std::string generated_type_; |
261 | base::Optional<const AbstractType*> non_constexpr_version_; |
262 | }; |
263 | |
264 | // For now, builtin pointers are restricted to Torque-defined builtins. |
265 | class BuiltinPointerType final : public Type { |
266 | public: |
267 | DECLARE_TYPE_BOILERPLATE(BuiltinPointerType) |
268 | std::string ToExplicitString() const override; |
269 | std::string MangledName() const override; |
270 | std::string GetGeneratedTypeNameImpl() const override { |
271 | return parent()->GetGeneratedTypeName(); |
272 | } |
273 | std::string GetGeneratedTNodeTypeNameImpl() const override { |
274 | return parent()->GetGeneratedTNodeTypeName(); |
275 | } |
276 | |
277 | const TypeVector& parameter_types() const { return parameter_types_; } |
278 | const Type* return_type() const { return return_type_; } |
279 | |
280 | friend size_t hash_value(const BuiltinPointerType& p) { |
281 | size_t result = base::hash_value(p.return_type_); |
282 | for (const Type* parameter : p.parameter_types_) { |
283 | result = base::hash_combine(result, parameter); |
284 | } |
285 | return result; |
286 | } |
287 | bool operator==(const BuiltinPointerType& other) const { |
288 | return parameter_types_ == other.parameter_types_ && |
289 | return_type_ == other.return_type_; |
290 | } |
291 | size_t function_pointer_type_id() const { return function_pointer_type_id_; } |
292 | |
293 | private: |
294 | friend class TypeOracle; |
295 | BuiltinPointerType(const Type* parent, TypeVector parameter_types, |
296 | const Type* return_type, size_t function_pointer_type_id) |
297 | : Type(Kind::kBuiltinPointerType, parent), |
298 | parameter_types_(parameter_types), |
299 | return_type_(return_type), |
300 | function_pointer_type_id_(function_pointer_type_id) {} |
301 | |
302 | const TypeVector parameter_types_; |
303 | const Type* const return_type_; |
304 | const size_t function_pointer_type_id_; |
305 | }; |
306 | |
307 | class ReferenceType final : public Type { |
308 | public: |
309 | DECLARE_TYPE_BOILERPLATE(ReferenceType) |
310 | std::string MangledName() const override { |
311 | return "RT" + referenced_type_->MangledName(); |
312 | } |
313 | std::string ToExplicitString() const override { |
314 | std::string s = referenced_type_->ToString(); |
315 | if (s.find(' ') != std::string::npos) { |
316 | s = "(" + s + ")" ; |
317 | } |
318 | return "&" + s; |
319 | } |
320 | std::string GetGeneratedTypeNameImpl() const override { |
321 | return "CodeStubAssembler::Reference" ; |
322 | } |
323 | std::string GetGeneratedTNodeTypeNameImpl() const override { UNREACHABLE(); } |
324 | |
325 | const Type* referenced_type() const { return referenced_type_; } |
326 | |
327 | friend size_t hash_value(const ReferenceType& p) { |
328 | return base::hash_combine(static_cast<size_t>(Kind::kReferenceType), |
329 | p.referenced_type_); |
330 | } |
331 | bool operator==(const ReferenceType& other) const { |
332 | return referenced_type_ == other.referenced_type_; |
333 | } |
334 | |
335 | private: |
336 | friend class TypeOracle; |
337 | explicit ReferenceType(const Type* referenced_type) |
338 | : Type(Kind::kReferenceType, nullptr), |
339 | referenced_type_(referenced_type) {} |
340 | |
341 | const Type* const referenced_type_; |
342 | }; |
343 | |
344 | bool operator<(const Type& a, const Type& b); |
345 | struct TypeLess { |
346 | bool operator()(const Type* const a, const Type* const b) const { |
347 | return *a < *b; |
348 | } |
349 | }; |
350 | |
351 | class UnionType final : public Type { |
352 | public: |
353 | DECLARE_TYPE_BOILERPLATE(UnionType) |
354 | std::string ToExplicitString() const override; |
355 | std::string MangledName() const override; |
356 | std::string GetGeneratedTypeNameImpl() const override { |
357 | return "compiler::TNode<" + GetGeneratedTNodeTypeName() + ">" ; |
358 | } |
359 | std::string GetGeneratedTNodeTypeNameImpl() const override; |
360 | |
361 | friend size_t hash_value(const UnionType& p) { |
362 | size_t result = 0; |
363 | for (const Type* t : p.types_) { |
364 | result = base::hash_combine(result, t); |
365 | } |
366 | return result; |
367 | } |
368 | bool operator==(const UnionType& other) const { |
369 | return types_ == other.types_; |
370 | } |
371 | |
372 | base::Optional<const Type*> GetSingleMember() const { |
373 | if (types_.size() == 1) { |
374 | DCHECK_EQ(*types_.begin(), parent()); |
375 | return *types_.begin(); |
376 | } |
377 | return base::nullopt; |
378 | } |
379 | |
380 | bool IsSubtypeOf(const Type* other) const override { |
381 | for (const Type* member : types_) { |
382 | if (!member->IsSubtypeOf(other)) return false; |
383 | } |
384 | return true; |
385 | } |
386 | |
387 | bool IsSupertypeOf(const Type* other) const { |
388 | for (const Type* member : types_) { |
389 | if (other->IsSubtypeOf(member)) { |
390 | return true; |
391 | } |
392 | } |
393 | return false; |
394 | } |
395 | |
396 | bool IsTransient() const override { |
397 | for (const Type* member : types_) { |
398 | if (member->IsTransient()) { |
399 | return true; |
400 | } |
401 | } |
402 | return false; |
403 | } |
404 | |
405 | void Extend(const Type* t) { |
406 | if (const UnionType* union_type = UnionType::DynamicCast(t)) { |
407 | for (const Type* member : union_type->types_) { |
408 | Extend(member); |
409 | } |
410 | } else { |
411 | if (t->IsSubtypeOf(this)) return; |
412 | set_parent(CommonSupertype(parent(), t)); |
413 | EraseIf(&types_, |
414 | [&](const Type* member) { return member->IsSubtypeOf(t); }); |
415 | types_.insert(t); |
416 | } |
417 | } |
418 | |
419 | void Subtract(const Type* t); |
420 | |
421 | static UnionType FromType(const Type* t) { |
422 | const UnionType* union_type = UnionType::DynamicCast(t); |
423 | return union_type ? UnionType(*union_type) : UnionType(t); |
424 | } |
425 | |
426 | private: |
427 | explicit UnionType(const Type* t) : Type(Kind::kUnionType, t), types_({t}) {} |
428 | void RecomputeParent(); |
429 | |
430 | std::set<const Type*, TypeLess> types_; |
431 | }; |
432 | |
433 | const Type* SubtractType(const Type* a, const Type* b); |
434 | |
435 | class AggregateType : public Type { |
436 | public: |
437 | DECLARE_TYPE_BOILERPLATE(AggregateType) |
438 | std::string MangledName() const override { return name_; } |
439 | std::string GetGeneratedTypeNameImpl() const override { UNREACHABLE(); } |
440 | std::string GetGeneratedTNodeTypeNameImpl() const override { UNREACHABLE(); } |
441 | |
442 | virtual bool HasIndexedField() const { return false; } |
443 | |
444 | void SetFields(std::vector<Field> fields) { fields_ = std::move(fields); } |
445 | const std::vector<Field>& fields() const { return fields_; } |
446 | bool HasField(const std::string& name) const; |
447 | const Field& LookupField(const std::string& name) const; |
448 | const std::string& name() const { return name_; } |
449 | Namespace* nspace() const { return namespace_; } |
450 | |
451 | std::string GetGeneratedMethodName(const std::string& name) const { |
452 | return "_method_" + name_ + "_" + name; |
453 | } |
454 | |
455 | virtual const Field& RegisterField(Field field) { |
456 | fields_.push_back(field); |
457 | return fields_.back(); |
458 | } |
459 | |
460 | void RegisterMethod(Method* method) { methods_.push_back(method); } |
461 | const std::vector<Method*>& Methods() const { return methods_; } |
462 | std::vector<Method*> Methods(const std::string& name) const; |
463 | |
464 | std::vector<const AggregateType*> GetHierarchy(); |
465 | |
466 | protected: |
467 | AggregateType(Kind kind, const Type* parent, Namespace* nspace, |
468 | const std::string& name) |
469 | : Type(kind, parent), namespace_(nspace), name_(name) {} |
470 | |
471 | void CheckForDuplicateFields(); |
472 | |
473 | private: |
474 | Namespace* namespace_; |
475 | std::string name_; |
476 | std::vector<Method*> methods_; |
477 | std::vector<Field> fields_; |
478 | }; |
479 | |
480 | class StructType final : public AggregateType { |
481 | public: |
482 | DECLARE_TYPE_BOILERPLATE(StructType) |
483 | std::string ToExplicitString() const override; |
484 | std::string GetGeneratedTypeNameImpl() const override; |
485 | |
486 | private: |
487 | friend class TypeOracle; |
488 | StructType(Namespace* nspace, const std::string& name) |
489 | : AggregateType(Kind::kStructType, nullptr, nspace, name) { |
490 | CheckForDuplicateFields(); |
491 | } |
492 | |
493 | const std::string& GetStructName() const { return name(); } |
494 | }; |
495 | |
496 | class ClassType final : public AggregateType { |
497 | public: |
498 | DECLARE_TYPE_BOILERPLATE(ClassType) |
499 | std::string ToExplicitString() const override; |
500 | std::string GetGeneratedTypeNameImpl() const override; |
501 | std::string GetGeneratedTNodeTypeNameImpl() const override; |
502 | bool IsExtern() const { return is_extern_; } |
503 | bool ShouldGeneratePrint() const { return generate_print_; } |
504 | bool IsTransient() const override { return transient_; } |
505 | bool HasIndexedField() const override; |
506 | size_t size() const { return size_; } |
507 | const ClassType* GetSuperClass() const { |
508 | if (parent() == nullptr) return nullptr; |
509 | return parent()->IsClassType() ? ClassType::DynamicCast(parent()) : nullptr; |
510 | } |
511 | void SetSize(size_t size) { size_ = size; } |
512 | bool AllowInstantiation() const; |
513 | const Field& RegisterField(Field field) override { |
514 | if (field.index) { |
515 | has_indexed_field_ = true; |
516 | } |
517 | return AggregateType::RegisterField(field); |
518 | } |
519 | |
520 | private: |
521 | friend class TypeOracle; |
522 | ClassType(const Type* parent, Namespace* nspace, const std::string& name, |
523 | bool is_extern, bool generate_print, bool transient, |
524 | const std::string& generates); |
525 | |
526 | bool is_extern_; |
527 | bool generate_print_; |
528 | bool transient_; |
529 | size_t size_; |
530 | bool has_indexed_field_; |
531 | const std::string generates_; |
532 | }; |
533 | |
534 | inline std::ostream& operator<<(std::ostream& os, const Type& t) { |
535 | os << t.ToString(); |
536 | return os; |
537 | } |
538 | |
539 | class VisitResult { |
540 | public: |
541 | VisitResult() = default; |
542 | VisitResult(const Type* type, const std::string& constexpr_value) |
543 | : type_(type), constexpr_value_(constexpr_value) { |
544 | DCHECK(type->IsConstexpr()); |
545 | } |
546 | static VisitResult NeverResult(); |
547 | VisitResult(const Type* type, StackRange stack_range) |
548 | : type_(type), stack_range_(stack_range) { |
549 | DCHECK(!type->IsConstexpr()); |
550 | } |
551 | const Type* type() const { return type_; } |
552 | const std::string& constexpr_value() const { return *constexpr_value_; } |
553 | const StackRange& stack_range() const { return *stack_range_; } |
554 | void SetType(const Type* new_type) { type_ = new_type; } |
555 | bool IsOnStack() const { return stack_range_ != base::nullopt; } |
556 | bool operator==(const VisitResult& other) const { |
557 | return type_ == other.type_ && constexpr_value_ == other.constexpr_value_ && |
558 | stack_range_ == other.stack_range_; |
559 | } |
560 | |
561 | private: |
562 | const Type* type_ = nullptr; |
563 | base::Optional<std::string> constexpr_value_; |
564 | base::Optional<StackRange> stack_range_; |
565 | }; |
566 | |
567 | typedef std::map<std::string, VisitResult> NameValueMap; |
568 | |
569 | VisitResult ProjectStructField(VisitResult structure, |
570 | const std::string& fieldname); |
571 | |
572 | class VisitResultVector : public std::vector<VisitResult> { |
573 | public: |
574 | VisitResultVector() : std::vector<VisitResult>() {} |
575 | VisitResultVector(std::initializer_list<VisitResult> init) |
576 | : std::vector<VisitResult>(init) {} |
577 | TypeVector GetTypeVector() const { |
578 | TypeVector result; |
579 | for (auto& visit_result : *this) { |
580 | result.push_back(visit_result.type()); |
581 | } |
582 | return result; |
583 | } |
584 | }; |
585 | |
586 | std::ostream& operator<<(std::ostream& os, const TypeVector& types); |
587 | |
588 | typedef std::vector<NameAndType> NameAndTypeVector; |
589 | |
590 | struct LabelDefinition { |
591 | std::string name; |
592 | NameAndTypeVector parameters; |
593 | }; |
594 | |
595 | typedef std::vector<LabelDefinition> LabelDefinitionVector; |
596 | |
597 | struct LabelDeclaration { |
598 | std::string name; |
599 | TypeVector types; |
600 | }; |
601 | |
602 | typedef std::vector<LabelDeclaration> LabelDeclarationVector; |
603 | |
604 | struct ParameterTypes { |
605 | TypeVector types; |
606 | bool var_args; |
607 | }; |
608 | |
609 | std::ostream& operator<<(std::ostream& os, const ParameterTypes& parameters); |
610 | |
611 | enum class ParameterMode { kProcessImplicit, kIgnoreImplicit }; |
612 | |
613 | typedef std::vector<Identifier*> NameVector; |
614 | |
615 | struct Signature { |
616 | Signature(NameVector n, base::Optional<std::string> arguments_variable, |
617 | ParameterTypes p, size_t i, const Type* r, LabelDeclarationVector l) |
618 | : parameter_names(std::move(n)), |
619 | arguments_variable(arguments_variable), |
620 | parameter_types(std::move(p)), |
621 | implicit_count(i), |
622 | return_type(r), |
623 | labels(std::move(l)) {} |
624 | Signature() : implicit_count(0), return_type(nullptr) {} |
625 | const TypeVector& types() const { return parameter_types.types; } |
626 | NameVector parameter_names; |
627 | base::Optional<std::string> arguments_variable; |
628 | ParameterTypes parameter_types; |
629 | size_t implicit_count; |
630 | const Type* return_type; |
631 | LabelDeclarationVector labels; |
632 | bool HasSameTypesAs( |
633 | const Signature& other, |
634 | ParameterMode mode = ParameterMode::kProcessImplicit) const; |
635 | TypeVector GetImplicitTypes() const { |
636 | return TypeVector(parameter_types.types.begin(), |
637 | parameter_types.types.begin() + implicit_count); |
638 | } |
639 | TypeVector GetExplicitTypes() const { |
640 | return TypeVector(parameter_types.types.begin() + implicit_count, |
641 | parameter_types.types.end()); |
642 | } |
643 | }; |
644 | |
645 | void PrintSignature(std::ostream& os, const Signature& sig, bool with_names); |
646 | std::ostream& operator<<(std::ostream& os, const Signature& sig); |
647 | |
648 | bool IsAssignableFrom(const Type* to, const Type* from); |
649 | |
650 | TypeVector LowerType(const Type* type); |
651 | size_t LoweredSlotCount(const Type* type); |
652 | TypeVector LowerParameterTypes(const TypeVector& parameters); |
653 | TypeVector LowerParameterTypes(const ParameterTypes& parameter_types, |
654 | size_t vararg_count = 0); |
655 | |
656 | } // namespace torque |
657 | } // namespace internal |
658 | } // namespace v8 |
659 | |
660 | #endif // V8_TORQUE_TYPES_H_ |
661 | |