aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/objects/fixed-array-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/objects/fixed-array-inl.h')
-rw-r--r--deps/v8/src/objects/fixed-array-inl.h523
1 files changed, 88 insertions, 435 deletions
diff --git a/deps/v8/src/objects/fixed-array-inl.h b/deps/v8/src/objects/fixed-array-inl.h
index d494f8d15b..6d2b42edbf 100644
--- a/deps/v8/src/objects/fixed-array-inl.h
+++ b/deps/v8/src/objects/fixed-array-inl.h
@@ -7,19 +7,19 @@
#include "src/objects/fixed-array.h"
-#include "src/base/tsan.h"
-#include "src/conversions.h"
-#include "src/handles-inl.h"
+#include "src/handles/handles-inl.h"
#include "src/heap/heap-write-barrier-inl.h"
-#include "src/objects-inl.h"
+#include "src/numbers/conversions.h"
#include "src/objects/bigint.h"
#include "src/objects/compressed-slots.h"
#include "src/objects/heap-number-inl.h"
#include "src/objects/map.h"
#include "src/objects/maybe-object-inl.h"
+#include "src/objects/objects-inl.h"
#include "src/objects/oddball.h"
#include "src/objects/slots.h"
-#include "src/roots-inl.h"
+#include "src/roots/roots-inl.h"
+#include "src/sanitizer/tsan.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@@ -30,7 +30,6 @@ namespace internal {
OBJECT_CONSTRUCTORS_IMPL(FixedArrayBase, HeapObject)
OBJECT_CONSTRUCTORS_IMPL(FixedArray, FixedArrayBase)
OBJECT_CONSTRUCTORS_IMPL(FixedDoubleArray, FixedArrayBase)
-OBJECT_CONSTRUCTORS_IMPL(FixedTypedArrayBase, FixedArrayBase)
OBJECT_CONSTRUCTORS_IMPL(ArrayList, FixedArray)
OBJECT_CONSTRUCTORS_IMPL(ByteArray, FixedArrayBase)
OBJECT_CONSTRUCTORS_IMPL(TemplateList, FixedArray)
@@ -58,13 +57,13 @@ CAST_ACCESSOR(ByteArray)
CAST_ACCESSOR(FixedArray)
CAST_ACCESSOR(FixedArrayBase)
CAST_ACCESSOR(FixedDoubleArray)
-CAST_ACCESSOR(FixedTypedArrayBase)
CAST_ACCESSOR(TemplateList)
CAST_ACCESSOR(WeakFixedArray)
CAST_ACCESSOR(WeakArrayList)
SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
SYNCHRONIZED_SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
+
SMI_ACCESSORS(WeakFixedArray, length, kLengthOffset)
SYNCHRONIZED_SMI_ACCESSORS(WeakFixedArray, length, kLengthOffset)
@@ -76,8 +75,6 @@ Object FixedArrayBase::unchecked_synchronized_length() const {
return ACQUIRE_READ_FIELD(*this, kLengthOffset);
}
-ACCESSORS(FixedTypedArrayBase, base_pointer, Object, kBasePointerOffset)
-
ObjectSlot FixedArray::GetFirstElementAddress() {
return RawField(OffsetOfElementAt(0));
}
@@ -87,7 +84,7 @@ bool FixedArray::ContainsOnlySmisOrHoles() {
ObjectSlot current = GetFirstElementAddress();
for (int i = 0; i < length(); ++i, ++current) {
Object candidate = *current;
- if (!candidate->IsSmi() && candidate != the_hole) return false;
+ if (!candidate.IsSmi() && candidate != the_hole) return false;
}
return true;
}
@@ -98,25 +95,11 @@ Object FixedArray::get(int index) const {
}
Handle<Object> FixedArray::get(FixedArray array, int index, Isolate* isolate) {
- return handle(array->get(index), isolate);
-}
-
-template <class T>
-MaybeHandle<T> FixedArray::GetValue(Isolate* isolate, int index) const {
- Object obj = get(index);
- if (obj->IsUndefined(isolate)) return MaybeHandle<T>();
- return Handle<T>(T::cast(obj), isolate);
-}
-
-template <class T>
-Handle<T> FixedArray::GetValueChecked(Isolate* isolate, int index) const {
- Object obj = get(index);
- CHECK(!obj->IsUndefined(isolate));
- return Handle<T>(T::cast(obj), isolate);
+ return handle(array.get(index), isolate);
}
bool FixedArray::is_the_hole(Isolate* isolate, int index) {
- return get(index)->IsTheHole(isolate);
+ return get(index).IsTheHole(isolate);
}
void FixedArray::set(int index, Smi value) {
@@ -147,9 +130,9 @@ void FixedArray::set(int index, Object value, WriteBarrierMode mode) {
}
void FixedArray::NoWriteBarrierSet(FixedArray array, int index, Object value) {
- DCHECK_NE(array->map(), array->GetReadOnlyRoots().fixed_cow_array_map());
+ DCHECK_NE(array.map(), array.GetReadOnlyRoots().fixed_cow_array_map());
DCHECK_GE(index, 0);
- DCHECK_LT(index, array->length());
+ DCHECK_LT(index, array.length());
DCHECK(!ObjectInYoungGeneration(value));
RELAXED_WRITE_FIELD(array, kHeaderSize + index * kTaggedSize, value);
}
@@ -202,16 +185,27 @@ ObjectSlot FixedArray::RawFieldOfElementAt(int index) {
return RawField(OffsetOfElementAt(index));
}
-void FixedArray::MoveElements(Heap* heap, int dst_index, int src_index, int len,
- WriteBarrierMode mode) {
+void FixedArray::MoveElements(Isolate* isolate, int dst_index, int src_index,
+ int len, WriteBarrierMode mode) {
+ if (len == 0) return;
+ DCHECK_LE(dst_index + len, length());
+ DCHECK_LE(src_index + len, length());
DisallowHeapAllocation no_gc;
- heap->MoveElements(*this, dst_index, src_index, len, mode);
+ ObjectSlot dst_slot(RawFieldOfElementAt(dst_index));
+ ObjectSlot src_slot(RawFieldOfElementAt(src_index));
+ isolate->heap()->MoveRange(*this, dst_slot, src_slot, len, mode);
}
-void FixedArray::CopyElements(Heap* heap, int dst_index, FixedArray src,
+void FixedArray::CopyElements(Isolate* isolate, int dst_index, FixedArray src,
int src_index, int len, WriteBarrierMode mode) {
+ if (len == 0) return;
+ DCHECK_LE(dst_index + len, length());
+ DCHECK_LE(src_index + len, src.length());
DisallowHeapAllocation no_gc;
- heap->CopyElements(*this, src, dst_index, src_index, len, mode);
+
+ ObjectSlot dst_slot(RawFieldOfElementAt(dst_index));
+ ObjectSlot src_slot(src.RawFieldOfElementAt(src_index));
+ isolate->heap()->CopyRange(*this, dst_slot, src_slot, len, mode);
}
// Perform a binary search in a fixed array.
@@ -221,7 +215,7 @@ int BinarySearch(T* array, Name name, int valid_entries,
DCHECK(search_mode == ALL_ENTRIES || out_insertion_index == nullptr);
int low = 0;
int high = array->number_of_entries() - 1;
- uint32_t hash = name->hash_field();
+ uint32_t hash = name.hash_field();
int limit = high;
DCHECK(low <= high);
@@ -229,7 +223,7 @@ int BinarySearch(T* array, Name name, int valid_entries,
while (low != high) {
int mid = low + (high - low) / 2;
Name mid_name = array->GetSortedKey(mid);
- uint32_t mid_hash = mid_name->hash_field();
+ uint32_t mid_hash = mid_name.hash_field();
if (mid_hash >= hash) {
high = mid;
@@ -241,7 +235,7 @@ int BinarySearch(T* array, Name name, int valid_entries,
for (; low <= limit; ++low) {
int sort_index = array->GetSortedKeyIndex(low);
Name entry = array->GetKey(sort_index);
- uint32_t current_hash = entry->hash_field();
+ uint32_t current_hash = entry.hash_field();
if (current_hash != hash) {
if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
*out_insertion_index = sort_index + (current_hash > hash ? 0 : 1);
@@ -268,12 +262,12 @@ template <SearchMode search_mode, typename T>
int LinearSearch(T* array, Name name, int valid_entries,
int* out_insertion_index) {
if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
- uint32_t hash = name->hash_field();
+ uint32_t hash = name.hash_field();
int len = array->number_of_entries();
for (int number = 0; number < len; number++) {
int sorted_index = array->GetSortedKeyIndex(number);
Name entry = array->GetKey(sorted_index);
- uint32_t current_hash = entry->hash_field();
+ uint32_t current_hash = entry.hash_field();
if (current_hash > hash) {
*out_insertion_index = sorted_index;
return T::kNotFound;
@@ -320,7 +314,7 @@ double FixedDoubleArray::get_scalar(int index) {
map() != GetReadOnlyRoots().fixed_array_map());
DCHECK(index >= 0 && index < this->length());
DCHECK(!is_the_hole(index));
- return READ_DOUBLE_FIELD(*this, kHeaderSize + index * kDoubleSize);
+ return ReadField<double>(kHeaderSize + index * kDoubleSize);
}
uint64_t FixedDoubleArray::get_representation(int index) {
@@ -328,15 +322,16 @@ uint64_t FixedDoubleArray::get_representation(int index) {
map() != GetReadOnlyRoots().fixed_array_map());
DCHECK(index >= 0 && index < this->length());
int offset = kHeaderSize + index * kDoubleSize;
- return READ_UINT64_FIELD(*this, offset);
+ // Bug(v8:8875): Doubles may be unaligned.
+ return ReadUnalignedValue<uint64_t>(field_address(offset));
}
Handle<Object> FixedDoubleArray::get(FixedDoubleArray array, int index,
Isolate* isolate) {
- if (array->is_the_hole(index)) {
+ if (array.is_the_hole(index)) {
return ReadOnlyRoots(isolate).the_hole_value_handle();
} else {
- return isolate->factory()->NewNumber(array->get_scalar(index));
+ return isolate->factory()->NewNumber(array.get_scalar(index));
}
}
@@ -345,9 +340,9 @@ void FixedDoubleArray::set(int index, double value) {
map() != GetReadOnlyRoots().fixed_array_map());
int offset = kHeaderSize + index * kDoubleSize;
if (std::isnan(value)) {
- WRITE_DOUBLE_FIELD(*this, offset, std::numeric_limits<double>::quiet_NaN());
+ WriteField<double>(offset, std::numeric_limits<double>::quiet_NaN());
} else {
- WRITE_DOUBLE_FIELD(*this, offset, value);
+ WriteField<double>(offset, value);
}
DCHECK(!is_the_hole(index));
}
@@ -360,7 +355,7 @@ void FixedDoubleArray::set_the_hole(int index) {
DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() &&
map() != GetReadOnlyRoots().fixed_array_map());
int offset = kHeaderSize + index * kDoubleSize;
- WRITE_UINT64_FIELD(*this, offset, kHoleNanInt64);
+ WriteUnalignedValue<uint64_t>(field_address(offset), kHoleNanInt64);
}
bool FixedDoubleArray::is_the_hole(Isolate* isolate, int index) {
@@ -371,8 +366,9 @@ bool FixedDoubleArray::is_the_hole(int index) {
return get_representation(index) == kHoleNanInt64;
}
-void FixedDoubleArray::MoveElements(Heap* heap, int dst_index, int src_index,
- int len, WriteBarrierMode mode) {
+void FixedDoubleArray::MoveElements(Isolate* isolate, int dst_index,
+ int src_index, int len,
+ WriteBarrierMode mode) {
DCHECK_EQ(SKIP_WRITE_BARRIER, mode);
double* data_start =
reinterpret_cast<double*>(FIELD_ADDR(*this, kHeaderSize));
@@ -414,6 +410,19 @@ MaybeObjectSlot WeakFixedArray::RawFieldOfElementAt(int index) {
return RawMaybeWeakField(OffsetOfElementAt(index));
}
+void WeakFixedArray::CopyElements(Isolate* isolate, int dst_index,
+ WeakFixedArray src, int src_index, int len,
+ WriteBarrierMode mode) {
+ if (len == 0) return;
+ DCHECK_LE(dst_index + len, length());
+ DCHECK_LE(src_index + len, src.length());
+ DisallowHeapAllocation no_gc;
+
+ MaybeObjectSlot dst_slot(data_start() + dst_index);
+ MaybeObjectSlot src_slot(src.data_start() + src_index);
+ isolate->heap()->CopyRange(*this, dst_slot, src_slot, len, mode);
+}
+
MaybeObject WeakArrayList::Get(int index) const {
DCHECK(index >= 0 && index < this->capacity());
return RELAXED_READ_WEAK_FIELD(*this, OffsetOfElementAt(index));
@@ -431,10 +440,23 @@ MaybeObjectSlot WeakArrayList::data_start() {
return RawMaybeWeakField(kHeaderSize);
}
+void WeakArrayList::CopyElements(Isolate* isolate, int dst_index,
+ WeakArrayList src, int src_index, int len,
+ WriteBarrierMode mode) {
+ if (len == 0) return;
+ DCHECK_LE(dst_index + len, capacity());
+ DCHECK_LE(src_index + len, src.capacity());
+ DisallowHeapAllocation no_gc;
+
+ MaybeObjectSlot dst_slot(data_start() + dst_index);
+ MaybeObjectSlot src_slot(src.data_start() + src_index);
+ isolate->heap()->CopyRange(*this, dst_slot, src_slot, len, mode);
+}
+
HeapObject WeakArrayList::Iterator::Next() {
if (!array_.is_null()) {
- while (index_ < array_->length()) {
- MaybeObject item = array_->Get(index_++);
+ while (index_ < array_.length()) {
+ MaybeObject item = array_.Get(index_++);
DCHECK(item->IsWeakOrCleared());
if (!item->IsCleared()) return item->GetHeapObjectAssumeWeak();
}
@@ -444,16 +466,16 @@ HeapObject WeakArrayList::Iterator::Next() {
}
int ArrayList::Length() const {
- if (FixedArray::cast(*this)->length() == 0) return 0;
- return Smi::ToInt(FixedArray::cast(*this)->get(kLengthIndex));
+ if (FixedArray::cast(*this).length() == 0) return 0;
+ return Smi::ToInt(FixedArray::cast(*this).get(kLengthIndex));
}
void ArrayList::SetLength(int length) {
- return FixedArray::cast(*this)->set(kLengthIndex, Smi::FromInt(length));
+ return FixedArray::cast(*this).set(kLengthIndex, Smi::FromInt(length));
}
Object ArrayList::Get(int index) const {
- return FixedArray::cast(*this)->get(kFirstIndex + index);
+ return FixedArray::cast(*this).get(kFirstIndex + index);
}
ObjectSlot ArrayList::Slot(int index) {
@@ -461,25 +483,25 @@ ObjectSlot ArrayList::Slot(int index) {
}
void ArrayList::Set(int index, Object obj, WriteBarrierMode mode) {
- FixedArray::cast(*this)->set(kFirstIndex + index, obj, mode);
+ FixedArray::cast(*this).set(kFirstIndex + index, obj, mode);
}
void ArrayList::Clear(int index, Object undefined) {
- DCHECK(undefined->IsUndefined());
- FixedArray::cast(*this)->set(kFirstIndex + index, undefined,
- SKIP_WRITE_BARRIER);
+ DCHECK(undefined.IsUndefined());
+ FixedArray::cast(*this).set(kFirstIndex + index, undefined,
+ SKIP_WRITE_BARRIER);
}
int ByteArray::Size() { return RoundUp(length() + kHeaderSize, kTaggedSize); }
byte ByteArray::get(int index) const {
DCHECK(index >= 0 && index < this->length());
- return READ_BYTE_FIELD(*this, kHeaderSize + index * kCharSize);
+ return ReadField<byte>(kHeaderSize + index * kCharSize);
}
void ByteArray::set(int index, byte value) {
DCHECK(index >= 0 && index < this->length());
- WRITE_BYTE_FIELD(*this, kHeaderSize + index * kCharSize, value);
+ WriteField<byte>(kHeaderSize + index * kCharSize, value);
}
void ByteArray::copy_in(int index, const byte* buffer, int length) {
@@ -498,22 +520,22 @@ void ByteArray::copy_out(int index, byte* buffer, int length) {
int ByteArray::get_int(int index) const {
DCHECK(index >= 0 && index < this->length() / kIntSize);
- return READ_INT_FIELD(*this, kHeaderSize + index * kIntSize);
+ return ReadField<int>(kHeaderSize + index * kIntSize);
}
void ByteArray::set_int(int index, int value) {
DCHECK(index >= 0 && index < this->length() / kIntSize);
- WRITE_INT_FIELD(*this, kHeaderSize + index * kIntSize, value);
+ WriteField<int>(kHeaderSize + index * kIntSize, value);
}
uint32_t ByteArray::get_uint32(int index) const {
DCHECK(index >= 0 && index < this->length() / kUInt32Size);
- return READ_UINT32_FIELD(*this, kHeaderSize + index * kUInt32Size);
+ return ReadField<uint32_t>(kHeaderSize + index * kUInt32Size);
}
void ByteArray::set_uint32(int index, uint32_t value) {
DCHECK(index >= 0 && index < this->length() / kUInt32Size);
- WRITE_UINT32_FIELD(*this, kHeaderSize + index * kUInt32Size, value);
+ WriteField<uint32_t>(kHeaderSize + index * kUInt32Size, value);
}
void ByteArray::clear_padding() {
@@ -559,385 +581,16 @@ int PodArray<T>::length() const {
return ByteArray::length() / sizeof(T);
}
-void* FixedTypedArrayBase::external_pointer() const {
- intptr_t ptr = READ_INTPTR_FIELD(*this, kExternalPointerOffset);
- return reinterpret_cast<void*>(ptr);
-}
-
-void FixedTypedArrayBase::set_external_pointer(void* value) {
- intptr_t ptr = reinterpret_cast<intptr_t>(value);
- WRITE_INTPTR_FIELD(*this, kExternalPointerOffset, ptr);
-}
-
-void* FixedTypedArrayBase::DataPtr() {
- return reinterpret_cast<void*>(
- base_pointer()->ptr() + reinterpret_cast<intptr_t>(external_pointer()));
-}
-
-int FixedTypedArrayBase::ElementSize(InstanceType type) {
- int element_size;
- switch (type) {
-#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
- case FIXED_##TYPE##_ARRAY_TYPE: \
- element_size = sizeof(ctype); \
- break;
-
- TYPED_ARRAYS(TYPED_ARRAY_CASE)
-#undef TYPED_ARRAY_CASE
- default:
- UNREACHABLE();
- }
- return element_size;
-}
-
-int FixedTypedArrayBase::DataSize(InstanceType type) const {
- if (base_pointer() == Smi::kZero) return 0;
- return length() * ElementSize(type);
-}
-
-int FixedTypedArrayBase::DataSize() const {
- return DataSize(map()->instance_type());
-}
-
-size_t FixedTypedArrayBase::ByteLength() const {
- return static_cast<size_t>(length()) *
- static_cast<size_t>(ElementSize(map()->instance_type()));
-}
-
-int FixedTypedArrayBase::size() const {
- return OBJECT_POINTER_ALIGN(kDataOffset + DataSize());
-}
-
-int FixedTypedArrayBase::TypedArraySize(InstanceType type) const {
- return OBJECT_POINTER_ALIGN(kDataOffset + DataSize(type));
-}
-
-// static
-int FixedTypedArrayBase::TypedArraySize(InstanceType type, int length) {
- return OBJECT_POINTER_ALIGN(kDataOffset + length * ElementSize(type));
-}
-
-uint8_t Uint8ArrayTraits::defaultValue() { return 0; }
-
-uint8_t Uint8ClampedArrayTraits::defaultValue() { return 0; }
-
-int8_t Int8ArrayTraits::defaultValue() { return 0; }
-
-uint16_t Uint16ArrayTraits::defaultValue() { return 0; }
-
-int16_t Int16ArrayTraits::defaultValue() { return 0; }
-
-uint32_t Uint32ArrayTraits::defaultValue() { return 0; }
-
-int32_t Int32ArrayTraits::defaultValue() { return 0; }
-
-float Float32ArrayTraits::defaultValue() {
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-double Float64ArrayTraits::defaultValue() {
- return std::numeric_limits<double>::quiet_NaN();
-}
-
-template <class Traits>
-typename Traits::ElementType FixedTypedArray<Traits>::get_scalar(int index) {
- DCHECK((index >= 0) && (index < this->length()));
- return FixedTypedArray<Traits>::get_scalar_from_data_ptr(DataPtr(), index);
-}
-
-// static
-template <class Traits>
-typename Traits::ElementType FixedTypedArray<Traits>::get_scalar_from_data_ptr(
- void* data_ptr, int index) {
- typename Traits::ElementType* ptr = reinterpret_cast<ElementType*>(data_ptr);
- // The JavaScript memory model allows for racy reads and writes to a
- // SharedArrayBuffer's backing store, which will always be a FixedTypedArray.
- // ThreadSanitizer will catch these racy accesses and warn about them, so we
- // disable TSAN for these reads and writes using annotations.
- //
- // We don't use relaxed atomics here, as it is not a requirement of the
- // JavaScript memory model to have tear-free reads of overlapping accesses,
- // and using relaxed atomics may introduce overhead.
- TSAN_ANNOTATE_IGNORE_READS_BEGIN;
- ElementType result;
- if (COMPRESS_POINTERS_BOOL && alignof(ElementType) > kTaggedSize) {
- // TODO(ishell, v8:8875): When pointer compression is enabled 8-byte size
- // fields (external pointers, doubles and BigInt data) are only kTaggedSize
- // aligned so we have to use unaligned pointer friendly way of accessing
- // them in order to avoid undefined behavior in C++ code.
- result = ReadUnalignedValue<ElementType>(reinterpret_cast<Address>(ptr) +
- index * sizeof(ElementType));
- } else {
- result = ptr[index];
- }
- TSAN_ANNOTATE_IGNORE_READS_END;
- return result;
-}
-
-template <class Traits>
-void FixedTypedArray<Traits>::set(int index, ElementType value) {
- CHECK((index >= 0) && (index < this->length()));
- // See the comment in FixedTypedArray<Traits>::get_scalar.
- auto* ptr = reinterpret_cast<ElementType*>(DataPtr());
- TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
- if (COMPRESS_POINTERS_BOOL && alignof(ElementType) > kTaggedSize) {
- // TODO(ishell, v8:8875): When pointer compression is enabled 8-byte size
- // fields (external pointers, doubles and BigInt data) are only kTaggedSize
- // aligned so we have to use unaligned pointer friendly way of accessing
- // them in order to avoid undefined behavior in C++ code.
- WriteUnalignedValue<ElementType>(
- reinterpret_cast<Address>(ptr) + index * sizeof(ElementType), value);
- } else {
- ptr[index] = value;
- }
- TSAN_ANNOTATE_IGNORE_WRITES_END;
-}
-
-template <class Traits>
-typename Traits::ElementType FixedTypedArray<Traits>::from(int value) {
- return static_cast<ElementType>(value);
-}
-
-template <>
-inline uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from(int value) {
- if (value < 0) return 0;
- if (value > 0xFF) return 0xFF;
- return static_cast<uint8_t>(value);
-}
-
-template <>
-inline int64_t FixedTypedArray<BigInt64ArrayTraits>::from(int value) {
- UNREACHABLE();
-}
-
-template <>
-inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::from(int value) {
- UNREACHABLE();
-}
-
-template <class Traits>
-typename Traits::ElementType FixedTypedArray<Traits>::from(uint32_t value) {
- return static_cast<ElementType>(value);
-}
-
-template <>
-inline uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from(uint32_t value) {
- // We need this special case for Uint32 -> Uint8Clamped, because the highest
- // Uint32 values will be negative as an int, clamping to 0, rather than 255.
- if (value > 0xFF) return 0xFF;
- return static_cast<uint8_t>(value);
-}
-
-template <>
-inline int64_t FixedTypedArray<BigInt64ArrayTraits>::from(uint32_t value) {
- UNREACHABLE();
-}
-
-template <>
-inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::from(uint32_t value) {
- UNREACHABLE();
-}
-
-template <class Traits>
-typename Traits::ElementType FixedTypedArray<Traits>::from(double value) {
- return static_cast<ElementType>(DoubleToInt32(value));
-}
-
-template <>
-inline uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from(double value) {
- // Handle NaNs and less than zero values which clamp to zero.
- if (!(value > 0)) return 0;
- if (value > 0xFF) return 0xFF;
- return static_cast<uint8_t>(lrint(value));
-}
-
-template <>
-inline int64_t FixedTypedArray<BigInt64ArrayTraits>::from(double value) {
- UNREACHABLE();
-}
-
-template <>
-inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::from(double value) {
- UNREACHABLE();
-}
-
-template <>
-inline float FixedTypedArray<Float32ArrayTraits>::from(double value) {
- using limits = std::numeric_limits<float>;
- if (value > limits::max()) return limits::infinity();
- if (value < limits::lowest()) return -limits::infinity();
- return static_cast<float>(value);
-}
-
-template <>
-inline double FixedTypedArray<Float64ArrayTraits>::from(double value) {
- return value;
-}
-
-template <class Traits>
-typename Traits::ElementType FixedTypedArray<Traits>::from(int64_t value) {
- UNREACHABLE();
-}
-
-template <class Traits>
-typename Traits::ElementType FixedTypedArray<Traits>::from(uint64_t value) {
- UNREACHABLE();
-}
-
-template <>
-inline int64_t FixedTypedArray<BigInt64ArrayTraits>::from(int64_t value) {
- return value;
-}
-
-template <>
-inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::from(uint64_t value) {
- return value;
-}
-
-template <>
-inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::from(int64_t value) {
- return static_cast<uint64_t>(value);
-}
-
-template <>
-inline int64_t FixedTypedArray<BigInt64ArrayTraits>::from(uint64_t value) {
- return static_cast<int64_t>(value);
-}
-
-template <class Traits>
-typename Traits::ElementType FixedTypedArray<Traits>::FromHandle(
- Handle<Object> value, bool* lossless) {
- if (value->IsSmi()) {
- return from(Smi::ToInt(*value));
- }
- DCHECK(value->IsHeapNumber());
- return from(HeapNumber::cast(*value)->value());
-}
-
-template <>
-inline int64_t FixedTypedArray<BigInt64ArrayTraits>::FromHandle(
- Handle<Object> value, bool* lossless) {
- DCHECK(value->IsBigInt());
- return BigInt::cast(*value)->AsInt64(lossless);
-}
-
-template <>
-inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::FromHandle(
- Handle<Object> value, bool* lossless) {
- DCHECK(value->IsBigInt());
- return BigInt::cast(*value)->AsUint64(lossless);
-}
-
-template <class Traits>
-Handle<Object> FixedTypedArray<Traits>::get(Isolate* isolate,
- FixedTypedArray<Traits> array,
- int index) {
- return Traits::ToHandle(isolate, array->get_scalar(index));
-}
-
-template <class Traits>
-void FixedTypedArray<Traits>::SetValue(uint32_t index, Object value) {
- ElementType cast_value = Traits::defaultValue();
- if (value->IsSmi()) {
- int int_value = Smi::ToInt(value);
- cast_value = from(int_value);
- } else if (value->IsHeapNumber()) {
- double double_value = HeapNumber::cast(value)->value();
- cast_value = from(double_value);
- } else {
- // Clamp undefined to the default value. All other types have been
- // converted to a number type further up in the call chain.
- DCHECK(value->IsUndefined());
- }
- set(index, cast_value);
-}
-
-template <>
-inline void FixedTypedArray<BigInt64ArrayTraits>::SetValue(uint32_t index,
- Object value) {
- DCHECK(value->IsBigInt());
- set(index, BigInt::cast(value)->AsInt64());
-}
-
-template <>
-inline void FixedTypedArray<BigUint64ArrayTraits>::SetValue(uint32_t index,
- Object value) {
- DCHECK(value->IsBigInt());
- set(index, BigInt::cast(value)->AsUint64());
-}
-
-Handle<Object> Uint8ArrayTraits::ToHandle(Isolate* isolate, uint8_t scalar) {
- return handle(Smi::FromInt(scalar), isolate);
-}
-
-Handle<Object> Uint8ClampedArrayTraits::ToHandle(Isolate* isolate,
- uint8_t scalar) {
- return handle(Smi::FromInt(scalar), isolate);
-}
-
-Handle<Object> Int8ArrayTraits::ToHandle(Isolate* isolate, int8_t scalar) {
- return handle(Smi::FromInt(scalar), isolate);
-}
-
-Handle<Object> Uint16ArrayTraits::ToHandle(Isolate* isolate, uint16_t scalar) {
- return handle(Smi::FromInt(scalar), isolate);
-}
-
-Handle<Object> Int16ArrayTraits::ToHandle(Isolate* isolate, int16_t scalar) {
- return handle(Smi::FromInt(scalar), isolate);
-}
-
-Handle<Object> Uint32ArrayTraits::ToHandle(Isolate* isolate, uint32_t scalar) {
- return isolate->factory()->NewNumberFromUint(scalar);
-}
-
-Handle<Object> Int32ArrayTraits::ToHandle(Isolate* isolate, int32_t scalar) {
- return isolate->factory()->NewNumberFromInt(scalar);
-}
-
-Handle<Object> Float32ArrayTraits::ToHandle(Isolate* isolate, float scalar) {
- return isolate->factory()->NewNumber(scalar);
-}
-
-Handle<Object> Float64ArrayTraits::ToHandle(Isolate* isolate, double scalar) {
- return isolate->factory()->NewNumber(scalar);
-}
-
-Handle<Object> BigInt64ArrayTraits::ToHandle(Isolate* isolate, int64_t scalar) {
- return BigInt::FromInt64(isolate, scalar);
-}
-
-Handle<Object> BigUint64ArrayTraits::ToHandle(Isolate* isolate,
- uint64_t scalar) {
- return BigInt::FromUint64(isolate, scalar);
-}
-
-// static
-template <class Traits>
-STATIC_CONST_MEMBER_DEFINITION const InstanceType
- FixedTypedArray<Traits>::kInstanceType;
-
-template <class Traits>
-FixedTypedArray<Traits>::FixedTypedArray(Address ptr)
- : FixedTypedArrayBase(ptr) {
- DCHECK(IsHeapObject() && map()->instance_type() == Traits::kInstanceType);
-}
-
-template <class Traits>
-FixedTypedArray<Traits> FixedTypedArray<Traits>::cast(Object object) {
- return FixedTypedArray<Traits>(object.ptr());
-}
-
int TemplateList::length() const {
- return Smi::ToInt(FixedArray::cast(*this)->get(kLengthIndex));
+ return Smi::ToInt(FixedArray::cast(*this).get(kLengthIndex));
}
Object TemplateList::get(int index) const {
- return FixedArray::cast(*this)->get(kFirstElementIndex + index);
+ return FixedArray::cast(*this).get(kFirstElementIndex + index);
}
void TemplateList::set(int index, Object value) {
- FixedArray::cast(*this)->set(kFirstElementIndex + index, value);
+ FixedArray::cast(*this).set(kFirstElementIndex + index, value);
}
} // namespace internal