1 // Copyright 2020 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_HEAP_FACTORY_BASE_INL_H_ 6 #define V8_HEAP_FACTORY_BASE_INL_H_ 7 8 #include "src/heap/factory-base.h" 9 10 #include "src/numbers/conversions.h" 11 #include "src/objects/heap-number.h" 12 #include "src/objects/smi.h" 13 #include "src/roots/roots.h" 14 15 namespace v8 { 16 namespace internal { 17 18 template <typename Impl> ToBoolean(bool value)19Handle<Oddball> FactoryBase<Impl>::ToBoolean(bool value) { 20 return value ? impl()->true_value() : impl()->false_value(); 21 } 22 23 template <typename Impl> 24 template <AllocationType allocation> NewNumber(double value)25Handle<Object> FactoryBase<Impl>::NewNumber(double value) { 26 // Materialize as a SMI if possible. 27 int32_t int_value; 28 if (DoubleToSmiInteger(value, &int_value)) { 29 return handle(Smi::FromInt(int_value), isolate()); 30 } 31 return NewHeapNumber<allocation>(value); 32 } 33 34 template <typename Impl> 35 template <AllocationType allocation> NewNumberFromInt(int32_t value)36Handle<Object> FactoryBase<Impl>::NewNumberFromInt(int32_t value) { 37 if (Smi::IsValid(value)) return handle(Smi::FromInt(value), isolate()); 38 // Bypass NewNumber to avoid various redundant checks. 39 return NewHeapNumber<allocation>(FastI2D(value)); 40 } 41 42 template <typename Impl> 43 template <AllocationType allocation> NewNumberFromUint(uint32_t value)44Handle<Object> FactoryBase<Impl>::NewNumberFromUint(uint32_t value) { 45 int32_t int32v = static_cast<int32_t>(value); 46 if (int32v >= 0 && Smi::IsValid(int32v)) { 47 return handle(Smi::FromInt(int32v), isolate()); 48 } 49 return NewHeapNumber<allocation>(FastUI2D(value)); 50 } 51 52 template <typename Impl> 53 template <AllocationType allocation> NewNumberFromSize(size_t value)54Handle<Object> FactoryBase<Impl>::NewNumberFromSize(size_t value) { 55 // We can't use Smi::IsValid() here because that operates on a signed 56 // intptr_t, and casting from size_t could create a bogus sign bit. 57 if (value <= static_cast<size_t>(Smi::kMaxValue)) { 58 return handle(Smi::FromIntptr(static_cast<intptr_t>(value)), isolate()); 59 } 60 return NewHeapNumber<allocation>(static_cast<double>(value)); 61 } 62 63 template <typename Impl> 64 template <AllocationType allocation> NewNumberFromInt64(int64_t value)65Handle<Object> FactoryBase<Impl>::NewNumberFromInt64(int64_t value) { 66 if (value <= std::numeric_limits<int32_t>::max() && 67 value >= std::numeric_limits<int32_t>::min() && 68 Smi::IsValid(static_cast<int32_t>(value))) { 69 return handle(Smi::FromInt(static_cast<int32_t>(value)), isolate()); 70 } 71 return NewHeapNumber<allocation>(static_cast<double>(value)); 72 } 73 74 template <typename Impl> 75 template <AllocationType allocation> NewHeapNumber(double value)76Handle<HeapNumber> FactoryBase<Impl>::NewHeapNumber(double value) { 77 Handle<HeapNumber> heap_number = NewHeapNumber<allocation>(); 78 heap_number->set_value(value); 79 return heap_number; 80 } 81 82 template <typename Impl> 83 template <AllocationType allocation> NewHeapNumberFromBits(uint64_t bits)84Handle<HeapNumber> FactoryBase<Impl>::NewHeapNumberFromBits(uint64_t bits) { 85 Handle<HeapNumber> heap_number = NewHeapNumber<allocation>(); 86 heap_number->set_value_as_bits(bits); 87 return heap_number; 88 } 89 90 template <typename Impl> 91 template <AllocationType allocation> NewHeapNumberWithHoleNaN()92Handle<HeapNumber> FactoryBase<Impl>::NewHeapNumberWithHoleNaN() { 93 return NewHeapNumberFromBits<allocation>(kHoleNanInt64); 94 } 95 96 } // namespace internal 97 } // namespace v8 98 99 #endif // V8_HEAP_FACTORY_BASE_INL_H_ 100