44#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
55
66#include " v8.h"
7- #include " util-inl .h"
7+ #include " util.h"
88
99namespace node {
1010
@@ -22,7 +22,9 @@ namespace node {
2222 * The encapsulation herein provides a placeholder where such writes can be
2323 * observed. Any notification APIs will be left as a future exercise.
2424 */
25- template <class NativeT , class V8T >
25+ template <class NativeT , class V8T ,
26+ // SFINAE NativeT to be scalar
27+ typename = std::enable_if_t <std::is_scalar<NativeT>::value>>
2628class AliasedBuffer {
2729 public:
2830 AliasedBuffer (v8::Isolate* isolate, const size_t count)
@@ -33,14 +35,14 @@ class AliasedBuffer {
3335 CHECK_GT (count, 0 );
3436 const v8::HandleScope handle_scope (isolate_);
3537
36- const size_t sizeInBytes = sizeof (NativeT) * count;
38+ const size_t size_in_bytes = sizeof (NativeT) * count;
3739
3840 // allocate native buffer
3941 buffer_ = Calloc<NativeT>(count);
4042
4143 // allocate v8 ArrayBuffer
4244 v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New (
43- isolate_, buffer_, sizeInBytes );
45+ isolate_, buffer_, size_in_bytes );
4446
4547 // allocate v8 TypedArray
4648 v8::Local<V8T> js_array = V8T::New (ab, byte_offset_, count);
@@ -55,6 +57,7 @@ class AliasedBuffer {
5557 *
5658 * Note that byte_offset must by aligned by sizeof(NativeT).
5759 */
60+ // TODO(refack): refactor into a non-owning `AliasedBufferView`
5861 AliasedBuffer (v8::Isolate* isolate,
5962 const size_t byte_offset,
6063 const size_t count,
@@ -96,7 +99,7 @@ class AliasedBuffer {
9699 js_array_.Reset ();
97100 }
98101
99- AliasedBuffer& operator =(AliasedBuffer&& that) {
102+ AliasedBuffer& operator =(AliasedBuffer&& that) noexcept {
100103 this ->~AliasedBuffer ();
101104 isolate_ = that.isolate_ ;
102105 count_ = that.count_ ;
@@ -226,6 +229,41 @@ class AliasedBuffer {
226229 return count_;
227230 }
228231
232+ // Should only be used to extend the array.
233+ // Should only be used on an owning array, not one created as a sub array of
234+ // an owning `AliasedBuffer`.
235+ void reserve (size_t new_capacity) {
236+ #if defined(DEBUG) && DEBUG
237+ CHECK_GE (new_capacity, count_);
238+ CHECK_EQ (byte_offset_, 0 );
239+ CHECK (free_buffer_);
240+ #endif
241+ const v8::HandleScope handle_scope (isolate_);
242+
243+ const size_t old_size_in_bytes = sizeof (NativeT) * count_;
244+ const size_t new_size_in_bytes = sizeof (NativeT) * new_capacity;
245+
246+ // allocate new native buffer
247+ NativeT* new_buffer = Calloc<NativeT>(new_capacity);
248+ // copy old content
249+ memcpy (new_buffer, buffer_, old_size_in_bytes);
250+
251+ // allocate v8 new ArrayBuffer
252+ v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New (
253+ isolate_, new_buffer, new_size_in_bytes);
254+
255+ // allocate v8 TypedArray
256+ v8::Local<V8T> js_array = V8T::New (ab, byte_offset_, new_capacity);
257+
258+ // move over old v8 TypedArray
259+ js_array_ = std::move (v8::Global<V8T>(isolate_, js_array));
260+
261+ // Free old buffer and set new values
262+ free (buffer_);
263+ buffer_ = new_buffer;
264+ count_ = new_capacity;
265+ }
266+
229267 private:
230268 v8::Isolate* isolate_;
231269 size_t count_;
0 commit comments