4
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
5
6
6
#include < cinttypes>
7
+ #include < iostream>
7
8
#include " util-inl.h"
8
9
#include " v8.h"
9
10
10
11
namespace node {
11
12
13
+ typedef size_t AliasedBufferInfo;
14
+
12
15
/* *
13
16
* Do not use this class directly when creating instances of it - use the
14
17
* Aliased*Array defined at the end of this file instead.
@@ -26,27 +29,53 @@ namespace node {
26
29
* The encapsulation herein provides a placeholder where such writes can be
27
30
* observed. Any notification APIs will be left as a future exercise.
28
31
*/
32
+
29
33
template <class NativeT ,
30
34
class V8T ,
31
35
// SFINAE NativeT to be scalar
32
36
typename = std::enable_if_t <std::is_scalar<NativeT>::value>>
33
37
class AliasedBufferBase {
34
38
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 )
36
42
: isolate_(isolate), count_(count), byte_offset_(0 ) {
37
43
CHECK_GT (count, 0 );
38
44
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
+ }
41
63
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
+ }
46
68
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 ;
50
79
}
51
80
52
81
/* *
@@ -62,23 +91,29 @@ class AliasedBufferBase {
62
91
v8::Isolate* isolate,
63
92
const size_t byte_offset,
64
93
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 )
66
96
: isolate_(isolate), count_(count), byte_offset_(byte_offset) {
67
97
const v8::HandleScope handle_scope (isolate_);
68
98
69
- v8::Local<v8::ArrayBuffer> ab = backing_buffer.GetArrayBuffer ();
99
+ if (info == nullptr ) {
100
+ v8::Local<v8::ArrayBuffer> ab = backing_buffer.GetArrayBuffer ();
70
101
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_ );
76
107
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_ ));
79
110
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
+ }
82
117
}
83
118
84
119
AliasedBufferBase (const AliasedBufferBase& that)
@@ -90,6 +125,7 @@ class AliasedBufferBase {
90
125
}
91
126
92
127
AliasedBufferBase& operator =(AliasedBufferBase&& that) noexcept {
128
+ DCHECK_NULL (info_);
93
129
this ->~AliasedBufferBase ();
94
130
isolate_ = that.isolate_ ;
95
131
count_ = that.count_ ;
@@ -155,6 +191,7 @@ class AliasedBufferBase {
155
191
* Get the underlying v8 TypedArray overlayed on top of the native buffer
156
192
*/
157
193
v8::Local<V8T> GetJSArray () const {
194
+ DCHECK_NULL (info_);
158
195
return js_array_.Get (isolate_);
159
196
}
160
197
@@ -171,6 +208,7 @@ class AliasedBufferBase {
171
208
* through the GetValue/SetValue/operator[] methods
172
209
*/
173
210
inline const NativeT* GetNativeBuffer () const {
211
+ DCHECK_NULL (info_);
174
212
return buffer_;
175
213
}
176
214
@@ -186,13 +224,15 @@ class AliasedBufferBase {
186
224
*/
187
225
inline void SetValue (const size_t index, NativeT value) {
188
226
DCHECK_LT (index , count_);
227
+ DCHECK_NULL (info_);
189
228
buffer_[index ] = value;
190
229
}
191
230
192
231
/* *
193
232
* Get value at position index
194
233
*/
195
234
inline const NativeT GetValue (const size_t index) const {
235
+ DCHECK_NULL (info_);
196
236
DCHECK_LT (index , count_);
197
237
return buffer_[index ];
198
238
}
@@ -201,6 +241,7 @@ class AliasedBufferBase {
201
241
* Effectively, a synonym for GetValue/SetValue
202
242
*/
203
243
Reference operator [](size_t index) {
244
+ DCHECK_NULL (info_);
204
245
return Reference (this , index );
205
246
}
206
247
@@ -243,12 +284,22 @@ class AliasedBufferBase {
243
284
count_ = new_capacity;
244
285
}
245
286
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
+
246
295
private:
247
296
v8::Isolate* isolate_;
248
297
size_t count_;
249
298
size_t byte_offset_;
250
299
NativeT* buffer_;
251
300
v8::Global<V8T> js_array_;
301
+
302
+ const AliasedBufferInfo* info_ = nullptr ;
252
303
};
253
304
254
305
typedef AliasedBufferBase<int32_t , v8::Int32Array> AliasedInt32Array;
0 commit comments