Bug 1690340 - Part 4: Insert the "Page Source" before the "Extensions for Developers...
[gecko.git] / js / public / ArrayBuffer.h
blobcf30faced0072f83c91262e2eadc99a127c0db08
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;
22 namespace JS {
24 // CREATION
26 /**
27 * Create a new ArrayBuffer with the given byte length.
29 extern JS_PUBLIC_API JSObject* NewArrayBuffer(JSContext* cx, size_t nbytes);
31 /**
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
34 * by |JS_free|.
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,
46 size_t nbytes,
47 void* contents);
49 /**
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);
72 /**
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
78 * contents.
80 * `freeFunc()` must not call any JSAPI functions that could cause a garbage
81 * collection.
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
90 * any thread.
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
108 * |contents|:
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,
129 size_t nbytes,
130 void* contents);
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,
137 size_t offset,
138 size_t length);
141 * Release the allocated resource of mapped ArrayBuffer contents before the
142 * object is created.
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,
148 size_t length);
150 // TYPE TESTING
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);
160 // PREDICATES
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
165 * unwrapping.
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
172 * unwrapping.
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);
186 // ACCESSORS
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
197 * |*data|.
199 extern JS_PUBLIC_API JSObject* GetObjectAsArrayBuffer(JSObject* obj,
200 size_t* length,
201 uint8_t** data);
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,
218 size_t* length,
219 bool* isSharedMemory,
220 uint8_t** data);
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&);
240 // MUTATORS
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
248 * in asm.js code.
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);
268 } // namespace JS
270 #endif /* js_ArrayBuffer_h */