Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/nodejs/src/aliased_buffer.h
1 #ifndef SRC_ALIASED_BUFFER_H_ 2 #define SRC_ALIASED_BUFFER_H_ 3 4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 5 6 #include <cinttypes> 7 #include "memory_tracker.h" 8 #include "v8.h" 9 10 namespace node { 11 12 typedef size_t AliasedBufferIndex; 13 14 /** 15 * Do not use this class directly when creating instances of it - use the 16 * Aliased*Array defined at the end of this file instead. 17 * 18 * This class encapsulates the technique of having a native buffer mapped to 19 * a JS object. Writes to the native buffer can happen efficiently without 20 * going through JS, and the data is then available to user's via the exposed 21 * JS object. 22 * 23 * While this technique is computationally efficient, it is effectively a 24 * write to JS program state w/out going through the standard 25 * (monitored) API. Thus, any VM capabilities to detect the modification are 26 * circumvented. 27 * 28 * The encapsulation herein provides a placeholder where such writes can be 29 * observed. Any notification APIs will be left as a future exercise. 30 */ 31 template <class NativeT, class V8T> 32 class AliasedBufferBase final : public MemoryRetainer { 33 public: 34 static_assert(std::is_scalar_v<NativeT>); 35 36 AliasedBufferBase(v8::Isolate* isolate, 37 size_t count, 38 const AliasedBufferIndex* index = nullptr); 39 40 /** 41 * Create an AliasedBufferBase over a sub-region of another aliased buffer. 42 * The two will share a v8::ArrayBuffer instance & 43 * a native buffer, but will each read/write to different sections of the 44 * native buffer. 45 * 46 * Note that byte_offset must be aligned by sizeof(NativeT). 47 */ 48 // TODO(refack): refactor into a non-owning `AliasedBufferBaseView` 49 AliasedBufferBase( 50 v8::Isolate* isolate, 51 size_t byte_offset, 52 size_t count, 53 const AliasedBufferBase<uint8_t, v8::Uint8Array>& backing_buffer, 54 const AliasedBufferIndex* index = nullptr); 55 56 AliasedBufferBase(const AliasedBufferBase& that); 57 58 AliasedBufferIndex Serialize(v8::Local<v8::Context> context, 59 v8::SnapshotCreator* creator); 60 61 void Deserialize(v8::Local<v8::Context> context); 62 63 AliasedBufferBase& operator=(AliasedBufferBase&& that) noexcept; 64 65 /** 66 * Helper class that is returned from operator[] to support assignment into 67 * a specified location. 68 */ 69 class Reference { 70 public: 71 Reference(AliasedBufferBase* aliased_buffer, const size_t index) 72 : aliased_buffer_(aliased_buffer), index_(index) {} 73 74 Reference(const Reference& that) 75 : aliased_buffer_(that.aliased_buffer_), 76 index_(that.index_) { 77 } 78 79 Reference& operator=(const NativeT& val) { 80 aliased_buffer_->SetValue(index_, val); 81 return *this; 82 } 83 84 Reference& operator=(const Reference& val) { 85 return *this = static_cast<NativeT>(val); 86 } 87 88 operator NativeT() const { 89 return aliased_buffer_->GetValue(index_); 90 } 91 92 Reference& operator+=(const NativeT& val) { 93 const NativeT current = aliased_buffer_->GetValue(index_); 94 aliased_buffer_->SetValue(index_, current + val); 95 return *this; 96 } 97 98 Reference& operator+=(const Reference& val) { 99 return this->operator+=(static_cast<NativeT>(val)); 100 } 101 102 Reference& operator-=(const NativeT& val) { 103 const NativeT current = aliased_buffer_->GetValue(index_); 104 aliased_buffer_->SetValue(index_, current - val); 105 return *this; 106 } 107 108 private: 109 AliasedBufferBase* aliased_buffer_; 110 size_t index_; 111 }; 112 113 /** 114 * Get the underlying v8 TypedArray overlaid on top of the native buffer 115 */ 116 v8::Local<V8T> GetJSArray() const; 117 118 void Release(); 119 120 /** 121 * Make the global reference to the typed array weak. The caller must make 122 * sure that no operation can be done on the AliasedBuffer when the typed 123 * array becomes unreachable. Usually this means the caller must maintain 124 * a JS reference to the typed array from JS object. 125 */ 126 void MakeWeak(); 127 128 /** 129 * Get the underlying v8::ArrayBuffer underlying the TypedArray and 130 * overlaying the native buffer 131 */ 132 v8::Local<v8::ArrayBuffer> GetArrayBuffer() const; 133 134 /** 135 * Get the underlying native buffer. Note that all reads/writes should occur 136 * through the GetValue/SetValue/operator[] methods 137 */ 138 const NativeT* GetNativeBuffer() const; 139 140 /** 141 * Synonym for GetBuffer() 142 */ 143 const NativeT* operator*() const; 144 145 /** 146 * Set position index to given value. 147 */ 148 void SetValue(size_t index, NativeT value); 149 150 /** 151 * Get value at position index 152 */ 153 const NativeT GetValue(size_t index) const; 154 155 /** 156 * Effectively, a synonym for GetValue/SetValue 157 */ 158 Reference operator[](size_t index); 159 160 NativeT operator[](size_t index) const; 161 162 size_t Length() const; 163 164 // Should only be used to extend the array. 165 // Should only be used on an owning array, not one created as a sub array of 166 // an owning `AliasedBufferBase`. 167 void reserve(size_t new_capacity); 168 169 size_t SelfSize() const override; 170 171 const char* MemoryInfoName() const override; 172 void MemoryInfo(MemoryTracker* tracker) const override; 173 174 private: 175 bool is_valid() const; 176 v8::Isolate* isolate_ = nullptr; 177 size_t count_ = 0; 178 size_t byte_offset_ = 0; 179 NativeT* buffer_ = nullptr; 180 v8::Global<V8T> js_array_; 181 182 // Deserialize data 183 const AliasedBufferIndex* index_ = nullptr; 184 }; 185 186 #define ALIASED_BUFFER_LIST(V) \ 187 V(int8_t, Int8Array) \ 188 V(uint8_t, Uint8Array) \ 189 V(int16_t, Int16Array) \ 190 V(uint16_t, Uint16Array) \ 191 V(int32_t, Int32Array) \ 192 V(uint32_t, Uint32Array) \ 193 V(float, Float32Array) \ 194 V(double, Float64Array) \ 195 V(int64_t, BigInt64Array) 196 197 #define V(NativeT, V8T) \ 198 typedef AliasedBufferBase<NativeT, v8::V8T> Aliased##V8T; 199 ALIASED_BUFFER_LIST(V) 200 #undef V 201 202 } // namespace node 203 204 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 205 206 #endif // SRC_ALIASED_BUFFER_H_