Back to home page

EIC code displayed by LXR

 
 

    


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_