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_HEAP_NUMBER_H_
6#define V8_OBJECTS_HEAP_NUMBER_H_
7
8#include "src/objects/heap-object.h"
9
10// Has to be the last include (doesn't have include guards):
11#include "src/objects/object-macros.h"
12
13namespace v8 {
14namespace internal {
15
16// The HeapNumber class describes heap allocated numbers that cannot be
17// represented in a Smi (small integer). MutableHeapNumber is the same, but its
18// number value can change over time (it is used only as property storage).
19// HeapNumberBase merely exists to avoid code duplication.
20class HeapNumberBase : public HeapObject {
21 public:
22 // [value]: number value.
23 inline double value() const;
24 inline void set_value(double value);
25
26 inline uint64_t value_as_bits() const;
27 inline void set_value_as_bits(uint64_t bits);
28
29 inline int get_exponent();
30 inline int get_sign();
31
32 // Layout description.
33 static const int kValueOffset = HeapObject::kHeaderSize;
34 // IEEE doubles are two 32 bit words. The first is just mantissa, the second
35 // is a mixture of sign, exponent and mantissa. The offsets of two 32 bit
36 // words within double numbers are endian dependent and they are set
37 // accordingly.
38#if defined(V8_TARGET_LITTLE_ENDIAN)
39 static const int kMantissaOffset = kValueOffset;
40 static const int kExponentOffset = kValueOffset + 4;
41#elif defined(V8_TARGET_BIG_ENDIAN)
42 static const int kMantissaOffset = kValueOffset + 4;
43 static const int kExponentOffset = kValueOffset;
44#else
45#error Unknown byte ordering
46#endif
47
48 static const int kSize = kValueOffset + kDoubleSize;
49 static const uint32_t kSignMask = 0x80000000u;
50 static const uint32_t kExponentMask = 0x7ff00000u;
51 static const uint32_t kMantissaMask = 0xfffffu;
52 static const int kMantissaBits = 52;
53 static const int kExponentBits = 11;
54 static const int kExponentBias = 1023;
55 static const int kExponentShift = 20;
56 static const int kInfinityOrNanExponent =
57 (kExponentMask >> kExponentShift) - kExponentBias;
58 static const int kMantissaBitsInTopWord = 20;
59 static const int kNonMantissaBitsInTopWord = 12;
60
61 // Just to make the macro-generated constructor happy. Subclasses should
62 // perform their own proper type checking.
63 inline bool IsHeapNumberBase() const { return true; }
64
65 OBJECT_CONSTRUCTORS(HeapNumberBase, HeapObject);
66};
67
68class HeapNumber : public HeapNumberBase {
69 public:
70 DECL_CAST(HeapNumber)
71 V8_EXPORT_PRIVATE void HeapNumberPrint(std::ostream& os);
72
73 OBJECT_CONSTRUCTORS(HeapNumber, HeapNumberBase);
74};
75
76class MutableHeapNumber : public HeapNumberBase {
77 public:
78 DECL_CAST(MutableHeapNumber)
79 V8_EXPORT_PRIVATE void MutableHeapNumberPrint(std::ostream& os);
80
81 OBJECT_CONSTRUCTORS(MutableHeapNumber, HeapNumberBase);
82};
83
84} // namespace internal
85} // namespace v8
86
87#include "src/objects/object-macros-undef.h"
88
89#endif // V8_OBJECTS_HEAP_NUMBER_H_
90