![]() |
|
|||
File indexing completed on 2025-02-21 10:05:23
0001 // Copyright 2021 the V8 project authors. All rights reserved. 0002 // Use of this source code is governed by a BSD-style license that can be 0003 // found in the LICENSE file. 0004 0005 #ifndef INCLUDE_V8_ARRAY_BUFFER_H_ 0006 #define INCLUDE_V8_ARRAY_BUFFER_H_ 0007 0008 #include <stddef.h> 0009 0010 #include <memory> 0011 0012 #include "v8-local-handle.h" // NOLINT(build/include_directory) 0013 #include "v8-object.h" // NOLINT(build/include_directory) 0014 #include "v8config.h" // NOLINT(build/include_directory) 0015 0016 namespace v8 { 0017 0018 class SharedArrayBuffer; 0019 0020 #ifndef V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT 0021 // The number of required internal fields can be defined by embedder. 0022 #define V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT 2 0023 #endif 0024 0025 enum class ArrayBufferCreationMode { kInternalized, kExternalized }; 0026 0027 /** 0028 * A wrapper around the backing store (i.e. the raw memory) of an array buffer. 0029 * See a document linked in http://crbug.com/v8/9908 for more information. 0030 * 0031 * The allocation and destruction of backing stores is generally managed by 0032 * V8. Clients should always use standard C++ memory ownership types (i.e. 0033 * std::unique_ptr and std::shared_ptr) to manage lifetimes of backing stores 0034 * properly, since V8 internal objects may alias backing stores. 0035 * 0036 * This object does not keep the underlying |ArrayBuffer::Allocator| alive by 0037 * default. Use Isolate::CreateParams::array_buffer_allocator_shared when 0038 * creating the Isolate to make it hold a reference to the allocator itself. 0039 */ 0040 class V8_EXPORT BackingStore : public v8::internal::BackingStoreBase { 0041 public: 0042 ~BackingStore(); 0043 0044 /** 0045 * Return a pointer to the beginning of the memory block for this backing 0046 * store. The pointer is only valid as long as this backing store object 0047 * lives. 0048 */ 0049 void* Data() const; 0050 0051 /** 0052 * The length (in bytes) of this backing store. 0053 */ 0054 size_t ByteLength() const; 0055 0056 /** 0057 * The maximum length (in bytes) that this backing store may grow to. 0058 * 0059 * If this backing store was created for a resizable ArrayBuffer or a growable 0060 * SharedArrayBuffer, it is >= ByteLength(). Otherwise it is == 0061 * ByteLength(). 0062 */ 0063 size_t MaxByteLength() const; 0064 0065 /** 0066 * Indicates whether the backing store was created for an ArrayBuffer or 0067 * a SharedArrayBuffer. 0068 */ 0069 bool IsShared() const; 0070 0071 /** 0072 * Indicates whether the backing store was created for a resizable ArrayBuffer 0073 * or a growable SharedArrayBuffer, and thus may be resized by user JavaScript 0074 * code. 0075 */ 0076 bool IsResizableByUserJavaScript() const; 0077 0078 /** 0079 * Prevent implicit instantiation of operator delete with size_t argument. 0080 * The size_t argument would be incorrect because ptr points to the 0081 * internal BackingStore object. 0082 */ 0083 void operator delete(void* ptr) { ::operator delete(ptr); } 0084 0085 /** 0086 * Wrapper around ArrayBuffer::Allocator::Reallocate that preserves IsShared. 0087 * Assumes that the backing_store was allocated by the ArrayBuffer allocator 0088 * of the given isolate. 0089 */ 0090 static std::unique_ptr<BackingStore> Reallocate( 0091 v8::Isolate* isolate, std::unique_ptr<BackingStore> backing_store, 0092 size_t byte_length); 0093 0094 /** 0095 * This callback is used only if the memory block for a BackingStore cannot be 0096 * allocated with an ArrayBuffer::Allocator. In such cases the destructor of 0097 * the BackingStore invokes the callback to free the memory block. 0098 */ 0099 using DeleterCallback = void (*)(void* data, size_t length, 0100 void* deleter_data); 0101 0102 /** 0103 * If the memory block of a BackingStore is static or is managed manually, 0104 * then this empty deleter along with nullptr deleter_data can be passed to 0105 * ArrayBuffer::NewBackingStore to indicate that. 0106 * 0107 * The manually managed case should be used with caution and only when it 0108 * is guaranteed that the memory block freeing happens after detaching its 0109 * ArrayBuffer. 0110 */ 0111 static void EmptyDeleter(void* data, size_t length, void* deleter_data); 0112 0113 private: 0114 /** 0115 * See [Shared]ArrayBuffer::GetBackingStore and 0116 * [Shared]ArrayBuffer::NewBackingStore. 0117 */ 0118 BackingStore(); 0119 }; 0120 0121 #if !defined(V8_IMMINENT_DEPRECATION_WARNINGS) 0122 // Use v8::BackingStore::DeleterCallback instead. 0123 using BackingStoreDeleterCallback = void (*)(void* data, size_t length, 0124 void* deleter_data); 0125 0126 #endif 0127 0128 /** 0129 * An instance of the built-in ArrayBuffer constructor (ES6 draft 15.13.5). 0130 */ 0131 class V8_EXPORT ArrayBuffer : public Object { 0132 public: 0133 /** 0134 * A thread-safe allocator that V8 uses to allocate |ArrayBuffer|'s memory. 0135 * The allocator is a global V8 setting. It has to be set via 0136 * Isolate::CreateParams. 0137 * 0138 * Memory allocated through this allocator by V8 is accounted for as external 0139 * memory by V8. Note that V8 keeps track of the memory for all internalized 0140 * |ArrayBuffer|s. Responsibility for tracking external memory (using 0141 * Isolate::AdjustAmountOfExternalAllocatedMemory) is handed over to the 0142 * embedder upon externalization and taken over upon internalization (creating 0143 * an internalized buffer from an existing buffer). 0144 * 0145 * Note that it is unsafe to call back into V8 from any of the allocator 0146 * functions. 0147 */ 0148 class V8_EXPORT Allocator { 0149 public: 0150 virtual ~Allocator() = default; 0151 0152 /** 0153 * Allocate |length| bytes. Return nullptr if allocation is not successful. 0154 * Memory should be initialized to zeroes. 0155 */ 0156 virtual void* Allocate(size_t length) = 0; 0157 0158 /** 0159 * Allocate |length| bytes. Return nullptr if allocation is not successful. 0160 * Memory does not have to be initialized. 0161 */ 0162 virtual void* AllocateUninitialized(size_t length) = 0; 0163 0164 /** 0165 * Free the memory block of size |length|, pointed to by |data|. 0166 * That memory is guaranteed to be previously allocated by |Allocate|. 0167 */ 0168 virtual void Free(void* data, size_t length) = 0; 0169 0170 /** 0171 * Reallocate the memory block of size |old_length| to a memory block of 0172 * size |new_length| by expanding, contracting, or copying the existing 0173 * memory block. If |new_length| > |old_length|, then the new part of 0174 * the memory must be initialized to zeros. Return nullptr if reallocation 0175 * is not successful. 0176 * 0177 * The caller guarantees that the memory block was previously allocated 0178 * using Allocate or AllocateUninitialized. 0179 * 0180 * The default implementation allocates a new block and copies data. 0181 */ 0182 virtual void* Reallocate(void* data, size_t old_length, size_t new_length); 0183 0184 /** 0185 * ArrayBuffer allocation mode. kNormal is a malloc/free style allocation, 0186 * while kReservation is for larger allocations with the ability to set 0187 * access permissions. 0188 */ 0189 enum class AllocationMode { kNormal, kReservation }; 0190 0191 /** 0192 * Convenience allocator. 0193 * 0194 * When the sandbox is enabled, this allocator will allocate its backing 0195 * memory inside the sandbox. Otherwise, it will rely on malloc/free. 0196 * 0197 * Caller takes ownership, i.e. the returned object needs to be freed using 0198 * |delete allocator| once it is no longer in use. 0199 */ 0200 static Allocator* NewDefaultAllocator(); 0201 }; 0202 0203 /** 0204 * Data length in bytes. 0205 */ 0206 size_t ByteLength() const; 0207 0208 /** 0209 * Maximum length in bytes. 0210 */ 0211 size_t MaxByteLength() const; 0212 0213 /** 0214 * Create a new ArrayBuffer. Allocate |byte_length| bytes. 0215 * Allocated memory will be owned by a created ArrayBuffer and 0216 * will be deallocated when it is garbage-collected, 0217 * unless the object is externalized. 0218 */ 0219 static Local<ArrayBuffer> New(Isolate* isolate, size_t byte_length); 0220 0221 /** 0222 * Create a new ArrayBuffer with an existing backing store. 0223 * The created array keeps a reference to the backing store until the array 0224 * is garbage collected. Note that the IsExternal bit does not affect this 0225 * reference from the array to the backing store. 0226 * 0227 * In future IsExternal bit will be removed. Until then the bit is set as 0228 * follows. If the backing store does not own the underlying buffer, then 0229 * the array is created in externalized state. Otherwise, the array is created 0230 * in internalized state. In the latter case the array can be transitioned 0231 * to the externalized state using Externalize(backing_store). 0232 */ 0233 static Local<ArrayBuffer> New(Isolate* isolate, 0234 std::shared_ptr<BackingStore> backing_store); 0235 0236 /** 0237 * Returns a new standalone BackingStore that is allocated using the array 0238 * buffer allocator of the isolate. The result can be later passed to 0239 * ArrayBuffer::New. 0240 * 0241 * If the allocator returns nullptr, then the function may cause GCs in the 0242 * given isolate and re-try the allocation. If GCs do not help, then the 0243 * function will crash with an out-of-memory error. 0244 */ 0245 static std::unique_ptr<BackingStore> NewBackingStore(Isolate* isolate, 0246 size_t byte_length); 0247 /** 0248 * Returns a new standalone BackingStore that takes over the ownership of 0249 * the given buffer. The destructor of the BackingStore invokes the given 0250 * deleter callback. 0251 * 0252 * The result can be later passed to ArrayBuffer::New. The raw pointer 0253 * to the buffer must not be passed again to any V8 API function. 0254 */ 0255 static std::unique_ptr<BackingStore> NewBackingStore( 0256 void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter, 0257 void* deleter_data); 0258 0259 /** 0260 * Returns a new resizable standalone BackingStore that is allocated using the 0261 * array buffer allocator of the isolate. The result can be later passed to 0262 * ArrayBuffer::New. 0263 * 0264 * |byte_length| must be <= |max_byte_length|. 0265 * 0266 * This function is usable without an isolate. Unlike |NewBackingStore| calls 0267 * with an isolate, GCs cannot be triggered, and there are no 0268 * retries. Allocation failure will cause the function to crash with an 0269 * out-of-memory error. 0270 */ 0271 static std::unique_ptr<BackingStore> NewResizableBackingStore( 0272 size_t byte_length, size_t max_byte_length); 0273 0274 /** 0275 * Returns true if this ArrayBuffer may be detached. 0276 */ 0277 bool IsDetachable() const; 0278 0279 /** 0280 * Returns true if this ArrayBuffer has been detached. 0281 */ 0282 bool WasDetached() const; 0283 0284 /** 0285 * Detaches this ArrayBuffer and all its views (typed arrays). 0286 * Detaching sets the byte length of the buffer and all typed arrays to zero, 0287 * preventing JavaScript from ever accessing underlying backing store. 0288 * ArrayBuffer should have been externalized and must be detachable. 0289 */ 0290 V8_DEPRECATE_SOON( 0291 "Use the version which takes a key parameter (passing a null handle is " 0292 "ok).") 0293 void Detach(); 0294 0295 /** 0296 * Detaches this ArrayBuffer and all its views (typed arrays). 0297 * Detaching sets the byte length of the buffer and all typed arrays to zero, 0298 * preventing JavaScript from ever accessing underlying backing store. 0299 * ArrayBuffer should have been externalized and must be detachable. Returns 0300 * Nothing if the key didn't pass the [[ArrayBufferDetachKey]] check, 0301 * Just(true) otherwise. 0302 */ 0303 V8_WARN_UNUSED_RESULT Maybe<bool> Detach(v8::Local<v8::Value> key); 0304 0305 /** 0306 * Sets the ArrayBufferDetachKey. 0307 */ 0308 void SetDetachKey(v8::Local<v8::Value> key); 0309 0310 /** 0311 * Get a shared pointer to the backing store of this array buffer. This 0312 * pointer coordinates the lifetime management of the internal storage 0313 * with any live ArrayBuffers on the heap, even across isolates. The embedder 0314 * should not attempt to manage lifetime of the storage through other means. 0315 * 0316 * The returned shared pointer will not be empty, even if the ArrayBuffer has 0317 * been detached. Use |WasDetached| to tell if it has been detached instead. 0318 */ 0319 std::shared_ptr<BackingStore> GetBackingStore(); 0320 0321 /** 0322 * More efficient shortcut for 0323 * GetBackingStore()->IsResizableByUserJavaScript(). 0324 */ 0325 bool IsResizableByUserJavaScript() const; 0326 0327 /** 0328 * More efficient shortcut for GetBackingStore()->Data(). The returned pointer 0329 * is valid as long as the ArrayBuffer is alive. 0330 */ 0331 void* Data() const; 0332 0333 V8_INLINE static ArrayBuffer* Cast(Value* value) { 0334 #ifdef V8_ENABLE_CHECKS 0335 CheckCast(value); 0336 #endif 0337 return static_cast<ArrayBuffer*>(value); 0338 } 0339 0340 static const int kInternalFieldCount = V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT; 0341 static const int kEmbedderFieldCount = V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT; 0342 0343 private: 0344 ArrayBuffer(); 0345 static void CheckCast(Value* obj); 0346 }; 0347 0348 #ifndef V8_ARRAY_BUFFER_VIEW_INTERNAL_FIELD_COUNT 0349 // The number of required internal fields can be defined by embedder. 0350 #define V8_ARRAY_BUFFER_VIEW_INTERNAL_FIELD_COUNT 2 0351 #endif 0352 0353 /** 0354 * A base class for an instance of one of "views" over ArrayBuffer, 0355 * including TypedArrays and DataView (ES6 draft 15.13). 0356 */ 0357 class V8_EXPORT ArrayBufferView : public Object { 0358 public: 0359 /** 0360 * Returns underlying ArrayBuffer. 0361 */ 0362 Local<ArrayBuffer> Buffer(); 0363 /** 0364 * Byte offset in |Buffer|. 0365 */ 0366 size_t ByteOffset(); 0367 /** 0368 * Size of a view in bytes. 0369 */ 0370 size_t ByteLength(); 0371 0372 /** 0373 * Copy the contents of the ArrayBufferView's buffer to an embedder defined 0374 * memory without additional overhead that calling ArrayBufferView::Buffer 0375 * might incur. 0376 * 0377 * Will write at most min(|byte_length|, ByteLength) bytes starting at 0378 * ByteOffset of the underlying buffer to the memory starting at |dest|. 0379 * Returns the number of bytes actually written. 0380 */ 0381 size_t CopyContents(void* dest, size_t byte_length); 0382 0383 /** 0384 * Returns true if ArrayBufferView's backing ArrayBuffer has already been 0385 * allocated. 0386 */ 0387 bool HasBuffer() const; 0388 0389 V8_INLINE static ArrayBufferView* Cast(Value* value) { 0390 #ifdef V8_ENABLE_CHECKS 0391 CheckCast(value); 0392 #endif 0393 return static_cast<ArrayBufferView*>(value); 0394 } 0395 0396 static const int kInternalFieldCount = 0397 V8_ARRAY_BUFFER_VIEW_INTERNAL_FIELD_COUNT; 0398 static const int kEmbedderFieldCount = 0399 V8_ARRAY_BUFFER_VIEW_INTERNAL_FIELD_COUNT; 0400 0401 private: 0402 ArrayBufferView(); 0403 static void CheckCast(Value* obj); 0404 }; 0405 0406 /** 0407 * An instance of DataView constructor (ES6 draft 15.13.7). 0408 */ 0409 class V8_EXPORT DataView : public ArrayBufferView { 0410 public: 0411 static Local<DataView> New(Local<ArrayBuffer> array_buffer, 0412 size_t byte_offset, size_t length); 0413 static Local<DataView> New(Local<SharedArrayBuffer> shared_array_buffer, 0414 size_t byte_offset, size_t length); 0415 V8_INLINE static DataView* Cast(Value* value) { 0416 #ifdef V8_ENABLE_CHECKS 0417 CheckCast(value); 0418 #endif 0419 return static_cast<DataView*>(value); 0420 } 0421 0422 private: 0423 DataView(); 0424 static void CheckCast(Value* obj); 0425 }; 0426 0427 /** 0428 * An instance of the built-in SharedArrayBuffer constructor. 0429 */ 0430 class V8_EXPORT SharedArrayBuffer : public Object { 0431 public: 0432 /** 0433 * Data length in bytes. 0434 */ 0435 size_t ByteLength() const; 0436 0437 /** 0438 * Maximum length in bytes. 0439 */ 0440 size_t MaxByteLength() const; 0441 0442 /** 0443 * Create a new SharedArrayBuffer. Allocate |byte_length| bytes. 0444 * Allocated memory will be owned by a created SharedArrayBuffer and 0445 * will be deallocated when it is garbage-collected, 0446 * unless the object is externalized. 0447 */ 0448 static Local<SharedArrayBuffer> New(Isolate* isolate, size_t byte_length); 0449 0450 /** 0451 * Create a new SharedArrayBuffer with an existing backing store. 0452 * The created array keeps a reference to the backing store until the array 0453 * is garbage collected. Note that the IsExternal bit does not affect this 0454 * reference from the array to the backing store. 0455 * 0456 * In future IsExternal bit will be removed. Until then the bit is set as 0457 * follows. If the backing store does not own the underlying buffer, then 0458 * the array is created in externalized state. Otherwise, the array is created 0459 * in internalized state. In the latter case the array can be transitioned 0460 * to the externalized state using Externalize(backing_store). 0461 */ 0462 static Local<SharedArrayBuffer> New( 0463 Isolate* isolate, std::shared_ptr<BackingStore> backing_store); 0464 0465 /** 0466 * Returns a new standalone BackingStore that is allocated using the array 0467 * buffer allocator of the isolate. The result can be later passed to 0468 * SharedArrayBuffer::New. 0469 * 0470 * If the allocator returns nullptr, then the function may cause GCs in the 0471 * given isolate and re-try the allocation. If GCs do not help, then the 0472 * function will crash with an out-of-memory error. 0473 */ 0474 static std::unique_ptr<BackingStore> NewBackingStore(Isolate* isolate, 0475 size_t byte_length); 0476 /** 0477 * Returns a new standalone BackingStore that takes over the ownership of 0478 * the given buffer. The destructor of the BackingStore invokes the given 0479 * deleter callback. 0480 * 0481 * The result can be later passed to SharedArrayBuffer::New. The raw pointer 0482 * to the buffer must not be passed again to any V8 functions. 0483 */ 0484 static std::unique_ptr<BackingStore> NewBackingStore( 0485 void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter, 0486 void* deleter_data); 0487 0488 /** 0489 * Get a shared pointer to the backing store of this array buffer. This 0490 * pointer coordinates the lifetime management of the internal storage 0491 * with any live ArrayBuffers on the heap, even across isolates. The embedder 0492 * should not attempt to manage lifetime of the storage through other means. 0493 */ 0494 std::shared_ptr<BackingStore> GetBackingStore(); 0495 0496 /** 0497 * More efficient shortcut for GetBackingStore()->Data(). The returned pointer 0498 * is valid as long as the ArrayBuffer is alive. 0499 */ 0500 void* Data() const; 0501 0502 V8_INLINE static SharedArrayBuffer* Cast(Value* value) { 0503 #ifdef V8_ENABLE_CHECKS 0504 CheckCast(value); 0505 #endif 0506 return static_cast<SharedArrayBuffer*>(value); 0507 } 0508 0509 static const int kInternalFieldCount = V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT; 0510 0511 private: 0512 SharedArrayBuffer(); 0513 static void CheckCast(Value* obj); 0514 }; 0515 0516 } // namespace v8 0517 0518 #endif // INCLUDE_V8_ARRAY_BUFFER_H_
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |