Line data Source code
1 : // Copyright 2014 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_COMPILER_TYPES_H_
6 : #define V8_COMPILER_TYPES_H_
7 :
8 : #include "src/base/compiler-specific.h"
9 : #include "src/conversions.h"
10 : #include "src/globals.h"
11 : #include "src/handles.h"
12 : #include "src/objects.h"
13 : #include "src/ostreams.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 : namespace compiler {
18 :
19 : // SUMMARY
20 : //
21 : // A simple type system for compiler-internal use. It is based entirely on
22 : // union types, and all subtyping hence amounts to set inclusion. Besides the
23 : // obvious primitive types and some predefined unions, the type language also
24 : // can express class types (a.k.a. specific maps) and singleton types (i.e.,
25 : // concrete constants).
26 : //
27 : // The following equations and inequations hold:
28 : //
29 : // None <= T
30 : // T <= Any
31 : //
32 : // Number = Signed32 \/ Unsigned32 \/ Double
33 : // Smi <= Signed32
34 : // Name = String \/ Symbol
35 : // UniqueName = InternalizedString \/ Symbol
36 : // InternalizedString < String
37 : //
38 : // Receiver = Object \/ Proxy
39 : // OtherUndetectable < Object
40 : // DetectableReceiver = Receiver - OtherUndetectable
41 : //
42 : // Constant(x) < T iff instance_type(map(x)) < T
43 : //
44 : //
45 : // RANGE TYPES
46 : //
47 : // A range type represents a continuous integer interval by its minimum and
48 : // maximum value. Either value may be an infinity, in which case that infinity
49 : // itself is also included in the range. A range never contains NaN or -0.
50 : //
51 : // If a value v happens to be an integer n, then Constant(v) is considered a
52 : // subtype of Range(n, n) (and therefore also a subtype of any larger range).
53 : // In order to avoid large unions, however, it is usually a good idea to use
54 : // Range rather than Constant.
55 : //
56 : //
57 : // PREDICATES
58 : //
59 : // There are two main functions for testing types:
60 : //
61 : // T1->Is(T2) -- tests whether T1 is included in T2 (i.e., T1 <= T2)
62 : // T1->Maybe(T2) -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0)
63 : //
64 : // Typically, the former is to be used to select representations (e.g., via
65 : // T->Is(SignedSmall())), and the latter to check whether a specific case needs
66 : // handling (e.g., via T->Maybe(Number())).
67 : //
68 : // There is no functionality to discover whether a type is a leaf in the
69 : // lattice. That is intentional. It should always be possible to refine the
70 : // lattice (e.g., splitting up number types further) without invalidating any
71 : // existing assumptions or tests.
72 : // Consequently, do not normally use Equals for type tests, always use Is!
73 : //
74 : // The NowIs operator implements state-sensitive subtying, as described above.
75 : // Any compilation decision based on such temporary properties requires runtime
76 : // guarding!
77 : //
78 : //
79 : // PROPERTIES
80 : //
81 : // Various formal properties hold for constructors, operators, and predicates
82 : // over types. For example, constructors are injective and subtyping is a
83 : // complete partial order.
84 : //
85 : // See test/cctest/test-types.cc for a comprehensive executable specification,
86 : // especially with respect to the properties of the more exotic 'temporal'
87 : // constructors and predicates (those prefixed 'Now').
88 : //
89 : //
90 : // IMPLEMENTATION
91 : //
92 : // Internally, all 'primitive' types, and their unions, are represented as
93 : // bitsets. Bit 0 is reserved for tagging. Only structured types require
94 : // allocation.
95 :
96 : // -----------------------------------------------------------------------------
97 : // Values for bitset types
98 :
99 : // clang-format off
100 :
101 : #define INTERNAL_BITSET_TYPE_LIST(V) \
102 : V(OtherUnsigned31, 1u << 1) \
103 : V(OtherUnsigned32, 1u << 2) \
104 : V(OtherSigned32, 1u << 3) \
105 : V(OtherNumber, 1u << 4) \
106 :
107 : #define PROPER_BITSET_TYPE_LIST(V) \
108 : V(None, 0u) \
109 : V(Negative31, 1u << 5) \
110 : V(Null, 1u << 6) \
111 : V(Undefined, 1u << 7) \
112 : V(Boolean, 1u << 8) \
113 : V(Unsigned30, 1u << 9) \
114 : V(MinusZero, 1u << 10) \
115 : V(NaN, 1u << 11) \
116 : V(Symbol, 1u << 12) \
117 : V(InternalizedString, 1u << 13) \
118 : V(OtherString, 1u << 14) \
119 : V(OtherCallable, 1u << 15) \
120 : V(OtherObject, 1u << 16) \
121 : V(OtherUndetectable, 1u << 17) \
122 : V(CallableProxy, 1u << 18) \
123 : V(OtherProxy, 1u << 19) \
124 : V(Function, 1u << 20) \
125 : V(BoundFunction, 1u << 21) \
126 : V(Hole, 1u << 22) \
127 : V(OtherInternal, 1u << 23) \
128 : V(ExternalPointer, 1u << 24) \
129 : V(Array, 1u << 25) \
130 : \
131 : V(Signed31, kUnsigned30 | kNegative31) \
132 : V(Signed32, kSigned31 | kOtherUnsigned31 | \
133 : kOtherSigned32) \
134 : V(Signed32OrMinusZero, kSigned32 | kMinusZero) \
135 : V(Signed32OrMinusZeroOrNaN, kSigned32 | kMinusZero | kNaN) \
136 : V(Negative32, kNegative31 | kOtherSigned32) \
137 : V(Unsigned31, kUnsigned30 | kOtherUnsigned31) \
138 : V(Unsigned32, kUnsigned30 | kOtherUnsigned31 | \
139 : kOtherUnsigned32) \
140 : V(Unsigned32OrMinusZero, kUnsigned32 | kMinusZero) \
141 : V(Unsigned32OrMinusZeroOrNaN, kUnsigned32 | kMinusZero | kNaN) \
142 : V(Integral32, kSigned32 | kUnsigned32) \
143 : V(Integral32OrMinusZero, kIntegral32 | kMinusZero) \
144 : V(Integral32OrMinusZeroOrNaN, kIntegral32OrMinusZero | kNaN) \
145 : V(PlainNumber, kIntegral32 | kOtherNumber) \
146 : V(OrderedNumber, kPlainNumber | kMinusZero) \
147 : V(MinusZeroOrNaN, kMinusZero | kNaN) \
148 : V(Number, kOrderedNumber | kNaN) \
149 : V(String, kInternalizedString | kOtherString) \
150 : V(UniqueName, kSymbol | kInternalizedString) \
151 : V(Name, kSymbol | kString) \
152 : V(InternalizedStringOrNull, kInternalizedString | kNull) \
153 : V(BooleanOrNumber, kBoolean | kNumber) \
154 : V(BooleanOrNullOrNumber, kBooleanOrNumber | kNull) \
155 : V(BooleanOrNullOrUndefined, kBoolean | kNull | kUndefined) \
156 : V(Oddball, kBooleanOrNullOrUndefined | kHole) \
157 : V(NullOrNumber, kNull | kNumber) \
158 : V(NullOrUndefined, kNull | kUndefined) \
159 : V(Undetectable, kNullOrUndefined | kOtherUndetectable) \
160 : V(NumberOrHole, kNumber | kHole) \
161 : V(NumberOrOddball, kNumber | kNullOrUndefined | kBoolean | \
162 : kHole) \
163 : V(NumberOrString, kNumber | kString) \
164 : V(NumberOrUndefined, kNumber | kUndefined) \
165 : V(PlainPrimitive, kNumberOrString | kBoolean | \
166 : kNullOrUndefined) \
167 : V(Primitive, kSymbol | kPlainPrimitive) \
168 : V(OtherUndetectableOrUndefined, kOtherUndetectable | kUndefined) \
169 : V(Proxy, kCallableProxy | kOtherProxy) \
170 : V(ArrayOrOtherObject, kArray | kOtherObject) \
171 : V(ArrayOrProxy, kArray | kProxy) \
172 : V(DetectableCallable, kFunction | kBoundFunction | \
173 : kOtherCallable | kCallableProxy) \
174 : V(Callable, kDetectableCallable | kOtherUndetectable) \
175 : V(NonCallable, kArray | kOtherObject | kOtherProxy) \
176 : V(NonCallableOrNull, kNonCallable | kNull) \
177 : V(DetectableObject, kArray | kFunction | kBoundFunction | \
178 : kOtherCallable | kOtherObject) \
179 : V(DetectableReceiver, kDetectableObject | kProxy) \
180 : V(DetectableReceiverOrNull, kDetectableReceiver | kNull) \
181 : V(Object, kDetectableObject | kOtherUndetectable) \
182 : V(Receiver, kObject | kProxy) \
183 : V(ReceiverOrUndefined, kReceiver | kUndefined) \
184 : V(ReceiverOrNullOrUndefined, kReceiver | kNull | kUndefined) \
185 : V(SymbolOrReceiver, kSymbol | kReceiver) \
186 : V(StringOrReceiver, kString | kReceiver) \
187 : V(Unique, kBoolean | kUniqueName | kNull | \
188 : kUndefined | kReceiver) \
189 : V(Internal, kHole | kExternalPointer | kOtherInternal) \
190 : V(NonInternal, kPrimitive | kReceiver) \
191 : V(NonNumber, kUnique | kString | kInternal) \
192 : V(Any, 0xfffffffeu)
193 :
194 : // clang-format on
195 :
196 : /*
197 : * The following diagrams show how integers (in the mathematical sense) are
198 : * divided among the different atomic numerical types.
199 : *
200 : * ON OS32 N31 U30 OU31 OU32 ON
201 : * ______[_______[_______[_______[_______[_______[_______
202 : * -2^31 -2^30 0 2^30 2^31 2^32
203 : *
204 : * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
205 : *
206 : * Some of the atomic numerical bitsets are internal only (see
207 : * INTERNAL_BITSET_TYPE_LIST). To a types user, they should only occur in
208 : * union with certain other bitsets. For instance, OtherNumber should only
209 : * occur as part of PlainNumber.
210 : */
211 :
212 : #define BITSET_TYPE_LIST(V) \
213 : INTERNAL_BITSET_TYPE_LIST(V) \
214 : PROPER_BITSET_TYPE_LIST(V)
215 :
216 : class Type;
217 :
218 : // -----------------------------------------------------------------------------
219 : // Bitset types (internal).
220 :
221 : class V8_EXPORT_PRIVATE BitsetType {
222 : public:
223 : typedef uint32_t bitset; // Internal
224 :
225 : enum : uint32_t {
226 : #define DECLARE_TYPE(type, value) k##type = (value),
227 : BITSET_TYPE_LIST(DECLARE_TYPE)
228 : #undef DECLARE_TYPE
229 : kUnusedEOL = 0
230 : };
231 :
232 : static bitset SignedSmall();
233 : static bitset UnsignedSmall();
234 :
235 : bitset Bitset() {
236 441690879 : return static_cast<bitset>(reinterpret_cast<uintptr_t>(this) ^ 1u);
237 : }
238 :
239 : static bool IsInhabited(bitset bits) { return bits != kNone; }
240 :
241 : static bool Is(bitset bits1, bitset bits2) {
242 245764425 : return (bits1 | bits2) == bits2;
243 : }
244 :
245 : static double Min(bitset);
246 : static double Max(bitset);
247 :
248 : static bitset Glb(Type* type); // greatest lower bound that's a bitset
249 : static bitset Glb(double min, double max);
250 : static bitset Lub(Type* type); // least upper bound that's a bitset
251 : static bitset Lub(i::Map* map);
252 : static bitset Lub(i::Object* value);
253 : static bitset Lub(double value);
254 : static bitset Lub(double min, double max);
255 : static bitset ExpandInternals(bitset bits);
256 :
257 : static const char* Name(bitset);
258 : static void Print(std::ostream& os, bitset); // NOLINT
259 : #ifdef DEBUG
260 : static void Print(bitset);
261 : #endif
262 :
263 : static bitset NumberBits(bitset bits);
264 :
265 : static bool IsBitset(Type* type) {
266 997139433 : return reinterpret_cast<uintptr_t>(type) & 1;
267 : }
268 :
269 : static Type* NewForTesting(bitset bits) { return New(bits); }
270 :
271 : private:
272 : friend class Type;
273 :
274 : static Type* New(bitset bits) {
275 41186739 : return reinterpret_cast<Type*>(static_cast<uintptr_t>(bits | 1u));
276 : }
277 :
278 : struct Boundary {
279 : bitset internal;
280 : bitset external;
281 : double min;
282 : };
283 : static const Boundary BoundariesArray[];
284 : static inline const Boundary* Boundaries();
285 : static inline size_t BoundariesSize();
286 : };
287 :
288 : // -----------------------------------------------------------------------------
289 : // Superclass for non-bitset types (internal).
290 : class TypeBase {
291 : protected:
292 : friend class Type;
293 :
294 : enum Kind { kHeapConstant, kOtherNumberConstant, kTuple, kUnion, kRange };
295 :
296 865799397 : Kind kind() const { return kind_; }
297 40942592 : explicit TypeBase(Kind kind) : kind_(kind) {}
298 :
299 : static bool IsKind(Type* type, Kind kind) {
300 912728006 : if (BitsetType::IsBitset(type)) return false;
301 : TypeBase* base = reinterpret_cast<TypeBase*>(type);
302 865799397 : return base->kind() == kind;
303 : }
304 :
305 : // The hacky conversion to/from Type*.
306 : static Type* AsType(TypeBase* type) { return reinterpret_cast<Type*>(type); }
307 : static TypeBase* FromType(Type* type) {
308 : return reinterpret_cast<TypeBase*>(type);
309 : }
310 :
311 : private:
312 : Kind kind_;
313 : };
314 :
315 : // -----------------------------------------------------------------------------
316 : // Constant types.
317 :
318 : class OtherNumberConstantType : public TypeBase {
319 : public:
320 : double Value() { return value_; }
321 :
322 : static bool IsOtherNumberConstant(double value);
323 : static bool IsOtherNumberConstant(Object* value);
324 :
325 : private:
326 : friend class Type;
327 : friend class BitsetType;
328 :
329 1720863 : static Type* New(double value, Zone* zone) {
330 : return AsType(new (zone->New(sizeof(OtherNumberConstantType)))
331 1720863 : OtherNumberConstantType(value)); // NOLINT
332 : }
333 :
334 : static OtherNumberConstantType* cast(Type* type) {
335 : DCHECK(IsKind(type, kOtherNumberConstant));
336 : return static_cast<OtherNumberConstantType*>(FromType(type));
337 : }
338 :
339 1720863 : explicit OtherNumberConstantType(double value)
340 1720863 : : TypeBase(kOtherNumberConstant), value_(value) {
341 1720863 : CHECK(IsOtherNumberConstant(value));
342 1720863 : }
343 :
344 : BitsetType::bitset Lub() { return BitsetType::kOtherNumber; }
345 :
346 : double value_;
347 : };
348 :
349 : class V8_EXPORT_PRIVATE HeapConstantType : public NON_EXPORTED_BASE(TypeBase) {
350 : public:
351 : i::Handle<i::HeapObject> Value() { return object_; }
352 :
353 : private:
354 : friend class Type;
355 : friend class BitsetType;
356 :
357 9429179 : static Type* New(i::Handle<i::HeapObject> value, Zone* zone) {
358 9429179 : BitsetType::bitset bitset = BitsetType::Lub(*value);
359 : return AsType(new (zone->New(sizeof(HeapConstantType)))
360 14878442 : HeapConstantType(bitset, value));
361 : }
362 :
363 : static HeapConstantType* cast(Type* type) {
364 : DCHECK(IsKind(type, kHeapConstant));
365 : return static_cast<HeapConstantType*>(FromType(type));
366 : }
367 :
368 : HeapConstantType(BitsetType::bitset bitset, i::Handle<i::HeapObject> object);
369 :
370 : BitsetType::bitset Lub() { return bitset_; }
371 :
372 : BitsetType::bitset bitset_;
373 : Handle<i::HeapObject> object_;
374 : };
375 :
376 : // -----------------------------------------------------------------------------
377 : // Range types.
378 :
379 : class RangeType : public TypeBase {
380 : public:
381 : struct Limits {
382 : double min;
383 : double max;
384 12046051 : Limits(double min, double max) : min(min), max(max) {}
385 6333390 : explicit Limits(RangeType* range) : min(range->Min()), max(range->Max()) {}
386 : bool IsEmpty();
387 : static Limits Empty() { return Limits(1, 0); }
388 : static Limits Intersect(Limits lhs, Limits rhs);
389 : static Limits Union(Limits lhs, Limits rhs);
390 : };
391 :
392 : double Min() { return limits_.min; }
393 : double Max() { return limits_.max; }
394 :
395 : private:
396 : friend class Type;
397 : friend class BitsetType;
398 : friend class UnionType;
399 :
400 : static Type* New(double min, double max, Zone* zone) {
401 12046051 : return New(Limits(min, max), zone);
402 : }
403 :
404 : static bool IsInteger(double x) {
405 : return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
406 : }
407 :
408 15403315 : static Type* New(Limits lim, Zone* zone) {
409 : DCHECK(IsInteger(lim.min) && IsInteger(lim.max));
410 : DCHECK(lim.min <= lim.max);
411 4105909 : BitsetType::bitset bits = BitsetType::Lub(lim.min, lim.max);
412 :
413 30806589 : return AsType(new (zone->New(sizeof(RangeType))) RangeType(bits, lim));
414 : }
415 :
416 : static RangeType* cast(Type* type) {
417 : DCHECK(IsKind(type, kRange));
418 : return static_cast<RangeType*>(FromType(type));
419 : }
420 :
421 : RangeType(BitsetType::bitset bitset, Limits limits)
422 15403217 : : TypeBase(kRange), bitset_(bitset), limits_(limits) {}
423 :
424 : BitsetType::bitset Lub() { return bitset_; }
425 :
426 : BitsetType::bitset bitset_;
427 : Limits limits_;
428 : };
429 :
430 : // -----------------------------------------------------------------------------
431 : // Superclass for types with variable number of type fields.
432 : class StructuralType : public TypeBase {
433 : public:
434 : int LengthForTesting() { return Length(); }
435 :
436 : protected:
437 : friend class Type;
438 :
439 : int Length() { return length_; }
440 :
441 : Type* Get(int i) {
442 : DCHECK(0 <= i && i < this->Length());
443 197218630 : return elements_[i];
444 : }
445 :
446 : void Set(int i, Type* type) {
447 : DCHECK(0 <= i && i < this->Length());
448 38571124 : elements_[i] = type;
449 : }
450 :
451 : void Shrink(int length) {
452 : DCHECK(2 <= length && length <= this->Length());
453 12456770 : length_ = length;
454 : }
455 :
456 : StructuralType(Kind kind, int length, i::Zone* zone)
457 14388644 : : TypeBase(kind), length_(length) {
458 14388644 : elements_ = reinterpret_cast<Type**>(zone->New(sizeof(Type*) * length));
459 : }
460 :
461 : private:
462 : int length_;
463 : Type** elements_;
464 : };
465 :
466 : // -----------------------------------------------------------------------------
467 : // Tuple types.
468 :
469 : class TupleType : public StructuralType {
470 : public:
471 4047 : int Arity() { return this->Length(); }
472 4617 : Type* Element(int i) { return this->Get(i); }
473 :
474 4104 : void InitElement(int i, Type* type) { this->Set(i, type); }
475 :
476 : private:
477 : friend class Type;
478 :
479 : TupleType(int length, Zone* zone) : StructuralType(kTuple, length, zone) {}
480 :
481 1368 : static Type* New(int length, Zone* zone) {
482 2736 : return AsType(new (zone->New(sizeof(TupleType))) TupleType(length, zone));
483 : }
484 :
485 : static TupleType* cast(Type* type) {
486 : DCHECK(IsKind(type, kTuple));
487 : return static_cast<TupleType*>(FromType(type));
488 : }
489 : };
490 :
491 : // -----------------------------------------------------------------------------
492 : // Union types (internal).
493 : // A union is a structured type with the following invariants:
494 : // - its length is at least 2
495 : // - at most one field is a bitset, and it must go into index 0
496 : // - no field is a union
497 : // - no field is a subtype of any other field
498 : class UnionType : public StructuralType {
499 : private:
500 : friend Type;
501 : friend BitsetType;
502 :
503 : UnionType(int length, Zone* zone) : StructuralType(kUnion, length, zone) {}
504 :
505 14387280 : static Type* New(int length, Zone* zone) {
506 28774548 : return AsType(new (zone->New(sizeof(UnionType))) UnionType(length, zone));
507 : }
508 :
509 : static UnionType* cast(Type* type) {
510 : DCHECK(IsKind(type, kUnion));
511 : return static_cast<UnionType*>(FromType(type));
512 : }
513 :
514 : bool Wellformed();
515 : };
516 :
517 : class V8_EXPORT_PRIVATE Type {
518 : public:
519 : typedef BitsetType::bitset bitset; // Internal
520 :
521 : // Constructors.
522 : #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
523 : static Type* type() { return BitsetType::New(BitsetType::k##type); }
524 : PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
525 : #undef DEFINE_TYPE_CONSTRUCTOR
526 :
527 : static Type* SignedSmall() {
528 2195690 : return BitsetType::New(BitsetType::SignedSmall());
529 : }
530 : static Type* UnsignedSmall() {
531 15517 : return BitsetType::New(BitsetType::UnsignedSmall());
532 : }
533 :
534 : static Type* OtherNumberConstant(double value, Zone* zone) {
535 1720863 : return OtherNumberConstantType::New(value, zone);
536 : }
537 : static Type* HeapConstant(i::Handle<i::HeapObject> value, Zone* zone) {
538 9429213 : return HeapConstantType::New(value, zone);
539 : }
540 : static Type* Range(double min, double max, Zone* zone) {
541 : return RangeType::New(min, max, zone);
542 : }
543 : static Type* Tuple(Type* first, Type* second, Type* third, Zone* zone) {
544 1368 : Type* tuple = TupleType::New(3, zone);
545 : tuple->AsTuple()->InitElement(0, first);
546 : tuple->AsTuple()->InitElement(1, second);
547 : tuple->AsTuple()->InitElement(2, third);
548 : return tuple;
549 : }
550 :
551 : // NewConstant is a factory that returns Constant, Range or Number.
552 : static Type* NewConstant(i::Handle<i::Object> value, Zone* zone);
553 : static Type* NewConstant(double value, Zone* zone);
554 :
555 : static Type* Union(Type* type1, Type* type2, Zone* zone);
556 : static Type* Intersect(Type* type1, Type* type2, Zone* zone);
557 :
558 : static Type* Of(double value, Zone* zone) {
559 : return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value)));
560 : }
561 : static Type* Of(i::Object* value, Zone* zone) {
562 : return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value)));
563 : }
564 : static Type* Of(i::Handle<i::Object> value, Zone* zone) {
565 : return Of(*value, zone);
566 : }
567 :
568 17651 : static Type* For(i::Map* map) {
569 35302 : return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(map)));
570 : }
571 17651 : static Type* For(i::Handle<i::Map> map) { return For(*map); }
572 :
573 : // Predicates.
574 : bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); }
575 :
576 255987511 : bool Is(Type* that) { return this == that || this->SlowIs(that); }
577 : bool Maybe(Type* that);
578 1026 : bool Equals(Type* that) { return this->Is(that) && that->Is(this); }
579 :
580 : // Inspection.
581 : bool IsRange() { return IsKind(TypeBase::kRange); }
582 : bool IsHeapConstant() { return IsKind(TypeBase::kHeapConstant); }
583 : bool IsOtherNumberConstant() {
584 : return IsKind(TypeBase::kOtherNumberConstant);
585 : }
586 : bool IsTuple() { return IsKind(TypeBase::kTuple); }
587 :
588 : HeapConstantType* AsHeapConstant() { return HeapConstantType::cast(this); }
589 : OtherNumberConstantType* AsOtherNumberConstant() {
590 : return OtherNumberConstantType::cast(this);
591 : }
592 : RangeType* AsRange() { return RangeType::cast(this); }
593 : TupleType* AsTuple() { return TupleType::cast(this); }
594 :
595 : // Minimum and maximum of a numeric type.
596 : // These functions do not distinguish between -0 and +0. If the type equals
597 : // kNaN, they return NaN; otherwise kNaN is ignored. Only call these
598 : // functions on subtypes of Number.
599 : double Min();
600 : double Max();
601 :
602 : // Extracts a range from the type: if the type is a range or a union
603 : // containing a range, that range is returned; otherwise, NULL is returned.
604 : Type* GetRange();
605 :
606 : static bool IsInteger(i::Object* x);
607 : static bool IsInteger(double x) {
608 17703425 : return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
609 : }
610 :
611 : int NumConstants();
612 :
613 : // Printing.
614 :
615 : void PrintTo(std::ostream& os);
616 :
617 : #ifdef DEBUG
618 : void Print();
619 : #endif
620 :
621 : // Helpers for testing.
622 : bool IsBitsetForTesting() { return IsBitset(); }
623 : bool IsUnionForTesting() { return IsUnion(); }
624 : bitset AsBitsetForTesting() { return AsBitset(); }
625 : UnionType* AsUnionForTesting() { return AsUnion(); }
626 :
627 : private:
628 : // Friends.
629 : template <class>
630 : friend class Iterator;
631 : friend BitsetType;
632 : friend UnionType;
633 :
634 : // Internal inspection.
635 : bool IsKind(TypeBase::Kind kind) { return TypeBase::IsKind(this, kind); }
636 :
637 : bool IsNone() { return this == None(); }
638 : bool IsAny() { return this == Any(); }
639 : bool IsBitset() { return BitsetType::IsBitset(this); }
640 : bool IsUnion() { return IsKind(TypeBase::kUnion); }
641 :
642 : bitset AsBitset() {
643 : DCHECK(this->IsBitset());
644 : return reinterpret_cast<BitsetType*>(this)->Bitset();
645 : }
646 : UnionType* AsUnion() { return UnionType::cast(this); }
647 :
648 78541480 : bitset BitsetGlb() { return BitsetType::Glb(this); }
649 261277723 : bitset BitsetLub() { return BitsetType::Lub(this); }
650 :
651 : bool SlowIs(Type* that);
652 :
653 : static bool Overlap(RangeType* lhs, RangeType* rhs);
654 : static bool Contains(RangeType* lhs, RangeType* rhs);
655 : static bool Contains(RangeType* range, i::Object* val);
656 :
657 : static int UpdateRange(Type* type, UnionType* result, int size, Zone* zone);
658 :
659 : static RangeType::Limits IntersectRangeAndBitset(Type* range, Type* bits,
660 : Zone* zone);
661 : static RangeType::Limits ToLimits(bitset bits, Zone* zone);
662 :
663 : bool SimplyEquals(Type* that);
664 :
665 : static int AddToUnion(Type* type, UnionType* result, int size, Zone* zone);
666 : static int IntersectAux(Type* type, Type* other, UnionType* result, int size,
667 : RangeType::Limits* limits, Zone* zone);
668 : static Type* NormalizeUnion(Type* unioned, int size, Zone* zone);
669 : static Type* NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone);
670 : };
671 :
672 : } // namespace compiler
673 : } // namespace internal
674 : } // namespace v8
675 :
676 : #endif // V8_COMPILER_TYPES_H_
|