44#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
55
66#include < cinttypes>
7+ #include < iostream>
78#include " util-inl.h"
89#include " v8.h"
910
1011namespace node {
1112
13+ typedef size_t AliasedBufferInfo;
14+
1215/* *
1316 * Do not use this class directly when creating instances of it - use the
1417 * Aliased*Array defined at the end of this file instead.
@@ -26,27 +29,53 @@ namespace node {
2629 * The encapsulation herein provides a placeholder where such writes can be
2730 * observed. Any notification APIs will be left as a future exercise.
2831 */
32+
2933template <class NativeT ,
3034 class V8T ,
3135 // SFINAE NativeT to be scalar
3236 typename = std::enable_if_t <std::is_scalar<NativeT>::value>>
3337class AliasedBufferBase {
3438 public:
35- AliasedBufferBase (v8::Isolate* isolate, const size_t count)
39+ AliasedBufferBase (v8::Isolate* isolate,
40+ const size_t count,
41+ const AliasedBufferInfo* info = nullptr )
3642 : isolate_(isolate), count_(count), byte_offset_(0 ) {
3743 CHECK_GT (count, 0 );
3844 const v8::HandleScope handle_scope (isolate_);
39- const size_t size_in_bytes =
40- MultiplyWithOverflowCheck (sizeof (NativeT), count);
45+ if (info == nullptr ) {
46+ CHECK_GT (count, 0 );
47+ const size_t size_in_bytes =
48+ MultiplyWithOverflowCheck (sizeof (NativeT), count);
49+
50+ // allocate v8 ArrayBuffer
51+ v8::Local<v8::ArrayBuffer> ab =
52+ v8::ArrayBuffer::New (isolate_, size_in_bytes);
53+ buffer_ = static_cast <NativeT*>(ab->GetBackingStore ()->Data ());
54+
55+ // allocate v8 TypedArray
56+ v8::Local<V8T> js_array = V8T::New (ab, byte_offset_, count);
57+ js_array_ = v8::Global<V8T>(isolate, js_array);
58+ } else {
59+ info_ = info;
60+ buffer_ = nullptr ;
61+ }
62+ }
4163
42- // allocate v8 ArrayBuffer
43- v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New (
44- isolate_, size_in_bytes );
45- buffer_ = static_cast <NativeT*>(ab-> GetBackingStore ()-> Data ());
64+ AliasedBufferInfo Serialize (v8::Local<v8::Context> context,
65+ v8::SnapshotCreator* creator) {
66+ return creator-> AddData (context, GetJSArray () );
67+ }
4668
47- // allocate v8 TypedArray
48- v8::Local<V8T> js_array = V8T::New (ab, byte_offset_, count);
49- js_array_ = v8::Global<V8T>(isolate, js_array);
69+ inline void Deserialize (v8::Local<v8::Context> context) {
70+ v8::Local<V8T> arr =
71+ context->GetDataFromSnapshotOnce <V8T>(*info_).ToLocalChecked ();
72+ CHECK_EQ (count_, arr->Length ());
73+ CHECK_EQ (byte_offset_, arr->ByteOffset ());
74+ uint8_t * raw =
75+ static_cast <uint8_t *>(arr->Buffer ()->GetBackingStore ()->Data ());
76+ buffer_ = reinterpret_cast <NativeT*>(raw + byte_offset_);
77+ js_array_.Reset (isolate_, arr);
78+ info_ = nullptr ;
5079 }
5180
5281 /* *
@@ -62,23 +91,29 @@ class AliasedBufferBase {
6291 v8::Isolate* isolate,
6392 const size_t byte_offset,
6493 const size_t count,
65- const AliasedBufferBase<uint8_t , v8::Uint8Array>& backing_buffer)
94+ const AliasedBufferBase<uint8_t , v8::Uint8Array>& backing_buffer,
95+ const AliasedBufferInfo* info = nullptr )
6696 : isolate_(isolate), count_(count), byte_offset_(byte_offset) {
6797 const v8::HandleScope handle_scope (isolate_);
6898
69- v8::Local<v8::ArrayBuffer> ab = backing_buffer.GetArrayBuffer ();
99+ if (info == nullptr ) {
100+ v8::Local<v8::ArrayBuffer> ab = backing_buffer.GetArrayBuffer ();
70101
71- // validate that the byte_offset is aligned with sizeof(NativeT)
72- CHECK_EQ (byte_offset & (sizeof (NativeT) - 1 ), 0 );
73- // validate this fits inside the backing buffer
74- CHECK_LE (MultiplyWithOverflowCheck (sizeof (NativeT), count ),
75- ab->ByteLength () - byte_offset );
102+ // validate that the byte_offset is aligned with sizeof(NativeT)
103+ CHECK_EQ (byte_offset_ & (sizeof (NativeT) - 1 ), 0 );
104+ // validate this fits inside the backing buffer
105+ CHECK_LE (MultiplyWithOverflowCheck (sizeof (NativeT), count_ ),
106+ ab->ByteLength () - byte_offset_ );
76107
77- buffer_ = reinterpret_cast <NativeT*>(
78- const_cast < uint8_t *>( backing_buffer.GetNativeBuffer () + byte_offset ));
108+ buffer_ = reinterpret_cast <NativeT*>( const_cast < uint8_t *>(
109+ backing_buffer.GetNativeBuffer () + byte_offset_ ));
79110
80- v8::Local<V8T> js_array = V8T::New (ab, byte_offset, count);
81- js_array_ = v8::Global<V8T>(isolate, js_array);
111+ v8::Local<V8T> js_array = V8T::New (ab, byte_offset_, count_);
112+ js_array_ = v8::Global<V8T>(isolate_, js_array);
113+ } else {
114+ info_ = info;
115+ buffer_ = nullptr ;
116+ }
82117 }
83118
84119 AliasedBufferBase (const AliasedBufferBase& that)
@@ -90,6 +125,7 @@ class AliasedBufferBase {
90125 }
91126
92127 AliasedBufferBase& operator =(AliasedBufferBase&& that) noexcept {
128+ DCHECK_NULL (info_);
93129 this ->~AliasedBufferBase ();
94130 isolate_ = that.isolate_ ;
95131 count_ = that.count_ ;
@@ -155,6 +191,7 @@ class AliasedBufferBase {
155191 * Get the underlying v8 TypedArray overlayed on top of the native buffer
156192 */
157193 v8::Local<V8T> GetJSArray () const {
194+ DCHECK_NULL (info_);
158195 return js_array_.Get (isolate_);
159196 }
160197
@@ -171,6 +208,7 @@ class AliasedBufferBase {
171208 * through the GetValue/SetValue/operator[] methods
172209 */
173210 inline const NativeT* GetNativeBuffer () const {
211+ DCHECK_NULL (info_);
174212 return buffer_;
175213 }
176214
@@ -186,13 +224,15 @@ class AliasedBufferBase {
186224 */
187225 inline void SetValue (const size_t index, NativeT value) {
188226 DCHECK_LT (index, count_);
227+ DCHECK_NULL (info_);
189228 buffer_[index] = value;
190229 }
191230
192231 /* *
193232 * Get value at position index
194233 */
195234 inline const NativeT GetValue (const size_t index) const {
235+ DCHECK_NULL (info_);
196236 DCHECK_LT (index, count_);
197237 return buffer_[index];
198238 }
@@ -201,6 +241,7 @@ class AliasedBufferBase {
201241 * Effectively, a synonym for GetValue/SetValue
202242 */
203243 Reference operator [](size_t index) {
244+ DCHECK_NULL (info_);
204245 return Reference (this , index);
205246 }
206247
@@ -243,12 +284,22 @@ class AliasedBufferBase {
243284 count_ = new_capacity;
244285 }
245286
287+ void Print () {
288+ std::cout << " [ " ;
289+ for (size_t i = 0 ; i < count_; ++i) {
290+ std::cout << std::to_string (buffer_[i])
291+ << (i == count_ - 1 ? " ]\n " : " , " );
292+ }
293+ }
294+
246295 private:
247296 v8::Isolate* isolate_;
248297 size_t count_;
249298 size_t byte_offset_;
250299 NativeT* buffer_;
251300 v8::Global<V8T> js_array_;
301+
302+ const AliasedBufferInfo* info_ = nullptr ;
252303};
253304
254305typedef AliasedBufferBase<int32_t , v8::Int32Array> AliasedInt32Array;
0 commit comments