Bug 1532005 - Implement a new js/public/ArrayBuffer.h header to centralize functionality for creating and interacting with ArrayBuffers. r=sfink

Differential Revision: https://phabricator.services.mozilla.com/D21827

--HG--
extra : rebase_source : 833bbfce12d90bcb92f7cd88ec65247e48c024c0
This commit is contained in:
Jeff Walden 2019-03-04 15:19:16 -08:00
parent b15a5f46a8
commit 3f385ffa33
44 changed files with 588 additions and 448 deletions

View File

@ -18,6 +18,7 @@
#include "nsStreamUtils.h"
#include "nsStringStream.h"
#include "js/ArrayBuffer.h" // JS::NewArrayBufferWithContents
#include "js/JSON.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/Exceptions.h"
@ -386,8 +387,8 @@ void BodyUtil::ConsumeArrayBuffer(JSContext* aCx,
uint32_t aInputLength, uint8_t* aInput,
ErrorResult& aRv) {
JS::Rooted<JSObject*> arrayBuffer(aCx);
arrayBuffer = JS_NewArrayBufferWithContents(aCx, aInputLength,
reinterpret_cast<void*>(aInput));
arrayBuffer = JS::NewArrayBufferWithContents(aCx, aInputLength,
reinterpret_cast<void*>(aInput));
if (!arrayBuffer) {
JS_ClearPendingException(aCx);
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);

View File

@ -20,6 +20,7 @@
#include "imgRequestProxy.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "js/ArrayBuffer.h" // JS::{GetArrayBufferData,IsArrayBufferObject,NewArrayBuffer}
#include "js/JSON.h"
#include "js/Value.h"
#include "Layers.h"
@ -6078,16 +6079,16 @@ nsresult nsContentUtils::CreateArrayBuffer(JSContext* aCx,
}
int32_t dataLen = aData.Length();
*aResult = JS_NewArrayBuffer(aCx, dataLen);
*aResult = JS::NewArrayBuffer(aCx, dataLen);
if (!*aResult) {
return NS_ERROR_FAILURE;
}
if (dataLen > 0) {
NS_ASSERTION(JS_IsArrayBufferObject(*aResult), "What happened?");
NS_ASSERTION(JS::IsArrayBufferObject(*aResult), "What happened?");
JS::AutoCheckCannotGC nogc;
bool isShared;
memcpy(JS_GetArrayBufferData(*aResult, &isShared, nogc),
memcpy(JS::GetArrayBufferData(*aResult, &isShared, nogc),
aData.BeginReading(), dataLen);
MOZ_ASSERT(!isShared);
}

View File

@ -7,6 +7,11 @@
#ifndef mozilla_dom_TypedArray_h
#define mozilla_dom_TypedArray_h
#include "jsfriendapi.h" // js::Scalar
#include "js/ArrayBuffer.h"
#include "js/SharedArrayBuffer.h"
#include "js/GCAPI.h" // JS::AutoCheckCannotGC
#include "js/RootingAPI.h" // JS::Rooted
#include "mozilla/Attributes.h"
#include "mozilla/Move.h"
#include "mozilla/dom/BindingDeclarations.h"
@ -72,7 +77,7 @@ struct TypedArray_base : public SpiderMonkeyInterfaceObjectStorage,
// value if the view may not have been computed and if the value is
// known to represent a JS TypedArray.
//
// (Just use JS_IsSharedArrayBuffer() to test if any object is of
// (Just use JS::IsSharedArrayBuffer() to test if any object is of
// that type.)
//
// Code that elects to allow views that map shared memory to be used
@ -257,13 +262,13 @@ typedef ArrayBufferView_base<js::UnwrapArrayBufferView,
js::GetArrayBufferViewLengthAndData,
JS_GetArrayBufferViewType>
ArrayBufferView;
typedef TypedArray<uint8_t, js::UnwrapArrayBuffer, JS_GetArrayBufferData,
js::GetArrayBufferLengthAndData, JS_NewArrayBuffer>
typedef TypedArray<uint8_t, JS::UnwrapArrayBuffer, JS::GetArrayBufferData,
JS::GetArrayBufferLengthAndData, JS::NewArrayBuffer>
ArrayBuffer;
typedef TypedArray<
uint8_t, js::UnwrapSharedArrayBuffer, JS_GetSharedArrayBufferData,
js::GetSharedArrayBufferLengthAndData, JS_NewSharedArrayBuffer>
uint8_t, JS::UnwrapSharedArrayBuffer, JS::GetSharedArrayBufferData,
JS::GetSharedArrayBufferLengthAndData, JS::NewSharedArrayBuffer>
SharedArrayBuffer;
// A class for converting an nsTArray to a TypedArray

View File

@ -10,6 +10,7 @@
#include "nsIGlobalObject.h"
#include "nsITimer.h"
#include "js/ArrayBuffer.h" // JS::NewArrayBufferWithContents
#include "mozilla/Base64.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/dom/DOMException.h"
@ -180,7 +181,7 @@ void FileReader::OnLoadEndArrayBuffer() {
JSContext* cx = jsapi.cx();
mResultArrayBuffer = JS_NewArrayBufferWithContents(cx, mDataLen, mFileData);
mResultArrayBuffer = JS::NewArrayBufferWithContents(cx, mDataLen, mFileData);
if (mResultArrayBuffer) {
mFileData = nullptr; // Transfer ownership
FreeDataAndDispatchSuccess();

View File

@ -6,7 +6,9 @@
#include "FileReaderSync.h"
#include "jsfriendapi.h"
#include "js/ArrayBuffer.h" // JS::NewArrayBufferWithContents
#include "js/RootingAPI.h" // JS::{,Mutable}Handle
#include "js/Utility.h" // js::ArrayBufferContentsArena, JS::FreePolicy, js_pod_arena_malloc
#include "mozilla/Unused.h"
#include "mozilla/Base64.h"
#include "mozilla/dom/File.h"
@ -83,7 +85,7 @@ void FileReaderSync::ReadAsArrayBuffer(JSContext* aCx,
}
JSObject* arrayBuffer =
JS_NewArrayBufferWithContents(aCx, blobSize, bufferData.get());
JS::NewArrayBufferWithContents(aCx, blobSize, bufferData.get());
if (!arrayBuffer) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;

View File

@ -9,6 +9,7 @@
#include <algorithm>
#include <stdint.h> // for UINT32_MAX, uintptr_t
#include "IndexedDatabaseManager.h"
#include "js/ArrayBuffer.h" // JS::{IsArrayBufferObject,NewArrayBuffer{,WithContents},GetArrayBufferLengthAndData}
#include "js/Date.h"
#include "js/MemoryFunctions.h"
#include "js/Value.h"
@ -296,7 +297,7 @@ nsresult Key::EncodeJSValInternal(JSContext* aCx, JS::Handle<JS::Value> aVal,
return NS_OK;
}
if (JS_IsArrayBufferObject(obj)) {
if (JS::IsArrayBufferObject(obj)) {
return EncodeBinary(obj, /* aIsViewObject */ false, aTypeOffset);
}
@ -635,7 +636,7 @@ nsresult Key::EncodeBinary(JSObject* aObject, bool aIsViewObject,
js::GetArrayBufferViewLengthAndData(aObject, &bufferLength, &unused,
&bufferData);
} else {
js::GetArrayBufferLengthAndData(aObject, &bufferLength, &unused,
JS::GetArrayBufferLengthAndData(aObject, &bufferLength, &unused,
&bufferData);
}
@ -661,7 +662,7 @@ JSObject* Key::DecodeBinary(const unsigned char*& aPos,
}
if (!size) {
return JS_NewArrayBuffer(aCx, 0);
return JS::NewArrayBuffer(aCx, 0);
}
uint8_t* out = static_cast<uint8_t*>(JS_malloc(aCx, size));
@ -696,7 +697,7 @@ JSObject* Key::DecodeBinary(const unsigned char*& aPos,
MOZ_ASSERT(static_cast<size_t>(pos - out) == size,
"Should have written the whole buffer");
return JS_NewArrayBufferWithContents(aCx, size, out);
return JS::NewArrayBufferWithContents(aCx, size, out);
}
nsresult Key::BindToStatement(mozIStorageStatement* aStatement,

View File

@ -7,6 +7,7 @@
#include "AudioBuffer.h"
#include "mozilla/dom/AudioBufferBinding.h"
#include "jsfriendapi.h"
#include "js/ArrayBuffer.h" // JS::StealArrayBufferContents
#include "mozilla/ErrorResult.h"
#include "AudioSegment.h"
#include "AudioChannelFormat.h"
@ -426,7 +427,7 @@ AudioBuffer::StealJSArrayDataIntoSharedChannels(JSContext* aJSContext) {
// RestoreJSChannelData, where they are created unshared.
MOZ_ASSERT(!isSharedMemory);
auto stolenData = arrayBuffer
? static_cast<float*>(JS_StealArrayBufferContents(
? static_cast<float*>(JS::StealArrayBufferContents(
aJSContext, arrayBuffer))
: nullptr;
if (stolenData) {

View File

@ -58,6 +58,7 @@
#include "DynamicsCompressorNode.h"
#include "GainNode.h"
#include "IIRFilterNode.h"
#include "js/ArrayBuffer.h" // JS::StealArrayBufferContents
#include "MediaElementAudioSourceNode.h"
#include "MediaStreamAudioDestinationNode.h"
#include "MediaStreamAudioSourceNode.h"
@ -584,7 +585,7 @@ already_AddRefed<Promise> AudioContext::DecodeAudioData(
// Detach the array buffer
size_t length = aBuffer.Length();
uint8_t* data = static_cast<uint8_t*>(JS_StealArrayBufferContents(cx, obj));
uint8_t* data = static_cast<uint8_t*>(JS::StealArrayBufferContents(cx, obj));
// Sniff the content of the media.
// Failed type sniffing will be handled by AsyncDecodeWebAudio.

View File

@ -40,7 +40,7 @@ class ThreadSharedFloatArrayBufferList final : public ThreadSharedObject {
}
/**
* Create with buffers suitable for transfer to
* JS_NewArrayBufferWithContents(). The buffer contents are uninitialized
* JS::NewArrayBufferWithContents(). The buffer contents are uninitialized
* and so should be set using GetDataForWrite().
*/
static already_AddRefed<ThreadSharedFloatArrayBufferList> Create(

View File

@ -301,7 +301,7 @@ void MediaDecodeTask::FinishDecode() {
mDecodeJob.mBuffer.mChannelData.SetLength(channelCount);
#if AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_FLOAT32
// This buffer has separate channel arrays that could be transferred to
// JS_NewArrayBufferWithContents(), but AudioBuffer::RestoreJSChannelData()
// JS::NewArrayBufferWithContents(), but AudioBuffer::RestoreJSChannelData()
// does not yet take advantage of this.
RefPtr<ThreadSharedFloatArrayBufferList> buffer =
ThreadSharedFloatArrayBufferList::Create(channelCount, resampledFrames,

View File

@ -14,8 +14,10 @@
#include "nsITCPSocketCallback.h"
#include "TCPSocket.h"
#include "nsContentUtils.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "js/ArrayBuffer.h" // JS::NewArrayBufferWithContents
#include "js/RootingAPI.h" // JS::MutableHandle
#include "js/Utility.h" // js::ArrayBufferContentsArena, JS::FreePolicy, js_pod_arena_malloc
#include "js/Value.h" // JS::Value
using mozilla::net::gNeckoChild;
@ -31,9 +33,9 @@ bool DeserializeArrayBuffer(JSContext* cx,
memcpy(data.get(), aBuffer.Elements(), aBuffer.Length());
JSObject* obj =
JS_NewArrayBufferWithContents(cx, aBuffer.Length(), data.get());
JS::NewArrayBufferWithContents(cx, aBuffer.Length(), data.get());
if (!obj) return false;
// If JS_NewArrayBufferWithContents returns non-null, the ownership of
// If JS::NewArrayBufferWithContents returns non-null, the ownership of
// the data is transfered to obj, so we release the ownership here.
mozilla::Unused << data.release();

View File

@ -7,7 +7,10 @@
#include "SDBConnection.h"
#include "ActorsChild.h"
#include "jsfriendapi.h"
#include "jsfriendapi.h" // JS_GetObjectAsArrayBufferView
#include "js/ArrayBuffer.h" // JS::{GetObjectAsArrayBuffer,IsArrayBufferObject}
#include "js/RootingAPI.h" // JS::{Handle,Rooted}
#include "js/Value.h" // JS::Value
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/ipc/BackgroundUtils.h"
@ -29,7 +32,7 @@ nsresult GetWriteData(JSContext* aCx, JS::Handle<JS::Value> aValue,
JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
bool isView = false;
if (JS_IsArrayBufferObject(obj) ||
if (JS::IsArrayBufferObject(obj) ||
(isView = JS_IsArrayBufferViewObject(obj))) {
uint8_t* data;
uint32_t length;
@ -37,7 +40,7 @@ nsresult GetWriteData(JSContext* aCx, JS::Handle<JS::Value> aValue,
if (isView) {
JS_GetObjectAsArrayBufferView(obj, &length, &unused, &data);
} else {
JS_GetObjectAsArrayBuffer(obj, &length, &data);
JS::GetObjectAsArrayBuffer(obj, &length, &data);
}
if (NS_WARN_IF(!aData.Assign(reinterpret_cast<char*>(data), length,

View File

@ -76,9 +76,12 @@
#include "nsStringBuffer.h"
#include "nsIFileChannel.h"
#include "mozilla/Telemetry.h"
#include "js/JSON.h"
#include "js/ArrayBuffer.h" // JS::{Create,Release}MappedArrayBufferContents,New{,Mapped}ArrayBufferWithContents
#include "js/JSON.h" // JS_ParseJSON
#include "js/MemoryFunctions.h"
#include "jsfriendapi.h"
#include "js/RootingAPI.h" // JS::{{,Mutable}Handle,Rooted}
#include "js/Value.h" // JS::{,Undefined}Value
#include "jsapi.h" // JS_ClearPendingException
#include "GeckoProfiler.h"
#include "mozilla/dom/XMLHttpRequestBinding.h"
#include "mozilla/Attributes.h"
@ -3629,7 +3632,7 @@ void ArrayBufferBuilder::reset() {
}
if (mMapPtr) {
JS_ReleaseMappedArrayBufferContents(mMapPtr, mLength);
JS::ReleaseMappedArrayBufferContents(mMapPtr, mLength);
mMapPtr = nullptr;
}
@ -3705,9 +3708,9 @@ bool ArrayBufferBuilder::append(const uint8_t* aNewData, uint32_t aDataLen,
JSObject* ArrayBufferBuilder::getArrayBuffer(JSContext* aCx) {
if (mMapPtr) {
JSObject* obj = JS_NewMappedArrayBufferWithContents(aCx, mLength, mMapPtr);
JSObject* obj = JS::NewMappedArrayBufferWithContents(aCx, mLength, mMapPtr);
if (!obj) {
JS_ReleaseMappedArrayBufferContents(mMapPtr, mLength);
JS::ReleaseMappedArrayBufferContents(mMapPtr, mLength);
}
mMapPtr = nullptr;
@ -3724,7 +3727,7 @@ JSObject* ArrayBufferBuilder::getArrayBuffer(JSContext* aCx) {
}
}
JSObject* obj = JS_NewArrayBufferWithContents(aCx, mLength, mDataPtr);
JSObject* obj = JS::NewArrayBufferWithContents(aCx, mLength, mDataPtr);
mLength = mCapacity = 0;
if (!obj) {
js_free(mDataPtr);
@ -3758,7 +3761,7 @@ nsresult ArrayBufferBuilder::mapToFileInPackage(const nsCString& aFile,
if (NS_FAILED(rv)) {
return rv;
}
mMapPtr = JS_CreateMappedArrayBufferContents(
mMapPtr = JS::CreateMappedArrayBufferContents(
PR_FileDesc2NativeHandle(pr_fd), offset, size);
if (mMapPtr) {
mLength = size;

View File

@ -10,9 +10,13 @@
#include "nsIRunnable.h"
#include "nsIXPConnect.h"
#include "jsapi.h" // JS::AutoValueArray
#include "jsfriendapi.h"
#include "js/TracingAPI.h"
#include "js/ArrayBuffer.h" // JS::Is{,Detached}ArrayBufferObject
#include "js/GCPolicyAPI.h"
#include "js/RootingAPI.h" // JS::{Handle,Heap},PersistentRooted
#include "js/TracingAPI.h"
#include "js/Value.h" // JS::{Undefined,}Value
#include "mozilla/ArrayUtils.h"
#include "mozilla/dom/Exceptions.h"
#include "mozilla/dom/Event.h"
@ -1034,14 +1038,14 @@ bool EventRunnable::PreDispatch(WorkerPrivate* /* unused */) {
JS::Rooted<JS::Value> transferable(cx);
JS::Rooted<JSObject*> obj(
cx, response.isObject() ? &response.toObject() : nullptr);
if (obj && JS_IsArrayBufferObject(obj)) {
if (obj && JS::IsArrayBufferObject(obj)) {
// Use cached response if the arraybuffer has been transfered.
if (mProxy->mArrayBufferResponseWasTransferred) {
MOZ_ASSERT(JS_IsDetachedArrayBufferObject(obj));
MOZ_ASSERT(JS::IsDetachedArrayBufferObject(obj));
mUseCachedArrayBufferResponse = true;
doClone = false;
} else {
MOZ_ASSERT(!JS_IsDetachedArrayBufferObject(obj));
MOZ_ASSERT(!JS::IsDetachedArrayBufferObject(obj));
JS::AutoValueArray<1> argv(cx);
argv[0].set(response);
obj = JS_NewArrayObject(cx, argv);
@ -1221,8 +1225,7 @@ bool EventRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) {
target->DispatchEvent(*event);
// After firing the event set mResponse to JSVAL_NULL for chunked response
// types.
// After firing the event set mResponse to null for chunked response types.
if (StringBeginsWith(mResponseType, NS_LITERAL_STRING("moz-chunked-"))) {
xhr->NullResponseText();
}
@ -2208,7 +2211,7 @@ void XMLHttpRequestWorker::UpdateState(const StateData& aStateData,
bool aUseCachedArrayBufferResponse) {
if (aUseCachedArrayBufferResponse) {
MOZ_ASSERT(mStateData.mResponse.isObject() &&
JS_IsArrayBufferObject(&mStateData.mResponse.toObject()));
JS::IsArrayBufferObject(&mStateData.mResponse.toObject()));
JS::Rooted<JS::Value> response(mWorkerPrivate->GetJSContext(),
mStateData.mResponse);

View File

@ -28,7 +28,9 @@
#include "ScriptedNotificationObserver.h"
#include "imgIScriptedNotificationObserver.h"
#include "gfxPlatform.h"
#include "jsfriendapi.h"
#include "js/ArrayBuffer.h"
#include "js/RootingAPI.h" // JS::{Handle,Rooted}
#include "js/Value.h" // JS::Value
using namespace mozilla::gfx;
@ -169,7 +171,7 @@ imgTools::~imgTools() { /* destructor code */
}
NS_IMETHODIMP
imgTools::DecodeImageFromArrayBuffer(JS::HandleValue aArrayBuffer,
imgTools::DecodeImageFromArrayBuffer(JS::Handle<JS::Value> aArrayBuffer,
const nsACString& aMimeType,
JSContext* aCx,
imgIContainer** aContainer) {
@ -178,7 +180,7 @@ imgTools::DecodeImageFromArrayBuffer(JS::HandleValue aArrayBuffer,
}
JS::Rooted<JSObject*> obj(aCx,
js::UnwrapArrayBuffer(&aArrayBuffer.toObject()));
JS::UnwrapArrayBuffer(&aArrayBuffer.toObject()));
if (!obj) {
return NS_ERROR_FAILURE;
}
@ -187,7 +189,7 @@ imgTools::DecodeImageFromArrayBuffer(JS::HandleValue aArrayBuffer,
uint32_t bufferLength = 0;
bool isSharedMemory = false;
js::GetArrayBufferLengthAndData(obj, &bufferLength, &isSharedMemory,
JS::GetArrayBufferLengthAndData(obj, &bufferLength, &isSharedMemory,
&bufferData);
return DecodeImageFromBuffer((char*)bufferData, bufferLength, aMimeType,
aContainer);

237
js/public/ArrayBuffer.h Normal file
View File

@ -0,0 +1,237 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* ArrayBuffer functionality. */
#ifndef js_ArrayBuffer_h
#define js_ArrayBuffer_h
#include <stddef.h> // size_t
#include <stdint.h> // uint32_t
#include "jstypes.h" // JS_PUBLIC_API
#include "js/GCAPI.h" // JS::AutoRequireNoGC
#include "js/RootingAPI.h" // JS::Handle
struct JSContext;
class JSObject;
namespace JS {
// CREATION
/**
* Create a new ArrayBuffer with the given byte length.
*/
extern JS_PUBLIC_API JSObject* NewArrayBuffer(JSContext* cx, uint32_t nbytes);
/**
* Create a new ArrayBuffer with the given |contents|, which may be null only
* if |nbytes == 0|. |contents| must be allocated compatible with deallocation
* by |JS_free|.
*
* If and only if an ArrayBuffer is successfully created and returned,
* ownership of |contents| is transferred to the new ArrayBuffer.
*/
extern JS_PUBLIC_API JSObject* NewArrayBufferWithContents(JSContext* cx,
size_t nbytes,
void* contents);
using BufferContentsFreeFunc = void (*)(void* contents, void* userData);
/**
* Create a new ArrayBuffer with the given contents. The contents must not be
* modified by any other code, internal or external.
*
* When the ArrayBuffer is ready to be disposed of, `freeFunc(contents,
* freeUserData)` will be called to release the ArrayBuffer's reference on the
* contents.
*
* `freeFunc()` must not call any JSAPI functions that could cause a garbage
* collection.
*
* The caller must keep the buffer alive until `freeFunc()` is called, or, if
* `freeFunc` is null, until the JSRuntime is destroyed.
*
* The caller must not access the buffer on other threads. The JS engine will
* not allow the buffer to be transferred to other threads. If you try to
* transfer an external ArrayBuffer to another thread, the data is copied to a
* new malloc buffer. `freeFunc()` must be threadsafe, and may be called from
* any thread.
*
* This allows ArrayBuffers to be used with embedder objects that use reference
* counting, for example. In that case the caller is responsible
* for incrementing the reference count before passing the contents to this
* function. This also allows using non-reference-counted contents that must be
* freed with some function other than free().
*/
extern JS_PUBLIC_API JSObject* NewExternalArrayBuffer(
JSContext* cx, size_t nbytes, void* contents,
BufferContentsFreeFunc freeFunc, void* freeUserData = nullptr);
/**
* Create a new ArrayBuffer with the given non-null |contents|.
*
* Ownership of |contents| remains with the caller: it isn't transferred to the
* returned ArrayBuffer. Callers of this function *must* ensure that they
* perform these two steps, in this order, to properly relinquish ownership of
* |contents|:
*
* 1. Call |JS::DetachArrayBuffer| on the buffer returned by this function.
* (|JS::DetachArrayBuffer| is generally fallible, but a call under these
* circumstances is guaranteed to succeed.)
* 2. |contents| may be deallocated or discarded consistent with the manner
* in which it was allocated.
*
* Do not simply allow the returned buffer to be garbage-collected before
* deallocating |contents|, because in general there is no way to know *when*
* an object is fully garbage-collected to the point where this would be safe.
*/
extern JS_PUBLIC_API JSObject* NewArrayBufferWithUserOwnedContents(
JSContext* cx, size_t nbytes, void* contents);
/**
* Create a new mapped ArrayBuffer with the given memory mapped contents. It
* must be legal to free the contents pointer by unmapping it. On success,
* ownership is transferred to the new mapped ArrayBuffer.
*/
extern JS_PUBLIC_API JSObject* NewMappedArrayBufferWithContents(JSContext* cx,
size_t nbytes,
void* contents);
/**
* Create memory mapped ArrayBuffer contents.
* Caller must take care of closing fd after calling this function.
*/
extern JS_PUBLIC_API void* CreateMappedArrayBufferContents(int fd,
size_t offset,
size_t length);
/**
* Release the allocated resource of mapped ArrayBuffer contents before the
* object is created.
* If a new object has been created by JS::NewMappedArrayBufferWithContents()
* with this content, then JS::DetachArrayBuffer() should be used instead to
* release the resource used by the object.
*/
extern JS_PUBLIC_API void ReleaseMappedArrayBufferContents(void* contents,
size_t length);
// TYPE TESTING
/*
* Check whether obj supports the JS::GetArrayBuffer* APIs. Note that this may
* return false if a security wrapper is encountered that denies the unwrapping.
* If this test succeeds, then it is safe to call the various predicate and
* accessor JSAPI calls defined below.
*/
extern JS_PUBLIC_API bool IsArrayBufferObject(JSObject* obj);
// PREDICATES
/**
* Check whether the obj is a detached ArrayBufferObject. Note that this may
* return false if a security wrapper is encountered that denies the
* unwrapping.
*/
extern JS_PUBLIC_API bool IsDetachedArrayBufferObject(JSObject* obj);
/**
* Check whether the obj is ArrayBufferObject and memory mapped. Note that this
* may return false if a security wrapper is encountered that denies the
* unwrapping.
*/
extern JS_PUBLIC_API bool IsMappedArrayBufferObject(JSObject* obj);
/**
* Return true if the ArrayBuffer |obj| contains any data, i.e. it is not a
* detached ArrayBuffer. (ArrayBuffer.prototype is not an ArrayBuffer.)
*
* |obj| must have passed a JS::IsArrayBufferObject test, or somehow be known
* that it would pass such a test: it is an ArrayBuffer or a wrapper of an
* ArrayBuffer, and the unwrapping will succeed.
*/
extern JS_PUBLIC_API bool ArrayBufferHasData(JSObject* obj);
// ACCESSORS
extern JS_PUBLIC_API JSObject* UnwrapArrayBuffer(JSObject* obj);
/**
* Attempt to unwrap |obj| as an ArrayBuffer.
*
* If |obj| *is* an ArrayBuffer, return it unwrapped and set |*length| and
* |*data| to weakly refer to the ArrayBuffer's contents.
*
* If |obj| isn't an ArrayBuffer, return nullptr and do not modify |*length| or
* |*data|.
*/
extern JS_PUBLIC_API JSObject* GetObjectAsArrayBuffer(JSObject* obj,
uint32_t* length,
uint8_t** data);
/**
* Return the available byte length of an ArrayBuffer.
*
* |obj| must have passed a JS::IsArrayBufferObject test, or somehow be known
* that it would pass such a test: it is an ArrayBuffer or a wrapper of an
* ArrayBuffer, and the unwrapping will succeed.
*/
extern JS_PUBLIC_API uint32_t GetArrayBufferByteLength(JSObject* obj);
// This one isn't inlined because there are a bunch of different ArrayBuffer
// classes that would have to be individually handled here.
//
// There is an isShared out argument for API consistency (eases use from DOM).
// It will always be set to false.
extern JS_PUBLIC_API void GetArrayBufferLengthAndData(JSObject* obj,
uint32_t* length,
bool* isSharedMemory,
uint8_t** data);
/**
* Return a pointer to the start of the data referenced by a typed array. The
* data is still owned by the typed array, and should not be modified on
* another thread. Furthermore, the pointer can become invalid on GC (if the
* data is small and fits inside the array's GC header), so callers must take
* care not to hold on across anything that could GC.
*
* |obj| must have passed a JS::IsArrayBufferObject test, or somehow be known
* that it would pass such a test: it is an ArrayBuffer or a wrapper of an
* ArrayBuffer, and the unwrapping will succeed.
*
* |*isSharedMemory| is always set to false. The argument is present to
* simplify its use from code that also interacts with SharedArrayBuffer.
*/
extern JS_PUBLIC_API uint8_t* GetArrayBufferData(JSObject* obj,
bool* isSharedMemory,
const AutoRequireNoGC&);
// MUTATORS
/**
* Detach an ArrayBuffer, causing all associated views to no longer refer to
* the ArrayBuffer's original attached memory.
*
* This function throws only if it is provided a non-ArrayBuffer object or if
* the provided ArrayBuffer is a WASM-backed ArrayBuffer or an ArrayBuffer used
* in asm.js code.
*/
extern JS_PUBLIC_API bool DetachArrayBuffer(JSContext* cx,
Handle<JSObject*> obj);
/**
* Steal the contents of the given ArrayBuffer. The ArrayBuffer has its length
* set to 0 and its contents array cleared. The caller takes ownership of the
* return value and must free it or transfer ownership via
* JS::NewArrayBufferWithContents when done using it.
*/
extern JS_PUBLIC_API void* StealArrayBufferContents(JSContext* cx,
Handle<JSObject*> obj);
} // namespace JS
#endif /* js_ArrayBuffer_h */

View File

@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* ArrayBuffer functionality. */
#ifndef js_SharedArrayBuffer_h
#define js_SharedArrayBuffer_h
#include <stddef.h> // size_t
#include <stdint.h> // uint32_t
#include "jstypes.h" // JS_PUBLIC_API
#include "js/GCAPI.h" // JS::AutoRequireNoGC
struct JSContext;
class JSObject;
namespace JS {
// CREATION
/**
* Create a new SharedArrayBuffer with the given byte length. This
* may only be called if
* JS::RealmCreationOptionsRef(cx).getSharedMemoryAndAtomicsEnabled() is
* true.
*/
extern JS_PUBLIC_API JSObject* NewSharedArrayBuffer(JSContext* cx,
uint32_t nbytes);
// TYPE TESTING
/**
* Check whether obj supports the JS::GetSharedArrayBuffer* APIs. Note that
* this may return false if a security wrapper is encountered that denies the
* unwrapping. If this test succeeds, then it is safe to call the various
* accessor JSAPI calls defined below.
*/
extern JS_PUBLIC_API bool IsSharedArrayBufferObject(JSObject* obj);
// ACCESSORS
extern JS_PUBLIC_API JSObject* UnwrapSharedArrayBuffer(JSObject* obj);
extern JS_PUBLIC_API uint32_t GetSharedArrayBufferByteLength(JSObject* obj);
extern JS_PUBLIC_API uint8_t* GetSharedArrayBufferData(JSObject* obj,
bool* isSharedMemory,
const AutoRequireNoGC&);
// Ditto for SharedArrayBuffer.
//
// There is an isShared out argument for API consistency (eases use from DOM).
// It will always be set to true.
extern JS_PUBLIC_API void GetSharedArrayBufferLengthAndData(
JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data);
} // namespace JS
#endif /* js_SharedArrayBuffer_h */

View File

@ -284,7 +284,7 @@ const WHITELIST_FUNCTIONS: &'static [&'static str] = &[
"JS_ForwardGetPropertyTo",
"JS_ForwardSetPropertyTo",
"JS::GCTraceKindToAscii",
"js::GetArrayBufferLengthAndData",
"JS::GetArrayBufferLengthAndData",
"js::GetArrayBufferViewLengthAndData",
"js::GetFunctionNativeReserved",
"JS::GetNonCCWObjectGlobal",
@ -325,7 +325,7 @@ const WHITELIST_FUNCTIONS: &'static [&'static str] = &[
"JS_FireOnNewGlobalObject",
"JS_free",
"JS_GC",
"JS_GetArrayBufferData",
"JS::GetArrayBufferData",
"JS_GetArrayBufferViewType",
"JS_GetFloat32ArrayData",
"JS_GetFloat64ArrayData",
@ -363,7 +363,7 @@ const WHITELIST_FUNCTIONS: &'static [&'static str] = &[
"JS::LeaveRealm",
"JS_LinkConstructorAndPrototype",
"JS_MayResolveStandardClass",
"JS_NewArrayBuffer",
"JS::NewArrayBuffer",
"JS_NewArrayObject",
"JS_NewContext",
"JS_NewFloat32Array",
@ -448,7 +448,7 @@ const WHITELIST_FUNCTIONS: &'static [&'static str] = &[
"JS_TransplantObject",
"js::detail::ToWindowProxyIfWindowSlow",
"JS::UnhideScriptedCaller",
"js::UnwrapArrayBuffer",
"JS::UnwrapArrayBuffer",
"js::UnwrapArrayBufferView",
"js::UnwrapFloat32Array",
"js::UnwrapFloat64Array",

View File

@ -13,6 +13,7 @@ typedef uint32_t HashNumber;
#include "jsapi.h"
#include "jsfriendapi.h"
#include "js/ArrayBuffer.h"
#include "js/CompilationAndEvaluation.h"
#include "js/CompileOptions.h"
#include "js/ContextOptions.h"

View File

@ -252,8 +252,8 @@ typed_array_element!(ArrayBufferU8,
u8,
UnwrapArrayBuffer,
GetArrayBufferLengthAndData,
JS_NewArrayBuffer,
JS_GetArrayBufferData);
NewArrayBuffer,
GetArrayBufferData);
typed_array_element!(ArrayBufferViewU8,
u8,
UnwrapArrayBufferView,

View File

@ -9,6 +9,7 @@
#include "js/Stream.h"
#include "gc/Heap.h"
#include "js/ArrayBuffer.h" // JS::NewArrayBuffer
#include "js/PropertySpec.h"
#include "vm/Interpreter.h"
#include "vm/JSContext.h"
@ -3732,7 +3733,7 @@ static MOZ_MUST_USE JSObject* ReadableByteStreamControllerPullSteps(
// Step 5.a: Let buffer be
// Construct(%ArrayBuffer%, « autoAllocateChunkSize »).
JSObject* bufferObj = JS_NewArrayBuffer(cx, autoAllocateChunkSize);
JSObject* bufferObj = JS::NewArrayBuffer(cx, autoAllocateChunkSize);
// Step 5.b: If buffer is an abrupt completion,
// return a promise rejected with buffer.[[Value]].

View File

@ -41,6 +41,7 @@
#include "jit/BaselineJIT.h"
#include "jit/InlinableNatives.h"
#include "jit/JitRealm.h"
#include "js/ArrayBuffer.h" // JS::{DetachArrayBuffer,GetArrayBufferLengthAndData,NewArrayBufferWithContents}
#include "js/CharacterEncoding.h"
#include "js/CompilationAndEvaluation.h"
#include "js/CompileOptions.h"
@ -2846,7 +2847,7 @@ class CloneBufferObject : public NativeObject {
ArrayBufferObject* buffer = &args[0].toObject().as<ArrayBufferObject>();
bool isSharedMemory;
uint8_t* dataBytes = nullptr;
js::GetArrayBufferLengthAndData(buffer, &nbytes, &isSharedMemory,
JS::GetArrayBufferLengthAndData(buffer, &nbytes, &isSharedMemory,
&dataBytes);
MOZ_ASSERT(!isSharedMemory);
data = reinterpret_cast<char*>(dataBytes);
@ -2966,7 +2967,7 @@ class CloneBufferObject : public NativeObject {
data->ReadBytes(iter, buffer.get(), size);
auto* rawBuffer = buffer.release();
JSObject* arrayBuffer = JS_NewArrayBufferWithContents(cx, size, rawBuffer);
JSObject* arrayBuffer = JS::NewArrayBufferWithContents(cx, size, rawBuffer);
if (!arrayBuffer) {
js_free(rawBuffer);
return false;
@ -3190,7 +3191,7 @@ static bool DetachArrayBuffer(JSContext* cx, unsigned argc, Value* vp) {
}
RootedObject obj(cx, &args[0].toObject());
if (!JS_DetachArrayBuffer(cx, obj)) {
if (!JS::DetachArrayBuffer(cx, obj)) {
return false;
}

View File

@ -39,8 +39,10 @@
#include "gc/FreeOp.h"
#include "gc/Policy.h"
#include "jit/AtomicOperations.h"
#include "js/ArrayBuffer.h" // JS::{IsArrayBufferObject,GetArrayBufferData,GetArrayBuffer{ByteLength,Data}}
#include "js/CharacterEncoding.h"
#include "js/PropertySpec.h"
#include "js/SharedArrayBuffer.h" // JS::{GetSharedArrayBuffer{ByteLength,Data},IsSharedArrayBufferObject}
#include "js/StableStringChars.h"
#include "js/UniquePtr.h"
#include "js/Utility.h"
@ -3383,7 +3385,7 @@ static bool ImplicitConvert(JSContext* cx, HandleValue val,
arrObj, arrIndex);
}
break;
} else if (val.isObject() && JS_IsArrayBufferObject(valObj)) {
} else if (val.isObject() && JS::IsArrayBufferObject(valObj)) {
// Convert ArrayBuffer to pointer without any copy. This is only valid
// when converting an argument to a function call, as it is possible for
// the pointer to be invalidated by anything that runs JS code. (It is
@ -3396,7 +3398,7 @@ static bool ImplicitConvert(JSContext* cx, HandleValue val,
{
JS::AutoCheckCannotGC nogc;
bool isShared;
ptr = JS_GetArrayBufferData(valObj, &isShared, nogc);
ptr = JS::GetArrayBufferData(valObj, &isShared, nogc);
MOZ_ASSERT(!isShared); // Because ArrayBuffer
}
if (!ptr) {
@ -3405,7 +3407,7 @@ static bool ImplicitConvert(JSContext* cx, HandleValue val,
}
*static_cast<void**>(buffer) = ptr;
break;
} else if (val.isObject() && JS_IsSharedArrayBufferObject(valObj)) {
} else if (val.isObject() && JS::IsSharedArrayBufferObject(valObj)) {
// CTypes has not yet opted in to allowing shared memory pointers
// to escape. Exporting a pointer to the shared buffer without
// indicating sharedness would expose client code to races.
@ -3560,8 +3562,8 @@ static bool ImplicitConvert(JSContext* cx, HandleValue val,
// copy the array.
const bool bufferShared = cls == ESClass::SharedArrayBuffer;
uint32_t sourceLength =
bufferShared ? JS_GetSharedArrayBufferByteLength(valObj)
: JS_GetArrayBufferByteLength(valObj);
bufferShared ? JS::GetSharedArrayBufferByteLength(valObj)
: JS::GetArrayBufferByteLength(valObj);
size_t elementSize = CType::GetSize(baseType);
size_t arraySize = elementSize * targetLength;
if (arraySize != size_t(sourceLength)) {
@ -3575,9 +3577,9 @@ static bool ImplicitConvert(JSContext* cx, HandleValue val,
SharedMem<void*> src =
(bufferShared
? SharedMem<void*>::shared(
JS_GetSharedArrayBufferData(valObj, &isShared, nogc))
JS::GetSharedArrayBufferData(valObj, &isShared, nogc))
: SharedMem<void*>::unshared(
JS_GetArrayBufferData(valObj, &isShared, nogc)));
JS::GetArrayBufferData(valObj, &isShared, nogc)));
MOZ_ASSERT(isShared == bufferShared);
jit::AtomicOperations::memcpySafeWhenRacy(target, src, sourceLength);
break;

View File

@ -5,6 +5,7 @@
#include "jsfriendapi.h"
#include "builtin/TestingFunctions.h"
#include "js/ArrayBuffer.h" // JS::{GetArrayBuffer{ByteLength,Data},IsArrayBufferObject,NewArrayBuffer{,WithContents},StealArrayBufferContents}
#include "js/MemoryFunctions.h"
#include "jsapi-tests/tests.h"
@ -21,13 +22,13 @@ BEGIN_TEST(testArrayBuffer_bug720949_steal) {
JS::HandleObject testArray[NUM_TEST_BUFFERS] = {tarray_len1, tarray_len200};
// Single-element ArrayBuffer (uses fixed slots for storage)
CHECK(buf_len1 = JS_NewArrayBuffer(cx, sizes[0]));
CHECK(buf_len1 = JS::NewArrayBuffer(cx, sizes[0]));
CHECK(tarray_len1 = JS_NewInt32ArrayWithBuffer(cx, testBuf[0], 0, -1));
CHECK(JS_SetElement(cx, testArray[0], 0, MAGIC_VALUE_1));
// Many-element ArrayBuffer (uses dynamic storage)
CHECK(buf_len200 = JS_NewArrayBuffer(cx, 200 * sizeof(uint32_t)));
CHECK(buf_len200 = JS::NewArrayBuffer(cx, 200 * sizeof(uint32_t)));
CHECK(tarray_len200 = JS_NewInt32ArrayWithBuffer(cx, testBuf[1], 0, -1));
for (unsigned i = 0; i < NUM_TEST_BUFFERS; i++) {
@ -37,8 +38,8 @@ BEGIN_TEST(testArrayBuffer_bug720949_steal) {
JS::RootedValue v(cx);
// Byte lengths should all agree
CHECK(JS_IsArrayBufferObject(obj));
CHECK_EQUAL(JS_GetArrayBufferByteLength(obj), size);
CHECK(JS::IsArrayBufferObject(obj));
CHECK_EQUAL(JS::GetArrayBufferByteLength(obj), size);
CHECK(JS_GetProperty(cx, obj, "byteLength", &v));
CHECK(v.isInt32(size));
CHECK(JS_GetProperty(cx, view, "byteLength", &v));
@ -49,7 +50,7 @@ BEGIN_TEST(testArrayBuffer_bug720949_steal) {
{
JS::AutoCheckCannotGC nogc;
bool sharedDummy;
uint8_t* data = JS_GetArrayBufferData(obj, &sharedDummy, nogc);
uint8_t* data = JS::GetArrayBufferData(obj, &sharedDummy, nogc);
CHECK(data != nullptr);
*reinterpret_cast<uint32_t*>(data) = MAGIC_VALUE_2;
}
@ -57,28 +58,29 @@ BEGIN_TEST(testArrayBuffer_bug720949_steal) {
CHECK(v.isInt32(MAGIC_VALUE_2));
// Steal the contents
void* contents = JS_StealArrayBufferContents(cx, obj);
void* contents = JS::StealArrayBufferContents(cx, obj);
CHECK(contents != nullptr);
CHECK(JS_IsDetachedArrayBufferObject(obj));
CHECK(JS::IsDetachedArrayBufferObject(obj));
// Transfer to a new ArrayBuffer
JS::RootedObject dst(cx, JS_NewArrayBufferWithContents(cx, size, contents));
CHECK(JS_IsArrayBufferObject(dst));
JS::RootedObject dst(cx,
JS::NewArrayBufferWithContents(cx, size, contents));
CHECK(JS::IsArrayBufferObject(dst));
{
JS::AutoCheckCannotGC nogc;
bool sharedDummy;
(void)JS_GetArrayBufferData(obj, &sharedDummy, nogc);
(void)JS::GetArrayBufferData(obj, &sharedDummy, nogc);
}
JS::RootedObject dstview(cx, JS_NewInt32ArrayWithBuffer(cx, dst, 0, -1));
CHECK(dstview != nullptr);
CHECK_EQUAL(JS_GetArrayBufferByteLength(dst), size);
CHECK_EQUAL(JS::GetArrayBufferByteLength(dst), size);
{
JS::AutoCheckCannotGC nogc;
bool sharedDummy;
uint8_t* data = JS_GetArrayBufferData(dst, &sharedDummy, nogc);
uint8_t* data = JS::GetArrayBufferData(dst, &sharedDummy, nogc);
CHECK(data != nullptr);
CHECK_EQUAL(*reinterpret_cast<uint32_t*>(data), MAGIC_VALUE_2);
}
@ -95,20 +97,20 @@ BEGIN_TEST(testArrayBuffer_bug720949_viewList) {
JS::RootedObject buffer(cx);
// No views
buffer = JS_NewArrayBuffer(cx, 2000);
buffer = JS::NewArrayBuffer(cx, 2000);
buffer = nullptr;
GC(cx);
// One view.
{
buffer = JS_NewArrayBuffer(cx, 2000);
buffer = JS::NewArrayBuffer(cx, 2000);
JS::RootedObject view(cx, JS_NewUint8ArrayWithBuffer(cx, buffer, 0, -1));
void* contents = JS_StealArrayBufferContents(cx, buffer);
void* contents = JS::StealArrayBufferContents(cx, buffer);
CHECK(contents != nullptr);
JS_free(nullptr, contents);
GC(cx);
CHECK(hasDetachedBuffer(view));
CHECK(JS_IsDetachedArrayBufferObject(buffer));
CHECK(JS::IsDetachedArrayBufferObject(buffer));
view = nullptr;
GC(cx);
buffer = nullptr;
@ -117,7 +119,7 @@ BEGIN_TEST(testArrayBuffer_bug720949_viewList) {
// Two views
{
buffer = JS_NewArrayBuffer(cx, 2000);
buffer = JS::NewArrayBuffer(cx, 2000);
JS::RootedObject view1(cx, JS_NewUint8ArrayWithBuffer(cx, buffer, 0, -1));
JS::RootedObject view2(cx, JS_NewUint8ArrayWithBuffer(cx, buffer, 1, 200));
@ -128,13 +130,13 @@ BEGIN_TEST(testArrayBuffer_bug720949_viewList) {
view2 = JS_NewUint8ArrayWithBuffer(cx, buffer, 1, 200);
// Detach
void* contents = JS_StealArrayBufferContents(cx, buffer);
void* contents = JS::StealArrayBufferContents(cx, buffer);
CHECK(contents != nullptr);
JS_free(nullptr, contents);
CHECK(hasDetachedBuffer(view1));
CHECK(hasDetachedBuffer(view2));
CHECK(JS_IsDetachedArrayBufferObject(buffer));
CHECK(JS::IsDetachedArrayBufferObject(buffer));
view1 = nullptr;
GC(cx);
@ -164,15 +166,15 @@ BEGIN_TEST(testArrayBuffer_customFreeFunc) {
// The buffer takes ownership of the data.
JS::RootedObject buffer(
cx, JS_NewExternalArrayBuffer(cx, data.len(), data.contents(),
&ExternalData::freeCallback, &data));
cx, JS::NewExternalArrayBuffer(cx, data.len(), data.contents(),
&ExternalData::freeCallback, &data));
CHECK(buffer);
CHECK(!data.wasFreed());
uint32_t len;
bool isShared;
uint8_t* bufferData;
js::GetArrayBufferLengthAndData(buffer, &len, &isShared, &bufferData);
JS::GetArrayBufferLengthAndData(buffer, &len, &isShared, &bufferData);
CHECK_EQUAL(len, data.len());
CHECK(bufferData == data.contents());
CHECK(strcmp(reinterpret_cast<char*>(bufferData), data.asString()) == 0);
@ -191,14 +193,14 @@ BEGIN_TEST(testArrayBuffer_staticContents) {
// When not passing a free function, the buffer doesn't own the data.
JS::RootedObject buffer(
cx, JS_NewExternalArrayBuffer(cx, data.len(), data.contents(), nullptr));
cx, JS::NewExternalArrayBuffer(cx, data.len(), data.contents(), nullptr));
CHECK(buffer);
CHECK(!data.wasFreed());
uint32_t len;
bool isShared;
uint8_t* bufferData;
js::GetArrayBufferLengthAndData(buffer, &len, &isShared, &bufferData);
JS::GetArrayBufferLengthAndData(buffer, &len, &isShared, &bufferData);
CHECK_EQUAL(len, data.len());
CHECK(bufferData == data.contents());
CHECK(strcmp(reinterpret_cast<char*>(bufferData), data.asString()) == 0);
@ -217,12 +219,12 @@ BEGIN_TEST(testArrayBuffer_stealDetachExternal) {
static const char dataBytes[] = "One two three four";
ExternalData data(dataBytes);
JS::RootedObject buffer(
cx, JS_NewExternalArrayBuffer(cx, data.len(), data.contents(),
&ExternalData::freeCallback, &data));
cx, JS::NewExternalArrayBuffer(cx, data.len(), data.contents(),
&ExternalData::freeCallback, &data));
CHECK(buffer);
CHECK(!data.wasFreed());
void* stolenContents = JS_StealArrayBufferContents(cx, buffer);
void* stolenContents = JS::StealArrayBufferContents(cx, buffer);
// External buffers are stealable: the data is copied into freshly allocated
// memory, and the buffer's data pointer is cleared (immediately freeing the
@ -230,7 +232,7 @@ BEGIN_TEST(testArrayBuffer_stealDetachExternal) {
CHECK(stolenContents != data.contents());
CHECK(strcmp(reinterpret_cast<char*>(stolenContents), dataBytes) == 0);
CHECK(data.wasFreed());
CHECK(JS_IsDetachedArrayBufferObject(buffer));
CHECK(JS::IsDetachedArrayBufferObject(buffer));
JS_free(cx, stolenContents);
return true;
@ -250,8 +252,8 @@ BEGIN_TEST(testArrayBuffer_serializeExternal) {
ExternalData data("One two three four");
JS::RootedObject externalBuffer(
cx, JS_NewExternalArrayBuffer(cx, data.len(), data.contents(),
&ExternalData::freeCallback, &data));
cx, JS::NewExternalArrayBuffer(cx, data.len(), data.contents(),
&ExternalData::freeCallback, &data));
CHECK(externalBuffer);
CHECK(!data.wasFreed());

View File

@ -4,6 +4,7 @@
#include "jsfriendapi.h"
#include "js/ArrayBuffer.h" // JS::NewArrayBuffer
#include "jsapi-tests/tests.h"
#include "vm/ProxyObject.h"
#include "vm/Realm.h"
@ -66,7 +67,7 @@ BEGIN_TEST(testArrayBufferView_type) {
}
static JSObject* CreateDataView(JSContext* cx) {
JS::Rooted<JSObject*> buffer(cx, JS_NewArrayBuffer(cx, 8));
JS::Rooted<JSObject*> buffer(cx, JS::NewArrayBuffer(cx, 8));
if (!buffer) {
return nullptr;
}
@ -117,7 +118,7 @@ bool TestViewType(JSContext* cx) {
JS::Rooted<JSObject*> buffer(cx);
{
AutoRealm ar(cx, otherGlobal);
buffer = JS_NewArrayBuffer(cx, 8);
buffer = JS::NewArrayBuffer(cx, 8);
CHECK(buffer);
CHECK(buffer->as<ArrayBufferObject>().byteLength() == 8);
}

View File

@ -2,7 +2,11 @@
* vim: set ts=8 sts=2 et sw=2 tw=80:
*/
#include "jsfriendapi.h"
#include <stdint.h> // uint32_t
#include "js/ArrayBuffer.h" // JS::{DetachArrayBuffer,GetArrayBuffer{ByteLength,Data},IsArrayBufferObject,NewArrayBufferWithUserOwnedContents}
#include "js/GCAPI.h" // JS::AutoCheckCannotGC, JS_GC
#include "js/RootingAPI.h" // JS::Rooted
#include "jsapi-tests/tests.h"
#include "vm/ArrayBufferObject.h"
@ -18,12 +22,12 @@ static void GC(JSContext* cx) {
}
BEGIN_TEST(testArrayBufferWithUserOwnedContents) {
JS::RootedObject obj(
cx, JS_NewArrayBufferWithUserOwnedContents(cx, testDataLength, testData));
JS::Rooted<JSObject*> obj(cx, JS::NewArrayBufferWithUserOwnedContents(
cx, testDataLength, testData));
GC(cx);
CHECK(VerifyObject(obj, testDataLength));
GC(cx);
JS_DetachArrayBuffer(cx, obj);
JS::DetachArrayBuffer(cx, obj);
GC(cx);
CHECK(VerifyObject(obj, 0));
@ -34,11 +38,11 @@ bool VerifyObject(JS::HandleObject obj, uint32_t length) {
JS::AutoCheckCannotGC nogc;
CHECK(obj);
CHECK(JS_IsArrayBufferObject(obj));
CHECK_EQUAL(JS_GetArrayBufferByteLength(obj), length);
CHECK(JS::IsArrayBufferObject(obj));
CHECK_EQUAL(JS::GetArrayBufferByteLength(obj), length);
bool sharedDummy;
const char* data = reinterpret_cast<const char*>(
JS_GetArrayBufferData(obj, &sharedDummy, nogc));
JS::GetArrayBufferData(obj, &sharedDummy, nogc));
if (length == testDataLength) {
CHECK(data);
CHECK(testData == data);

View File

@ -8,6 +8,7 @@
#include "mozilla/TypeTraits.h"
#include "mozilla/UniquePtr.h"
#include "js/ArrayBuffer.h" // JS::NewArrayBuffer
#include "js/RootingAPI.h"
#include "jsapi-tests/tests.h"
#include "vm/Runtime.h"
@ -180,8 +181,8 @@ BEGIN_TEST(testUnbarrieredEquality) {
// Use ArrayBuffers because they have finalizers, which allows using them
// in ObjectPtr without awkward conversations about nursery allocatability.
JS::RootedObject robj(cx, JS_NewArrayBuffer(cx, 20));
JS::RootedObject robj2(cx, JS_NewArrayBuffer(cx, 30));
JS::RootedObject robj(cx, JS::NewArrayBuffer(cx, 20));
JS::RootedObject robj2(cx, JS::NewArrayBuffer(cx, 30));
cx->runtime()->gc.evictNursery(); // Need tenured objects
// Need some bare pointers to compare against.

View File

@ -6,6 +6,7 @@
#include <stdio.h>
#include "jsfriendapi.h"
#include "js/ArrayBuffer.h" // JS::{{Create,Release}MappedArrayBufferContents,DetachArrayBuffer,GetArrayBuffer{ByteLength,Data},Is{,Detached,Mapped}ArrayBufferObject,NewMappedArrayBufferWithContents,StealArrayBufferContents}
#include "js/StructuredClone.h"
#include "jsapi-tests/tests.h"
#include "vm/ArrayBufferObject.h"
@ -65,14 +66,15 @@ BEGIN_TEST(testMappedArrayBuffer_bug945152) {
JSObject* CreateNewObject(const int offset, const int length) {
int fd = open(test_filename, O_RDONLY);
void* ptr = JS_CreateMappedArrayBufferContents(GET_OS_FD(fd), offset, length);
void* ptr =
JS::CreateMappedArrayBufferContents(GET_OS_FD(fd), offset, length);
close(fd);
if (!ptr) {
return nullptr;
}
JSObject* obj = JS_NewMappedArrayBufferWithContents(cx, length, ptr);
JSObject* obj = JS::NewMappedArrayBufferWithContents(cx, length, ptr);
if (!obj) {
JS_ReleaseMappedArrayBufferContents(ptr, length);
JS::ReleaseMappedArrayBufferContents(ptr, length);
return nullptr;
}
return obj;
@ -83,16 +85,16 @@ bool VerifyObject(JS::HandleObject obj, uint32_t offset, uint32_t length,
JS::AutoCheckCannotGC nogc;
CHECK(obj);
CHECK(JS_IsArrayBufferObject(obj));
CHECK_EQUAL(JS_GetArrayBufferByteLength(obj), length);
CHECK(JS::IsArrayBufferObject(obj));
CHECK_EQUAL(JS::GetArrayBufferByteLength(obj), length);
if (mapped) {
CHECK(JS_IsMappedArrayBufferObject(obj));
CHECK(JS::IsMappedArrayBufferObject(obj));
} else {
CHECK(!JS_IsMappedArrayBufferObject(obj));
CHECK(!JS::IsMappedArrayBufferObject(obj));
}
bool sharedDummy;
const char* data = reinterpret_cast<const char*>(
JS_GetArrayBufferData(obj, &sharedDummy, nogc));
JS::GetArrayBufferData(obj, &sharedDummy, nogc));
CHECK(data);
CHECK(memcmp(data, test_data + offset, length) == 0);
@ -108,12 +110,12 @@ bool TestCreateObject(uint32_t offset, uint32_t length) {
bool TestReleaseContents() {
int fd = open(test_filename, O_RDONLY);
void* ptr = JS_CreateMappedArrayBufferContents(GET_OS_FD(fd), 0, 12);
void* ptr = JS::CreateMappedArrayBufferContents(GET_OS_FD(fd), 0, 12);
close(fd);
if (!ptr) {
return false;
}
JS_ReleaseMappedArrayBufferContents(ptr, 12);
JS::ReleaseMappedArrayBufferContents(ptr, 12);
return true;
}
@ -121,8 +123,8 @@ bool TestReleaseContents() {
bool TestDetachObject() {
JS::RootedObject obj(cx, CreateNewObject(8, 12));
CHECK(obj);
JS_DetachArrayBuffer(cx, obj);
CHECK(JS_IsDetachedArrayBufferObject(obj));
JS::DetachArrayBuffer(cx, obj);
CHECK(JS::IsDetachedArrayBufferObject(obj));
return true;
}
@ -145,10 +147,10 @@ bool TestCloneObject() {
bool TestStealContents() {
JS::RootedObject obj(cx, CreateNewObject(8, 12));
CHECK(obj);
void* contents = JS_StealArrayBufferContents(cx, obj);
void* contents = JS::StealArrayBufferContents(cx, obj);
CHECK(contents);
CHECK(memcmp(contents, test_data + 8, 12) == 0);
CHECK(JS_IsDetachedArrayBufferObject(obj));
CHECK(JS::IsDetachedArrayBufferObject(obj));
return true;
}
@ -178,7 +180,7 @@ bool TestTransferObject() {
CHECK(cloned_buffer.read(cx, &v2, nullptr, nullptr));
JS::RootedObject obj2(cx, v2.toObjectOrNull());
CHECK(VerifyObject(obj2, 8, 12, true));
CHECK(JS_IsDetachedArrayBufferObject(obj1));
CHECK(JS::IsDetachedArrayBufferObject(obj1));
return true;
}

View File

@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "builtin/TestingFunctions.h"
#include "js/ArrayBuffer.h" // JS::{IsArrayBufferObject,GetArrayBufferLengthAndData,NewExternalArrayBuffer}
#include "js/StructuredClone.h"
#include "jsapi-tests/tests.h"
@ -93,8 +94,8 @@ BEGIN_TEST(testStructuredClone_externalArrayBuffer) {
JSAutoRealm ar(cx, g1);
JS::RootedObject obj(
cx, JS_NewExternalArrayBuffer(cx, data.len(), data.contents(),
&ExternalData::freeCallback, &data));
cx, JS::NewExternalArrayBuffer(cx, data.len(), data.contents(),
&ExternalData::freeCallback, &data));
CHECK(!data.wasFreed());
v1 = JS::ObjectOrNullValue(obj);
@ -114,7 +115,7 @@ BEGIN_TEST(testStructuredClone_externalArrayBuffer) {
uint32_t len;
bool isShared;
uint8_t* clonedData;
js::GetArrayBufferLengthAndData(obj, &len, &isShared, &clonedData);
JS::GetArrayBufferLengthAndData(obj, &len, &isShared, &clonedData);
// The contents of the two array buffers should be equal, but not the
// same pointer.
@ -146,8 +147,8 @@ BEGIN_TEST(testStructuredClone_externalArrayBufferDifferentThreadOrProcess) {
bool testStructuredCloneCopy(JS::StructuredCloneScope scope) {
ExternalData data("One two three four");
JS::RootedObject buffer(
cx, JS_NewExternalArrayBuffer(cx, data.len(), data.contents(),
&ExternalData::freeCallback, &data));
cx, JS::NewExternalArrayBuffer(cx, data.len(), data.contents(),
&ExternalData::freeCallback, &data));
CHECK(buffer);
CHECK(!data.wasFreed());
@ -156,12 +157,12 @@ bool testStructuredCloneCopy(JS::StructuredCloneScope scope) {
CHECK(clone(scope, v1, &v2));
JS::RootedObject bufferOut(cx, v2.toObjectOrNull());
CHECK(bufferOut);
CHECK(JS_IsArrayBufferObject(bufferOut));
CHECK(JS::IsArrayBufferObject(bufferOut));
uint32_t len;
bool isShared;
uint8_t* clonedData;
js::GetArrayBufferLengthAndData(bufferOut, &len, &isShared, &clonedData);
JS::GetArrayBufferLengthAndData(bufferOut, &len, &isShared, &clonedData);
// Cloning should copy the data, so the contents of the two array buffers
// should be equal, but not the same pointer.

View File

@ -7,6 +7,8 @@
#include "jsfriendapi.h"
#include "js/ArrayBuffer.h" // JS::{NewArrayBuffer,IsArrayBufferObject,GetArrayBuffer{ByteLength,Data}}
#include "js/SharedArrayBuffer.h" // JS::{NewSharedArrayBuffer,GetSharedArrayBufferData}
#include "jsapi-tests/tests.h"
#include "vm/Realm.h"
@ -35,18 +37,18 @@ BEGIN_TEST(testTypedArrays) {
cx);
size_t nbytes = sizeof(double) * 8;
RootedObject buffer(cx, JS_NewArrayBuffer(cx, nbytes));
CHECK(JS_IsArrayBufferObject(buffer));
RootedObject buffer(cx, JS::NewArrayBuffer(cx, nbytes));
CHECK(JS::IsArrayBufferObject(buffer));
RootedObject proto(cx);
JS_GetPrototype(cx, buffer, &proto);
CHECK(!JS_IsArrayBufferObject(proto));
CHECK(!JS::IsArrayBufferObject(proto));
{
JS::AutoCheckCannotGC nogc;
bool isShared;
CHECK_EQUAL(JS_GetArrayBufferByteLength(buffer), nbytes);
memset(JS_GetArrayBufferData(buffer, &isShared, nogc), 1, nbytes);
CHECK_EQUAL(JS::GetArrayBufferByteLength(buffer), nbytes);
memset(JS::GetArrayBufferData(buffer, &isShared, nogc), 1, nbytes);
CHECK(!isShared); // Because ArrayBuffer
}
@ -154,13 +156,13 @@ bool TestArrayFromBuffer(JSContext* cx) {
size_t elts = 8;
size_t nbytes = elts * sizeof(Element);
RootedObject buffer(cx, Shared ? JS_NewSharedArrayBuffer(cx, nbytes)
: JS_NewArrayBuffer(cx, nbytes));
RootedObject buffer(cx, Shared ? JS::NewSharedArrayBuffer(cx, nbytes)
: JS::NewArrayBuffer(cx, nbytes));
{
JS::AutoCheckCannotGC nogc;
bool isShared;
void* data = Shared ? JS_GetSharedArrayBufferData(buffer, &isShared, nogc)
: JS_GetArrayBufferData(buffer, &isShared, nogc);
void* data = Shared ? JS::GetSharedArrayBufferData(buffer, &isShared, nogc)
: JS::GetArrayBufferData(buffer, &isShared, nogc);
CHECK_EQUAL(Shared, isShared);
memset(data, 1, nbytes);
}
@ -191,8 +193,8 @@ bool TestArrayFromBuffer(JSContext* cx) {
CHECK_EQUAL(
(void*)data,
Shared ? (void*)JS_GetSharedArrayBufferData(buffer, &isShared, nogc)
: (void*)JS_GetArrayBufferData(buffer, &isShared, nogc));
Shared ? (void*)JS::GetSharedArrayBufferData(buffer, &isShared, nogc)
: (void*)JS::GetArrayBufferData(buffer, &isShared, nogc));
CHECK_EQUAL(Shared, isShared);
CHECK_EQUAL(*reinterpret_cast<uint8_t*>(data), 1u);

View File

@ -2020,110 +2020,6 @@ extern JS_PUBLIC_API bool IsSetObject(JSContext* cx, JS::HandleObject obj,
JS_PUBLIC_API void JS_SetAllNonReservedSlotsToUndefined(JSContext* cx,
JSObject* objArg);
/**
* Create a new ArrayBuffer with the given |contents|, which may be null only
* if |nbytes == 0|. |contents| must be allocated compatible with deallocation
* by |JS_free|.
*
* If and only if an ArrayBuffer is successfully created and returned,
* ownership of |contents| is transferred to the new ArrayBuffer.
*/
extern JS_PUBLIC_API JSObject* JS_NewArrayBufferWithContents(JSContext* cx,
size_t nbytes,
void* contents);
namespace JS {
using BufferContentsFreeFunc = void (*)(void* contents, void* userData);
} /* namespace JS */
/**
* Create a new ArrayBuffer with the given contents. The contents must not be
* modified by any other code, internal or external.
*
* When the ArrayBuffer is ready to be disposed of, `freeFunc(contents,
* freeUserData)` will be called to release the ArrayBuffer's reference on the
* contents.
*
* `freeFunc()` must not call any JSAPI functions that could cause a garbage
* collection.
*
* The caller must keep the buffer alive until `freeFunc()` is called, or, if
* `freeFunc` is null, until the JSRuntime is destroyed.
*
* The caller must not access the buffer on other threads. The JS engine will
* not allow the buffer to be transferred to other threads. If you try to
* transfer an external ArrayBuffer to another thread, the data is copied to a
* new malloc buffer. `freeFunc()` must be threadsafe, and may be called from
* any thread.
*
* This allows ArrayBuffers to be used with embedder objects that use reference
* counting, for example. In that case the caller is responsible
* for incrementing the reference count before passing the contents to this
* function. This also allows using non-reference-counted contents that must be
* freed with some function other than free().
*/
extern JS_PUBLIC_API JSObject* JS_NewExternalArrayBuffer(
JSContext* cx, size_t nbytes, void* contents,
JS::BufferContentsFreeFunc freeFunc, void* freeUserData = nullptr);
/**
* Create a new ArrayBuffer with the given non-null |contents|.
*
* Ownership of |contents| remains with the caller: it isn't transferred to the
* returned ArrayBuffer. Callers of this function *must* ensure that they
* perform these two steps, in this order, to properly relinquish ownership of
* |contents|:
*
* 1. Call |JS_DetachArrayBuffer| on the buffer returned by this function.
* (|JS_DetachArrayBuffer| is generally fallible, but a call under these
* circumstances is guaranteed to succeed.)
* 2. |contents| may be deallocated or discarded consistent with the manner
* in which it was allocated.
*
* Do not simply allow the returned buffer to be garbage-collected before
* deallocating |contents|, because in general there is no way to know *when*
* an object is fully garbage-collected to the point where this would be safe.
*/
extern JS_PUBLIC_API JSObject* JS_NewArrayBufferWithUserOwnedContents(
JSContext* cx, size_t nbytes, void* contents);
/**
* Steal the contents of the given ArrayBuffer. The ArrayBuffer has its length
* set to 0 and its contents array cleared. The caller takes ownership of the
* return value and must free it or transfer ownership via
* JS_NewArrayBufferWithContents when done using it.
*/
extern JS_PUBLIC_API void* JS_StealArrayBufferContents(JSContext* cx,
JS::HandleObject obj);
/**
* Create a new mapped ArrayBuffer with the given memory mapped contents. It
* must be legal to free the contents pointer by unmapping it. On success,
* ownership is transferred to the new mapped ArrayBuffer.
*/
extern JS_PUBLIC_API JSObject* JS_NewMappedArrayBufferWithContents(
JSContext* cx, size_t nbytes, void* contents);
/**
* Create memory mapped ArrayBuffer contents.
* Caller must take care of closing fd after calling this function.
*/
extern JS_PUBLIC_API void* JS_CreateMappedArrayBufferContents(int fd,
size_t offset,
size_t length);
/**
* Release the allocated resource of mapped ArrayBuffer contents before the
* object is created.
* If a new object has been created by JS_NewMappedArrayBufferWithContents()
* with this content, then JS_DetachArrayBuffer() should be used instead to
* release the resource used by the object.
*/
extern JS_PUBLIC_API void JS_ReleaseMappedArrayBufferContents(void* contents,
size_t length);
extern JS_PUBLIC_API JS::Value JS_GetReservedSlot(JSObject* obj,
uint32_t index);

View File

@ -1575,21 +1575,6 @@ extern JS_FRIEND_API JSObject* JS_NewFloat64ArrayWithBuffer(
JSContext* cx, JS::HandleObject arrayBuffer, uint32_t byteOffset,
int32_t length);
/**
* Create a new SharedArrayBuffer with the given byte length. This
* may only be called if
* JS::RealmCreationOptionsRef(cx).getSharedMemoryAndAtomicsEnabled() is
* true.
*/
extern JS_FRIEND_API JSObject* JS_NewSharedArrayBuffer(JSContext* cx,
uint32_t nbytes);
/**
* Create a new ArrayBuffer with the given byte length.
*/
extern JS_FRIEND_API JSObject* JS_NewArrayBuffer(JSContext* cx,
uint32_t nbytes);
/**
* Check whether obj supports JS_GetTypedArray* APIs. Note that this may return
* false if a security wrapper is encountered that denies the unwrapping. If
@ -1648,12 +1633,8 @@ extern JS_FRIEND_API JSObject* UnwrapUint32Array(JSObject* obj);
extern JS_FRIEND_API JSObject* UnwrapFloat32Array(JSObject* obj);
extern JS_FRIEND_API JSObject* UnwrapFloat64Array(JSObject* obj);
extern JS_FRIEND_API JSObject* UnwrapArrayBuffer(JSObject* obj);
extern JS_FRIEND_API JSObject* UnwrapArrayBufferView(JSObject* obj);
extern JS_FRIEND_API JSObject* UnwrapSharedArrayBuffer(JSObject* obj);
extern JS_FRIEND_API JSObject* UnwrapReadableStream(JSObject* obj);
namespace detail {
@ -1702,29 +1683,8 @@ extern JS_FRIEND_API void GetArrayBufferViewLengthAndData(JSObject* obj,
bool* isSharedMemory,
uint8_t** data);
// This one isn't inlined because there are a bunch of different ArrayBuffer
// classes that would have to be individually handled here.
//
// There is an isShared out argument for API consistency (eases use from DOM).
// It will always be set to false.
extern JS_FRIEND_API void GetArrayBufferLengthAndData(JSObject* obj,
uint32_t* length,
bool* isSharedMemory,
uint8_t** data);
// Ditto for SharedArrayBuffer.
//
// There is an isShared out argument for API consistency (eases use from DOM).
// It will always be set to true.
extern JS_FRIEND_API void GetSharedArrayBufferLengthAndData(
JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data);
} // namespace js
JS_FRIEND_API uint8_t* JS_GetSharedArrayBufferData(JSObject* obj,
bool* isSharedMemory,
const JS::AutoRequireNoGC&);
/*
* Unwrap Typed arrays all at once. Return nullptr without throwing if the
* object cannot be viewed as the correct typed array, or the typed array
@ -1767,13 +1727,6 @@ extern JS_FRIEND_API JSObject* JS_GetObjectAsFloat64Array(JSObject* obj,
extern JS_FRIEND_API JSObject* JS_GetObjectAsArrayBufferView(
JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data);
/*
* Unwrap an ArrayBuffer, return nullptr if it's a different type.
*/
extern JS_FRIEND_API JSObject* JS_GetObjectAsArrayBuffer(JSObject* obj,
uint32_t* length,
uint8_t** data);
/*
* Get the type of elements in a typed array, or MaxTypedArrayViewType if a
* DataView.
@ -1787,62 +1740,6 @@ extern JS_FRIEND_API js::Scalar::Type JS_GetArrayBufferViewType(JSObject* obj);
extern JS_FRIEND_API js::Scalar::Type JS_GetSharedArrayBufferViewType(
JSObject* obj);
/*
* Check whether obj supports the JS_GetArrayBuffer* APIs. Note that this may
* return false if a security wrapper is encountered that denies the
* unwrapping. If this test succeeds, then it is safe to call the various
* accessor JSAPI calls defined below.
*/
extern JS_FRIEND_API bool JS_IsArrayBufferObject(JSObject* obj);
extern JS_FRIEND_API bool JS_IsSharedArrayBufferObject(JSObject* obj);
/**
* Return the available byte length of an ArrayBuffer.
*
* |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
* that it would pass such a test: it is an ArrayBuffer or a wrapper of an
* ArrayBuffer, and the unwrapping will succeed.
*/
extern JS_FRIEND_API uint32_t JS_GetArrayBufferByteLength(JSObject* obj);
extern JS_FRIEND_API uint32_t JS_GetSharedArrayBufferByteLength(JSObject* obj);
/**
* Return true if the ArrayBuffer |obj| contains any data, i.e. it is not a
* detached ArrayBuffer. (ArrayBuffer.prototype is not an ArrayBuffer.)
*
* |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
* that it would pass such a test: it is an ArrayBuffer or a wrapper of an
* ArrayBuffer, and the unwrapping will succeed.
*/
extern JS_FRIEND_API bool JS_ArrayBufferHasData(JSObject* obj);
/**
* Return a pointer to the start of the data referenced by a typed array. The
* data is still owned by the typed array, and should not be modified on
* another thread. Furthermore, the pointer can become invalid on GC (if the
* data is small and fits inside the array's GC header), so callers must take
* care not to hold on across anything that could GC.
*
* |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
* that it would pass such a test: it is an ArrayBuffer or a wrapper of an
* ArrayBuffer, and the unwrapping will succeed.
*
* |*isSharedMemory| will be set to false, the argument is present to simplify
* its use from code that also interacts with SharedArrayBuffer.
*/
extern JS_FRIEND_API uint8_t* JS_GetArrayBufferData(JSObject* obj,
bool* isSharedMemory,
const JS::AutoRequireNoGC&);
/**
* Check whether the obj is ArrayBufferObject and memory mapped. Note that this
* may return false if a security wrapper is encountered that denies the
* unwrapping.
*/
extern JS_FRIEND_API bool JS_IsMappedArrayBufferObject(JSObject* obj);
/**
* Return the number of elements in a typed array.
*
@ -1943,24 +1840,6 @@ extern JS_FRIEND_API void* JS_GetArrayBufferViewData(
extern JS_FRIEND_API JSObject* JS_GetArrayBufferViewBuffer(
JSContext* cx, JS::HandleObject obj, bool* isSharedMemory);
/**
* Detach an ArrayBuffer, causing all associated views to no longer refer to
* the ArrayBuffer's original attached memory.
*
* This function throws only if it is provided a non-ArrayBuffer object or if
* the provided ArrayBuffer is a WASM-backed ArrayBuffer or an ArrayBuffer used
* in asm.js code.
*/
extern JS_FRIEND_API bool JS_DetachArrayBuffer(JSContext* cx,
JS::HandleObject obj);
/**
* Check whether the obj is a detached ArrayBufferObject. Note that this may
* return false if a security wrapper is encountered that denies the
* unwrapping.
*/
extern JS_FRIEND_API bool JS_IsDetachedArrayBufferObject(JSObject* obj);
/**
* Create a new DataView using the given buffer for storage. The given buffer
* must be an ArrayBuffer or SharedArrayBuffer (or a cross-compartment wrapper

View File

@ -117,6 +117,7 @@ EXPORTS += [
EXPORTS.js += [
'../public/AllocPolicy.h',
'../public/ArrayBuffer.h',
'../public/BuildId.h',
'../public/CallArgs.h',
'../public/CallNonGenericMethod.h',
@ -161,6 +162,7 @@ EXPORTS.js += [
'../public/Result.h',
'../public/RootingAPI.h',
'../public/SavedFrameAPI.h',
'../public/SharedArrayBuffer.h',
'../public/SliceBudget.h',
'../public/SourceText.h',
'../public/StableStringChars.h',

View File

@ -84,6 +84,7 @@
#include "jit/JitcodeMap.h"
#include "jit/JitRealm.h"
#include "jit/shared/CodeGenerator-shared.h"
#include "js/ArrayBuffer.h" // JS::{CreateMappedArrayBufferContents,NewMappedArrayBufferWithContents,IsArrayBufferObject,GetArrayBufferLengthAndData}
#include "js/BuildId.h" // JS::BuildIdCharVector, JS::SetProcessBuildIdOp
#include "js/CharacterEncoding.h"
#include "js/CompilationAndEvaluation.h"
@ -1536,7 +1537,7 @@ static bool CreateMappedArrayBuffer(JSContext* cx, unsigned argc, Value* vp) {
}
void* contents =
JS_CreateMappedArrayBufferContents(GET_FD_FROM_FILE(file), offset, size);
JS::CreateMappedArrayBufferContents(GET_FD_FROM_FILE(file), offset, size);
if (!contents) {
JS_ReportErrorASCII(cx,
"failed to allocate mapped array buffer contents "
@ -1544,7 +1545,8 @@ static bool CreateMappedArrayBuffer(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
RootedObject obj(cx, JS_NewMappedArrayBufferWithContents(cx, size, contents));
RootedObject obj(cx,
JS::NewMappedArrayBufferWithContents(cx, size, contents));
if (!obj) {
return false;
}
@ -5032,7 +5034,7 @@ static bool BinParse(JSContext* cx, unsigned argc, Value* vp) {
}
RootedObject objBuf(cx, &args[0].toObject());
if (!JS_IsArrayBufferObject(objBuf)) {
if (!JS::IsArrayBufferObject(objBuf)) {
const char* typeName = InformalValueTypeName(args[0]);
JS_ReportErrorASCII(cx, "expected ArrayBuffer to parse, got %s", typeName);
return false;
@ -5041,8 +5043,8 @@ static bool BinParse(JSContext* cx, unsigned argc, Value* vp) {
uint32_t buf_length = 0;
bool buf_isSharedMemory = false;
uint8_t* buf_data = nullptr;
GetArrayBufferLengthAndData(objBuf, &buf_length, &buf_isSharedMemory,
&buf_data);
JS::GetArrayBufferLengthAndData(objBuf, &buf_length, &buf_isSharedMemory,
&buf_data);
MOZ_ASSERT(buf_data);
// Extract argument 2: Options.

View File

@ -36,9 +36,11 @@
#include "gc/Barrier.h"
#include "gc/FreeOp.h"
#include "gc/Memory.h"
#include "js/ArrayBuffer.h"
#include "js/Conversions.h"
#include "js/MemoryMetrics.h"
#include "js/PropertySpec.h"
#include "js/SharedArrayBuffer.h"
#include "js/Wrapper.h"
#include "util/Windows.h"
#include "vm/GlobalObject.h"
@ -1644,14 +1646,14 @@ bool JSObject::is<js::ArrayBufferObjectMaybeShared>() const {
return is<ArrayBufferObject>() || is<SharedArrayBufferObject>();
}
JS_FRIEND_API uint32_t JS_GetArrayBufferByteLength(JSObject* obj) {
JS_FRIEND_API uint32_t JS::GetArrayBufferByteLength(JSObject* obj) {
ArrayBufferObject* aobj = obj->maybeUnwrapAs<ArrayBufferObject>();
return aobj ? aobj->byteLength() : 0;
}
JS_FRIEND_API uint8_t* JS_GetArrayBufferData(JSObject* obj,
bool* isSharedMemory,
const JS::AutoRequireNoGC&) {
JS_FRIEND_API uint8_t* JS::GetArrayBufferData(JSObject* obj,
bool* isSharedMemory,
const JS::AutoRequireNoGC&) {
ArrayBufferObject* aobj = obj->maybeUnwrapIf<ArrayBufferObject>();
if (!aobj) {
return nullptr;
@ -1660,7 +1662,7 @@ JS_FRIEND_API uint8_t* JS_GetArrayBufferData(JSObject* obj,
return aobj->dataPointer();
}
JS_FRIEND_API bool JS_DetachArrayBuffer(JSContext* cx, HandleObject obj) {
JS_FRIEND_API bool JS::DetachArrayBuffer(JSContext* cx, HandleObject obj) {
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(obj);
@ -1682,7 +1684,7 @@ JS_FRIEND_API bool JS_DetachArrayBuffer(JSContext* cx, HandleObject obj) {
return true;
}
JS_FRIEND_API bool JS_IsDetachedArrayBufferObject(JSObject* obj) {
JS_FRIEND_API bool JS::IsDetachedArrayBufferObject(JSObject* obj) {
ArrayBufferObject* aobj = obj->maybeUnwrapIf<ArrayBufferObject>();
if (!aobj) {
return false;
@ -1691,16 +1693,16 @@ JS_FRIEND_API bool JS_IsDetachedArrayBufferObject(JSObject* obj) {
return aobj->isDetached();
}
JS_FRIEND_API JSObject* JS_NewArrayBuffer(JSContext* cx, uint32_t nbytes) {
JS_FRIEND_API JSObject* JS::NewArrayBuffer(JSContext* cx, uint32_t nbytes) {
AssertHeapIsIdle();
CHECK_THREAD(cx);
return ArrayBufferObject::createZeroed(cx, nbytes);
}
JS_PUBLIC_API JSObject* JS_NewArrayBufferWithContents(JSContext* cx,
size_t nbytes,
void* data) {
JS_PUBLIC_API JSObject* JS::NewArrayBufferWithContents(JSContext* cx,
size_t nbytes,
void* data) {
AssertHeapIsIdle();
CHECK_THREAD(cx);
MOZ_ASSERT_IF(!data, nbytes == 0);
@ -1716,7 +1718,7 @@ JS_PUBLIC_API JSObject* JS_NewArrayBufferWithContents(JSContext* cx,
return ArrayBufferObject::createForContents(cx, nbytes, contents);
}
JS_PUBLIC_API JSObject* JS_NewExternalArrayBuffer(
JS_PUBLIC_API JSObject* JS::NewExternalArrayBuffer(
JSContext* cx, size_t nbytes, void* data,
JS::BufferContentsFreeFunc freeFunc, void* freeUserData) {
AssertHeapIsIdle();
@ -1732,9 +1734,9 @@ JS_PUBLIC_API JSObject* JS_NewExternalArrayBuffer(
return ArrayBufferObject::createForContents(cx, nbytes, contents);
}
JS_PUBLIC_API JSObject* JS_NewArrayBufferWithUserOwnedContents(JSContext* cx,
size_t nbytes,
void* data) {
JS_PUBLIC_API JSObject* JS::NewArrayBufferWithUserOwnedContents(JSContext* cx,
size_t nbytes,
void* data) {
AssertHeapIsIdle();
CHECK_THREAD(cx);
@ -1746,24 +1748,24 @@ JS_PUBLIC_API JSObject* JS_NewArrayBufferWithUserOwnedContents(JSContext* cx,
return ArrayBufferObject::createForContents(cx, nbytes, contents);
}
JS_FRIEND_API bool JS_IsArrayBufferObject(JSObject* obj) {
JS_FRIEND_API bool JS::IsArrayBufferObject(JSObject* obj) {
return obj->canUnwrapAs<ArrayBufferObject>();
}
JS_FRIEND_API bool JS_ArrayBufferHasData(JSObject* obj) {
JS_FRIEND_API bool JS::ArrayBufferHasData(JSObject* obj) {
return !obj->unwrapAs<ArrayBufferObject>().isDetached();
}
JS_FRIEND_API JSObject* js::UnwrapArrayBuffer(JSObject* obj) {
JS_FRIEND_API JSObject* JS::UnwrapArrayBuffer(JSObject* obj) {
return obj->maybeUnwrapIf<ArrayBufferObject>();
}
JS_FRIEND_API JSObject* js::UnwrapSharedArrayBuffer(JSObject* obj) {
JS_FRIEND_API JSObject* JS::UnwrapSharedArrayBuffer(JSObject* obj) {
return obj->maybeUnwrapIf<SharedArrayBufferObject>();
}
JS_PUBLIC_API void* JS_StealArrayBufferContents(JSContext* cx,
HandleObject objArg) {
JS_PUBLIC_API void* JS::StealArrayBufferContents(JSContext* cx,
HandleObject objArg) {
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(objArg);
@ -1797,9 +1799,9 @@ JS_PUBLIC_API void* JS_StealArrayBufferContents(JSContext* cx,
return ArrayBufferObject::stealMallocedContents(cx, buffer);
}
JS_PUBLIC_API JSObject* JS_NewMappedArrayBufferWithContents(JSContext* cx,
size_t nbytes,
void* data) {
JS_PUBLIC_API JSObject* JS::NewMappedArrayBufferWithContents(JSContext* cx,
size_t nbytes,
void* data) {
AssertHeapIsIdle();
CHECK_THREAD(cx);
@ -1811,17 +1813,17 @@ JS_PUBLIC_API JSObject* JS_NewMappedArrayBufferWithContents(JSContext* cx,
return ArrayBufferObject::createForContents(cx, nbytes, contents);
}
JS_PUBLIC_API void* JS_CreateMappedArrayBufferContents(int fd, size_t offset,
size_t length) {
JS_PUBLIC_API void* JS::CreateMappedArrayBufferContents(int fd, size_t offset,
size_t length) {
return ArrayBufferObject::createMappedContents(fd, offset, length).data();
}
JS_PUBLIC_API void JS_ReleaseMappedArrayBufferContents(void* contents,
size_t length) {
JS_PUBLIC_API void JS::ReleaseMappedArrayBufferContents(void* contents,
size_t length) {
gc::DeallocateMappedContent(contents, length);
}
JS_FRIEND_API bool JS_IsMappedArrayBufferObject(JSObject* obj) {
JS_FRIEND_API bool JS::IsMappedArrayBufferObject(JSObject* obj) {
ArrayBufferObject* aobj = obj->maybeUnwrapIf<ArrayBufferObject>();
if (!aobj) {
return false;
@ -1830,9 +1832,9 @@ JS_FRIEND_API bool JS_IsMappedArrayBufferObject(JSObject* obj) {
return aobj->isMapped();
}
JS_FRIEND_API JSObject* JS_GetObjectAsArrayBuffer(JSObject* obj,
uint32_t* length,
uint8_t** data) {
JS_FRIEND_API JSObject* JS::GetObjectAsArrayBuffer(JSObject* obj,
uint32_t* length,
uint8_t** data) {
ArrayBufferObject* aobj = obj->maybeUnwrapIf<ArrayBufferObject>();
if (!aobj) {
return nullptr;
@ -1844,7 +1846,7 @@ JS_FRIEND_API JSObject* JS_GetObjectAsArrayBuffer(JSObject* obj,
return aobj;
}
JS_FRIEND_API void js::GetArrayBufferLengthAndData(JSObject* obj,
JS_FRIEND_API void JS::GetArrayBufferLengthAndData(JSObject* obj,
uint32_t* length,
bool* isSharedMemory,
uint8_t** data) {

View File

@ -10,6 +10,7 @@
#include "mozilla/Maybe.h"
#include "builtin/TypedObjectConstants.h"
#include "js/ArrayBuffer.h"
#include "js/GCHashTable.h"
#include "vm/JSObject.h"
#include "vm/Runtime.h"

View File

@ -14,6 +14,7 @@
#include "gc/FreeOp.h"
#include "jit/AtomicOperations.h"
#include "js/PropertySpec.h"
#include "js/SharedArrayBuffer.h"
#include "js/Wrapper.h"
#include "vm/SharedMem.h"
#include "wasm/WasmSignalHandlers.h"
@ -409,12 +410,12 @@ SharedArrayBufferObject& js::AsSharedArrayBuffer(HandleObject obj) {
return obj->as<SharedArrayBufferObject>();
}
JS_FRIEND_API uint32_t JS_GetSharedArrayBufferByteLength(JSObject* obj) {
JS_FRIEND_API uint32_t JS::GetSharedArrayBufferByteLength(JSObject* obj) {
auto* aobj = obj->maybeUnwrapAs<SharedArrayBufferObject>();
return aobj ? aobj->byteLength() : 0;
}
JS_FRIEND_API void js::GetSharedArrayBufferLengthAndData(JSObject* obj,
JS_FRIEND_API void JS::GetSharedArrayBufferLengthAndData(JSObject* obj,
uint32_t* length,
bool* isSharedMemory,
uint8_t** data) {
@ -425,21 +426,20 @@ JS_FRIEND_API void js::GetSharedArrayBufferLengthAndData(JSObject* obj,
*isSharedMemory = true;
}
JS_FRIEND_API JSObject* JS_NewSharedArrayBuffer(JSContext* cx,
uint32_t nbytes) {
JS_FRIEND_API JSObject* JS::NewSharedArrayBuffer(JSContext* cx,
uint32_t nbytes) {
MOZ_ASSERT(cx->realm()->creationOptions().getSharedMemoryAndAtomicsEnabled());
MOZ_ASSERT(nbytes <= INT32_MAX);
return SharedArrayBufferObject::New(cx, nbytes, /* proto = */ nullptr);
}
JS_FRIEND_API bool JS_IsSharedArrayBufferObject(JSObject* obj) {
JS_FRIEND_API bool JS::IsSharedArrayBufferObject(JSObject* obj) {
return obj->canUnwrapAs<SharedArrayBufferObject>();
}
JS_FRIEND_API uint8_t* JS_GetSharedArrayBufferData(JSObject* obj,
bool* isSharedMemory,
const JS::AutoRequireNoGC&) {
JS_FRIEND_API uint8_t* JS::GetSharedArrayBufferData(
JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&) {
auto* aobj = obj->maybeUnwrapAs<SharedArrayBufferObject>();
if (!aobj) {
return nullptr;

View File

@ -43,8 +43,10 @@
#include "builtin/DataViewObject.h"
#include "builtin/MapObject.h"
#include "js/ArrayBuffer.h" // JS::{ArrayBufferHasData,DetachArrayBuffer,IsArrayBufferObject,New{,Mapped}ArrayBufferWithContents,ReleaseMappedArrayBufferContents}
#include "js/Date.h"
#include "js/GCHashTable.h"
#include "js/SharedArrayBuffer.h" // JS::IsSharedArrayBufferObject
#include "js/Wrapper.h"
#include "vm/BigIntType.h"
#include "vm/JSContext.h"
@ -981,7 +983,7 @@ void JSStructuredCloneData::discardTransferables() {
if (ownership == JS::SCTAG_TMO_ALLOC_DATA) {
js_free(content);
} else if (ownership == JS::SCTAG_TMO_MAPPED_DATA) {
JS_ReleaseMappedArrayBufferContents(content, extraData);
JS::ReleaseMappedArrayBufferContents(content, extraData);
} else if (freeTransfer) {
freeTransfer(tag, JS::TransferableOwnership(ownership), content,
extraData, closure_);
@ -1670,13 +1672,13 @@ bool JSStructuredCloneWriter::startWrite(HandleValue v) {
writeString(SCTAG_STRING, re->getSource());
}
case ESClass::ArrayBuffer: {
if (JS_IsArrayBufferObject(obj) && JS_ArrayBufferHasData(obj)) {
if (JS::IsArrayBufferObject(obj) && JS::ArrayBufferHasData(obj)) {
return writeArrayBuffer(obj);
}
break;
}
case ESClass::SharedArrayBuffer:
if (JS_IsSharedArrayBufferObject(obj)) {
if (JS::IsSharedArrayBufferObject(obj)) {
return writeSharedArrayBuffer(obj);
}
break;
@ -1862,7 +1864,7 @@ bool JSStructuredCloneWriter::transferOwnership() {
point = out.iter();
point += pointOffset;
if (!JS_DetachArrayBuffer(cx, arrayBuffer)) {
if (!JS::DetachArrayBuffer(cx, arrayBuffer)) {
return false;
}
} else {
@ -2700,9 +2702,9 @@ bool JSStructuredCloneReader::readTransferMap() {
MOZ_ASSERT(data == JS::SCTAG_TMO_ALLOC_DATA ||
data == JS::SCTAG_TMO_MAPPED_DATA);
if (data == JS::SCTAG_TMO_ALLOC_DATA) {
obj = JS_NewArrayBufferWithContents(cx, nbytes, content);
obj = JS::NewArrayBufferWithContents(cx, nbytes, content);
} else if (data == JS::SCTAG_TMO_MAPPED_DATA) {
obj = JS_NewMappedArrayBufferWithContents(cx, nbytes, content);
obj = JS::NewMappedArrayBufferWithContents(cx, nbytes, content);
}
} else if (tag == SCTAG_TRANSFER_MAP_STORED_ARRAY_BUFFER) {
auto savedPos = in.tell();

View File

@ -1,4 +1,3 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -80,7 +79,9 @@
#include "nsURLHelper.h"
#include "nsNetUtil.h"
#include "nsIURLParser.h"
#include "js/GCAnnotations.h"
#include "js/ArrayBuffer.h" // JS::NewArrayBufferWithContents
#include "js/GCAnnotations.h" // JS_HAZ_ROOTED
#include "js/RootingAPI.h" // JS::{{,Mutable}Handle,Rooted}
#include "mozilla/PeerIdentity.h"
#include "mozilla/dom/RTCCertificate.h"
#include "mozilla/dom/RTCDTMFSenderBinding.h"
@ -1804,7 +1805,7 @@ void PeerConnectionImpl::DumpPacket_m(size_t level, dom::mozPacketDumpType type,
JS::Rooted<JSObject*> jsobj(
jsapi.cx(),
JS_NewArrayBufferWithContents(jsapi.cx(), size, packet.release()));
JS::NewArrayBufferWithContents(jsapi.cx(), size, packet.release()));
RootedSpiderMonkeyInterface<ArrayBuffer> arrayBuffer(jsapi.cx());
if (!arrayBuffer.Init(jsobj)) {

View File

@ -6,8 +6,9 @@
#include <algorithm>
#include "ArrayBufferInputStream.h"
#include "nsStreamUtils.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "js/ArrayBuffer.h" // JS::{GetArrayBuffer{ByteLength,Data},IsArrayBufferObject}
#include "js/RootingAPI.h" // JS::{Handle,Rooted}
#include "js/Value.h" // JS::Value
#include "mozilla/UniquePtrExtensions.h"
#include "mozilla/dom/ScriptSettings.h"
@ -27,12 +28,12 @@ ArrayBufferInputStream::SetData(JS::Handle<JS::Value> aBuffer,
if (!aBuffer.isObject()) {
return NS_ERROR_FAILURE;
}
JS::RootedObject arrayBuffer(RootingCx(), &aBuffer.toObject());
if (!JS_IsArrayBufferObject(arrayBuffer)) {
JS::Rooted<JSObject *> arrayBuffer(RootingCx(), &aBuffer.toObject());
if (!JS::IsArrayBufferObject(arrayBuffer)) {
return NS_ERROR_FAILURE;
}
uint32_t buflen = JS_GetArrayBufferByteLength(arrayBuffer);
uint32_t buflen = JS::GetArrayBufferByteLength(arrayBuffer);
uint32_t offset = std::min(buflen, aByteOffset);
uint32_t bufferLength = std::min(buflen - offset, aLength);
@ -46,7 +47,7 @@ ArrayBufferInputStream::SetData(JS::Handle<JS::Value> aBuffer,
JS::AutoCheckCannotGC nogc;
bool isShared;
char *src =
(char *)JS_GetArrayBufferData(arrayBuffer, &isShared, nogc) + offset;
(char *)JS::GetArrayBufferData(arrayBuffer, &isShared, nogc) + offset;
memcpy(&mArrayBuffer[0], src, mBufferLength);
return NS_OK;
}

View File

@ -36,8 +36,10 @@
#include "jsapi.h"
#include "jsfriendapi.h"
#include "js/ArrayBuffer.h" // JS::GetArrayBufferByteLength,IsArrayBufferObject,NewArrayBufferWithContents,StealArrayBufferContents
#include "js/Conversions.h"
#include "js/MemoryFunctions.h"
#include "js/UniquePtr.h"
#include "js/Utility.h"
#include "xpcpublic.h"
@ -356,7 +358,7 @@ nsresult TypedArrayResult::GetCacheableResult(
MOZ_ASSERT(contents.data);
JS::Rooted<JSObject*> arrayBuffer(
cx, JS_NewArrayBufferWithContents(cx, contents.nbytes, contents.data));
cx, JS::NewArrayBufferWithContents(cx, contents.nbytes, contents.data));
if (!arrayBuffer) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -889,9 +891,9 @@ class DoWriteAtomicEvent : public AbstractDoEvent {
* @param aPath The path of the file.
*/
DoWriteAtomicEvent(
const nsAString& aPath, UniquePtr<char> aBuffer, const uint64_t aBytes,
const nsAString& aTmpPath, const nsAString& aBackupTo, const bool aFlush,
const bool aNoOverwrite,
const nsAString& aPath, UniquePtr<char[], JS::FreePolicy> aBuffer,
const uint64_t aBytes, const nsAString& aTmpPath,
const nsAString& aBackupTo, const bool aFlush, const bool aNoOverwrite,
nsMainThreadPtrHandle<nsINativeOSFileSuccessCallback>& aOnSuccess,
nsMainThreadPtrHandle<nsINativeOSFileErrorCallback>& aOnError)
: AbstractDoEvent(aOnSuccess, aOnError),
@ -1120,7 +1122,7 @@ class DoWriteAtomicEvent : public AbstractDoEvent {
}
const nsString mPath;
const UniquePtr<char> mBuffer;
const UniquePtr<char[], JS::FreePolicy> mBuffer;
const int32_t mBytes;
const nsString mTmpPath;
const nsString mBackupTo;
@ -1201,7 +1203,7 @@ NativeOSFileInternalsService::WriteAtomic(
MOZ_ASSERT(NS_IsMainThread());
// Extract typed-array/string into buffer. We also need to store the length
// of the buffer as that may be required if not provided in `aOptions`.
UniquePtr<char> buffer;
UniquePtr<char[], JS::FreePolicy> buffer;
int32_t bytes;
// The incoming buffer must be an Object.
@ -1213,13 +1215,13 @@ NativeOSFileInternalsService::WriteAtomic(
if (!JS_ValueToObject(cx, aBuffer, &bufferObject)) {
return NS_ERROR_FAILURE;
}
if (!JS_IsArrayBufferObject(bufferObject.get())) {
if (!JS::IsArrayBufferObject(bufferObject.get())) {
return NS_ERROR_INVALID_ARG;
}
bytes = JS_GetArrayBufferByteLength(bufferObject.get());
bytes = JS::GetArrayBufferByteLength(bufferObject.get());
buffer.reset(
static_cast<char*>(JS_StealArrayBufferContents(cx, bufferObject)));
static_cast<char*>(JS::StealArrayBufferContents(cx, bufferObject)));
if (!buffer) {
return NS_ERROR_FAILURE;

View File

@ -8,6 +8,7 @@
#include "jsapi.h"
#include "jsfriendapi.h"
#include "js/ArrayBuffer.h"
#include "js/JSON.h"
#include "js/TracingAPI.h"
#include "xpcpublic.h"
@ -534,8 +535,8 @@ nsresult AddonManagerStartup::EncodeBlob(JS::HandleValue value, JSContext* cx,
nsresult AddonManagerStartup::DecodeBlob(JS::HandleValue value, JSContext* cx,
JS::MutableHandleValue result) {
NS_ENSURE_TRUE(value.isObject() &&
JS_IsArrayBufferObject(&value.toObject()) &&
JS_ArrayBufferHasData(&value.toObject()),
JS::IsArrayBufferObject(&value.toObject()) &&
JS::ArrayBufferHasData(&value.toObject()),
NS_ERROR_INVALID_ARG);
StructuredCloneData holder;
@ -548,8 +549,8 @@ nsresult AddonManagerStartup::DecodeBlob(JS::HandleValue value, JSContext* cx,
bool isShared;
nsDependentCSubstring lz4(
reinterpret_cast<char*>(JS_GetArrayBufferData(obj, &isShared, nogc)),
JS_GetArrayBufferByteLength(obj));
reinterpret_cast<char*>(JS::GetArrayBufferData(obj, &isShared, nogc)),
JS::GetArrayBufferByteLength(obj));
MOZ_TRY_VAR(data, DecodeLZ4(lz4, STRUCTURED_CLONE_MAGIC));
}

View File

@ -10,6 +10,10 @@
#include "ParentInternal.h"
#include "chrome/common/mach_ipc_mac.h"
#include "jsapi.h" // JSAutoRealm
#include "js/ArrayBuffer.h" // JS::{DetachArrayBuffer,NewArrayBufferWithUserOwnedContents}
#include "js/RootingAPI.h" // JS::Rooted
#include "js/Value.h" // JS::{,Object}Value
#include "mozilla/Assertions.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/StaticPtr.h"
@ -165,12 +169,12 @@ void UpdateGraphicsInUIProcess(const PaintMessage* aMsg) {
JSAutoRealm ar(cx, xpc::PrivilegedJunkScope());
// Create an ArrayBuffer whose contents are the externally-provided |memory|.
JS::RootedObject bufferObject(cx);
JS::Rooted<JSObject*> bufferObject(cx);
bufferObject =
JS_NewArrayBufferWithUserOwnedContents(cx, width * height * 4, memory);
JS::NewArrayBufferWithUserOwnedContents(cx, width * height * 4, memory);
MOZ_RELEASE_ASSERT(bufferObject);
JS::RootedValue buffer(cx, ObjectValue(*bufferObject));
JS::Rooted<JS::Value> buffer(cx, JS::ObjectValue(*bufferObject));
// Call into the graphics module to update the canvas it manages.
if (NS_FAILED(gGraphics->UpdateCanvas(buffer, width, height, hadFailure))) {
@ -178,9 +182,9 @@ void UpdateGraphicsInUIProcess(const PaintMessage* aMsg) {
}
// Manually detach this ArrayBuffer once this update completes, as the
// JS_NewArrayBufferWithUserOwnedContents API mandates. (The API also
// JS::NewArrayBufferWithUserOwnedContents API mandates. (The API also
// guarantees that this call always succeeds.)
MOZ_ALWAYS_TRUE(JS_DetachArrayBuffer(cx, bufferObject));
MOZ_ALWAYS_TRUE(JS::DetachArrayBuffer(cx, bufferObject));
}
static void MaybeTriggerExplicitPaint() {

View File

@ -36,7 +36,10 @@
#include "nsIURI.h" // for NS_IURI_IID
#include "nsIX509Cert.h" // for NS_IX509CERT_IID
#include "jsfriendapi.h"
#include "js/ArrayBuffer.h" // JS::{GetArrayBuffer{,ByteLength},IsArrayBufferObject}
#include "js/GCAPI.h" // JS::AutoCheckCannotGC
#include "js/RootingAPI.h" // JS::{Handle,Rooted}
#include "js/Value.h" // JS::Value
using mozilla::MakeUnique;
using mozilla::PodCopy;
@ -771,12 +774,12 @@ nsBinaryInputStream::ReadArrayBuffer(uint32_t aLength,
if (!aBuffer.isObject()) {
return NS_ERROR_FAILURE;
}
JS::RootedObject buffer(aCx, &aBuffer.toObject());
if (!JS_IsArrayBufferObject(buffer)) {
JS::Rooted<JSObject*> buffer(aCx, &aBuffer.toObject());
if (!JS::IsArrayBufferObject(buffer)) {
return NS_ERROR_FAILURE;
}
uint32_t bufferLength = JS_GetArrayBufferByteLength(buffer);
uint32_t bufferLength = JS::GetArrayBufferByteLength(buffer);
if (bufferLength < aLength) {
return NS_ERROR_FAILURE;
}
@ -804,13 +807,13 @@ nsBinaryInputStream::ReadArrayBuffer(uint32_t aLength,
JS::AutoCheckCannotGC nogc;
bool isShared;
if (bufferLength != JS_GetArrayBufferByteLength(buffer)) {
if (bufferLength != JS::GetArrayBufferByteLength(buffer)) {
return NS_ERROR_FAILURE;
}
char* data =
reinterpret_cast<char*>(JS_GetArrayBufferData(buffer, &isShared, nogc));
MOZ_ASSERT(!isShared); // Implied by JS_GetArrayBufferData()
char* data = reinterpret_cast<char*>(
JS::GetArrayBufferData(buffer, &isShared, nogc));
MOZ_ASSERT(!isShared); // Implied by JS::GetArrayBufferData()
if (!data) {
return NS_ERROR_FAILURE;
}