v8-array-buffer.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. // Copyright 2021 the V8 project authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef INCLUDE_V8_ARRAY_BUFFER_H_
  5. #define INCLUDE_V8_ARRAY_BUFFER_H_
  6. #include <stddef.h>
  7. #include <memory>
  8. #include "v8-local-handle.h" // NOLINT(build/include_directory)
  9. #include "v8-object.h" // NOLINT(build/include_directory)
  10. #include "v8config.h" // NOLINT(build/include_directory)
  11. namespace v8 {
  12. class SharedArrayBuffer;
  13. #ifndef V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT
  14. // The number of required internal fields can be defined by embedder.
  15. #define V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT 2
  16. #endif
  17. enum class ArrayBufferCreationMode { kInternalized, kExternalized };
  18. /**
  19. * A wrapper around the backing store (i.e. the raw memory) of an array buffer.
  20. * See a document linked in http://crbug.com/v8/9908 for more information.
  21. *
  22. * The allocation and destruction of backing stores is generally managed by
  23. * V8. Clients should always use standard C++ memory ownership types (i.e.
  24. * std::unique_ptr and std::shared_ptr) to manage lifetimes of backing stores
  25. * properly, since V8 internal objects may alias backing stores.
  26. *
  27. * This object does not keep the underlying |ArrayBuffer::Allocator| alive by
  28. * default. Use Isolate::CreateParams::array_buffer_allocator_shared when
  29. * creating the Isolate to make it hold a reference to the allocator itself.
  30. */
  31. class V8_EXPORT BackingStore : public v8::internal::BackingStoreBase {
  32. public:
  33. ~BackingStore();
  34. /**
  35. * Return a pointer to the beginning of the memory block for this backing
  36. * store. The pointer is only valid as long as this backing store object
  37. * lives.
  38. */
  39. void* Data() const;
  40. /**
  41. * The length (in bytes) of this backing store.
  42. */
  43. size_t ByteLength() const;
  44. /**
  45. * Indicates whether the backing store was created for an ArrayBuffer or
  46. * a SharedArrayBuffer.
  47. */
  48. bool IsShared() const;
  49. /**
  50. * Prevent implicit instantiation of operator delete with size_t argument.
  51. * The size_t argument would be incorrect because ptr points to the
  52. * internal BackingStore object.
  53. */
  54. void operator delete(void* ptr) { ::operator delete(ptr); }
  55. /**
  56. * Wrapper around ArrayBuffer::Allocator::Reallocate that preserves IsShared.
  57. * Assumes that the backing_store was allocated by the ArrayBuffer allocator
  58. * of the given isolate.
  59. */
  60. static std::unique_ptr<BackingStore> Reallocate(
  61. v8::Isolate* isolate, std::unique_ptr<BackingStore> backing_store,
  62. size_t byte_length);
  63. /**
  64. * This callback is used only if the memory block for a BackingStore cannot be
  65. * allocated with an ArrayBuffer::Allocator. In such cases the destructor of
  66. * the BackingStore invokes the callback to free the memory block.
  67. */
  68. using DeleterCallback = void (*)(void* data, size_t length,
  69. void* deleter_data);
  70. /**
  71. * If the memory block of a BackingStore is static or is managed manually,
  72. * then this empty deleter along with nullptr deleter_data can be passed to
  73. * ArrayBuffer::NewBackingStore to indicate that.
  74. *
  75. * The manually managed case should be used with caution and only when it
  76. * is guaranteed that the memory block freeing happens after detaching its
  77. * ArrayBuffer.
  78. */
  79. static void EmptyDeleter(void* data, size_t length, void* deleter_data);
  80. private:
  81. /**
  82. * See [Shared]ArrayBuffer::GetBackingStore and
  83. * [Shared]ArrayBuffer::NewBackingStore.
  84. */
  85. BackingStore();
  86. };
  87. #if !defined(V8_IMMINENT_DEPRECATION_WARNINGS)
  88. // Use v8::BackingStore::DeleterCallback instead.
  89. using BackingStoreDeleterCallback = void (*)(void* data, size_t length,
  90. void* deleter_data);
  91. #endif
  92. /**
  93. * An instance of the built-in ArrayBuffer constructor (ES6 draft 15.13.5).
  94. */
  95. class V8_EXPORT ArrayBuffer : public Object {
  96. public:
  97. /**
  98. * A thread-safe allocator that V8 uses to allocate |ArrayBuffer|'s memory.
  99. * The allocator is a global V8 setting. It has to be set via
  100. * Isolate::CreateParams.
  101. *
  102. * Memory allocated through this allocator by V8 is accounted for as external
  103. * memory by V8. Note that V8 keeps track of the memory for all internalized
  104. * |ArrayBuffer|s. Responsibility for tracking external memory (using
  105. * Isolate::AdjustAmountOfExternalAllocatedMemory) is handed over to the
  106. * embedder upon externalization and taken over upon internalization (creating
  107. * an internalized buffer from an existing buffer).
  108. *
  109. * Note that it is unsafe to call back into V8 from any of the allocator
  110. * functions.
  111. */
  112. class V8_EXPORT Allocator {
  113. public:
  114. virtual ~Allocator() = default;
  115. /**
  116. * Allocate |length| bytes. Return nullptr if allocation is not successful.
  117. * Memory should be initialized to zeroes.
  118. */
  119. virtual void* Allocate(size_t length) = 0;
  120. /**
  121. * Allocate |length| bytes. Return nullptr if allocation is not successful.
  122. * Memory does not have to be initialized.
  123. */
  124. virtual void* AllocateUninitialized(size_t length) = 0;
  125. /**
  126. * Free the memory block of size |length|, pointed to by |data|.
  127. * That memory is guaranteed to be previously allocated by |Allocate|.
  128. */
  129. virtual void Free(void* data, size_t length) = 0;
  130. /**
  131. * Reallocate the memory block of size |old_length| to a memory block of
  132. * size |new_length| by expanding, contracting, or copying the existing
  133. * memory block. If |new_length| > |old_length|, then the new part of
  134. * the memory must be initialized to zeros. Return nullptr if reallocation
  135. * is not successful.
  136. *
  137. * The caller guarantees that the memory block was previously allocated
  138. * using Allocate or AllocateUninitialized.
  139. *
  140. * The default implementation allocates a new block and copies data.
  141. */
  142. virtual void* Reallocate(void* data, size_t old_length, size_t new_length);
  143. /**
  144. * ArrayBuffer allocation mode. kNormal is a malloc/free style allocation,
  145. * while kReservation is for larger allocations with the ability to set
  146. * access permissions.
  147. */
  148. enum class AllocationMode { kNormal, kReservation };
  149. /**
  150. * Convenience allocator.
  151. *
  152. * When the sandbox is enabled, this allocator will allocate its backing
  153. * memory inside the sandbox. Otherwise, it will rely on malloc/free.
  154. *
  155. * Caller takes ownership, i.e. the returned object needs to be freed using
  156. * |delete allocator| once it is no longer in use.
  157. */
  158. static Allocator* NewDefaultAllocator();
  159. };
  160. /**
  161. * Data length in bytes.
  162. */
  163. size_t ByteLength() const;
  164. /**
  165. * Create a new ArrayBuffer. Allocate |byte_length| bytes.
  166. * Allocated memory will be owned by a created ArrayBuffer and
  167. * will be deallocated when it is garbage-collected,
  168. * unless the object is externalized.
  169. */
  170. static Local<ArrayBuffer> New(Isolate* isolate, size_t byte_length);
  171. /**
  172. * Create a new ArrayBuffer with an existing backing store.
  173. * The created array keeps a reference to the backing store until the array
  174. * is garbage collected. Note that the IsExternal bit does not affect this
  175. * reference from the array to the backing store.
  176. *
  177. * In future IsExternal bit will be removed. Until then the bit is set as
  178. * follows. If the backing store does not own the underlying buffer, then
  179. * the array is created in externalized state. Otherwise, the array is created
  180. * in internalized state. In the latter case the array can be transitioned
  181. * to the externalized state using Externalize(backing_store).
  182. */
  183. static Local<ArrayBuffer> New(Isolate* isolate,
  184. std::shared_ptr<BackingStore> backing_store);
  185. /**
  186. * Returns a new standalone BackingStore that is allocated using the array
  187. * buffer allocator of the isolate. The result can be later passed to
  188. * ArrayBuffer::New.
  189. *
  190. * If the allocator returns nullptr, then the function may cause GCs in the
  191. * given isolate and re-try the allocation. If GCs do not help, then the
  192. * function will crash with an out-of-memory error.
  193. */
  194. static std::unique_ptr<BackingStore> NewBackingStore(Isolate* isolate,
  195. size_t byte_length);
  196. /**
  197. * Returns a new standalone BackingStore that takes over the ownership of
  198. * the given buffer. The destructor of the BackingStore invokes the given
  199. * deleter callback.
  200. *
  201. * The result can be later passed to ArrayBuffer::New. The raw pointer
  202. * to the buffer must not be passed again to any V8 API function.
  203. */
  204. static std::unique_ptr<BackingStore> NewBackingStore(
  205. void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter,
  206. void* deleter_data);
  207. /**
  208. * Returns true if this ArrayBuffer may be detached.
  209. */
  210. bool IsDetachable() const;
  211. /**
  212. * Detaches this ArrayBuffer and all its views (typed arrays).
  213. * Detaching sets the byte length of the buffer and all typed arrays to zero,
  214. * preventing JavaScript from ever accessing underlying backing store.
  215. * ArrayBuffer should have been externalized and must be detachable.
  216. */
  217. void Detach();
  218. /**
  219. * Get a shared pointer to the backing store of this array buffer. This
  220. * pointer coordinates the lifetime management of the internal storage
  221. * with any live ArrayBuffers on the heap, even across isolates. The embedder
  222. * should not attempt to manage lifetime of the storage through other means.
  223. */
  224. std::shared_ptr<BackingStore> GetBackingStore();
  225. V8_INLINE static ArrayBuffer* Cast(Value* value) {
  226. #ifdef V8_ENABLE_CHECKS
  227. CheckCast(value);
  228. #endif
  229. return static_cast<ArrayBuffer*>(value);
  230. }
  231. static const int kInternalFieldCount = V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT;
  232. static const int kEmbedderFieldCount = V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT;
  233. private:
  234. ArrayBuffer();
  235. static void CheckCast(Value* obj);
  236. };
  237. #ifndef V8_ARRAY_BUFFER_VIEW_INTERNAL_FIELD_COUNT
  238. // The number of required internal fields can be defined by embedder.
  239. #define V8_ARRAY_BUFFER_VIEW_INTERNAL_FIELD_COUNT 2
  240. #endif
  241. /**
  242. * A base class for an instance of one of "views" over ArrayBuffer,
  243. * including TypedArrays and DataView (ES6 draft 15.13).
  244. */
  245. class V8_EXPORT ArrayBufferView : public Object {
  246. public:
  247. /**
  248. * Returns underlying ArrayBuffer.
  249. */
  250. Local<ArrayBuffer> Buffer();
  251. /**
  252. * Byte offset in |Buffer|.
  253. */
  254. size_t ByteOffset();
  255. /**
  256. * Size of a view in bytes.
  257. */
  258. size_t ByteLength();
  259. /**
  260. * Copy the contents of the ArrayBufferView's buffer to an embedder defined
  261. * memory without additional overhead that calling ArrayBufferView::Buffer
  262. * might incur.
  263. *
  264. * Will write at most min(|byte_length|, ByteLength) bytes starting at
  265. * ByteOffset of the underlying buffer to the memory starting at |dest|.
  266. * Returns the number of bytes actually written.
  267. */
  268. size_t CopyContents(void* dest, size_t byte_length);
  269. /**
  270. * Returns true if ArrayBufferView's backing ArrayBuffer has already been
  271. * allocated.
  272. */
  273. bool HasBuffer() const;
  274. V8_INLINE static ArrayBufferView* Cast(Value* value) {
  275. #ifdef V8_ENABLE_CHECKS
  276. CheckCast(value);
  277. #endif
  278. return static_cast<ArrayBufferView*>(value);
  279. }
  280. static const int kInternalFieldCount =
  281. V8_ARRAY_BUFFER_VIEW_INTERNAL_FIELD_COUNT;
  282. static const int kEmbedderFieldCount =
  283. V8_ARRAY_BUFFER_VIEW_INTERNAL_FIELD_COUNT;
  284. private:
  285. ArrayBufferView();
  286. static void CheckCast(Value* obj);
  287. };
  288. /**
  289. * An instance of DataView constructor (ES6 draft 15.13.7).
  290. */
  291. class V8_EXPORT DataView : public ArrayBufferView {
  292. public:
  293. static Local<DataView> New(Local<ArrayBuffer> array_buffer,
  294. size_t byte_offset, size_t length);
  295. static Local<DataView> New(Local<SharedArrayBuffer> shared_array_buffer,
  296. size_t byte_offset, size_t length);
  297. V8_INLINE static DataView* Cast(Value* value) {
  298. #ifdef V8_ENABLE_CHECKS
  299. CheckCast(value);
  300. #endif
  301. return static_cast<DataView*>(value);
  302. }
  303. private:
  304. DataView();
  305. static void CheckCast(Value* obj);
  306. };
  307. /**
  308. * An instance of the built-in SharedArrayBuffer constructor.
  309. */
  310. class V8_EXPORT SharedArrayBuffer : public Object {
  311. public:
  312. /**
  313. * Data length in bytes.
  314. */
  315. size_t ByteLength() const;
  316. /**
  317. * Create a new SharedArrayBuffer. Allocate |byte_length| bytes.
  318. * Allocated memory will be owned by a created SharedArrayBuffer and
  319. * will be deallocated when it is garbage-collected,
  320. * unless the object is externalized.
  321. */
  322. static Local<SharedArrayBuffer> New(Isolate* isolate, size_t byte_length);
  323. /**
  324. * Create a new SharedArrayBuffer with an existing backing store.
  325. * The created array keeps a reference to the backing store until the array
  326. * is garbage collected. Note that the IsExternal bit does not affect this
  327. * reference from the array to the backing store.
  328. *
  329. * In future IsExternal bit will be removed. Until then the bit is set as
  330. * follows. If the backing store does not own the underlying buffer, then
  331. * the array is created in externalized state. Otherwise, the array is created
  332. * in internalized state. In the latter case the array can be transitioned
  333. * to the externalized state using Externalize(backing_store).
  334. */
  335. static Local<SharedArrayBuffer> New(
  336. Isolate* isolate, std::shared_ptr<BackingStore> backing_store);
  337. /**
  338. * Returns a new standalone BackingStore that is allocated using the array
  339. * buffer allocator of the isolate. The result can be later passed to
  340. * SharedArrayBuffer::New.
  341. *
  342. * If the allocator returns nullptr, then the function may cause GCs in the
  343. * given isolate and re-try the allocation. If GCs do not help, then the
  344. * function will crash with an out-of-memory error.
  345. */
  346. static std::unique_ptr<BackingStore> NewBackingStore(Isolate* isolate,
  347. size_t byte_length);
  348. /**
  349. * Returns a new standalone BackingStore that takes over the ownership of
  350. * the given buffer. The destructor of the BackingStore invokes the given
  351. * deleter callback.
  352. *
  353. * The result can be later passed to SharedArrayBuffer::New. The raw pointer
  354. * to the buffer must not be passed again to any V8 functions.
  355. */
  356. static std::unique_ptr<BackingStore> NewBackingStore(
  357. void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter,
  358. void* deleter_data);
  359. /**
  360. * Get a shared pointer to the backing store of this array buffer. This
  361. * pointer coordinates the lifetime management of the internal storage
  362. * with any live ArrayBuffers on the heap, even across isolates. The embedder
  363. * should not attempt to manage lifetime of the storage through other means.
  364. */
  365. std::shared_ptr<BackingStore> GetBackingStore();
  366. V8_INLINE static SharedArrayBuffer* Cast(Value* value) {
  367. #ifdef V8_ENABLE_CHECKS
  368. CheckCast(value);
  369. #endif
  370. return static_cast<SharedArrayBuffer*>(value);
  371. }
  372. static const int kInternalFieldCount = V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT;
  373. private:
  374. SharedArrayBuffer();
  375. static void CheckCast(Value* obj);
  376. };
  377. } // namespace v8
  378. #endif // INCLUDE_V8_ARRAY_BUFFER_H_