Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/nodejs/src/aliased_buffer-inl.h
1 #ifndef SRC_ALIASED_BUFFER_INL_H_ 2 #define SRC_ALIASED_BUFFER_INL_H_ 3 4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 5 6 #include "aliased_buffer.h" 7 #include "memory_tracker-inl.h" 8 #include "util-inl.h" 9 10 namespace node { 11 12 typedef size_t AliasedBufferIndex; 13 14 template <typename NativeT, typename V8T> 15 AliasedBufferBase<NativeT, V8T>::AliasedBufferBase( 16 v8::Isolate* isolate, const size_t count, const AliasedBufferIndex* index) 17 : isolate_(isolate), count_(count), byte_offset_(0), index_(index) { 18 CHECK_GT(count, 0); 19 if (index != nullptr) { 20 // Will be deserialized later. 21 return; 22 } 23 const v8::HandleScope handle_scope(isolate_); 24 const size_t size_in_bytes = 25 MultiplyWithOverflowCheck(sizeof(NativeT), count); 26 27 // allocate v8 ArrayBuffer 28 v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate_, size_in_bytes); 29 buffer_ = static_cast<NativeT*>(ab->Data()); 30 31 // allocate v8 TypedArray 32 v8::Local<V8T> js_array = V8T::New(ab, byte_offset_, count); 33 js_array_ = v8::Global<V8T>(isolate, js_array); 34 } 35 36 template <typename NativeT, typename V8T> 37 AliasedBufferBase<NativeT, V8T>::AliasedBufferBase( 38 v8::Isolate* isolate, 39 const size_t byte_offset, 40 const size_t count, 41 const AliasedBufferBase<uint8_t, v8::Uint8Array>& backing_buffer, 42 const AliasedBufferIndex* index) 43 : isolate_(isolate), 44 count_(count), 45 byte_offset_(byte_offset), 46 index_(index) { 47 if (index != nullptr) { 48 // Will be deserialized later. 49 return; 50 } 51 const v8::HandleScope handle_scope(isolate_); 52 v8::Local<v8::ArrayBuffer> ab = backing_buffer.GetArrayBuffer(); 53 54 // validate that the byte_offset is aligned with sizeof(NativeT) 55 CHECK_EQ(byte_offset & (sizeof(NativeT) - 1), 0); 56 // validate this fits inside the backing buffer 57 CHECK_LE(MultiplyWithOverflowCheck(sizeof(NativeT), count), 58 ab->ByteLength() - byte_offset); 59 60 buffer_ = reinterpret_cast<NativeT*>( 61 const_cast<uint8_t*>(backing_buffer.GetNativeBuffer() + byte_offset)); 62 63 v8::Local<V8T> js_array = V8T::New(ab, byte_offset, count); 64 js_array_ = v8::Global<V8T>(isolate, js_array); 65 } 66 67 template <typename NativeT, typename V8T> 68 AliasedBufferBase<NativeT, V8T>::AliasedBufferBase( 69 const AliasedBufferBase& that) 70 : isolate_(that.isolate_), 71 count_(that.count_), 72 byte_offset_(that.byte_offset_), 73 buffer_(that.buffer_) { 74 js_array_ = v8::Global<V8T>(that.isolate_, that.GetJSArray()); 75 DCHECK(is_valid()); 76 } 77 78 template <typename NativeT, typename V8T> 79 AliasedBufferIndex AliasedBufferBase<NativeT, V8T>::Serialize( 80 v8::Local<v8::Context> context, v8::SnapshotCreator* creator) { 81 DCHECK(is_valid()); 82 return creator->AddData(context, GetJSArray()); 83 } 84 85 template <typename NativeT, typename V8T> 86 inline void AliasedBufferBase<NativeT, V8T>::Deserialize( 87 v8::Local<v8::Context> context) { 88 DCHECK_NOT_NULL(index_); 89 v8::Local<V8T> arr = 90 context->GetDataFromSnapshotOnce<V8T>(*index_).ToLocalChecked(); 91 // These may not hold true for AliasedBuffers that have grown, so should 92 // be removed when we expand the snapshot support. 93 DCHECK_EQ(count_, arr->Length()); 94 DCHECK_EQ(byte_offset_, arr->ByteOffset()); 95 uint8_t* raw = static_cast<uint8_t*>(arr->Buffer()->Data()); 96 buffer_ = reinterpret_cast<NativeT*>(raw + byte_offset_); 97 js_array_.Reset(isolate_, arr); 98 index_ = nullptr; 99 } 100 101 template <typename NativeT, typename V8T> 102 AliasedBufferBase<NativeT, V8T>& AliasedBufferBase<NativeT, V8T>::operator=( 103 AliasedBufferBase<NativeT, V8T>&& that) noexcept { 104 DCHECK(is_valid()); 105 this->~AliasedBufferBase(); 106 isolate_ = that.isolate_; 107 count_ = that.count_; 108 byte_offset_ = that.byte_offset_; 109 buffer_ = that.buffer_; 110 111 js_array_.Reset(isolate_, that.js_array_.Get(isolate_)); 112 113 that.buffer_ = nullptr; 114 that.js_array_.Reset(); 115 return *this; 116 } 117 118 template <typename NativeT, typename V8T> 119 v8::Local<V8T> AliasedBufferBase<NativeT, V8T>::GetJSArray() const { 120 DCHECK(is_valid()); 121 return js_array_.Get(isolate_); 122 } 123 124 template <typename NativeT, typename V8T> 125 void AliasedBufferBase<NativeT, V8T>::Release() { 126 DCHECK_NULL(index_); 127 js_array_.Reset(); 128 } 129 130 template <typename NativeT, typename V8T> 131 inline void AliasedBufferBase<NativeT, V8T>::MakeWeak() { 132 DCHECK(is_valid()); 133 js_array_.SetWeak(); 134 } 135 136 template <typename NativeT, typename V8T> 137 v8::Local<v8::ArrayBuffer> AliasedBufferBase<NativeT, V8T>::GetArrayBuffer() 138 const { 139 return GetJSArray()->Buffer(); 140 } 141 142 template <typename NativeT, typename V8T> 143 inline const NativeT* AliasedBufferBase<NativeT, V8T>::GetNativeBuffer() const { 144 DCHECK(is_valid()); 145 return buffer_; 146 } 147 148 template <typename NativeT, typename V8T> 149 inline const NativeT* AliasedBufferBase<NativeT, V8T>::operator*() const { 150 return GetNativeBuffer(); 151 } 152 153 template <typename NativeT, typename V8T> 154 inline void AliasedBufferBase<NativeT, V8T>::SetValue(const size_t index, 155 NativeT value) { 156 DCHECK_LT(index, count_); 157 DCHECK(is_valid()); 158 buffer_[index] = value; 159 } 160 161 template <typename NativeT, typename V8T> 162 inline const NativeT AliasedBufferBase<NativeT, V8T>::GetValue( 163 const size_t index) const { 164 DCHECK(is_valid()); 165 DCHECK_LT(index, count_); 166 return buffer_[index]; 167 } 168 169 template <typename NativeT, typename V8T> 170 typename AliasedBufferBase<NativeT, V8T>::Reference 171 AliasedBufferBase<NativeT, V8T>::operator[](size_t index) { 172 DCHECK(is_valid()); 173 return Reference(this, index); 174 } 175 176 template <typename NativeT, typename V8T> 177 NativeT AliasedBufferBase<NativeT, V8T>::operator[](size_t index) const { 178 return GetValue(index); 179 } 180 181 template <typename NativeT, typename V8T> 182 size_t AliasedBufferBase<NativeT, V8T>::Length() const { 183 return count_; 184 } 185 186 template <typename NativeT, typename V8T> 187 void AliasedBufferBase<NativeT, V8T>::reserve(size_t new_capacity) { 188 DCHECK(is_valid()); 189 DCHECK_GE(new_capacity, count_); 190 DCHECK_EQ(byte_offset_, 0); 191 const v8::HandleScope handle_scope(isolate_); 192 193 const size_t old_size_in_bytes = sizeof(NativeT) * count_; 194 const size_t new_size_in_bytes = 195 MultiplyWithOverflowCheck(sizeof(NativeT), new_capacity); 196 197 // allocate v8 new ArrayBuffer 198 v8::Local<v8::ArrayBuffer> ab = 199 v8::ArrayBuffer::New(isolate_, new_size_in_bytes); 200 201 // allocate new native buffer 202 NativeT* new_buffer = static_cast<NativeT*>(ab->Data()); 203 // copy old content 204 memcpy(new_buffer, buffer_, old_size_in_bytes); 205 206 // allocate v8 TypedArray 207 v8::Local<V8T> js_array = V8T::New(ab, byte_offset_, new_capacity); 208 209 // move over old v8 TypedArray 210 js_array_ = std::move(v8::Global<V8T>(isolate_, js_array)); 211 212 buffer_ = new_buffer; 213 count_ = new_capacity; 214 } 215 216 template <typename NativeT, typename V8T> 217 inline bool AliasedBufferBase<NativeT, V8T>::is_valid() const { 218 return index_ == nullptr && !js_array_.IsEmpty(); 219 } 220 221 template <typename NativeT, typename V8T> 222 inline size_t AliasedBufferBase<NativeT, V8T>::SelfSize() const { 223 return sizeof(*this); 224 } 225 226 #define VM(NativeT, V8T) \ 227 template <> \ 228 inline const char* AliasedBufferBase<NativeT, v8::V8T>::MemoryInfoName() \ 229 const { \ 230 return "Aliased" #V8T; \ 231 } \ 232 template <> \ 233 inline void AliasedBufferBase<NativeT, v8::V8T>::MemoryInfo( \ 234 node::MemoryTracker* tracker) const { \ 235 tracker->TrackField("js_array", js_array_); \ 236 } 237 ALIASED_BUFFER_LIST(VM) 238 #undef VM 239 240 } // namespace node 241 242 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 243 244 #endif // SRC_ALIASED_BUFFER_INL_H_