// Copyright 2018 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_OBJECTS_JS_ARRAY_BUFFER_H_ #define V8_OBJECTS_JS_ARRAY_BUFFER_H_ #include "src/objects.h" // Has to be the last include (doesn't have include guards): #include "src/objects/object-macros.h" namespace v8 { namespace internal { // Whether a JSArrayBuffer is a SharedArrayBuffer or not. enum class SharedFlag { kNotShared, kShared }; class JSArrayBuffer : public JSObject { public: // [byte_length]: length in bytes DECL_ACCESSORS(byte_length, Object) // [backing_store]: backing memory for this array DECL_ACCESSORS(backing_store, void) // For non-wasm, allocation_length and allocation_base are byte_length and // backing_store, respectively. inline size_t allocation_length() const; inline void* allocation_base() const; inline uint32_t bit_field() const; inline void set_bit_field(uint32_t bits); // [is_external]: true indicates that the embedder is in charge of freeing the // backing_store, while is_external == false means that v8 will free the // memory block once all ArrayBuffers referencing it are collected by the GC. inline bool is_external(); inline void set_is_external(bool value); inline bool is_neuterable(); inline void set_is_neuterable(bool value); inline bool was_neutered(); inline void set_was_neutered(bool value); inline bool is_shared(); inline void set_is_shared(bool value); inline bool is_growable(); inline void set_is_growable(bool value); DECL_CAST(JSArrayBuffer) void Neuter(); struct Allocation { Allocation(void* allocation_base, size_t length, void* backing_store, bool is_wasm_memory) : allocation_base(allocation_base), length(length), backing_store(backing_store), is_wasm_memory(is_wasm_memory) {} void* allocation_base; size_t length; void* backing_store; bool is_wasm_memory; }; // Returns whether the buffer is tracked by the WasmMemoryTracker. inline bool is_wasm_memory() const; // Sets whether the buffer is tracked by the WasmMemoryTracker. void set_is_wasm_memory(bool is_wasm_memory); // Removes the backing store from the WasmMemoryTracker and sets // |is_wasm_memory| to false. void StopTrackingWasmMemory(Isolate* isolate); void FreeBackingStoreFromMainThread(); static void FreeBackingStore(Isolate* isolate, Allocation allocation); V8_EXPORT_PRIVATE static void Setup( Handle array_buffer, Isolate* isolate, bool is_external, void* data, size_t allocated_length, SharedFlag shared = SharedFlag::kNotShared, bool is_wasm_memory = false); // Returns false if array buffer contents could not be allocated. // In this case, |array_buffer| will not be set up. static bool SetupAllocatingData( Handle array_buffer, Isolate* isolate, size_t allocated_length, bool initialize = true, SharedFlag shared = SharedFlag::kNotShared) V8_WARN_UNUSED_RESULT; // Dispatched behavior. DECL_PRINTER(JSArrayBuffer) DECL_VERIFIER(JSArrayBuffer) static const int kByteLengthOffset = JSObject::kHeaderSize; // The rest of the fields are not JSObjects, so they are not iterated over in // objects-body-descriptors-inl.h. static const int kBackingStoreOffset = kByteLengthOffset + kPointerSize; static const int kBitFieldSlot = kBackingStoreOffset + kPointerSize; #if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT static const int kBitFieldOffset = kBitFieldSlot; #else static const int kBitFieldOffset = kBitFieldSlot + kInt32Size; #endif static const int kSize = kBitFieldSlot + kPointerSize; static const int kSizeWithEmbedderFields = kSize + v8::ArrayBuffer::kEmbedderFieldCount * kPointerSize; // Iterates all fields in the object including internal ones except // kBackingStoreOffset and kBitFieldSlot. class BodyDescriptor; // No weak fields. typedef BodyDescriptor BodyDescriptorWeak; class IsExternal : public BitField {}; class IsNeuterable : public BitField {}; class WasNeutered : public BitField {}; class IsShared : public BitField {}; class IsGrowable : public BitField {}; class IsWasmMemory : public BitField {}; private: DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBuffer); }; class JSArrayBufferView : public JSObject { public: // [buffer]: ArrayBuffer that this typed array views. DECL_ACCESSORS(buffer, Object) // [byte_offset]: offset of typed array in bytes. DECL_ACCESSORS(byte_offset, Object) // [byte_length]: length of typed array in bytes. DECL_ACCESSORS(byte_length, Object) DECL_CAST(JSArrayBufferView) DECL_VERIFIER(JSArrayBufferView) inline bool WasNeutered() const; static const int kBufferOffset = JSObject::kHeaderSize; static const int kByteOffsetOffset = kBufferOffset + kPointerSize; static const int kByteLengthOffset = kByteOffsetOffset + kPointerSize; static const int kViewSize = kByteLengthOffset + kPointerSize; private: #ifdef VERIFY_HEAP DECL_ACCESSORS(raw_byte_offset, Object) DECL_ACCESSORS(raw_byte_length, Object) #endif DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBufferView); }; class JSTypedArray : public JSArrayBufferView { public: // [length]: length of typed array in elements. DECL_ACCESSORS(length, Object) inline size_t length_value() const; // ES6 9.4.5.3 V8_WARN_UNUSED_RESULT static Maybe DefineOwnProperty( Isolate* isolate, Handle o, Handle key, PropertyDescriptor* desc, ShouldThrow should_throw); DECL_CAST(JSTypedArray) ExternalArrayType type(); V8_EXPORT_PRIVATE size_t element_size(); Handle GetBuffer(); // Whether the buffer's backing store is on-heap or off-heap. inline bool is_on_heap() const; static inline MaybeHandle Validate(Isolate* isolate, Handle receiver, const char* method_name); // Dispatched behavior. DECL_PRINTER(JSTypedArray) DECL_VERIFIER(JSTypedArray) static const int kLengthOffset = kViewSize; static const int kSize = kLengthOffset + kPointerSize; static const int kSizeWithEmbedderFields = kSize + v8::ArrayBufferView::kEmbedderFieldCount * kPointerSize; private: static Handle MaterializeArrayBuffer( Handle typed_array); #ifdef VERIFY_HEAP DECL_ACCESSORS(raw_length, Object) #endif DISALLOW_IMPLICIT_CONSTRUCTORS(JSTypedArray); }; class JSDataView : public JSArrayBufferView { public: DECL_CAST(JSDataView) // Dispatched behavior. DECL_PRINTER(JSDataView) DECL_VERIFIER(JSDataView) static const int kSize = kViewSize; static const int kSizeWithEmbedderFields = kSize + v8::ArrayBufferView::kEmbedderFieldCount * kPointerSize; private: DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataView); }; } // namespace internal } // namespace v8 #include "src/objects/object-macros-undef.h" #endif // V8_OBJECTS_JS_ARRAY_BUFFER_H_