V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
smi.h
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 ObjectPtr {
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() : ObjectPtr() {}
28  explicit constexpr Smi(Address ptr) : ObjectPtr(ptr) {
29 #if V8_CAN_HAVE_DCHECK_IN_CONSTEXPR
30  DCHECK(HAS_SMI_TAG(ptr));
31 #endif
32  }
33  Smi* operator->() { return this; }
34  const Smi* operator->() const { return this; }
35 
36  // Returns the integer value.
37  inline int value() const { return Internals::SmiValue(ptr()); }
38  inline Smi ToUint32Smi() {
39  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  static inline int ToInt(ObjectPtr object);
46 
47  // TODO(3770): Drop this when merging Object and ObjectPtr.
48  bool ToInt32(int32_t* value) {
49  *value = this->value();
50  return true;
51  }
52 
53  // Convert a value to a Smi object.
54  static inline constexpr Smi FromInt(int value) {
55 #if V8_CAN_HAVE_DCHECK_IN_CONSTEXPR
56  DCHECK(Smi::IsValid(value));
57 #endif
58  return Smi(Internals::IntToSmi(value));
59  }
60 
61  static inline Smi FromIntptr(intptr_t value) {
62  DCHECK(Smi::IsValid(value));
63  int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
64  return Smi((value << smi_shift_bits) | kSmiTag);
65  }
66 
67  template <typename E,
68  typename = typename std::enable_if<std::is_enum<E>::value>::type>
69  static inline Smi FromEnum(E value) {
70  STATIC_ASSERT(sizeof(E) <= sizeof(int));
71  return FromInt(static_cast<int>(value));
72  }
73 
74  // Returns whether value can be represented in a Smi.
75  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  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_CAST2(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 ObjectPtr. Consider it deprecated; new code
100  // should use zero() instead.
101  static constexpr ObjectPtr kZero = ObjectPtr(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  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_
Definition: libplatform.h:13