• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef SRC_ALLOCATED_BUFFER_INL_H_
2 #define SRC_ALLOCATED_BUFFER_INL_H_
3 
4 #include "allocated_buffer.h"
5 #include "base_object-inl.h"
6 #include "node_buffer.h"
7 #include "env-inl.h"
8 #include "uv.h"
9 #include "v8.h"
10 #include "util-inl.h"
11 #include "node_internals.h"
12 
13 namespace node {
14 
15 // It's a bit awkward to define this Buffer::New() overload here, but it
16 // avoids a circular dependency with node_internals.h.
17 namespace Buffer {
18 v8::MaybeLocal<v8::Uint8Array> New(Environment* env,
19                                    v8::Local<v8::ArrayBuffer> ab,
20                                    size_t byte_offset,
21                                    size_t length);
22 }
23 
NoArrayBufferZeroFillScope(IsolateData * isolate_data)24 NoArrayBufferZeroFillScope::NoArrayBufferZeroFillScope(
25     IsolateData* isolate_data)
26   : node_allocator_(isolate_data->node_allocator()) {
27   if (node_allocator_ != nullptr) node_allocator_->zero_fill_field()[0] = 0;
28 }
29 
~NoArrayBufferZeroFillScope()30 NoArrayBufferZeroFillScope::~NoArrayBufferZeroFillScope() {
31   if (node_allocator_ != nullptr) node_allocator_->zero_fill_field()[0] = 1;
32 }
33 
AllocateManaged(Environment * env,size_t size)34 AllocatedBuffer AllocatedBuffer::AllocateManaged(
35     Environment* env,
36     size_t size) {
37   NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
38   std::unique_ptr<v8::BackingStore> bs =
39       v8::ArrayBuffer::NewBackingStore(env->isolate(), size);
40   return AllocatedBuffer(env, std::move(bs));
41 }
42 
AllocatedBuffer(Environment * env,std::unique_ptr<v8::BackingStore> bs)43 AllocatedBuffer::AllocatedBuffer(
44     Environment* env, std::unique_ptr<v8::BackingStore> bs)
45     : env_(env), backing_store_(std::move(bs)) {}
46 
AllocatedBuffer(Environment * env,uv_buf_t buffer)47 AllocatedBuffer::AllocatedBuffer(
48     Environment* env, uv_buf_t buffer)
49     : env_(env) {
50   if (buffer.base == nullptr) return;
51   auto map = env->released_allocated_buffers();
52   auto it = map->find(buffer.base);
53   CHECK_NE(it, map->end());
54   backing_store_ = std::move(it->second);
55   map->erase(it);
56 }
57 
Resize(size_t len)58 void AllocatedBuffer::Resize(size_t len) {
59   if (len == 0) {
60     backing_store_ = v8::ArrayBuffer::NewBackingStore(env_->isolate(), 0);
61     return;
62   }
63   NoArrayBufferZeroFillScope no_zero_fill_scope(env_->isolate_data());
64   backing_store_ = v8::BackingStore::Reallocate(
65       env_->isolate(), std::move(backing_store_), len);
66 }
67 
release()68 uv_buf_t AllocatedBuffer::release() {
69   if (data() == nullptr) return uv_buf_init(nullptr, 0);
70 
71   CHECK_NOT_NULL(env_);
72   uv_buf_t ret = uv_buf_init(data(), size());
73   env_->released_allocated_buffers()->emplace(
74       ret.base, std::move(backing_store_));
75   return ret;
76 }
77 
data()78 char* AllocatedBuffer::data() {
79   if (!backing_store_) return nullptr;
80   return static_cast<char*>(backing_store_->Data());
81 }
82 
data()83 const char* AllocatedBuffer::data() const {
84   if (!backing_store_) return nullptr;
85   return static_cast<char*>(backing_store_->Data());
86 }
87 
88 
size()89 size_t AllocatedBuffer::size() const {
90   if (!backing_store_) return 0;
91   return backing_store_->ByteLength();
92 }
93 
clear()94 void AllocatedBuffer::clear() {
95   backing_store_.reset();
96 }
97 
ToBuffer()98 v8::MaybeLocal<v8::Object> AllocatedBuffer::ToBuffer() {
99   v8::Local<v8::ArrayBuffer> ab = ToArrayBuffer();
100   return Buffer::New(env_, ab, 0, ab->ByteLength())
101       .FromMaybe(v8::Local<v8::Uint8Array>());
102 }
103 
ToArrayBuffer()104 v8::Local<v8::ArrayBuffer> AllocatedBuffer::ToArrayBuffer() {
105   return v8::ArrayBuffer::New(env_->isolate(), std::move(backing_store_));
106 }
107 
108 }  // namespace node
109 
110 #endif  // SRC_ALLOCATED_BUFFER_INL_H_
111