V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
types.cc
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 <iostream>
6 
7 #include "src/torque/declarable.h"
8 #include "src/torque/type-oracle.h"
9 #include "src/torque/types.h"
10 
11 namespace v8 {
12 namespace internal {
13 namespace torque {
14 
15 std::string Type::ToString() const {
16  if (aliases_.size() == 0) return ToExplicitString();
17  if (aliases_.size() == 1) return *aliases_.begin();
18  std::stringstream result;
19  int i = 0;
20  for (const std::string& alias : aliases_) {
21  if (i == 0) {
22  result << alias << " (aka. ";
23  } else if (i == 1) {
24  result << alias;
25  } else {
26  result << ", " << alias;
27  }
28  ++i;
29  }
30  result << ")";
31  return result.str();
32 }
33 
34 bool Type::IsSubtypeOf(const Type* supertype) const {
35  if (supertype->IsTopType()) return true;
36  if (IsNever()) return true;
37  if (const UnionType* union_type = UnionType::DynamicCast(supertype)) {
38  return union_type->IsSupertypeOf(this);
39  }
40  const Type* subtype = this;
41  while (subtype != nullptr) {
42  if (subtype == supertype) return true;
43  subtype = subtype->parent();
44  }
45  return false;
46 }
47 
48 // static
49 const Type* Type::CommonSupertype(const Type* a, const Type* b) {
50  int diff = a->Depth() - b->Depth();
51  const Type* a_supertype = a;
52  const Type* b_supertype = b;
53  for (; diff > 0; --diff) a_supertype = a_supertype->parent();
54  for (; diff < 0; ++diff) b_supertype = b_supertype->parent();
55  while (a_supertype && b_supertype) {
56  if (a_supertype == b_supertype) return a_supertype;
57  a_supertype = a_supertype->parent();
58  b_supertype = b_supertype->parent();
59  }
60  ReportError("types " + a->ToString() + " and " + b->ToString() +
61  " have no common supertype");
62 }
63 
64 int Type::Depth() const {
65  int result = 0;
66  for (const Type* current = parent_; current; current = current->parent_) {
67  ++result;
68  }
69  return result;
70 }
71 
72 bool Type::IsAbstractName(const std::string& name) const {
73  if (!IsAbstractType()) return false;
74  return AbstractType::cast(this)->name() == name;
75 }
76 
77 std::string AbstractType::GetGeneratedTNodeTypeName() const {
78  return generated_type_;
79 }
80 
81 std::string FunctionPointerType::ToExplicitString() const {
82  std::stringstream result;
83  result << "builtin (";
84  PrintCommaSeparatedList(result, parameter_types_);
85  result << ") => " << *return_type_;
86  return result.str();
87 }
88 
89 std::string FunctionPointerType::MangledName() const {
90  std::stringstream result;
91  result << "FT";
92  for (const Type* t : parameter_types_) {
93  std::string arg_type_string = t->MangledName();
94  result << arg_type_string.size() << arg_type_string;
95  }
96  std::string return_type_string = return_type_->MangledName();
97  result << return_type_string.size() << return_type_string;
98  return result.str();
99 }
100 
101 std::string UnionType::ToExplicitString() const {
102  std::stringstream result;
103  result << "(";
104  bool first = true;
105  for (const Type* t : types_) {
106  if (!first) {
107  result << " | ";
108  }
109  first = false;
110  result << *t;
111  }
112  result << ")";
113  return result.str();
114 }
115 
116 std::string UnionType::MangledName() const {
117  std::stringstream result;
118  result << "UT";
119  for (const Type* t : types_) {
120  std::string arg_type_string = t->MangledName();
121  result << arg_type_string.size() << arg_type_string;
122  }
123  return result.str();
124 }
125 
126 std::string UnionType::GetGeneratedTNodeTypeName() const {
127  if (types_.size() <= 3) {
128  std::set<std::string> members;
129  for (const Type* t : types_) {
130  members.insert(t->GetGeneratedTNodeTypeName());
131  }
132  if (members == std::set<std::string>{"Smi", "HeapNumber"}) {
133  return "Number";
134  }
135  if (members == std::set<std::string>{"Smi", "HeapNumber", "BigInt"}) {
136  return "Numeric";
137  }
138  }
139  return parent()->GetGeneratedTNodeTypeName();
140 }
141 
142 const Type* UnionType::NonConstexprVersion() const {
143  if (IsConstexpr()) {
144  auto it = types_.begin();
145  UnionType result((*it)->NonConstexprVersion());
146  ++it;
147  for (; it != types_.end(); ++it) {
148  result.Extend((*it)->NonConstexprVersion());
149  }
150  return TypeOracle::GetUnionType(std::move(result));
151  }
152  return this;
153 }
154 
155 void UnionType::RecomputeParent() {
156  const Type* parent = nullptr;
157  for (const Type* t : types_) {
158  if (parent == nullptr) {
159  parent = t;
160  } else {
161  parent = CommonSupertype(parent, t);
162  }
163  }
164  set_parent(parent);
165 }
166 
167 void UnionType::Subtract(const Type* t) {
168  for (auto it = types_.begin(); it != types_.end();) {
169  if ((*it)->IsSubtypeOf(t)) {
170  it = types_.erase(it);
171  } else {
172  ++it;
173  }
174  }
175  if (types_.size() == 0) types_.insert(TypeOracle::GetNeverType());
176  RecomputeParent();
177 }
178 
179 const Type* SubtractType(const Type* a, const Type* b) {
180  UnionType result = UnionType::FromType(a);
181  result.Subtract(b);
182  return TypeOracle::GetUnionType(result);
183 }
184 
185 std::string StructType::ToExplicitString() const {
186  std::stringstream result;
187  result << "{";
188  PrintCommaSeparatedList(result, fields_);
189  result << "}";
190  return result.str();
191 }
192 
193 std::string StructType::GetGeneratedTypeName() const {
194  return namespace_->ExternalName() + "::" + GetStructName();
195 }
196 
197 void PrintSignature(std::ostream& os, const Signature& sig, bool with_names) {
198  os << "(";
199  for (size_t i = 0; i < sig.parameter_types.types.size(); ++i) {
200  if (i == 0 && sig.implicit_count != 0) os << "implicit ";
201  if (sig.implicit_count > 0 && sig.implicit_count == i) {
202  os << ")(";
203  } else {
204  if (i > 0) os << ", ";
205  }
206  if (with_names && !sig.parameter_names.empty()) {
207  if (i < sig.parameter_names.size()) {
208  os << sig.parameter_names[i] << ": ";
209  }
210  }
211  os << *sig.parameter_types.types[i];
212  }
213  if (sig.parameter_types.var_args) {
214  if (sig.parameter_names.size()) os << ", ";
215  os << "...";
216  }
217  os << ")";
218  os << ": " << *sig.return_type;
219 
220  if (sig.labels.empty()) return;
221 
222  os << " labels ";
223  for (size_t i = 0; i < sig.labels.size(); ++i) {
224  if (i > 0) os << ", ";
225  os << sig.labels[i].name;
226  if (sig.labels[i].types.size() > 0) os << "(" << sig.labels[i].types << ")";
227  }
228 }
229 
230 std::ostream& operator<<(std::ostream& os, const NameAndType& name_and_type) {
231  os << name_and_type.name;
232  os << ": ";
233  os << *name_and_type.type;
234  return os;
235 }
236 
237 std::ostream& operator<<(std::ostream& os, const Signature& sig) {
238  PrintSignature(os, sig, true);
239  return os;
240 }
241 
242 std::ostream& operator<<(std::ostream& os, const TypeVector& types) {
243  PrintCommaSeparatedList(os, types);
244  return os;
245 }
246 
247 std::ostream& operator<<(std::ostream& os, const ParameterTypes& p) {
248  PrintCommaSeparatedList(os, p.types);
249  if (p.var_args) {
250  if (p.types.size() > 0) os << ", ";
251  os << "...";
252  }
253  return os;
254 }
255 
256 bool Signature::HasSameTypesAs(const Signature& other,
257  ParameterMode mode) const {
258  auto compare_types = GetTypes();
259  auto other_compare_types = other.GetTypes();
260  if (mode == ParameterMode::kIgnoreImplicit) {
261  compare_types = GetExplicitTypes();
262  other_compare_types = other.GetExplicitTypes();
263  }
264  if (!(compare_types == other_compare_types &&
265  parameter_types.var_args == other.parameter_types.var_args &&
266  return_type == other.return_type)) {
267  return false;
268  }
269  if (labels.size() != other.labels.size()) {
270  return false;
271  }
272  size_t i = 0;
273  for (const auto& l : labels) {
274  if (l.types != other.labels[i++].types) {
275  return false;
276  }
277  }
278  return true;
279 }
280 
281 bool IsAssignableFrom(const Type* to, const Type* from) {
282  if (to == from) return true;
283  if (from->IsSubtypeOf(to)) return true;
284  return TypeOracle::IsImplicitlyConvertableFrom(to, from);
285 }
286 
287 bool operator<(const Type& a, const Type& b) {
288  return a.MangledName() < b.MangledName();
289 }
290 
291 VisitResult ProjectStructField(VisitResult structure,
292  const std::string& fieldname) {
293  DCHECK(structure.IsOnStack());
294  BottomOffset begin = structure.stack_range().begin();
295  const StructType* type = StructType::cast(structure.type());
296  for (auto& field : type->fields()) {
297  BottomOffset end = begin + LoweredSlotCount(field.type);
298  if (field.name == fieldname) {
299  return VisitResult(field.type, StackRange{begin, end});
300  }
301  begin = end;
302  }
303  UNREACHABLE();
304 }
305 
306 namespace {
307 void AppendLoweredTypes(const Type* type, std::vector<const Type*>* result) {
308  DCHECK_NE(type, TypeOracle::GetNeverType());
309  if (type->IsConstexpr()) return;
310  if (type == TypeOracle::GetVoidType()) return;
311  if (auto* s = StructType::DynamicCast(type)) {
312  for (const NameAndType& field : s->fields()) {
313  AppendLoweredTypes(field.type, result);
314  }
315  } else {
316  result->push_back(type);
317  }
318 }
319 } // namespace
320 
321 TypeVector LowerType(const Type* type) {
322  TypeVector result;
323  AppendLoweredTypes(type, &result);
324  return result;
325 }
326 
327 size_t LoweredSlotCount(const Type* type) { return LowerType(type).size(); }
328 
329 TypeVector LowerParameterTypes(const TypeVector& parameters) {
330  std::vector<const Type*> result;
331  for (const Type* t : parameters) {
332  AppendLoweredTypes(t, &result);
333  }
334  return result;
335 }
336 
337 TypeVector LowerParameterTypes(const ParameterTypes& parameter_types,
338  size_t arg_count) {
339  std::vector<const Type*> result = LowerParameterTypes(parameter_types.types);
340  for (size_t i = parameter_types.types.size(); i < arg_count; ++i) {
341  DCHECK(parameter_types.var_args);
342  AppendLoweredTypes(TypeOracle::GetObjectType(), &result);
343  }
344  return result;
345 }
346 
347 VisitResult VisitResult::NeverResult() {
348  VisitResult result;
349  result.type_ = TypeOracle::GetNeverType();
350  return result;
351 }
352 
353 } // namespace torque
354 } // namespace internal
355 } // namespace v8
Definition: libplatform.h:13