1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* ArrayBuffer functionality. */
8 #ifndef js_ArrayBuffer_h
9 #define js_ArrayBuffer_h
11 #include <stddef.h> // size_t
12 #include <stdint.h> // uint32_t
14 #include "jstypes.h" // JS_PUBLIC_API
16 #include "js/GCAPI.h" // JS::AutoRequireNoGC
17 #include "js/RootingAPI.h" // JS::Handle
19 struct JS_PUBLIC_API JSContext
;
20 class JS_PUBLIC_API JSObject
;
27 * Create a new ArrayBuffer with the given byte length.
29 extern JS_PUBLIC_API JSObject
* NewArrayBuffer(JSContext
* cx
, size_t nbytes
);
32 * Create a new ArrayBuffer with the given |contents|, which may be null only
33 * if |nbytes == 0|. |contents| must be allocated compatible with deallocation
36 * If and only if an ArrayBuffer is successfully created and returned,
37 * ownership of |contents| is transferred to the new ArrayBuffer.
39 * Care must be taken that |nbytes| bytes of |content| remain valid for the
40 * duration of this call. In particular, passing the length/pointer of existing
41 * typed array or ArrayBuffer data is generally unsafe: if a GC occurs during a
42 * call to this function, it could move those contents to a different location
43 * and invalidate the provided pointer.
45 extern JS_PUBLIC_API JSObject
* NewArrayBufferWithContents(JSContext
* cx
,
50 * Create a new ArrayBuffer, whose bytes are set to the values of the bytes in
51 * the provided ArrayBuffer.
53 * |maybeArrayBuffer| is asserted to be non-null. An error is thrown if
54 * |maybeArrayBuffer| would fail the |IsArrayBufferObject| test given further
55 * below or if |maybeArrayBuffer| is detached.
57 * |maybeArrayBuffer| may store its contents in any fashion (i.e. it doesn't
58 * matter whether |maybeArrayBuffer| was allocated using |JS::NewArrayBuffer|,
59 * |JS::NewExternalArrayBuffer|, or any other ArrayBuffer-allocating function).
61 * The newly-created ArrayBuffer is effectively creatd as if by
62 * |JS::NewArrayBufferWithContents| passing in |maybeArrayBuffer|'s internal
63 * data pointer and length, in a manner safe against |maybeArrayBuffer|'s data
64 * being moved around by the GC. In particular, the new ArrayBuffer will not
65 * behave like one created for WASM or asm.js, so it *can* be detached.
67 extern JS_PUBLIC_API JSObject
* CopyArrayBuffer(
68 JSContext
* cx
, JS::Handle
<JSObject
*> maybeArrayBuffer
);
70 using BufferContentsFreeFunc
= void (*)(void* contents
, void* userData
);
73 * Create a new ArrayBuffer with the given contents. The contents must not be
74 * modified by any other code, internal or external.
76 * When the ArrayBuffer is ready to be disposed of, `freeFunc(contents,
77 * freeUserData)` will be called to release the ArrayBuffer's reference on the
80 * `freeFunc()` must not call any JSAPI functions that could cause a garbage
83 * The caller must keep the buffer alive until `freeFunc()` is called, or, if
84 * `freeFunc` is null, until the JSRuntime is destroyed.
86 * The caller must not access the buffer on other threads. The JS engine will
87 * not allow the buffer to be transferred to other threads. If you try to
88 * transfer an external ArrayBuffer to another thread, the data is copied to a
89 * new malloc buffer. `freeFunc()` must be threadsafe, and may be called from
92 * This allows ArrayBuffers to be used with embedder objects that use reference
93 * counting, for example. In that case the caller is responsible
94 * for incrementing the reference count before passing the contents to this
95 * function. This also allows using non-reference-counted contents that must be
96 * freed with some function other than free().
98 extern JS_PUBLIC_API JSObject
* NewExternalArrayBuffer(
99 JSContext
* cx
, size_t nbytes
, void* contents
,
100 BufferContentsFreeFunc freeFunc
, void* freeUserData
= nullptr);
103 * Create a new ArrayBuffer with the given non-null |contents|.
105 * Ownership of |contents| remains with the caller: it isn't transferred to the
106 * returned ArrayBuffer. Callers of this function *must* ensure that they
107 * perform these two steps, in this order, to properly relinquish ownership of
110 * 1. Call |JS::DetachArrayBuffer| on the buffer returned by this function.
111 * (|JS::DetachArrayBuffer| is generally fallible, but a call under these
112 * circumstances is guaranteed to succeed.)
113 * 2. |contents| may be deallocated or discarded consistent with the manner
114 * in which it was allocated.
116 * Do not simply allow the returned buffer to be garbage-collected before
117 * deallocating |contents|, because in general there is no way to know *when*
118 * an object is fully garbage-collected to the point where this would be safe.
120 extern JS_PUBLIC_API JSObject
* NewArrayBufferWithUserOwnedContents(
121 JSContext
* cx
, size_t nbytes
, void* contents
);
124 * Create a new mapped ArrayBuffer with the given memory mapped contents. It
125 * must be legal to free the contents pointer by unmapping it. On success,
126 * ownership is transferred to the new mapped ArrayBuffer.
128 extern JS_PUBLIC_API JSObject
* NewMappedArrayBufferWithContents(JSContext
* cx
,
133 * Create memory mapped ArrayBuffer contents.
134 * Caller must take care of closing fd after calling this function.
136 extern JS_PUBLIC_API
void* CreateMappedArrayBufferContents(int fd
,
141 * Release the allocated resource of mapped ArrayBuffer contents before the
143 * If a new object has been created by JS::NewMappedArrayBufferWithContents()
144 * with this content, then JS::DetachArrayBuffer() should be used instead to
145 * release the resource used by the object.
147 extern JS_PUBLIC_API
void ReleaseMappedArrayBufferContents(void* contents
,
153 * Check whether obj supports the JS::GetArrayBuffer* APIs. Note that this may
154 * return false if a security wrapper is encountered that denies the unwrapping.
155 * If this test succeeds, then it is safe to call the various predicate and
156 * accessor JSAPI calls defined below.
158 extern JS_PUBLIC_API
bool IsArrayBufferObject(JSObject
* obj
);
163 * Check whether the obj is a detached ArrayBufferObject. Note that this may
164 * return false if a security wrapper is encountered that denies the
167 extern JS_PUBLIC_API
bool IsDetachedArrayBufferObject(JSObject
* obj
);
170 * Check whether the obj is ArrayBufferObject and memory mapped. Note that this
171 * may return false if a security wrapper is encountered that denies the
174 extern JS_PUBLIC_API
bool IsMappedArrayBufferObject(JSObject
* obj
);
177 * Return true if the ArrayBuffer |obj| contains any data, i.e. it is not a
178 * detached ArrayBuffer. (ArrayBuffer.prototype is not an ArrayBuffer.)
180 * |obj| must have passed a JS::IsArrayBufferObject test, or somehow be known
181 * that it would pass such a test: it is an ArrayBuffer or a wrapper of an
182 * ArrayBuffer, and the unwrapping will succeed.
184 extern JS_PUBLIC_API
bool ArrayBufferHasData(JSObject
* obj
);
188 extern JS_PUBLIC_API JSObject
* UnwrapArrayBuffer(JSObject
* obj
);
191 * Attempt to unwrap |obj| as an ArrayBuffer.
193 * If |obj| *is* an ArrayBuffer, return it unwrapped and set |*length| and
194 * |*data| to weakly refer to the ArrayBuffer's contents.
196 * If |obj| isn't an ArrayBuffer, return nullptr and do not modify |*length| or
199 extern JS_PUBLIC_API JSObject
* GetObjectAsArrayBuffer(JSObject
* obj
,
204 * Return the available byte length of an ArrayBuffer.
206 * |obj| must have passed a JS::IsArrayBufferObject test, or somehow be known
207 * that it would pass such a test: it is an ArrayBuffer or a wrapper of an
208 * ArrayBuffer, and the unwrapping will succeed.
210 extern JS_PUBLIC_API
size_t GetArrayBufferByteLength(JSObject
* obj
);
212 // This one isn't inlined because there are a bunch of different ArrayBuffer
213 // classes that would have to be individually handled here.
215 // There is an isShared out argument for API consistency (eases use from DOM).
216 // It will always be set to false.
217 extern JS_PUBLIC_API
void GetArrayBufferLengthAndData(JSObject
* obj
,
219 bool* isSharedMemory
,
223 * Return a pointer to the start of the data referenced by a typed array. The
224 * data is still owned by the typed array, and should not be modified on
225 * another thread. Furthermore, the pointer can become invalid on GC (if the
226 * data is small and fits inside the array's GC header), so callers must take
227 * care not to hold on across anything that could GC.
229 * |obj| must have passed a JS::IsArrayBufferObject test, or somehow be known
230 * that it would pass such a test: it is an ArrayBuffer or a wrapper of an
231 * ArrayBuffer, and the unwrapping will succeed.
233 * |*isSharedMemory| is always set to false. The argument is present to
234 * simplify its use from code that also interacts with SharedArrayBuffer.
236 extern JS_PUBLIC_API
uint8_t* GetArrayBufferData(JSObject
* obj
,
237 bool* isSharedMemory
,
238 const AutoRequireNoGC
&);
243 * Detach an ArrayBuffer, causing all associated views to no longer refer to
244 * the ArrayBuffer's original attached memory.
246 * This function throws only if it is provided a non-ArrayBuffer object or if
247 * the provided ArrayBuffer is a WASM-backed ArrayBuffer or an ArrayBuffer used
250 extern JS_PUBLIC_API
bool DetachArrayBuffer(JSContext
* cx
,
251 Handle
<JSObject
*> obj
);
254 * Steal the contents of the given ArrayBuffer. The ArrayBuffer has its length
255 * set to 0 and its contents array cleared. The caller takes ownership of the
256 * return value and must free it or transfer ownership via
257 * JS::NewArrayBufferWithContents when done using it.
259 extern JS_PUBLIC_API
void* StealArrayBufferContents(JSContext
* cx
,
260 Handle
<JSObject
*> obj
);
263 * Enable or disable support for large (>= 2 GB) ArrayBuffers on 64-bit builds.
264 * Has no effect on 32-bit builds.
266 extern JS_PUBLIC_API
void SetLargeArrayBuffersEnabled(bool enable
);
270 #endif /* js_ArrayBuffer_h */