Line data Source code
1 : // Copyright 2018 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_OBJECTS_SMI_H_
6 : #define V8_OBJECTS_SMI_H_
7 :
8 : #include "src/globals.h"
9 : #include "src/objects/heap-object.h"
10 :
11 : // Has to be the last include (doesn't have include guards):
12 : #include "src/objects/object-macros.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 : // Smi represents integer Numbers that can be stored in 31 bits.
18 : // Smis are immediate which means they are NOT allocated in the heap.
19 : // The ptr_ value has the following format: [31 bit signed int] 0
20 : // For long smis it has the following format:
21 : // [32 bit signed int] [31 bits zero padding] 0
22 : // Smi stands for small integer.
23 : class Smi : public Object {
24 : public:
25 : // This replaces the OBJECT_CONSTRUCTORS macro, because Smis are special
26 : // in that we want them to be constexprs.
27 : constexpr Smi() : Object() {}
28 8389858773 : explicit constexpr Smi(Address ptr) : Object(ptr) {
29 : #if V8_CAN_HAVE_DCHECK_IN_CONSTEXPR
30 : DCHECK(HAS_SMI_TAG(ptr));
31 : #endif
32 8389858773 : }
33 7960344 : Smi* operator->() { return this; }
34 : const Smi* operator->() const { return this; }
35 :
36 : // Returns the integer value.
37 15914534 : inline int value() const { return Internals::SmiValue(ptr()); }
38 : inline Smi ToUint32Smi() {
39 432377 : if (value() <= 0) return Smi::FromInt(0);
40 : return Smi::FromInt(static_cast<uint32_t>(value()));
41 : }
42 :
43 : // Convert a Smi object to an int.
44 : static inline int ToInt(const Object object);
45 :
46 : // Convert a value to a Smi object.
47 12704555 : static inline constexpr Smi FromInt(int value) {
48 : #if V8_CAN_HAVE_DCHECK_IN_CONSTEXPR
49 : DCHECK(Smi::IsValid(value));
50 : #endif
51 12704555 : return Smi(Internals::IntToSmi(value));
52 : }
53 :
54 : static inline Smi FromIntptr(intptr_t value) {
55 : DCHECK(Smi::IsValid(value));
56 : int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
57 97157 : return Smi((static_cast<Address>(value) << smi_shift_bits) | kSmiTag);
58 : }
59 :
60 : // Given {value} in [0, 2^31-1], force it into Smi range by changing at most
61 : // the MSB (leaving the lower 31 bit unchanged).
62 : static inline Smi From31BitPattern(int value) {
63 : return Smi::FromInt((value << (32 - kSmiValueSize)) >>
64 : (32 - kSmiValueSize));
65 : }
66 :
67 : template <typename E,
68 : typename = typename std::enable_if<std::is_enum<E>::value>::type>
69 560 : static inline Smi FromEnum(E value) {
70 : STATIC_ASSERT(sizeof(E) <= sizeof(int));
71 652050 : return FromInt(static_cast<int>(value));
72 : }
73 :
74 : // Returns whether value can be represented in a Smi.
75 5333 : static inline bool constexpr IsValid(intptr_t value) {
76 : #if V8_CAN_HAVE_DCHECK_IN_CONSTEXPR
77 : DCHECK(Internals::IsValidSmi(value) ==
78 : (value >= kMinValue && value <= kMaxValue));
79 : #endif
80 5333 : return Internals::IsValidSmi(value);
81 : }
82 :
83 : // Compare two Smis x, y as if they were converted to strings and then
84 : // compared lexicographically. Returns:
85 : // -1 if x < y.
86 : // 0 if x == y.
87 : // 1 if x > y.
88 : // Returns the result (a tagged Smi) as a raw Address for ExternalReference
89 : // usage.
90 : static Address LexicographicCompare(Isolate* isolate, Smi x, Smi y);
91 :
92 : DECL_CAST(Smi)
93 :
94 : // Dispatched behavior.
95 : V8_EXPORT_PRIVATE void SmiPrint(std::ostream& os) const; // NOLINT
96 : DECL_VERIFIER(Smi)
97 :
98 : // C++ does not allow us to have an object of type Smi within class Smi,
99 : // so the kZero value has type Object. Consider it deprecated; new code
100 : // should use zero() instead.
101 : V8_EXPORT_PRIVATE static constexpr Object kZero = Object(0);
102 : // If you need something with type Smi, call zero() instead. Since it is
103 : // a constexpr, "calling" it is just as efficient as reading kZero.
104 194306933 : static inline constexpr Smi zero() { return Smi::FromInt(0); }
105 : static constexpr int kMinValue = kSmiMinValue;
106 : static constexpr int kMaxValue = kSmiMaxValue;
107 : };
108 :
109 : } // namespace internal
110 : } // namespace v8
111 :
112 : #include "src/objects/object-macros-undef.h"
113 :
114 : #endif // V8_OBJECTS_SMI_H_
|