11cb0ef41Sopenharmony_ci#ifndef SRC_ALIASED_BUFFER_INL_H_ 21cb0ef41Sopenharmony_ci#define SRC_ALIASED_BUFFER_INL_H_ 31cb0ef41Sopenharmony_ci 41cb0ef41Sopenharmony_ci#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ci#include "aliased_buffer.h" 71cb0ef41Sopenharmony_ci#include "util-inl.h" 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_cinamespace node { 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_citypedef size_t AliasedBufferIndex; 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 141cb0ef41Sopenharmony_ciAliasedBufferBase<NativeT, V8T>::AliasedBufferBase( 151cb0ef41Sopenharmony_ci v8::Isolate* isolate, const size_t count, const AliasedBufferIndex* index) 161cb0ef41Sopenharmony_ci : isolate_(isolate), count_(count), byte_offset_(0), index_(index) { 171cb0ef41Sopenharmony_ci CHECK_GT(count, 0); 181cb0ef41Sopenharmony_ci if (index != nullptr) { 191cb0ef41Sopenharmony_ci // Will be deserialized later. 201cb0ef41Sopenharmony_ci return; 211cb0ef41Sopenharmony_ci } 221cb0ef41Sopenharmony_ci const v8::HandleScope handle_scope(isolate_); 231cb0ef41Sopenharmony_ci const size_t size_in_bytes = 241cb0ef41Sopenharmony_ci MultiplyWithOverflowCheck(sizeof(NativeT), count); 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci // allocate v8 ArrayBuffer 271cb0ef41Sopenharmony_ci v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate_, size_in_bytes); 281cb0ef41Sopenharmony_ci buffer_ = static_cast<NativeT*>(ab->Data()); 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ci // allocate v8 TypedArray 311cb0ef41Sopenharmony_ci v8::Local<V8T> js_array = V8T::New(ab, byte_offset_, count); 321cb0ef41Sopenharmony_ci js_array_ = v8::Global<V8T>(isolate, js_array); 331cb0ef41Sopenharmony_ci} 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 361cb0ef41Sopenharmony_ciAliasedBufferBase<NativeT, V8T>::AliasedBufferBase( 371cb0ef41Sopenharmony_ci v8::Isolate* isolate, 381cb0ef41Sopenharmony_ci const size_t byte_offset, 391cb0ef41Sopenharmony_ci const size_t count, 401cb0ef41Sopenharmony_ci const AliasedBufferBase<uint8_t, v8::Uint8Array>& backing_buffer, 411cb0ef41Sopenharmony_ci const AliasedBufferIndex* index) 421cb0ef41Sopenharmony_ci : isolate_(isolate), 431cb0ef41Sopenharmony_ci count_(count), 441cb0ef41Sopenharmony_ci byte_offset_(byte_offset), 451cb0ef41Sopenharmony_ci index_(index) { 461cb0ef41Sopenharmony_ci if (index != nullptr) { 471cb0ef41Sopenharmony_ci // Will be deserialized later. 481cb0ef41Sopenharmony_ci return; 491cb0ef41Sopenharmony_ci } 501cb0ef41Sopenharmony_ci const v8::HandleScope handle_scope(isolate_); 511cb0ef41Sopenharmony_ci v8::Local<v8::ArrayBuffer> ab = backing_buffer.GetArrayBuffer(); 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci // validate that the byte_offset is aligned with sizeof(NativeT) 541cb0ef41Sopenharmony_ci CHECK_EQ(byte_offset & (sizeof(NativeT) - 1), 0); 551cb0ef41Sopenharmony_ci // validate this fits inside the backing buffer 561cb0ef41Sopenharmony_ci CHECK_LE(MultiplyWithOverflowCheck(sizeof(NativeT), count), 571cb0ef41Sopenharmony_ci ab->ByteLength() - byte_offset); 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci buffer_ = reinterpret_cast<NativeT*>( 601cb0ef41Sopenharmony_ci const_cast<uint8_t*>(backing_buffer.GetNativeBuffer() + byte_offset)); 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ci v8::Local<V8T> js_array = V8T::New(ab, byte_offset, count); 631cb0ef41Sopenharmony_ci js_array_ = v8::Global<V8T>(isolate, js_array); 641cb0ef41Sopenharmony_ci} 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 671cb0ef41Sopenharmony_ciAliasedBufferBase<NativeT, V8T>::AliasedBufferBase( 681cb0ef41Sopenharmony_ci const AliasedBufferBase& that) 691cb0ef41Sopenharmony_ci : isolate_(that.isolate_), 701cb0ef41Sopenharmony_ci count_(that.count_), 711cb0ef41Sopenharmony_ci byte_offset_(that.byte_offset_), 721cb0ef41Sopenharmony_ci buffer_(that.buffer_) { 731cb0ef41Sopenharmony_ci DCHECK_NULL(index_); 741cb0ef41Sopenharmony_ci js_array_ = v8::Global<V8T>(that.isolate_, that.GetJSArray()); 751cb0ef41Sopenharmony_ci} 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 781cb0ef41Sopenharmony_ciAliasedBufferIndex AliasedBufferBase<NativeT, V8T>::Serialize( 791cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, v8::SnapshotCreator* creator) { 801cb0ef41Sopenharmony_ci DCHECK_NULL(index_); 811cb0ef41Sopenharmony_ci return creator->AddData(context, GetJSArray()); 821cb0ef41Sopenharmony_ci} 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 851cb0ef41Sopenharmony_ciinline void AliasedBufferBase<NativeT, V8T>::Deserialize( 861cb0ef41Sopenharmony_ci v8::Local<v8::Context> context) { 871cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(index_); 881cb0ef41Sopenharmony_ci v8::Local<V8T> arr = 891cb0ef41Sopenharmony_ci context->GetDataFromSnapshotOnce<V8T>(*index_).ToLocalChecked(); 901cb0ef41Sopenharmony_ci // These may not hold true for AliasedBuffers that have grown, so should 911cb0ef41Sopenharmony_ci // be removed when we expand the snapshot support. 921cb0ef41Sopenharmony_ci DCHECK_EQ(count_, arr->Length()); 931cb0ef41Sopenharmony_ci DCHECK_EQ(byte_offset_, arr->ByteOffset()); 941cb0ef41Sopenharmony_ci uint8_t* raw = static_cast<uint8_t*>(arr->Buffer()->Data()); 951cb0ef41Sopenharmony_ci buffer_ = reinterpret_cast<NativeT*>(raw + byte_offset_); 961cb0ef41Sopenharmony_ci js_array_.Reset(isolate_, arr); 971cb0ef41Sopenharmony_ci index_ = nullptr; 981cb0ef41Sopenharmony_ci} 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 1011cb0ef41Sopenharmony_ciAliasedBufferBase<NativeT, V8T>& AliasedBufferBase<NativeT, V8T>::operator=( 1021cb0ef41Sopenharmony_ci AliasedBufferBase<NativeT, V8T>&& that) noexcept { 1031cb0ef41Sopenharmony_ci DCHECK_NULL(index_); 1041cb0ef41Sopenharmony_ci this->~AliasedBufferBase(); 1051cb0ef41Sopenharmony_ci isolate_ = that.isolate_; 1061cb0ef41Sopenharmony_ci count_ = that.count_; 1071cb0ef41Sopenharmony_ci byte_offset_ = that.byte_offset_; 1081cb0ef41Sopenharmony_ci buffer_ = that.buffer_; 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci js_array_.Reset(isolate_, that.js_array_.Get(isolate_)); 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci that.buffer_ = nullptr; 1131cb0ef41Sopenharmony_ci that.js_array_.Reset(); 1141cb0ef41Sopenharmony_ci return *this; 1151cb0ef41Sopenharmony_ci} 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 1181cb0ef41Sopenharmony_civ8::Local<V8T> AliasedBufferBase<NativeT, V8T>::GetJSArray() const { 1191cb0ef41Sopenharmony_ci DCHECK_NULL(index_); 1201cb0ef41Sopenharmony_ci return js_array_.Get(isolate_); 1211cb0ef41Sopenharmony_ci} 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 1241cb0ef41Sopenharmony_civoid AliasedBufferBase<NativeT, V8T>::Release() { 1251cb0ef41Sopenharmony_ci DCHECK_NULL(index_); 1261cb0ef41Sopenharmony_ci js_array_.Reset(); 1271cb0ef41Sopenharmony_ci} 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 1301cb0ef41Sopenharmony_civ8::Local<v8::ArrayBuffer> AliasedBufferBase<NativeT, V8T>::GetArrayBuffer() 1311cb0ef41Sopenharmony_ci const { 1321cb0ef41Sopenharmony_ci return GetJSArray()->Buffer(); 1331cb0ef41Sopenharmony_ci} 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 1361cb0ef41Sopenharmony_ciinline const NativeT* AliasedBufferBase<NativeT, V8T>::GetNativeBuffer() const { 1371cb0ef41Sopenharmony_ci DCHECK_NULL(index_); 1381cb0ef41Sopenharmony_ci return buffer_; 1391cb0ef41Sopenharmony_ci} 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 1421cb0ef41Sopenharmony_ciinline const NativeT* AliasedBufferBase<NativeT, V8T>::operator*() const { 1431cb0ef41Sopenharmony_ci return GetNativeBuffer(); 1441cb0ef41Sopenharmony_ci} 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 1471cb0ef41Sopenharmony_ciinline void AliasedBufferBase<NativeT, V8T>::SetValue(const size_t index, 1481cb0ef41Sopenharmony_ci NativeT value) { 1491cb0ef41Sopenharmony_ci DCHECK_LT(index, count_); 1501cb0ef41Sopenharmony_ci DCHECK_NULL(index_); 1511cb0ef41Sopenharmony_ci buffer_[index] = value; 1521cb0ef41Sopenharmony_ci} 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 1551cb0ef41Sopenharmony_ciinline const NativeT AliasedBufferBase<NativeT, V8T>::GetValue( 1561cb0ef41Sopenharmony_ci const size_t index) const { 1571cb0ef41Sopenharmony_ci DCHECK_NULL(index_); 1581cb0ef41Sopenharmony_ci DCHECK_LT(index, count_); 1591cb0ef41Sopenharmony_ci return buffer_[index]; 1601cb0ef41Sopenharmony_ci} 1611cb0ef41Sopenharmony_ci 1621cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 1631cb0ef41Sopenharmony_citypename AliasedBufferBase<NativeT, V8T>::Reference 1641cb0ef41Sopenharmony_ciAliasedBufferBase<NativeT, V8T>::operator[](size_t index) { 1651cb0ef41Sopenharmony_ci DCHECK_NULL(index_); 1661cb0ef41Sopenharmony_ci return Reference(this, index); 1671cb0ef41Sopenharmony_ci} 1681cb0ef41Sopenharmony_ci 1691cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 1701cb0ef41Sopenharmony_ciNativeT AliasedBufferBase<NativeT, V8T>::operator[](size_t index) const { 1711cb0ef41Sopenharmony_ci return GetValue(index); 1721cb0ef41Sopenharmony_ci} 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 1751cb0ef41Sopenharmony_cisize_t AliasedBufferBase<NativeT, V8T>::Length() const { 1761cb0ef41Sopenharmony_ci return count_; 1771cb0ef41Sopenharmony_ci} 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 1801cb0ef41Sopenharmony_civoid AliasedBufferBase<NativeT, V8T>::reserve(size_t new_capacity) { 1811cb0ef41Sopenharmony_ci DCHECK_NULL(index_); 1821cb0ef41Sopenharmony_ci DCHECK_GE(new_capacity, count_); 1831cb0ef41Sopenharmony_ci DCHECK_EQ(byte_offset_, 0); 1841cb0ef41Sopenharmony_ci const v8::HandleScope handle_scope(isolate_); 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_ci const size_t old_size_in_bytes = sizeof(NativeT) * count_; 1871cb0ef41Sopenharmony_ci const size_t new_size_in_bytes = 1881cb0ef41Sopenharmony_ci MultiplyWithOverflowCheck(sizeof(NativeT), new_capacity); 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ci // allocate v8 new ArrayBuffer 1911cb0ef41Sopenharmony_ci v8::Local<v8::ArrayBuffer> ab = 1921cb0ef41Sopenharmony_ci v8::ArrayBuffer::New(isolate_, new_size_in_bytes); 1931cb0ef41Sopenharmony_ci 1941cb0ef41Sopenharmony_ci // allocate new native buffer 1951cb0ef41Sopenharmony_ci NativeT* new_buffer = static_cast<NativeT*>(ab->Data()); 1961cb0ef41Sopenharmony_ci // copy old content 1971cb0ef41Sopenharmony_ci memcpy(new_buffer, buffer_, old_size_in_bytes); 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_ci // allocate v8 TypedArray 2001cb0ef41Sopenharmony_ci v8::Local<V8T> js_array = V8T::New(ab, byte_offset_, new_capacity); 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ci // move over old v8 TypedArray 2031cb0ef41Sopenharmony_ci js_array_ = std::move(v8::Global<V8T>(isolate_, js_array)); 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_ci buffer_ = new_buffer; 2061cb0ef41Sopenharmony_ci count_ = new_capacity; 2071cb0ef41Sopenharmony_ci} 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_citemplate <typename NativeT, typename V8T> 2101cb0ef41Sopenharmony_ciinline size_t AliasedBufferBase<NativeT, V8T>::SelfSize() const { 2111cb0ef41Sopenharmony_ci return sizeof(*this); 2121cb0ef41Sopenharmony_ci} 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ci#define VM(NativeT, V8T) \ 2151cb0ef41Sopenharmony_ci template <> \ 2161cb0ef41Sopenharmony_ci inline const char* AliasedBufferBase<NativeT, v8::V8T>::MemoryInfoName() \ 2171cb0ef41Sopenharmony_ci const { \ 2181cb0ef41Sopenharmony_ci return "Aliased" #V8T; \ 2191cb0ef41Sopenharmony_ci } \ 2201cb0ef41Sopenharmony_ci template <> \ 2211cb0ef41Sopenharmony_ci inline void AliasedBufferBase<NativeT, v8::V8T>::MemoryInfo( \ 2221cb0ef41Sopenharmony_ci node::MemoryTracker* tracker) const { \ 2231cb0ef41Sopenharmony_ci tracker->TrackField("js_array", js_array_); \ 2241cb0ef41Sopenharmony_ci } 2251cb0ef41Sopenharmony_ciALIASED_BUFFER_LIST(VM) 2261cb0ef41Sopenharmony_ci#undef VM 2271cb0ef41Sopenharmony_ci 2281cb0ef41Sopenharmony_ci} // namespace node 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_ci#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 2311cb0ef41Sopenharmony_ci 2321cb0ef41Sopenharmony_ci#endif // SRC_ALIASED_BUFFER_INL_H_ 233