mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 711843 - Update JSAPI for typed arrays, remove uses of jstypedarray.h outside the engine [r=Waldo,bz,Ms2ger,bholley,bjacob,philikon,evilpie,bent,yourmama] [a=mfinkle thanks to gkw]
This commit is contained in:
parent
748a97a1ee
commit
0fe26d128c
@ -59,7 +59,7 @@ class nsString;
|
||||
* http://dev.w3.org/html5/websockets/
|
||||
*
|
||||
*/
|
||||
[scriptable, uuid(f463b9b5-1408-4057-9224-e4f5bc33f17b)]
|
||||
[scriptable, uuid(e59c8c65-df29-485c-a00b-8fac3dc1573a)]
|
||||
interface nsIWebSocket : nsISupports
|
||||
{
|
||||
readonly attribute DOMString url;
|
||||
@ -93,7 +93,7 @@ interface nsIWebSocket : nsISupports
|
||||
* @return if the connection is still established and the data was queued or
|
||||
* sent successfully.
|
||||
*/
|
||||
void send(in nsIVariant data);
|
||||
[implicit_jscontext] void send(in nsIVariant data);
|
||||
|
||||
/**
|
||||
* Closes the Web Socket connection or connection attempt, if any.
|
||||
|
@ -111,7 +111,7 @@ interface nsIXMLHttpRequestUpload : nsIXMLHttpRequestEventTarget {
|
||||
* you're aware of all the security implications. And then think twice about
|
||||
* it.
|
||||
*/
|
||||
[scriptable, uuid(88ffc45a-22e2-44f4-9a6e-f4586fbde376)]
|
||||
[scriptable, uuid(8681ffbc-4755-45de-9fc1-b63e6930e76a)]
|
||||
interface nsIXMLHttpRequest : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -260,7 +260,7 @@ interface nsIXMLHttpRequest : nsISupports
|
||||
* Type header via the setRequestHeader method before
|
||||
* calling send.
|
||||
*/
|
||||
void send([optional] in nsIVariant body);
|
||||
[implicit_jscontext] void send([optional] in nsIVariant body);
|
||||
|
||||
/**
|
||||
* A variant of the send() method used to send binary data.
|
||||
@ -269,7 +269,7 @@ interface nsIXMLHttpRequest : nsISupports
|
||||
* converted to a single-byte string by truncation (i.e., the
|
||||
* high-order byte of each character will be discarded).
|
||||
*/
|
||||
void sendAsBinary(in DOMString body);
|
||||
[implicit_jscontext] void sendAsBinary(in DOMString body);
|
||||
|
||||
/**
|
||||
* Sets a HTTP request header for HTTP requests. You must call open
|
||||
|
@ -45,7 +45,7 @@
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jstypedarray.h"
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@ -5872,15 +5872,14 @@ nsContentUtils::CreateArrayBuffer(JSContext *aCx, const nsACString& aData,
|
||||
}
|
||||
|
||||
PRInt32 dataLen = aData.Length();
|
||||
*aResult = js_CreateArrayBuffer(aCx, dataLen);
|
||||
*aResult = JS_NewArrayBuffer(aCx, dataLen);
|
||||
if (!*aResult) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (dataLen > 0) {
|
||||
JSObject *abuf = js::ArrayBuffer::getArrayBuffer(*aResult);
|
||||
NS_ASSERTION(abuf, "What happened?");
|
||||
memcpy(JS_GetArrayBufferData(abuf), aData.BeginReading(), dataLen);
|
||||
NS_ASSERTION(JS_IsArrayBufferObject(*aResult, aCx), "What happened?");
|
||||
memcpy(JS_GetArrayBufferData(*aResult, aCx), aData.BeginReading(), dataLen);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -36,7 +36,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsDOMBlobBuilder.h"
|
||||
#include "jstypedarray.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsIMultiplexInputStream.h"
|
||||
@ -249,11 +249,8 @@ nsDOMMultipartFile::InitInternal(JSContext* aCx,
|
||||
} else {
|
||||
blobSet.AppendBlob(blob);
|
||||
}
|
||||
} else if (js_IsArrayBuffer(&obj)) {
|
||||
JSObject* buffer = js::ArrayBuffer::getArrayBuffer(&obj);
|
||||
if (!buffer)
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
blobSet.AppendArrayBuffer(buffer);
|
||||
} else if (JS_IsArrayBufferObject(&obj, aCx)) {
|
||||
blobSet.AppendArrayBuffer(&obj, aCx);
|
||||
} else {
|
||||
// neither arraybuffer nor blob
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
@ -331,9 +328,10 @@ BlobSet::AppendBlobs(const nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlob)
|
||||
}
|
||||
|
||||
nsresult
|
||||
BlobSet::AppendArrayBuffer(JSObject* aBuffer)
|
||||
BlobSet::AppendArrayBuffer(JSObject* aBuffer, JSContext *aCx)
|
||||
{
|
||||
return AppendVoidPtr(JS_GetArrayBufferData(aBuffer), JS_GetArrayBufferByteLength(aBuffer));
|
||||
return AppendVoidPtr(JS_GetArrayBufferData(aBuffer, aCx),
|
||||
JS_GetArrayBufferByteLength(aBuffer, aCx));
|
||||
}
|
||||
|
||||
DOMCI_DATA(MozBlobBuilder, nsDOMBlobBuilder)
|
||||
@ -436,10 +434,8 @@ nsDOMBlobBuilder::Append(const jsval& aData,
|
||||
}
|
||||
|
||||
// Is it an array buffer?
|
||||
if (js_IsArrayBuffer(obj)) {
|
||||
JSObject* buffer = js::ArrayBuffer::getArrayBuffer(obj);
|
||||
if (buffer)
|
||||
return mBlobSet.AppendArrayBuffer(buffer);
|
||||
if (JS_IsArrayBufferObject(obj, aCx)) {
|
||||
return mBlobSet.AppendArrayBuffer(obj, aCx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ public:
|
||||
nsresult AppendVoidPtr(const void* aData, PRUint32 aLength);
|
||||
nsresult AppendString(JSString* aString, bool nativeEOL, JSContext* aCx);
|
||||
nsresult AppendBlob(nsIDOMBlob* aBlob);
|
||||
nsresult AppendArrayBuffer(JSObject* aBuffer);
|
||||
nsresult AppendArrayBuffer(JSObject* aBuffer, JSContext *aCx);
|
||||
nsresult AppendBlobs(const nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlob);
|
||||
|
||||
nsTArray<nsCOMPtr<nsIDOMBlob> >& GetBlobs() { Flush(); return mBlobs; }
|
||||
|
@ -81,7 +81,7 @@
|
||||
#include "nsDOMJSUtils.h"
|
||||
#include "nsDOMEventTargetHelper.h"
|
||||
|
||||
#include "jstypedarray.h"
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -359,11 +359,9 @@ nsDOMFileReader::DoOnDataAvailable(nsIRequest *aRequest,
|
||||
NS_ASSERTION(bytesRead == aCount, "failed to read data");
|
||||
}
|
||||
else if (mDataFormat == FILE_AS_ARRAYBUFFER) {
|
||||
JSObject* abuf = js::ArrayBuffer::getArrayBuffer(mResultArrayBuffer);
|
||||
NS_ASSERTION(abuf, "What happened?");
|
||||
|
||||
PRUint32 bytesRead = 0;
|
||||
aInputStream->Read((char*)JS_GetArrayBufferData(abuf) + aOffset, aCount, &bytesRead);
|
||||
aInputStream->Read((char*)JS_GetArrayBufferData(mResultArrayBuffer, NULL) + aOffset,
|
||||
aCount, &bytesRead);
|
||||
NS_ASSERTION(bytesRead == aCount, "failed to read data");
|
||||
}
|
||||
else {
|
||||
@ -470,7 +468,7 @@ nsDOMFileReader::ReadFileContent(JSContext* aCx,
|
||||
|
||||
if (mDataFormat == FILE_AS_ARRAYBUFFER) {
|
||||
RootResultArrayBuffer();
|
||||
mResultArrayBuffer = js_CreateArrayBuffer(aCx, mTotal);
|
||||
mResultArrayBuffer = JS_NewArrayBuffer(aCx, mTotal);
|
||||
if (!mResultArrayBuffer) {
|
||||
NS_WARNING("Failed to create JS array buffer");
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -79,7 +79,7 @@
|
||||
#include "xpcpublic.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsContentErrors.h"
|
||||
#include "jstypedarray.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "prmem.h"
|
||||
#include "nsDOMFile.h"
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
@ -1301,7 +1301,7 @@ ContainsUnpairedSurrogates(const nsAString& aData)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebSocket::Send(nsIVariant *aData)
|
||||
nsWebSocket::Send(nsIVariant *aData, JSContext *aCx)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
|
||||
@ -1313,7 +1313,7 @@ nsWebSocket::Send(nsIVariant *aData)
|
||||
nsCOMPtr<nsIInputStream> msgStream;
|
||||
bool isBinary;
|
||||
PRUint32 msgLen;
|
||||
nsresult rv = GetSendParams(aData, msgString, msgStream, isBinary, msgLen);
|
||||
nsresult rv = GetSendParams(aData, msgString, msgStream, isBinary, msgLen, aCx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Always increment outgoing buffer len, even if closed
|
||||
@ -1346,7 +1346,8 @@ nsWebSocket::Send(nsIVariant *aData)
|
||||
nsresult
|
||||
nsWebSocket::GetSendParams(nsIVariant *aData, nsCString &aStringOut,
|
||||
nsCOMPtr<nsIInputStream> &aStreamOut,
|
||||
bool &aIsBinary, PRUint32 &aOutgoingLength)
|
||||
bool &aIsBinary, PRUint32 &aOutgoingLength,
|
||||
JSContext *aCx)
|
||||
{
|
||||
// Get type of data (arraybuffer, blob, or string)
|
||||
PRUint16 dataType;
|
||||
@ -1368,9 +1369,9 @@ nsWebSocket::GetSendParams(nsIVariant *aData, nsCString &aStringOut,
|
||||
nsresult rv = aData->GetAsJSVal(&realVal);
|
||||
if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal) &&
|
||||
(obj = JSVAL_TO_OBJECT(realVal)) &&
|
||||
(js_IsArrayBuffer(obj))) {
|
||||
PRInt32 len = JS_GetArrayBufferByteLength(obj);
|
||||
char* data = (char*)JS_GetArrayBufferData(obj);
|
||||
(JS_IsArrayBufferObject(obj, aCx))) {
|
||||
PRInt32 len = JS_GetArrayBufferByteLength(obj, aCx);
|
||||
char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj, aCx));
|
||||
|
||||
aStringOut.Assign(data, len);
|
||||
aIsBinary = true;
|
||||
|
@ -136,7 +136,8 @@ protected:
|
||||
// Get msg info out of JS variable being sent (string, arraybuffer, blob)
|
||||
nsresult GetSendParams(nsIVariant *aData, nsCString &aStringOut,
|
||||
nsCOMPtr<nsIInputStream> &aStreamOut,
|
||||
bool &aIsBinary, PRUint32 &aOutgoingLength);
|
||||
bool &aIsBinary, PRUint32 &aOutgoingLength,
|
||||
JSContext *aCx);
|
||||
|
||||
nsresult DoOnMessageAvailable(const nsACString & aMsg, bool isBinary);
|
||||
nsresult CreateAndDispatchSimpleEvent(const nsString& aName);
|
||||
|
@ -99,11 +99,11 @@
|
||||
#include "nsChannelPolicy.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "nsAsyncRedirectVerifyHelper.h"
|
||||
#include "jstypedarray.h"
|
||||
#include "nsStringBuffer.h"
|
||||
#include "nsDOMFile.h"
|
||||
#include "nsIFileChannel.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "sampler.h"
|
||||
#include "mozilla/dom/bindings/XMLHttpRequestBinding.h"
|
||||
#include "nsIDOMFormData.h"
|
||||
@ -2511,15 +2511,15 @@ nsXMLHttpRequest::ChangeStateToDone()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXMLHttpRequest::SendAsBinary(const nsAString &aBody)
|
||||
nsXMLHttpRequest::SendAsBinary(const nsAString &aBody, JSContext *aCx)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
SendAsBinary(aBody, rv);
|
||||
SendAsBinary(aCx, aBody, rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLHttpRequest::SendAsBinary(const nsAString &aBody, nsresult& aRv)
|
||||
nsXMLHttpRequest::SendAsBinary(JSContext *aCx, const nsAString &aBody, nsresult& aRv)
|
||||
{
|
||||
char *data = static_cast<char*>(NS_Alloc(aBody.Length() + 1));
|
||||
if (!data) {
|
||||
@ -2556,7 +2556,7 @@ nsXMLHttpRequest::SendAsBinary(const nsAString &aBody, nsresult& aRv)
|
||||
return;
|
||||
}
|
||||
|
||||
aRv = Send(variant);
|
||||
aRv = Send(variant, aCx);
|
||||
}
|
||||
|
||||
static nsresult
|
||||
@ -2627,15 +2627,15 @@ GetRequestBody(nsIXHRSendable* aSendable, nsIInputStream** aResult,
|
||||
}
|
||||
|
||||
static nsresult
|
||||
GetRequestBody(JSObject* aArrayBuffer, nsIInputStream** aResult,
|
||||
GetRequestBody(JSObject* aArrayBuffer, JSContext *aCx, nsIInputStream** aResult,
|
||||
nsACString& aContentType, nsACString& aCharset)
|
||||
{
|
||||
NS_ASSERTION(js_IsArrayBuffer(aArrayBuffer), "Not an ArrayBuffer!");
|
||||
NS_ASSERTION(JS_IsArrayBufferObject(aArrayBuffer, aCx), "Not an ArrayBuffer!");
|
||||
aContentType.SetIsVoid(true);
|
||||
aCharset.Truncate();
|
||||
|
||||
PRInt32 length = JS_GetArrayBufferByteLength(aArrayBuffer);
|
||||
char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(aArrayBuffer));
|
||||
PRInt32 length = JS_GetArrayBufferByteLength(aArrayBuffer, aCx);
|
||||
char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(aArrayBuffer, aCx));
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), data, length,
|
||||
@ -2648,7 +2648,7 @@ GetRequestBody(JSObject* aArrayBuffer, nsIInputStream** aResult,
|
||||
}
|
||||
|
||||
static nsresult
|
||||
GetRequestBody(nsIVariant* aBody, nsIInputStream** aResult,
|
||||
GetRequestBody(nsIVariant* aBody, JSContext *aCx, nsIInputStream** aResult,
|
||||
nsACString& aContentType, nsACString& aCharset)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
@ -2699,8 +2699,8 @@ GetRequestBody(nsIVariant* aBody, nsIInputStream** aResult,
|
||||
nsresult rv = aBody->GetAsJSVal(&realVal);
|
||||
if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal) &&
|
||||
(obj = JSVAL_TO_OBJECT(realVal)) &&
|
||||
(js_IsArrayBuffer(obj))) {
|
||||
return GetRequestBody(obj, aResult, aContentType, aCharset);
|
||||
(JS_IsArrayBufferObject(obj, aCx))) {
|
||||
return GetRequestBody(obj, aCx, aResult, aContentType, aCharset);
|
||||
}
|
||||
}
|
||||
else if (dataType == nsIDataType::VTYPE_VOID ||
|
||||
@ -2725,13 +2725,13 @@ GetRequestBody(nsIVariant* aBody, nsIInputStream** aResult,
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsXMLHttpRequest::GetRequestBody(nsIVariant* aVariant,
|
||||
nsXMLHttpRequest::GetRequestBody(nsIVariant* aVariant, JSContext *aCx,
|
||||
const Nullable<RequestBody>& aBody,
|
||||
nsIInputStream** aResult,
|
||||
nsACString& aContentType, nsACString& aCharset)
|
||||
{
|
||||
if (aVariant) {
|
||||
return ::GetRequestBody(aVariant, aResult, aContentType, aCharset);
|
||||
return ::GetRequestBody(aVariant, aCx, aResult, aContentType, aCharset);
|
||||
}
|
||||
|
||||
const RequestBody& body = aBody.Value();
|
||||
@ -2739,7 +2739,7 @@ nsXMLHttpRequest::GetRequestBody(nsIVariant* aVariant,
|
||||
switch (body.GetType()) {
|
||||
case nsXMLHttpRequest::RequestBody::ArrayBuffer:
|
||||
{
|
||||
return ::GetRequestBody(value.mArrayBuffer, aResult, aContentType, aCharset);
|
||||
return ::GetRequestBody(value.mArrayBuffer, aCx, aResult, aContentType, aCharset);
|
||||
}
|
||||
case nsXMLHttpRequest::RequestBody::Blob:
|
||||
{
|
||||
@ -2782,13 +2782,13 @@ nsXMLHttpRequest::GetRequestBody(nsIVariant* aVariant,
|
||||
|
||||
/* void send (in nsIVariant aBody); */
|
||||
NS_IMETHODIMP
|
||||
nsXMLHttpRequest::Send(nsIVariant *aBody)
|
||||
nsXMLHttpRequest::Send(nsIVariant *aBody, JSContext *aCx)
|
||||
{
|
||||
return Send(aBody, Nullable<RequestBody>());
|
||||
return Send(aCx, aBody, Nullable<RequestBody>());
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
|
||||
nsXMLHttpRequest::Send(JSContext *aCx, nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPrincipal, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
@ -2912,7 +2912,7 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
|
||||
nsCAutoString defaultContentType;
|
||||
nsCOMPtr<nsIInputStream> postDataStream;
|
||||
|
||||
rv = GetRequestBody(aVariant, aBody, getter_AddRefs(postDataStream),
|
||||
rv = GetRequestBody(aVariant, aCx, aBody, getter_AddRefs(postDataStream),
|
||||
defaultContentType, charset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -370,61 +370,62 @@ private:
|
||||
};
|
||||
|
||||
static nsresult GetRequestBody(nsIVariant* aVariant,
|
||||
JSContext* aCx,
|
||||
const Nullable<RequestBody>& aBody,
|
||||
nsIInputStream** aResult,
|
||||
nsACString& aContentType,
|
||||
nsACString& aCharset);
|
||||
|
||||
nsresult Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody);
|
||||
nsresult Send(const Nullable<RequestBody>& aBody)
|
||||
nsresult Send(JSContext *aCx, nsIVariant* aVariant, const Nullable<RequestBody>& aBody);
|
||||
nsresult Send(JSContext *aCx, const Nullable<RequestBody>& aBody)
|
||||
{
|
||||
return Send(nsnull, aBody);
|
||||
return Send(aCx, nsnull, aBody);
|
||||
}
|
||||
nsresult Send(const RequestBody& aBody)
|
||||
nsresult Send(JSContext *aCx, const RequestBody& aBody)
|
||||
{
|
||||
return Send(Nullable<RequestBody>(aBody));
|
||||
return Send(aCx, Nullable<RequestBody>(aBody));
|
||||
}
|
||||
|
||||
public:
|
||||
void Send(nsresult& aRv)
|
||||
void Send(JSContext *aCx, nsresult& aRv)
|
||||
{
|
||||
aRv = Send(Nullable<RequestBody>());
|
||||
aRv = Send(aCx, Nullable<RequestBody>());
|
||||
}
|
||||
void Send(JSObject* aArrayBuffer, nsresult& aRv)
|
||||
void Send(JSContext *aCx, JSObject* aArrayBuffer, nsresult& aRv)
|
||||
{
|
||||
NS_ASSERTION(aArrayBuffer, "Null should go to string version");
|
||||
aRv = Send(RequestBody(aArrayBuffer));
|
||||
aRv = Send(aCx, RequestBody(aArrayBuffer));
|
||||
}
|
||||
void Send(nsIDOMBlob* aBlob, nsresult& aRv)
|
||||
void Send(JSContext *aCx, nsIDOMBlob* aBlob, nsresult& aRv)
|
||||
{
|
||||
NS_ASSERTION(aBlob, "Null should go to string version");
|
||||
aRv = Send(RequestBody(aBlob));
|
||||
aRv = Send(aCx, RequestBody(aBlob));
|
||||
}
|
||||
void Send(nsIDocument* aDoc, nsresult& aRv)
|
||||
void Send(JSContext *aCx, nsIDocument* aDoc, nsresult& aRv)
|
||||
{
|
||||
NS_ASSERTION(aDoc, "Null should go to string version");
|
||||
aRv = Send(RequestBody(aDoc));
|
||||
aRv = Send(aCx, RequestBody(aDoc));
|
||||
}
|
||||
void Send(const nsAString& aString, nsresult& aRv)
|
||||
void Send(JSContext *aCx, const nsAString& aString, nsresult& aRv)
|
||||
{
|
||||
if (DOMStringIsNull(aString)) {
|
||||
Send(aRv);
|
||||
Send(aCx, aRv);
|
||||
}
|
||||
else {
|
||||
aRv = Send(RequestBody(aString));
|
||||
aRv = Send(aCx, RequestBody(aString));
|
||||
}
|
||||
}
|
||||
void Send(nsIDOMFormData* aFormData, nsresult& aRv)
|
||||
void Send(JSContext *aCx, nsIDOMFormData* aFormData, nsresult& aRv)
|
||||
{
|
||||
NS_ASSERTION(aFormData, "Null should go to string version");
|
||||
aRv = Send(RequestBody(aFormData));
|
||||
aRv = Send(aCx, RequestBody(aFormData));
|
||||
}
|
||||
void Send(nsIInputStream* aStream, nsresult& aRv)
|
||||
void Send(JSContext *aCx, nsIInputStream* aStream, nsresult& aRv)
|
||||
{
|
||||
NS_ASSERTION(aStream, "Null should go to string version");
|
||||
aRv = Send(RequestBody(aStream));
|
||||
aRv = Send(aCx, RequestBody(aStream));
|
||||
}
|
||||
void SendAsBinary(const nsAString& aBody, nsresult& aRv);
|
||||
void SendAsBinary(JSContext *aCx, const nsAString& aBody, nsresult& aRv);
|
||||
|
||||
void Abort();
|
||||
|
||||
@ -475,7 +476,7 @@ public:
|
||||
}
|
||||
|
||||
// We need a GetInterface callable from JS for chrome JS
|
||||
JS::Value GetInterface(JSContext*aCx, nsIJSIID* aIID, nsresult& aRv);
|
||||
JS::Value GetInterface(JSContext* aCx, nsIJSIID* aIID, nsresult& aRv);
|
||||
|
||||
// This creates a trusted readystatechange event, which is not cancelable and
|
||||
// doesn't bubble.
|
||||
|
@ -79,7 +79,7 @@ nsresult TestGetURL(const nsCString& aURL)
|
||||
rv = xhr->Open(getString, aURL, false, empty, empty);
|
||||
TEST_ENSURE_SUCCESS(rv, "OpenRequest failed!");
|
||||
|
||||
rv = xhr->Send(nsnull);
|
||||
rv = xhr->Send(nsnull, nsnull);
|
||||
TEST_ENSURE_SUCCESS(rv, "Send failed!");
|
||||
|
||||
nsAutoString response;
|
||||
|
@ -95,7 +95,7 @@ nsresult TestNativeXMLHttpRequest()
|
||||
rv = xhr->Open(getString, testURL, false, empty, empty);
|
||||
TEST_ENSURE_SUCCESS(rv, "Open failed!");
|
||||
|
||||
rv = xhr->Send(nsnull);
|
||||
rv = xhr->Send(nsnull, nsnull);
|
||||
TEST_ENSURE_SUCCESS(rv, "Send failed!");
|
||||
|
||||
nsAutoString response;
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "CustomQS_Canvas.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
typedef NS_STDCALL_FUNCPROTO(nsresult, CanvasStyleSetterType, nsIDOMCanvasRenderingContext2D,
|
||||
SetStrokeStyle_multi, (const nsAString &, nsISupports *));
|
||||
@ -173,8 +174,7 @@ CreateImageData(JSContext* cx, JSObject* obj, uint32_t w, uint32_t h, jsval* vp)
|
||||
}
|
||||
|
||||
// Create the fast typed array; it's initialized to 0 by default.
|
||||
JSObject* darray =
|
||||
js_CreateTypedArray(cx, js::TypedArray::TYPE_UINT8_CLAMPED, len.value());
|
||||
JSObject* darray = JS_NewUint8ClampedArray(cx, len.value());
|
||||
JS::AutoObjectRooter rd(cx, darray);
|
||||
if (!darray) {
|
||||
return false;
|
||||
@ -305,26 +305,30 @@ nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, unsigned argc, jsval
|
||||
|
||||
JS::AutoValueRooter tsrc_tvr(cx);
|
||||
|
||||
JSObject *tsrc = NULL;
|
||||
if (js::GetObjectClass(darray.get()) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8] ||
|
||||
js::GetObjectClass(darray.get()) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8_CLAMPED])
|
||||
JSObject * tsrc = NULL;
|
||||
if (JS_IsInt8Array(darray.get(), cx) ||
|
||||
JS_IsUint8Array(darray.get(), cx) ||
|
||||
JS_IsUint8ClampedArray(darray.get(), cx))
|
||||
{
|
||||
tsrc = darray.get();
|
||||
} else if (JS_IsArrayObject(cx, darray.get()) || js_IsTypedArray(darray.get())) {
|
||||
} else if (JS_IsTypedArrayObject(darray.get(), cx) || JS_IsArrayObject(cx, darray.get())) {
|
||||
// ugh, this isn't a uint8 typed array, someone made their own object; convert it to a typed array
|
||||
JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_UINT8, darray.get());
|
||||
JSObject *nobj = JS_NewUint8ClampedArrayFromArray(cx, darray.get());
|
||||
if (!nobj)
|
||||
return JS_FALSE;
|
||||
|
||||
*tsrc_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
|
||||
tsrc = js::TypedArray::getTypedArray(nobj);
|
||||
tsrc = nobj;
|
||||
} else {
|
||||
// yeah, no.
|
||||
return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR);
|
||||
}
|
||||
|
||||
// make the call
|
||||
rv = self->PutImageData_explicit(x, y, w, h, static_cast<PRUint8*>(JS_GetTypedArrayData(tsrc)), JS_GetTypedArrayByteLength(tsrc), hasDirtyRect, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
|
||||
MOZ_ASSERT(JS_IsTypedArrayObject(tsrc, cx));
|
||||
PRUint8* data = reinterpret_cast<PRUint8*>(JS_GetArrayBufferViewData(tsrc, cx));
|
||||
uint32_t byteLength = JS_GetTypedArrayByteLength(tsrc, cx);
|
||||
rv = self->PutImageData_explicit(x, y, w, h, data, byteLength, hasDirtyRect, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
|
||||
if (NS_FAILED(rv))
|
||||
return xpc_qsThrowMethodFailed(cx, rv, vp);
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
||||
*/
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jstypedarray.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "CustomQS_Canvas.h"
|
||||
|
||||
#define GET_INT32_ARG(var, index) \
|
||||
@ -84,10 +84,10 @@ public:
|
||||
{}
|
||||
|
||||
nsresult DoCallForImageData(WebGLsizei width, WebGLsizei height,
|
||||
JSObject* pixels)
|
||||
JSObject* pixels, JSContext *cx)
|
||||
{
|
||||
return self->TexImage2D_imageData(target, level, internalformat, width,
|
||||
height, 0, format, type, pixels);
|
||||
height, 0, format, type, pixels, cx);
|
||||
}
|
||||
nsresult DoCallForElement(mozilla::dom::Element* elt)
|
||||
{
|
||||
@ -126,11 +126,11 @@ public:
|
||||
{}
|
||||
|
||||
nsresult DoCallForImageData(WebGLsizei width, WebGLsizei height,
|
||||
JSObject* pixels)
|
||||
JSObject* pixels, JSContext *cx)
|
||||
{
|
||||
return self->TexSubImage2D_imageData(target, level, xoffset, yoffset,
|
||||
width, height, format, type,
|
||||
pixels);
|
||||
pixels, cx);
|
||||
}
|
||||
nsresult DoCallForElement(mozilla::dom::Element* elt)
|
||||
{
|
||||
@ -160,11 +160,11 @@ TexImage2DImageDataOrElement(JSContext* cx, T& self, JS::Value* object)
|
||||
if (!GetImageData(cx, *object, &int_width, &int_height, &obj_data)) {
|
||||
return false;
|
||||
}
|
||||
if (!js_IsTypedArray(obj_data.get())) {
|
||||
if (!JS_IsTypedArrayObject(obj_data.get(), cx)) {
|
||||
return xpc_qsThrow(cx, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
nsresult rv = self.DoCallForImageData(int_width, int_height, obj_data.get());
|
||||
nsresult rv = self.DoCallForImageData(int_width, int_height, obj_data.get(), cx);
|
||||
return NS_SUCCEEDED(rv) || xpc_qsThrow(cx, rv);
|
||||
}
|
||||
|
||||
@ -225,11 +225,11 @@ nsIDOMWebGLRenderingContext_TexImage2D(JSContext *cx, unsigned argc, jsval *vp)
|
||||
if (argv8 == nsnull) {
|
||||
rv = self->TexImage2D_array(argv0, argv1, argv2, argv3,
|
||||
argv4, argv5, argv6, argv7,
|
||||
nsnull);
|
||||
} else if (js_IsTypedArray(argv8)) {
|
||||
nsnull, cx);
|
||||
} else if (JS_IsTypedArrayObject(argv8, cx)) {
|
||||
rv = self->TexImage2D_array(argv0, argv1, argv2, argv3,
|
||||
argv4, argv5, argv6, argv7,
|
||||
js::TypedArray::getTypedArray(argv8));
|
||||
argv8, cx);
|
||||
} else {
|
||||
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 8);
|
||||
return JS_FALSE;
|
||||
@ -297,10 +297,10 @@ nsIDOMWebGLRenderingContext_TexSubImage2D(JSContext *cx, unsigned argc, jsval *v
|
||||
|
||||
JSObject *argv8 = JSVAL_TO_OBJECT(argv[8]);
|
||||
// try to grab a js::TypedArray
|
||||
if (js_IsTypedArray(argv8)) {
|
||||
if (JS_IsTypedArrayObject(argv8, cx)) {
|
||||
rv = self->TexSubImage2D_array(argv0, argv1, argv2, argv3,
|
||||
argv4, argv5, argv6, argv7,
|
||||
js::TypedArray::getTypedArray(argv8));
|
||||
argv8, cx);
|
||||
} else {
|
||||
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 8);
|
||||
return JS_FALSE;
|
||||
|
@ -691,11 +691,11 @@ protected:
|
||||
}
|
||||
|
||||
nsresult BufferData_size(WebGLenum target, WebGLsizei size, WebGLenum usage);
|
||||
nsresult BufferData_buf(WebGLenum target, JSObject* data, WebGLenum usage);
|
||||
nsresult BufferData_array(WebGLenum target, JSObject* data, WebGLenum usage);
|
||||
nsresult BufferData_buf(WebGLenum target, JSObject* data, WebGLenum usage, JSContext *cx);
|
||||
nsresult BufferData_array(WebGLenum target, JSObject* data, WebGLenum usage, JSContext *cx);
|
||||
|
||||
nsresult BufferSubData_buf(WebGLenum target, PRInt32 offset, JSObject* data);
|
||||
nsresult BufferSubData_array(WebGLenum target, PRInt32 offset, JSObject* data);
|
||||
nsresult BufferSubData_buf(WebGLenum target, PRInt32 offset, JSObject* data, JSContext *cx);
|
||||
nsresult BufferSubData_array(WebGLenum target, PRInt32 offset, JSObject* data, JSContext *cx);
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLCanvasElement> mCanvasElement;
|
||||
|
||||
|
@ -54,7 +54,7 @@
|
||||
|
||||
#include "CanvasUtils.h"
|
||||
|
||||
#include "jstypedarray.h"
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
#include "WebGLTexelConversions.h"
|
||||
#include "WebGLValidateStrings.h"
|
||||
@ -455,12 +455,12 @@ WebGLContext::BufferData(PRInt32 target, const JS::Value& data, PRInt32 usage,
|
||||
|
||||
if (data.isObject()) {
|
||||
JSObject& dataObj = data.toObject();
|
||||
if (js_IsArrayBuffer(&dataObj)) {
|
||||
return BufferData_buf(target, &dataObj, usage);
|
||||
if (JS_IsArrayBufferObject(&dataObj, cx)) {
|
||||
return BufferData_buf(target, &dataObj, usage, cx);
|
||||
}
|
||||
|
||||
if (js_IsTypedArray(&dataObj)) {
|
||||
return BufferData_array(target, &dataObj, usage);
|
||||
if (JS_IsTypedArrayObject(&dataObj, cx)) {
|
||||
return BufferData_array(target, &dataObj, usage, cx);
|
||||
}
|
||||
|
||||
return ErrorInvalidValue("bufferData: object passed that is not an "
|
||||
@ -516,11 +516,14 @@ WebGLContext::BufferData_size(WebGLenum target, WebGLsizei size, WebGLenum usage
|
||||
}
|
||||
|
||||
nsresult
|
||||
WebGLContext::BufferData_buf(WebGLenum target, JSObject *wb, WebGLenum usage)
|
||||
WebGLContext::BufferData_buf(WebGLenum target, JSObject *wb, WebGLenum usage, JSContext *cx)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return NS_OK;
|
||||
|
||||
if (!JS_IsArrayBufferObject(wb, cx))
|
||||
return ErrorInvalidOperation("BufferData: incorrect type");
|
||||
|
||||
WebGLBuffer *boundBuffer = NULL;
|
||||
|
||||
if (target == LOCAL_GL_ARRAY_BUFFER) {
|
||||
@ -540,24 +543,24 @@ WebGLContext::BufferData_buf(WebGLenum target, JSObject *wb, WebGLenum usage)
|
||||
MakeContextCurrent();
|
||||
|
||||
GLenum error = CheckedBufferData(target,
|
||||
JS_GetArrayBufferByteLength(wb),
|
||||
JS_GetArrayBufferData(wb),
|
||||
JS_GetArrayBufferByteLength(wb, cx),
|
||||
JS_GetArrayBufferData(wb, cx),
|
||||
usage);
|
||||
if (error) {
|
||||
LogMessageIfVerbose("bufferData generated error %s", ErrorName(error));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
boundBuffer->SetByteLength(JS_GetArrayBufferByteLength(wb));
|
||||
boundBuffer->SetByteLength(JS_GetArrayBufferByteLength(wb, cx));
|
||||
boundBuffer->InvalidateCachedMaxElements();
|
||||
if (!boundBuffer->CopyDataIfElementArray(JS_GetArrayBufferData(wb)))
|
||||
if (!boundBuffer->CopyDataIfElementArray(JS_GetArrayBufferData(wb, cx)))
|
||||
return ErrorOutOfMemory("bufferData: out of memory");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
WebGLContext::BufferData_array(WebGLenum target, JSObject *wa, WebGLenum usage)
|
||||
WebGLContext::BufferData_array(WebGLenum target, JSObject *wa, WebGLenum usage, JSContext *cx)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return NS_OK;
|
||||
@ -580,25 +583,27 @@ WebGLContext::BufferData_array(WebGLenum target, JSObject *wa, WebGLenum usage)
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
GLenum error = CheckedBufferData(target,
|
||||
JS_GetTypedArrayByteLength(wa),
|
||||
JS_GetTypedArrayData(wa),
|
||||
usage);
|
||||
if (!JS_IsTypedArrayObject(wa, cx))
|
||||
return ErrorInvalidOperation("BufferData: incorrect type");
|
||||
|
||||
uint32_t byteLength = JS_GetTypedArrayByteLength(wa, cx);
|
||||
void *data = JS_GetArrayBufferViewData(wa, cx);
|
||||
GLenum error = CheckedBufferData(target, byteLength, data, usage);
|
||||
if (error) {
|
||||
LogMessageIfVerbose("bufferData generated error %s", ErrorName(error));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
boundBuffer->SetByteLength(JS_GetTypedArrayByteLength(wa));
|
||||
boundBuffer->SetByteLength(byteLength);
|
||||
boundBuffer->InvalidateCachedMaxElements();
|
||||
if (!boundBuffer->CopyDataIfElementArray(JS_GetTypedArrayData(wa)))
|
||||
if (!boundBuffer->CopyDataIfElementArray(data))
|
||||
return ErrorOutOfMemory("bufferData: out of memory");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::BufferSubData(PRInt32 target, PRInt32 offset, const JS::Value& data)
|
||||
WebGLContext::BufferSubData(PRInt32 target, PRInt32 offset, const JS::Value& data, JSContext *cx)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return NS_OK;
|
||||
@ -613,23 +618,26 @@ WebGLContext::BufferSubData(PRInt32 target, PRInt32 offset, const JS::Value& dat
|
||||
}
|
||||
|
||||
JSObject& dataObj = data.toObject();
|
||||
if (js_IsArrayBuffer(&dataObj)) {
|
||||
return BufferSubData_buf(target, offset, &dataObj);
|
||||
if (JS_IsArrayBufferObject(&dataObj, cx)) {
|
||||
return BufferSubData_buf(target, offset, &dataObj, cx);
|
||||
}
|
||||
|
||||
if (js_IsTypedArray(&dataObj)) {
|
||||
return BufferSubData_array(target, offset, &dataObj);
|
||||
if (JS_IsTypedArrayObject(&dataObj, cx)) {
|
||||
return BufferSubData_array(target, offset, &dataObj, cx);
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
WebGLContext::BufferSubData_buf(GLenum target, WebGLsizei byteOffset, JSObject *wb)
|
||||
WebGLContext::BufferSubData_buf(GLenum target, WebGLsizei byteOffset, JSObject *wb, JSContext *cx)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return NS_OK;
|
||||
|
||||
if (!JS_IsArrayBufferObject(wb, cx))
|
||||
return ErrorInvalidOperation("BufferSubData: incorrect type");
|
||||
|
||||
WebGLBuffer *boundBuffer = NULL;
|
||||
|
||||
if (target == LOCAL_GL_ARRAY_BUFFER) {
|
||||
@ -646,30 +654,33 @@ WebGLContext::BufferSubData_buf(GLenum target, WebGLsizei byteOffset, JSObject *
|
||||
if (!boundBuffer)
|
||||
return ErrorInvalidOperation("BufferData: no buffer bound!");
|
||||
|
||||
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + JS_GetArrayBufferByteLength(wb);
|
||||
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + JS_GetArrayBufferByteLength(wb, cx);
|
||||
if (!checked_neededByteLength.valid())
|
||||
return ErrorInvalidOperation("bufferSubData: integer overflow computing the needed byte length");
|
||||
|
||||
if (checked_neededByteLength.value() > boundBuffer->ByteLength())
|
||||
return ErrorInvalidOperation("BufferSubData: not enough data - operation requires %d bytes, but buffer only has %d bytes",
|
||||
byteOffset, JS_GetArrayBufferByteLength(wb), boundBuffer->ByteLength());
|
||||
byteOffset, JS_GetArrayBufferByteLength(wb, cx), boundBuffer->ByteLength());
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
boundBuffer->CopySubDataIfElementArray(byteOffset, JS_GetArrayBufferByteLength(wb), JS_GetArrayBufferData(wb));
|
||||
boundBuffer->CopySubDataIfElementArray(byteOffset, JS_GetArrayBufferByteLength(wb, cx), JS_GetArrayBufferData(wb, cx));
|
||||
boundBuffer->InvalidateCachedMaxElements();
|
||||
|
||||
gl->fBufferSubData(target, byteOffset, JS_GetArrayBufferByteLength(wb), JS_GetArrayBufferData(wb));
|
||||
gl->fBufferSubData(target, byteOffset, JS_GetArrayBufferByteLength(wb, cx), JS_GetArrayBufferData(wb, cx));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
WebGLContext::BufferSubData_array(WebGLenum target, WebGLsizei byteOffset, JSObject *wa)
|
||||
WebGLContext::BufferSubData_array(WebGLenum target, WebGLsizei byteOffset, JSObject *wa, JSContext *cx)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return NS_OK;
|
||||
|
||||
if (!JS_IsTypedArrayObject(wa, cx))
|
||||
return ErrorInvalidOperation("BufferSubData: incorrect type");
|
||||
|
||||
WebGLBuffer *boundBuffer = NULL;
|
||||
|
||||
if (target == LOCAL_GL_ARRAY_BUFFER) {
|
||||
@ -686,20 +697,20 @@ WebGLContext::BufferSubData_array(WebGLenum target, WebGLsizei byteOffset, JSObj
|
||||
if (!boundBuffer)
|
||||
return ErrorInvalidOperation("BufferData: no buffer bound!");
|
||||
|
||||
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + JS_GetTypedArrayByteLength(wa);
|
||||
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + JS_GetTypedArrayByteLength(wa, cx);
|
||||
if (!checked_neededByteLength.valid())
|
||||
return ErrorInvalidOperation("bufferSubData: integer overflow computing the needed byte length");
|
||||
|
||||
if (checked_neededByteLength.value() > boundBuffer->ByteLength())
|
||||
return ErrorInvalidOperation("BufferSubData: not enough data -- operation requires %d bytes, but buffer only has %d bytes",
|
||||
byteOffset, JS_GetTypedArrayByteLength(wa), boundBuffer->ByteLength());
|
||||
byteOffset, JS_GetTypedArrayByteLength(wa, cx), boundBuffer->ByteLength());
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
boundBuffer->CopySubDataIfElementArray(byteOffset, JS_GetTypedArrayByteLength(wa), JS_GetTypedArrayData(wa));
|
||||
boundBuffer->CopySubDataIfElementArray(byteOffset, JS_GetTypedArrayByteLength(wa, cx), JS_GetArrayBufferViewData(wa, cx));
|
||||
boundBuffer->InvalidateCachedMaxElements();
|
||||
|
||||
gl->fBufferSubData(target, byteOffset, JS_GetTypedArrayByteLength(wa), JS_GetTypedArrayData(wa));
|
||||
gl->fBufferSubData(target, byteOffset, JS_GetTypedArrayByteLength(wa, cx), JS_GetArrayBufferViewData(wa, cx));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -3381,9 +3392,13 @@ GL_SAME_METHOD_2(PolygonOffset, PolygonOffset, WebGLfloat, WebGLfloat)
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::ReadPixels(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height,
|
||||
WebGLenum format, WebGLenum type, const JS::Value& pixelsVal)
|
||||
WebGLenum format, WebGLenum type, const JS::Value& pixelsVal, JSContext *cx)
|
||||
{
|
||||
if (!pixelsVal.isObject() || !js_IsTypedArray(&pixelsVal.toObject())) {
|
||||
if (!pixelsVal.isObject()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!JS_IsTypedArrayObject(&pixelsVal.toObject(), cx)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -3405,9 +3420,9 @@ WebGLContext::ReadPixels(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei he
|
||||
WebGLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
|
||||
WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
|
||||
|
||||
void* data = JS_GetTypedArrayData(&pixels);
|
||||
PRUint32 dataByteLen = JS_GetTypedArrayByteLength(&pixels);
|
||||
int dataType = JS_GetTypedArrayType(&pixels);
|
||||
void* data = JS_GetArrayBufferViewData(&pixels, cx);
|
||||
PRUint32 dataByteLen = JS_GetTypedArrayByteLength(&pixels, cx);
|
||||
int dataType = JS_GetTypedArrayType(&pixels, cx);
|
||||
|
||||
PRUint32 channels = 0;
|
||||
|
||||
@ -3433,13 +3448,13 @@ WebGLContext::ReadPixels(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei he
|
||||
switch (type) {
|
||||
case LOCAL_GL_UNSIGNED_BYTE:
|
||||
bytesPerPixel = 1 * channels;
|
||||
requiredDataType = js::TypedArray::TYPE_UINT8;
|
||||
requiredDataType = js::ArrayBufferView::TYPE_UINT8;
|
||||
break;
|
||||
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
|
||||
bytesPerPixel = 2;
|
||||
requiredDataType = js::TypedArray::TYPE_UINT16;
|
||||
requiredDataType = js::ArrayBufferView::TYPE_UINT16;
|
||||
break;
|
||||
default:
|
||||
return ErrorInvalidEnum("readPixels: Bad type");
|
||||
@ -4105,7 +4120,8 @@ WebGLContext::DOMElementToImageSurface(Element* imageOrCanvas,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
template<size_t type>
|
||||
template<JSBool TypedArrayTest(JSObject* obj, JSContext* cx),
|
||||
JSObject* TypedArrayCopy(JSContext* cx, JSObject* src)>
|
||||
static JSObject*
|
||||
GetTypedArray(JSContext* aCx, const JS::Value& aValue)
|
||||
{
|
||||
@ -4115,12 +4131,12 @@ GetTypedArray(JSContext* aCx, const JS::Value& aValue)
|
||||
|
||||
JSObject& value = aValue.toObject();
|
||||
|
||||
if (js::GetObjectClass(&value) == &js::TypedArray::fastClasses[type]) {
|
||||
if (TypedArrayTest(&value, aCx)) {
|
||||
return &value;
|
||||
}
|
||||
|
||||
if (JS_IsArrayObject(aCx, &value)) {
|
||||
return js_CreateTypedArrayWithArray(aCx, type, &value);
|
||||
return TypedArrayCopy(aCx, &value);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -4129,7 +4145,7 @@ GetTypedArray(JSContext* aCx, const JS::Value& aValue)
|
||||
static JSObject*
|
||||
GetFloat32Array(JSContext* aCx, const JS::Value& aValue)
|
||||
{
|
||||
return GetTypedArray<js::TypedArray::TYPE_FLOAT32>(aCx, aValue);
|
||||
return GetTypedArray<JS_IsFloat32Array, JS_NewFloat32ArrayFromArray>(aCx, aValue);
|
||||
}
|
||||
|
||||
#define OBTAIN_UNIFORM_LOCATION(info) \
|
||||
@ -4153,7 +4169,7 @@ NS_IMETHODIMP
|
||||
WebGLContext::name(nsIWebGLUniformLocation *aLocation, const JS::Value& aValue, \
|
||||
JSContext* aCx) \
|
||||
{ \
|
||||
JSObject* wa = GetTypedArray<js::TypedArray::arrayType>(aCx, aValue); \
|
||||
JSObject* wa = GetTypedArray<JS_Is ## arrayType ## Array, JS_New ## arrayType ## ArrayFromArray>(aCx, aValue); \
|
||||
if (!wa) { \
|
||||
return NS_ERROR_FAILURE; \
|
||||
} \
|
||||
@ -4164,9 +4180,6 @@ WebGLContext::name(nsIWebGLUniformLocation *aLocation, const JS::Value& aValue,
|
||||
\
|
||||
nsIWebGLUniformLocation* ploc = aLocation; \
|
||||
OBTAIN_UNIFORM_LOCATION(#name ": location") \
|
||||
if (JS_GetTypedArrayType(wa) != js::TypedArray::arrayType) { \
|
||||
return ErrorInvalidOperation(#name ": array must be " #arrayType); \
|
||||
} \
|
||||
int elementSize = location_object->ElementSize(); \
|
||||
if (cnt != elementSize) { \
|
||||
return ErrorInvalidOperation( \
|
||||
@ -4175,7 +4188,7 @@ WebGLContext::name(nsIWebGLUniformLocation *aLocation, const JS::Value& aValue,
|
||||
cnt, \
|
||||
elementSize); \
|
||||
} \
|
||||
PRUint32 arrayLength = JS_GetTypedArrayLength(wa); \
|
||||
PRUint32 arrayLength = JS_GetTypedArrayLength(wa, aCx); \
|
||||
const WebGLUniformInfo& info = location_object->Info(); \
|
||||
PRUint32 expectedArrayLength = cnt * info.arraySize; \
|
||||
if (arrayLength < expectedArrayLength || \
|
||||
@ -4200,7 +4213,7 @@ WebGLContext::name(nsIWebGLUniformLocation *aLocation, const JS::Value& aValue,
|
||||
\
|
||||
MakeContextCurrent(); \
|
||||
gl->f##name(location, info.arraySize, \
|
||||
static_cast<ptrType*>(JS_GetTypedArrayData(wa))); \
|
||||
static_cast<ptrType*>(JS_GetArrayBufferViewData(wa, aCx))); \
|
||||
return NS_OK; \
|
||||
}
|
||||
|
||||
@ -4220,7 +4233,7 @@ WebGLContext::name(nsIWebGLUniformLocation* aLocation, bool aTranspose,
|
||||
\
|
||||
nsIWebGLUniformLocation* ploc = aLocation; \
|
||||
OBTAIN_UNIFORM_LOCATION(#name ": location") \
|
||||
if (JS_GetTypedArrayType(wa) != js::TypedArray::TYPE_FLOAT32) { \
|
||||
if (!wa || !JS_IsFloat32Array(wa, aCx)) { \
|
||||
return ErrorInvalidValue(#name ": array must be of Float32 type"); \
|
||||
} \
|
||||
int elementSize = location_object->ElementSize(); \
|
||||
@ -4231,7 +4244,7 @@ WebGLContext::name(nsIWebGLUniformLocation* aLocation, bool aTranspose,
|
||||
dim*dim, \
|
||||
elementSize); \
|
||||
} \
|
||||
PRUint32 arrayLength = JS_GetTypedArrayLength(wa); \
|
||||
PRUint32 arrayLength = JS_GetTypedArrayLength(wa, aCx); \
|
||||
const WebGLUniformInfo& info = location_object->Info(); \
|
||||
PRUint32 expectedArrayLength = dim * dim * info.arraySize; \
|
||||
if (arrayLength < expectedArrayLength || \
|
||||
@ -4260,7 +4273,7 @@ WebGLContext::name(nsIWebGLUniformLocation* aLocation, bool aTranspose,
|
||||
\
|
||||
MakeContextCurrent(); \
|
||||
gl->f##name(location, info.arraySize, false, \
|
||||
static_cast<WebGLfloat*>(JS_GetTypedArrayData(wa))); \
|
||||
static_cast<WebGLfloat*>(JS_GetArrayBufferViewData(wa, aCx))); \
|
||||
return NS_OK; \
|
||||
}
|
||||
|
||||
@ -4306,15 +4319,15 @@ SIMPLE_METHOD_UNIFORM_2(Uniform2f, Uniform2f, WebGLfloat, WebGLfloat)
|
||||
SIMPLE_METHOD_UNIFORM_3(Uniform3f, Uniform3f, WebGLfloat, WebGLfloat, WebGLfloat)
|
||||
SIMPLE_METHOD_UNIFORM_4(Uniform4f, Uniform4f, WebGLfloat, WebGLfloat, WebGLfloat, WebGLfloat)
|
||||
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform1iv, 1, TYPE_INT32, WebGLint)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform2iv, 2, TYPE_INT32, WebGLint)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform3iv, 3, TYPE_INT32, WebGLint)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform4iv, 4, TYPE_INT32, WebGLint)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform1iv, 1, Int32, WebGLint)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform2iv, 2, Int32, WebGLint)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform3iv, 3, Int32, WebGLint)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform4iv, 4, Int32, WebGLint)
|
||||
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform1fv, 1, TYPE_FLOAT32, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform2fv, 2, TYPE_FLOAT32, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform3fv, 3, TYPE_FLOAT32, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform4fv, 4, TYPE_FLOAT32, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform1fv, 1, Float32, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform2fv, 2, Float32, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform3fv, 3, Float32, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform4fv, 4, Float32, WebGLfloat)
|
||||
|
||||
SIMPLE_MATRIX_METHOD_UNIFORM(UniformMatrix2fv, 2)
|
||||
SIMPLE_MATRIX_METHOD_UNIFORM(UniformMatrix3fv, 3)
|
||||
@ -4409,7 +4422,7 @@ WebGLContext::VertexAttrib4f(PRUint32 index, WebGLfloat x0, WebGLfloat x1,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#define SIMPLE_ARRAY_METHOD_NO_COUNT(name, cnt, arrayType, ptrType) \
|
||||
#define SIMPLE_ARRAY_METHOD_NO_COUNT(name, cnt, ptrType) \
|
||||
NS_IMETHODIMP \
|
||||
WebGLContext::name(WebGLuint idx, const JS::Value& aValue, JSContext* aCx) \
|
||||
{ \
|
||||
@ -4421,16 +4434,13 @@ WebGLContext::name(WebGLuint idx, const JS::Value& aValue, JSContext* aCx)
|
||||
if (!IsContextStable()) { \
|
||||
return NS_OK; \
|
||||
} \
|
||||
if (JS_GetTypedArrayType(wa) != js::TypedArray::arrayType) { \
|
||||
return ErrorInvalidOperation(#name ": array must be " #arrayType); \
|
||||
} \
|
||||
if (JS_GetTypedArrayLength(wa) < cnt) { \
|
||||
if (JS_GetTypedArrayLength(wa, aCx) < cnt) { \
|
||||
return ErrorInvalidOperation(#name ": array must be >= %d elements", \
|
||||
cnt); \
|
||||
} \
|
||||
\
|
||||
MakeContextCurrent(); \
|
||||
ptrType *ptr = static_cast<ptrType*>(JS_GetTypedArrayData(wa)); \
|
||||
ptrType *ptr = static_cast<ptrType*>(JS_GetFloat32ArrayData(wa, aCx)); \
|
||||
if (idx) { \
|
||||
gl->f##name(idx, ptr); \
|
||||
} else { \
|
||||
@ -4444,10 +4454,10 @@ WebGLContext::name(WebGLuint idx, const JS::Value& aValue, JSContext* aCx)
|
||||
return NS_OK; \
|
||||
}
|
||||
|
||||
SIMPLE_ARRAY_METHOD_NO_COUNT(VertexAttrib1fv, 1, TYPE_FLOAT32, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_NO_COUNT(VertexAttrib2fv, 2, TYPE_FLOAT32, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_NO_COUNT(VertexAttrib3fv, 3, TYPE_FLOAT32, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_NO_COUNT(VertexAttrib4fv, 4, TYPE_FLOAT32, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_NO_COUNT(VertexAttrib1fv, 1, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_NO_COUNT(VertexAttrib2fv, 2, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_NO_COUNT(VertexAttrib3fv, 3, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_NO_COUNT(VertexAttrib4fv, 4, WebGLfloat)
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::UseProgram(nsIWebGLProgram *pobj)
|
||||
@ -4733,9 +4743,9 @@ WebGLContext::CompileShader(nsIWebGLShader *sobj)
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::CompressedTexImage2D(WebGLenum target, WebGLint level, WebGLenum internalformat,
|
||||
WebGLsizei width, WebGLsizei height, WebGLint border,
|
||||
const JS::Value& pixels)
|
||||
const JS::Value& pixels, JSContext *cx)
|
||||
{
|
||||
if (!pixels.isObject() || !js_IsTypedArray(&pixels.toObject())) {
|
||||
if (!pixels.isObject() || !JS_IsTypedArrayObject(&pixels.toObject(), cx)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -4753,9 +4763,9 @@ WebGLContext::CompressedTexImage2D(WebGLenum target, WebGLint level, WebGLenum i
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::CompressedTexSubImage2D(WebGLenum target, WebGLint level, WebGLint xoffset,
|
||||
WebGLint yoffset, WebGLsizei width, WebGLsizei height,
|
||||
WebGLenum format, const JS::Value& pixels)
|
||||
WebGLenum format, const JS::Value& pixels, JSContext *cx)
|
||||
{
|
||||
if (!pixels.isObject() || !js_IsTypedArray(&pixels.toObject())) {
|
||||
if (!pixels.isObject() || !JS_IsTypedArrayObject(&pixels.toObject(), cx)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -5225,30 +5235,35 @@ NS_IMETHODIMP
|
||||
WebGLContext::TexImage2D_array(WebGLenum target, WebGLint level, WebGLenum internalformat,
|
||||
WebGLsizei width, WebGLsizei height, WebGLint border,
|
||||
WebGLenum format, WebGLenum type,
|
||||
JSObject *pixels)
|
||||
JSObject *pixels, JSContext *cx)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return NS_OK;
|
||||
|
||||
if (pixels && !JS_IsTypedArrayObject(pixels, cx))
|
||||
return ErrorInvalidValue("TexSubImage2D: pixels are wrong type!");
|
||||
|
||||
return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type,
|
||||
pixels ? JS_GetTypedArrayData(pixels) : 0,
|
||||
pixels ? JS_GetTypedArrayByteLength(pixels) : 0,
|
||||
pixels ? (int)JS_GetTypedArrayType(pixels) : -1,
|
||||
pixels ? JS_GetArrayBufferViewData(pixels, cx) : 0,
|
||||
pixels ? JS_GetArrayBufferViewByteLength(pixels, cx) : 0,
|
||||
pixels ? (int)JS_GetTypedArrayType(pixels, cx) : -1,
|
||||
WebGLTexelFormat::Auto, false);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::TexImage2D_imageData(WebGLenum target, WebGLint level, WebGLenum internalformat,
|
||||
WebGLsizei width, WebGLsizei height, WebGLint border,
|
||||
WebGLenum format, WebGLenum type,
|
||||
JSObject *pixels)
|
||||
WebGLsizei width, WebGLsizei height, WebGLint border,
|
||||
WebGLenum format, WebGLenum type,
|
||||
JSObject *pixels, JSContext *cx)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return NS_OK;
|
||||
|
||||
NS_ABORT_IF_FALSE(JS_IsTypedArrayObject(pixels, cx), "bad pixels object");
|
||||
|
||||
return TexImage2D_base(target, level, internalformat, width, height, 4*width, border, format, type,
|
||||
pixels ? JS_GetTypedArrayData(pixels) : 0,
|
||||
pixels ? JS_GetTypedArrayByteLength(pixels) : 0,
|
||||
pixels ? JS_GetArrayBufferViewData(pixels, cx) : 0,
|
||||
pixels ? JS_GetArrayBufferViewByteLength(pixels, cx) : 0,
|
||||
-1,
|
||||
WebGLTexelFormat::RGBA8, false);
|
||||
}
|
||||
@ -5406,7 +5421,7 @@ WebGLContext::TexSubImage2D_array(WebGLenum target, WebGLint level,
|
||||
WebGLint xoffset, WebGLint yoffset,
|
||||
WebGLsizei width, WebGLsizei height,
|
||||
WebGLenum format, WebGLenum type,
|
||||
JSObject *pixels)
|
||||
JSObject *pixels, JSContext *cx)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return NS_OK;
|
||||
@ -5414,10 +5429,12 @@ WebGLContext::TexSubImage2D_array(WebGLenum target, WebGLint level,
|
||||
if (!pixels)
|
||||
return ErrorInvalidValue("TexSubImage2D: pixels must not be null!");
|
||||
|
||||
NS_ABORT_IF_FALSE(JS_IsTypedArrayObject(pixels, cx), "bad pixels object");
|
||||
|
||||
return TexSubImage2D_base(target, level, xoffset, yoffset,
|
||||
width, height, 0, format, type,
|
||||
JS_GetTypedArrayData(pixels), JS_GetTypedArrayByteLength(pixels),
|
||||
JS_GetTypedArrayType(pixels),
|
||||
JS_GetArrayBufferViewData(pixels, cx), JS_GetArrayBufferViewByteLength(pixels, cx),
|
||||
JS_GetTypedArrayType(pixels, cx),
|
||||
WebGLTexelFormat::Auto, false);
|
||||
}
|
||||
|
||||
@ -5426,7 +5443,7 @@ WebGLContext::TexSubImage2D_imageData(WebGLenum target, WebGLint level,
|
||||
WebGLint xoffset, WebGLint yoffset,
|
||||
WebGLsizei width, WebGLsizei height,
|
||||
WebGLenum format, WebGLenum type,
|
||||
JSObject *pixels)
|
||||
JSObject *pixels, JSContext *cx)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return NS_OK;
|
||||
@ -5434,9 +5451,11 @@ WebGLContext::TexSubImage2D_imageData(WebGLenum target, WebGLint level,
|
||||
if (!pixels)
|
||||
return ErrorInvalidValue("TexSubImage2D: pixels must not be null!");
|
||||
|
||||
NS_ABORT_IF_FALSE(JS_IsTypedArrayObject(pixels, cx), "bad pixels object");
|
||||
|
||||
return TexSubImage2D_base(target, level, xoffset, yoffset,
|
||||
width, height, 4*width, format, type,
|
||||
JS_GetTypedArrayData(pixels), JS_GetTypedArrayByteLength(pixels),
|
||||
JS_GetArrayBufferViewData(pixels, cx), JS_GetArrayBufferViewByteLength(pixels, cx),
|
||||
-1,
|
||||
WebGLTexelFormat::RGBA8, false);
|
||||
}
|
||||
|
@ -43,7 +43,7 @@
|
||||
|
||||
#include "CheckedInt.h"
|
||||
|
||||
#include "jstypedarray.h"
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
#if defined(USE_ANGLE)
|
||||
#include "angle/ShaderLang.h"
|
||||
@ -406,10 +406,10 @@ bool WebGLContext::ValidateTexFormatAndType(WebGLenum format, WebGLenum type, in
|
||||
(IsExtensionEnabled(WebGL_OES_texture_float) && type == LOCAL_GL_FLOAT))
|
||||
{
|
||||
if (jsArrayType != -1) {
|
||||
if ((type == LOCAL_GL_UNSIGNED_BYTE && jsArrayType != js::TypedArray::TYPE_UINT8) ||
|
||||
(type == LOCAL_GL_FLOAT && jsArrayType != js::TypedArray::TYPE_FLOAT32))
|
||||
if ((type == LOCAL_GL_UNSIGNED_BYTE && jsArrayType != js::ArrayBufferView::TYPE_UINT8) ||
|
||||
(type == LOCAL_GL_FLOAT && jsArrayType != js::ArrayBufferView::TYPE_FLOAT32))
|
||||
{
|
||||
ErrorInvalidOperation("%s: invalid typed array type for given format", info);
|
||||
ErrorInvalidOperation("%s: invalid typed array type for given texture data type", info);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -440,8 +440,8 @@ bool WebGLContext::ValidateTexFormatAndType(WebGLenum format, WebGLenum type, in
|
||||
switch (type) {
|
||||
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
|
||||
if (jsArrayType != -1 && jsArrayType != js::TypedArray::TYPE_UINT16) {
|
||||
ErrorInvalidOperation("%s: invalid typed array type for given format", info);
|
||||
if (jsArrayType != -1 && jsArrayType != js::ArrayBufferView::TYPE_UINT16) {
|
||||
ErrorInvalidOperation("%s: invalid typed array type for given texture data type", info);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -453,8 +453,8 @@ bool WebGLContext::ValidateTexFormatAndType(WebGLenum format, WebGLenum type, in
|
||||
return false;
|
||||
|
||||
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
|
||||
if (jsArrayType != -1 && jsArrayType != js::TypedArray::TYPE_UINT16) {
|
||||
ErrorInvalidOperation("%s: invalid typed array type for given format", info);
|
||||
if (jsArrayType != -1 && jsArrayType != js::ArrayBufferView::TYPE_UINT16) {
|
||||
ErrorInvalidOperation("%s: invalid typed array type for given texture data type", info);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jstypedarray.h"
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
@ -3935,13 +3935,12 @@ nsCanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
JSObject* darray =
|
||||
js_CreateTypedArray(aCx, js::TypedArray::TYPE_UINT8_CLAMPED, len.value());
|
||||
JSObject* darray = JS_NewUint8ClampedArray(aCx, len.value());
|
||||
if (!darray) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
uint8_t* data = static_cast<uint8_t*>(JS_GetTypedArrayData(darray));
|
||||
uint8_t* data = JS_GetUint8ClampedArrayData(darray, aCx);
|
||||
|
||||
/* Copy the surface contents to the buffer */
|
||||
nsRefPtr<gfxImageSurface> tmpsurf =
|
||||
|
@ -109,7 +109,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jstypedarray.h"
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
@ -4103,8 +4103,7 @@ nsCanvasRenderingContext2DAzure::GetImageDataArray(JSContext* aCx,
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
JSObject* darray =
|
||||
js_CreateTypedArray(aCx, js::TypedArray::TYPE_UINT8_CLAMPED, len.value());
|
||||
JSObject* darray = JS_NewUint8ClampedArray(aCx, len.value());
|
||||
if (!darray) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -4114,7 +4113,7 @@ nsCanvasRenderingContext2DAzure::GetImageDataArray(JSContext* aCx,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint8_t* data = static_cast<uint8_t*>(JS_GetTypedArrayData(darray));
|
||||
uint8_t* data = JS_GetUint8ClampedArrayData(darray, aCx);
|
||||
|
||||
IntRect srcRect(0, 0, mWidth, mHeight);
|
||||
IntRect destRect(aX, aY, aWidth, aHeight);
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include "nsDOMNotifyAudioAvailableEvent.h"
|
||||
#include "nsDOMClassInfoID.h" // DOMCI_DATA, NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO
|
||||
#include "nsContentUtils.h" // NS_DROP_JS_OBJECTS
|
||||
#include "jstypedarray.h"
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
nsDOMNotifyAudioAvailableEvent::nsDOMNotifyAudioAvailableEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
@ -113,15 +113,12 @@ nsDOMNotifyAudioAvailableEvent::GetFrameBuffer(JSContext* aCx, jsval* aResult)
|
||||
// Cache this array so we don't recreate on next call.
|
||||
NS_HOLD_JS_OBJECTS(this, nsDOMNotifyAudioAvailableEvent);
|
||||
|
||||
mCachedArray = js_CreateTypedArray(aCx, js::TypedArray::TYPE_FLOAT32, mFrameBufferLength);
|
||||
mCachedArray = JS_NewFloat32Array(aCx, mFrameBufferLength);
|
||||
if (!mCachedArray) {
|
||||
NS_DROP_JS_OBJECTS(this, nsDOMNotifyAudioAvailableEvent);
|
||||
NS_ERROR("Failed to get audio signal!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JSObject *tdest = js::TypedArray::getTypedArray(mCachedArray);
|
||||
memcpy(JS_GetTypedArrayData(tdest), mFrameBuffer.get(), mFrameBufferLength * sizeof(float));
|
||||
memcpy(JS_GetFloat32ArrayData(mCachedArray, aCx), mFrameBuffer.get(), mFrameBufferLength * sizeof(float));
|
||||
|
||||
*aResult = OBJECT_TO_JSVAL(mCachedArray);
|
||||
return NS_OK;
|
||||
|
@ -57,7 +57,6 @@
|
||||
#include "nsIXPConnect.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jstypedarray.h"
|
||||
#include "nsJSUtils.h"
|
||||
|
||||
#include "nsITimer.h"
|
||||
@ -184,36 +183,35 @@ nsHTMLAudioElement::MozSetup(PRUint32 aChannels, PRUint32 aRate)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAudioElement::MozWriteAudio(const jsval &aData, JSContext *aCx, PRUint32 *aRetVal)
|
||||
nsHTMLAudioElement::MozWriteAudio(const JS::Value& aData, JSContext* aCx, PRUint32* aRetVal)
|
||||
{
|
||||
if (!mAudioStream) {
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
if (JSVAL_IS_PRIMITIVE(aData)) {
|
||||
if (!aData.isObject()) {
|
||||
return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
|
||||
}
|
||||
|
||||
JSObject *darray = JSVAL_TO_OBJECT(aData);
|
||||
JS::AutoValueRooter tsrc_tvr(aCx);
|
||||
JSObject *tsrc = NULL;
|
||||
JSObject* darray = &aData.toObject();
|
||||
JS::AutoObjectRooter tvr(aCx);
|
||||
JSObject* tsrc = NULL;
|
||||
|
||||
// Allow either Float32Array or plain JS Array
|
||||
if (js::GetObjectClass(darray) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_FLOAT32])
|
||||
{
|
||||
tsrc = js::TypedArray::getTypedArray(darray);
|
||||
if (JS_IsFloat32Array(darray, aCx)) {
|
||||
tsrc = darray;
|
||||
} else if (JS_IsArrayObject(aCx, darray)) {
|
||||
JSObject *nobj = js_CreateTypedArrayWithArray(aCx, js::TypedArray::TYPE_FLOAT32, darray);
|
||||
JSObject* nobj = JS_NewFloat32ArrayFromArray(aCx, darray);
|
||||
if (!nobj) {
|
||||
return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
|
||||
}
|
||||
*tsrc_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
|
||||
tsrc = js::TypedArray::getTypedArray(nobj);
|
||||
tsrc = nobj;
|
||||
} else {
|
||||
return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
|
||||
}
|
||||
tvr.setObject(tsrc);
|
||||
|
||||
PRUint32 dataLength = JS_GetTypedArrayLength(tsrc);
|
||||
PRUint32 dataLength = JS_GetTypedArrayLength(tsrc, aCx);
|
||||
|
||||
// Make sure that we are going to write the correct amount of data based
|
||||
// on number of channels.
|
||||
@ -224,7 +222,7 @@ nsHTMLAudioElement::MozWriteAudio(const jsval &aData, JSContext *aCx, PRUint32 *
|
||||
// Don't write more than can be written without blocking.
|
||||
PRUint32 writeLen = NS_MIN(mAudioStream->Available(), dataLength / mChannels);
|
||||
|
||||
nsresult rv = mAudioStream->Write(JS_GetTypedArrayData(tsrc), writeLen);
|
||||
nsresult rv = mAudioStream->Write(JS_GetFloat32ArrayData(tsrc, aCx), writeLen);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ nsXULTemplateQueryProcessorXML::GetDatasource(nsIArray* aDataSources,
|
||||
rv = target->AddEventListener(NS_LITERAL_STRING("error"), this, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = req->Send(nsnull);
|
||||
rv = req->Send(nsnull, context->GetNativeContext());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mTemplateBuilder = aBuilder;
|
||||
|
@ -55,7 +55,7 @@ DOMInterfaces = {
|
||||
},
|
||||
'implicitJSContext': {
|
||||
'all': [
|
||||
'response', 'getInterface'
|
||||
'response', 'getInterface', 'send', 'sendAsBinary'
|
||||
],
|
||||
'setterOnly': [
|
||||
'onreadystatechange'
|
||||
|
@ -324,7 +324,7 @@ class CGHeaders(CGWrapper):
|
||||
for t in types:
|
||||
if t.unroll().isInterface():
|
||||
if t.unroll().isArrayBuffer():
|
||||
bindingHeaders.add("jstypedarray.h")
|
||||
bindingHeaders.add("jsfriendapi.h")
|
||||
else:
|
||||
typeDesc = d.getDescriptor(t.unroll().inner.identifier.name)
|
||||
if typeDesc is not None:
|
||||
@ -1189,7 +1189,7 @@ def getArgumentConversionTemplate(type, descriptor):
|
||||
if type.isArrayBuffer():
|
||||
template = (
|
||||
" JSObject* ${name};\n"
|
||||
" if (${argVal}.isObject() && JS_IsArrayBufferObject(&${argVal}.toObject())) {\n"
|
||||
" if (${argVal}.isObject() && JS_IsArrayBufferObject(&${argVal}.toObject(), cx)) {\n"
|
||||
" ${name} = &${argVal}.toObject();\n"
|
||||
" }")
|
||||
if type.nullable():
|
||||
@ -1900,7 +1900,7 @@ class CGMethodCall(CGThing):
|
||||
# other things.
|
||||
# XXXbz Do we need to worry about security
|
||||
# wrappers around the array buffer?
|
||||
pickFirstSignature("%s.isObject() && JS_IsArrayBufferObject(&%s.toObject())" %
|
||||
pickFirstSignature("%s.isObject() && JS_IsArrayBufferObject(&%s.toObject(), cx)" %
|
||||
(distinguishingArg, distinguishingArg),
|
||||
lambda s: (s[1][distinguishingIndex].type.isArrayBuffer() or
|
||||
s[1][distinguishingIndex].type.isObject()))
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "mozilla/dom/bindings/DOMJSClass.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jstypedarray.h"
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
#include "XPCQuickStubs.h"
|
||||
#include "XPCWrapper.h"
|
||||
@ -169,7 +169,7 @@ IsPlatformObject(JSContext* cx, JSObject* obj)
|
||||
clasp = js::GetObjectJSClass(obj);
|
||||
}
|
||||
return IS_WRAPPER_CLASS(js::Valueify(clasp)) || IsDOMClass(clasp) ||
|
||||
JS_IsArrayBufferObject(obj);
|
||||
JS_IsArrayBufferObject(obj, cx);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
@ -177,7 +177,7 @@ interface nsIWebGLExtensionTextureFilterAnisotropic : nsIWebGLExtension
|
||||
const WebGLenum MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF;
|
||||
};
|
||||
|
||||
[scriptable, builtinclass, uuid(dcba5412-42b4-4897-b2f4-56a5cae7ef2d)]
|
||||
[scriptable, builtinclass, uuid(ba7635d7-98af-41ac-8bf9-9f08cf441958)]
|
||||
interface nsIDOMWebGLRenderingContext : nsISupports
|
||||
{
|
||||
//
|
||||
@ -624,7 +624,7 @@ interface nsIDOMWebGLRenderingContext : nsISupports
|
||||
// Modified: void glBufferData(WebGLenum target, long size, const void* data, WebGLenum usage);
|
||||
[implicit_jscontext] void bufferData(in long target, in jsval data, in long usage);
|
||||
|
||||
void bufferSubData(in long target, in long offset, in jsval data);
|
||||
[implicit_jscontext] void bufferSubData(in long target, in long offset, in jsval data);
|
||||
|
||||
WebGLenum checkFramebufferStatus(in WebGLenum target);
|
||||
void clear(in WebGLbitfield mask);
|
||||
@ -634,11 +634,11 @@ interface nsIDOMWebGLRenderingContext : nsISupports
|
||||
void colorMask(in WebGLboolean red, in WebGLboolean green, in WebGLboolean blue, in WebGLboolean alpha);
|
||||
void compileShader([optional] in nsIWebGLShader shader);
|
||||
|
||||
void compressedTexImage2D(in WebGLenum target, in WebGLint level, in WebGLenum internalformat,
|
||||
[implicit_jscontext] void compressedTexImage2D(in WebGLenum target, in WebGLint level, in WebGLenum internalformat,
|
||||
in WebGLsizei width, in WebGLsizei height, in WebGLint border,
|
||||
in jsval pixels);
|
||||
|
||||
void compressedTexSubImage2D(in WebGLenum target, in WebGLint level, in WebGLint xoffset,
|
||||
[implicit_jscontext] void compressedTexSubImage2D(in WebGLenum target, in WebGLint level, in WebGLint xoffset,
|
||||
in WebGLint yoffset, in WebGLsizei width, in WebGLsizei height,
|
||||
in WebGLenum format, in jsval pixels);
|
||||
|
||||
@ -749,7 +749,7 @@ interface nsIDOMWebGLRenderingContext : nsISupports
|
||||
void pixelStorei(in WebGLenum pname, in WebGLint param);
|
||||
void polygonOffset(in WebGLfloat factor, in WebGLfloat units);
|
||||
|
||||
void readPixels(in WebGLint x, in WebGLint y, in WebGLsizei width, in WebGLsizei height,
|
||||
[implicit_jscontext] void readPixels(in WebGLint x, in WebGLint y, in WebGLsizei width, in WebGLsizei height,
|
||||
in WebGLenum format, in WebGLenum type, in jsval pixels);
|
||||
|
||||
//void glReleaseShaderCompiler();
|
||||
@ -769,10 +769,10 @@ interface nsIDOMWebGLRenderingContext : nsISupports
|
||||
void stencilOpSeparate(in WebGLenum face, in WebGLenum fail, in WebGLenum zfail, in WebGLenum zpass);
|
||||
|
||||
void texImage2D([optional] in long dummy);
|
||||
[noscript] void texImage2D_array(in WebGLenum target, in WebGLint level, in WebGLenum internalformat,
|
||||
[noscript,implicit_jscontext] void texImage2D_array(in WebGLenum target, in WebGLint level, in WebGLenum internalformat,
|
||||
in WebGLsizei width, in WebGLsizei height,
|
||||
in WebGLint border, in WebGLenum format, in WebGLenum type, in WebGLJSObjectPtr pixels);
|
||||
[noscript] void texImage2D_imageData(in WebGLenum target, in WebGLint level, in WebGLenum internalformat,
|
||||
[noscript,implicit_jscontext] void texImage2D_imageData(in WebGLenum target, in WebGLint level, in WebGLenum internalformat,
|
||||
in WebGLsizei width, in WebGLsizei height,
|
||||
in WebGLint border, in WebGLenum format, in WebGLenum type, in WebGLJSObjectPtr pixels);
|
||||
|
||||
@ -781,10 +781,10 @@ interface nsIDOMWebGLRenderingContext : nsISupports
|
||||
in WebGLenum format, in WebGLenum type, in Element element);
|
||||
|
||||
void texSubImage2D([optional] in long dummy);
|
||||
[noscript] void texSubImage2D_array(in WebGLenum target, in WebGLint level,
|
||||
[noscript,implicit_jscontext] void texSubImage2D_array(in WebGLenum target, in WebGLint level,
|
||||
in WebGLint xoffset, in WebGLint yoffset, in WebGLsizei width, in WebGLsizei height,
|
||||
in WebGLenum format, in WebGLenum type, in WebGLJSObjectPtr pixels);
|
||||
[noscript] void texSubImage2D_imageData(in WebGLenum target, in WebGLint level,
|
||||
[noscript,implicit_jscontext] void texSubImage2D_imageData(in WebGLenum target, in WebGLint level,
|
||||
in WebGLint xoffset, in WebGLint yoffset, in WebGLsizei width, in WebGLsizei height,
|
||||
in WebGLenum format, in WebGLenum type, in WebGLJSObjectPtr pixels);
|
||||
// HTMLImageElement, HTMLCanvasElement, HTMLVideoElement
|
||||
|
@ -46,7 +46,7 @@
|
||||
#include "nsIWorkerHolder.h"
|
||||
#include "nsIXPConnect.h"
|
||||
|
||||
#include "jstypedarray.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/dom/workers/Workers.h"
|
||||
#include "mozilla/ipc/Ril.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -100,21 +100,21 @@ PostToRIL(JSContext *cx, unsigned argc, jsval *vp)
|
||||
data = abs.ptr();
|
||||
} else if (!JSVAL_IS_PRIMITIVE(v)) {
|
||||
JSObject *obj = JSVAL_TO_OBJECT(v);
|
||||
if (!js_IsTypedArray(obj)) {
|
||||
if (!JS_IsTypedArrayObject(obj, cx)) {
|
||||
JS_ReportError(cx, "Object passed in wasn't a typed array");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t type = JS_GetTypedArrayType(obj);
|
||||
if (type != js::TypedArray::TYPE_INT8 &&
|
||||
type != js::TypedArray::TYPE_UINT8 &&
|
||||
type != js::TypedArray::TYPE_UINT8_CLAMPED) {
|
||||
uint32_t type = JS_GetTypedArrayType(obj, cx);
|
||||
if (type != js::ArrayBufferView::TYPE_INT8 &&
|
||||
type != js::ArrayBufferView::TYPE_UINT8 &&
|
||||
type != js::ArrayBufferView::TYPE_UINT8_CLAMPED) {
|
||||
JS_ReportError(cx, "Typed array data is not octets");
|
||||
return false;
|
||||
}
|
||||
|
||||
size = JS_GetTypedArrayByteLength(obj);
|
||||
data = JS_GetTypedArrayData(obj);
|
||||
size = JS_GetTypedArrayByteLength(obj, cx);
|
||||
data = JS_GetArrayBufferViewData(obj, cx);
|
||||
} else {
|
||||
JS_ReportError(cx,
|
||||
"Incorrect argument. Expecting a string or a typed array");
|
||||
@ -181,13 +181,12 @@ RILReceiver::DispatchRILEvent::RunTask(JSContext *aCx)
|
||||
{
|
||||
JSObject *obj = JS_GetGlobalObject(aCx);
|
||||
|
||||
JSObject *array =
|
||||
js_CreateTypedArray(aCx, js::TypedArray::TYPE_UINT8, mMessage->mSize);
|
||||
JSObject *array = JS_NewUint8Array(aCx, mMessage->mSize);
|
||||
if (!array) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(JS_GetTypedArrayData(array), mMessage->mData, mMessage->mSize);
|
||||
memcpy(JS_GetArrayBufferViewData(array, aCx), mMessage->mData, mMessage->mSize);
|
||||
jsval argv[] = { OBJECT_TO_JSVAL(array) };
|
||||
return JS_CallFunctionName(aCx, obj, "onRILMessage", NS_ARRAY_LENGTH(argv),
|
||||
argv, argv);
|
||||
|
@ -44,7 +44,6 @@
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jstypedarray.h"
|
||||
#include "nsJSUtils.h"
|
||||
|
||||
#include "Exceptions.h"
|
||||
@ -58,7 +57,6 @@
|
||||
USING_WORKERS_NAMESPACE
|
||||
|
||||
using mozilla::dom::workers::exceptions::ThrowFileExceptionForCode;
|
||||
using js::ArrayBuffer;
|
||||
|
||||
namespace {
|
||||
|
||||
@ -194,13 +192,13 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
JSObject* jsArrayBuffer = js_CreateArrayBuffer(aCx, blobSize);
|
||||
JSObject* jsArrayBuffer = JS_NewArrayBuffer(aCx, blobSize);
|
||||
if (!jsArrayBuffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t bufferLength = JS_GetArrayBufferByteLength(jsArrayBuffer);
|
||||
uint8_t* arrayBuffer = JS_GetArrayBufferData(jsArrayBuffer);
|
||||
uint32_t bufferLength = JS_GetArrayBufferByteLength(jsArrayBuffer, aCx);
|
||||
uint8_t* arrayBuffer = JS_GetArrayBufferData(jsArrayBuffer, aCx);
|
||||
|
||||
rv = fileReader->ReadAsArrayBuffer(blob, bufferLength, arrayBuffer);
|
||||
if (!EnsureSucceededOrThrow(aCx, rv)) {
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "nsIXMLHttpRequest.h"
|
||||
#include "nsIXPConnect.h"
|
||||
|
||||
#include "jstypedarray.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
@ -1158,12 +1158,12 @@ public:
|
||||
MainThreadRun()
|
||||
{
|
||||
nsCOMPtr<nsIVariant> variant;
|
||||
RuntimeService::AutoSafeJSContext cx;
|
||||
|
||||
if (mBody.data()) {
|
||||
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||
NS_ASSERTION(xpc, "This should never be null!");
|
||||
|
||||
RuntimeService::AutoSafeJSContext cx;
|
||||
|
||||
int error = 0;
|
||||
|
||||
JSStructuredCloneCallbacks* callbacks =
|
||||
@ -1216,7 +1216,7 @@ public:
|
||||
|
||||
mProxy->mInnerChannelId++;
|
||||
|
||||
nsresult rv = mProxy->mXHR->Send(variant);
|
||||
nsresult rv = mProxy->mXHR->Send(variant, cx);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mProxy->mOutstandingSendCount++;
|
||||
@ -1987,7 +1987,7 @@ XMLHttpRequest::Send(JSObject* aBody, nsresult& aRv)
|
||||
JSContext* cx = GetJSContext();
|
||||
|
||||
jsval valToClone;
|
||||
if (js_IsArrayBuffer(aBody) || file::GetDOMBlobFromJSObject(aBody)) {
|
||||
if (JS_IsArrayBufferObject(aBody, cx) || file::GetDOMBlobFromJSObject(aBody)) {
|
||||
valToClone = OBJECT_TO_JSVAL(aBody);
|
||||
}
|
||||
else {
|
||||
|
@ -205,7 +205,6 @@ INSTALLED_HEADERS = \
|
||||
jsproto.tbl \
|
||||
jsprvtd.h \
|
||||
jspubtd.h \
|
||||
jstypedarray.h \
|
||||
jstypes.h \
|
||||
jsutil.h \
|
||||
jsversion.h \
|
||||
|
@ -89,6 +89,7 @@ CPPSRCS = \
|
||||
testSetProperty.cpp \
|
||||
testStringBuffer.cpp \
|
||||
testTrap.cpp \
|
||||
testTypedArrays.cpp \
|
||||
testUTF8.cpp \
|
||||
testValueABI.cpp \
|
||||
testVersion.cpp \
|
||||
|
155
js/src/jsapi-tests/testTypedArrays.cpp
Normal file
155
js/src/jsapi-tests/testTypedArrays.cpp
Normal file
@ -0,0 +1,155 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99:
|
||||
*/
|
||||
|
||||
#include "tests.h"
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
BEGIN_TEST(testTypedArrays)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
ok = ok &&
|
||||
TestPlainTypedArray<JS_NewInt8Array, int8_t, JS_GetInt8ArrayData>(cx) &&
|
||||
TestPlainTypedArray<JS_NewUint8Array, uint8_t, JS_GetUint8ArrayData>(cx) &&
|
||||
TestPlainTypedArray<JS_NewUint8ClampedArray, uint8_t, JS_GetUint8ClampedArrayData>(cx) &&
|
||||
TestPlainTypedArray<JS_NewInt16Array, int16_t, JS_GetInt16ArrayData>(cx) &&
|
||||
TestPlainTypedArray<JS_NewUint16Array, uint16_t, JS_GetUint16ArrayData>(cx) &&
|
||||
TestPlainTypedArray<JS_NewInt32Array, int32_t, JS_GetInt32ArrayData>(cx) &&
|
||||
TestPlainTypedArray<JS_NewUint32Array, uint32_t, JS_GetUint32ArrayData>(cx) &&
|
||||
TestPlainTypedArray<JS_NewFloat32Array, float, JS_GetFloat32ArrayData>(cx) &&
|
||||
TestPlainTypedArray<JS_NewFloat64Array, double, JS_GetFloat64ArrayData>(cx);
|
||||
|
||||
size_t nbytes = sizeof(double) * 8;
|
||||
JSObject *buffer = JS_NewArrayBuffer(cx, nbytes);
|
||||
CHECK(JS_IsArrayBufferObject(buffer, cx));
|
||||
|
||||
JSObject *proto = JS_GetPrototype(buffer);
|
||||
CHECK(!JS_IsArrayBufferObject(proto, cx));
|
||||
JSObject *dummy = JS_GetParent(proto);
|
||||
CHECK(!JS_IsArrayBufferObject(dummy, cx));
|
||||
|
||||
CHECK_EQUAL(JS_GetArrayBufferByteLength(buffer, cx), nbytes);
|
||||
memset(JS_GetArrayBufferData(buffer, cx), 1, nbytes);
|
||||
|
||||
ok = ok &&
|
||||
TestArrayFromBuffer<JS_NewInt8ArrayWithBuffer, JS_NewInt8ArrayFromArray, int8_t, JS_GetInt8ArrayData>(cx) &&
|
||||
TestArrayFromBuffer<JS_NewUint8ArrayWithBuffer, JS_NewUint8ArrayFromArray, uint8_t, JS_GetUint8ArrayData>(cx) &&
|
||||
TestArrayFromBuffer<JS_NewUint8ClampedArrayWithBuffer, JS_NewUint8ClampedArrayFromArray, uint8_t, JS_GetUint8ClampedArrayData>(cx) &&
|
||||
TestArrayFromBuffer<JS_NewInt16ArrayWithBuffer, JS_NewInt16ArrayFromArray, int16_t, JS_GetInt16ArrayData>(cx) &&
|
||||
TestArrayFromBuffer<JS_NewUint16ArrayWithBuffer, JS_NewUint16ArrayFromArray, uint16_t, JS_GetUint16ArrayData>(cx) &&
|
||||
TestArrayFromBuffer<JS_NewInt32ArrayWithBuffer, JS_NewInt32ArrayFromArray, int32_t, JS_GetInt32ArrayData>(cx) &&
|
||||
TestArrayFromBuffer<JS_NewUint32ArrayWithBuffer, JS_NewUint32ArrayFromArray, uint32_t, JS_GetUint32ArrayData>(cx) &&
|
||||
TestArrayFromBuffer<JS_NewFloat32ArrayWithBuffer, JS_NewFloat32ArrayFromArray, float, JS_GetFloat32ArrayData>(cx) &&
|
||||
TestArrayFromBuffer<JS_NewFloat64ArrayWithBuffer, JS_NewFloat64ArrayFromArray, double, JS_GetFloat64ArrayData>(cx);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
template<JSObject *Create(JSContext *, uint32_t),
|
||||
typename Element,
|
||||
Element *GetData(JSObject *, JSContext *)>
|
||||
bool
|
||||
TestPlainTypedArray(JSContext *cx)
|
||||
{
|
||||
JSObject *array = Create(cx, 7);
|
||||
CHECK(JS_IsTypedArrayObject(array, cx));
|
||||
JSObject *proto = JS_GetPrototype(array);
|
||||
CHECK(!JS_IsTypedArrayObject(proto, cx));
|
||||
JSObject *dummy = JS_GetParent(proto);
|
||||
CHECK(!JS_IsTypedArrayObject(dummy, cx));
|
||||
|
||||
CHECK_EQUAL(JS_GetTypedArrayLength(array, cx), 7);
|
||||
CHECK_EQUAL(JS_GetTypedArrayByteOffset(array, cx), 0);
|
||||
CHECK_EQUAL(JS_GetTypedArrayByteLength(array, cx), sizeof(Element) * 7);
|
||||
|
||||
Element *data;
|
||||
CHECK(data = GetData(array, cx));
|
||||
*data = 13;
|
||||
jsval v;
|
||||
CHECK(JS_GetElement(cx, array, 0, &v));
|
||||
CHECK_SAME(v, INT_TO_JSVAL(13));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<JSObject *CreateWithBuffer(JSContext *, JSObject *, uint32_t, int32_t),
|
||||
JSObject *CreateFromArray(JSContext *, JSObject *),
|
||||
typename Element,
|
||||
Element *GetData(JSObject *, JSContext *)>
|
||||
bool
|
||||
TestArrayFromBuffer(JSContext *cx)
|
||||
{
|
||||
size_t elts = 8;
|
||||
size_t nbytes = elts * sizeof(Element);
|
||||
JSObject *buffer = JS_NewArrayBuffer(cx, nbytes);
|
||||
uint8_t *bufdata;
|
||||
CHECK(bufdata = JS_GetArrayBufferData(buffer, cx));
|
||||
memset(bufdata, 1, nbytes);
|
||||
|
||||
JSObject *array = CreateWithBuffer(cx, buffer, 0, -1);
|
||||
CHECK_EQUAL(JS_GetTypedArrayLength(array, cx), elts);
|
||||
CHECK_EQUAL(JS_GetTypedArrayByteOffset(array, cx), 0);
|
||||
CHECK_EQUAL(JS_GetTypedArrayByteLength(array, cx), nbytes);
|
||||
|
||||
Element *data;
|
||||
CHECK(data = GetData(array, cx));
|
||||
CHECK(bufdata = JS_GetArrayBufferData(buffer, cx));
|
||||
CHECK_EQUAL((void*) data, (void*) bufdata);
|
||||
|
||||
CHECK_EQUAL(*bufdata, 1);
|
||||
CHECK_EQUAL(*reinterpret_cast<uint8_t*>(data), 1);
|
||||
|
||||
JSObject *shortArray = CreateWithBuffer(cx, buffer, 0, elts / 2);
|
||||
CHECK_EQUAL(JS_GetTypedArrayLength(shortArray, cx), elts / 2);
|
||||
CHECK_EQUAL(JS_GetTypedArrayByteOffset(shortArray, cx), 0);
|
||||
CHECK_EQUAL(JS_GetTypedArrayByteLength(shortArray, cx), nbytes / 2);
|
||||
|
||||
JSObject *ofsArray = CreateWithBuffer(cx, buffer, nbytes / 2, -1);
|
||||
CHECK_EQUAL(JS_GetTypedArrayLength(ofsArray, cx), elts / 2);
|
||||
CHECK_EQUAL(JS_GetTypedArrayByteOffset(ofsArray, cx), nbytes / 2);
|
||||
CHECK_EQUAL(JS_GetTypedArrayByteLength(ofsArray, cx), nbytes / 2);
|
||||
|
||||
// Make sure all 3 views reflect the same buffer at the expected locations
|
||||
jsval v = INT_TO_JSVAL(39);
|
||||
JS_SetElement(cx, array, 0, &v);
|
||||
jsval v2;
|
||||
CHECK(JS_GetElement(cx, array, 0, &v2));
|
||||
CHECK_SAME(v, v2);
|
||||
CHECK(JS_GetElement(cx, shortArray, 0, &v2));
|
||||
CHECK_SAME(v, v2);
|
||||
CHECK_EQUAL(long(JSVAL_TO_INT(v)), long(reinterpret_cast<Element*>(data)[0]));
|
||||
|
||||
v = INT_TO_JSVAL(40);
|
||||
JS_SetElement(cx, array, elts / 2, &v);
|
||||
CHECK(JS_GetElement(cx, array, elts / 2, &v2));
|
||||
CHECK_SAME(v, v2);
|
||||
CHECK(JS_GetElement(cx, ofsArray, 0, &v2));
|
||||
CHECK_SAME(v, v2);
|
||||
CHECK_EQUAL(long(JSVAL_TO_INT(v)), long(reinterpret_cast<Element*>(data)[elts / 2]));
|
||||
|
||||
v = INT_TO_JSVAL(41);
|
||||
JS_SetElement(cx, array, elts - 1, &v);
|
||||
CHECK(JS_GetElement(cx, array, elts - 1, &v2));
|
||||
CHECK_SAME(v, v2);
|
||||
CHECK(JS_GetElement(cx, ofsArray, elts / 2 - 1, &v2));
|
||||
CHECK_SAME(v, v2);
|
||||
CHECK_EQUAL(long(JSVAL_TO_INT(v)), long(reinterpret_cast<Element*>(data)[elts - 1]));
|
||||
|
||||
JSObject *copy = CreateFromArray(cx, array);
|
||||
CHECK(JS_GetElement(cx, array, 0, &v));
|
||||
CHECK(JS_GetElement(cx, copy, 0, &v2));
|
||||
CHECK_SAME(v, v2);
|
||||
|
||||
/* The copy should not see changes in the original */
|
||||
v2 = INT_TO_JSVAL(42);
|
||||
JS_SetElement(cx, array, 0, &v2);
|
||||
CHECK(JS_GetElement(cx, copy, 0, &v2));
|
||||
CHECK_SAME(v2, v); /* v is still the original value from 'array' */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
END_TEST(testTypedArrays)
|
@ -96,12 +96,29 @@ enum StructuredDataType {
|
||||
SCTAG_NUMBER_OBJECT,
|
||||
SCTAG_BACK_REFERENCE_OBJECT,
|
||||
SCTAG_TYPED_ARRAY_MIN = 0xFFFF0100,
|
||||
SCTAG_TYPED_ARRAY_INT8 = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_INT8,
|
||||
SCTAG_TYPED_ARRAY_UINT8 = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_UINT8,
|
||||
SCTAG_TYPED_ARRAY_INT16 = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_INT16,
|
||||
SCTAG_TYPED_ARRAY_UINT16 = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_UINT16,
|
||||
SCTAG_TYPED_ARRAY_INT32 = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_INT32,
|
||||
SCTAG_TYPED_ARRAY_UINT32 = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_UINT32,
|
||||
SCTAG_TYPED_ARRAY_FLOAT32 = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_FLOAT32,
|
||||
SCTAG_TYPED_ARRAY_FLOAT64 = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_FLOAT64,
|
||||
SCTAG_TYPED_ARRAY_UINT8_CLAMPED = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_UINT8_CLAMPED,
|
||||
SCTAG_TYPED_ARRAY_MAX = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_MAX - 1,
|
||||
SCTAG_END_OF_BUILTIN_TYPES
|
||||
};
|
||||
|
||||
static StructuredDataType
|
||||
ArrayTypeToTag(uint32_t type)
|
||||
{
|
||||
JS_ASSERT(type < TypedArray::TYPE_MAX);
|
||||
return static_cast<StructuredDataType>(uint32_t(SCTAG_TYPED_ARRAY_MIN) + type);
|
||||
}
|
||||
|
||||
JS_STATIC_ASSERT(SCTAG_END_OF_BUILTIN_TYPES <= JS_SCTAG_USER_MIN);
|
||||
JS_STATIC_ASSERT(JS_SCTAG_USER_MIN <= JS_SCTAG_USER_MAX);
|
||||
JS_STATIC_ASSERT(TypedArray::TYPE_INT8 == 0);
|
||||
|
||||
static uint8_t
|
||||
SwapBytes(uint8_t u)
|
||||
@ -407,36 +424,6 @@ JSStructuredCloneWriter::checkStack()
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
ArrayTypeToTag(uint32_t type)
|
||||
{
|
||||
/*
|
||||
* As long as these are all true, we can just add. Note that for backward
|
||||
* compatibility, the tags cannot change. So if the ArrayType type codes
|
||||
* change, this function and TagToArrayType will have to do more work.
|
||||
*/
|
||||
JS_STATIC_ASSERT(TypedArray::TYPE_INT8 == 0);
|
||||
JS_STATIC_ASSERT(TypedArray::TYPE_UINT8 == 1);
|
||||
JS_STATIC_ASSERT(TypedArray::TYPE_INT16 == 2);
|
||||
JS_STATIC_ASSERT(TypedArray::TYPE_UINT16 == 3);
|
||||
JS_STATIC_ASSERT(TypedArray::TYPE_INT32 == 4);
|
||||
JS_STATIC_ASSERT(TypedArray::TYPE_UINT32 == 5);
|
||||
JS_STATIC_ASSERT(TypedArray::TYPE_FLOAT32 == 6);
|
||||
JS_STATIC_ASSERT(TypedArray::TYPE_FLOAT64 == 7);
|
||||
JS_STATIC_ASSERT(TypedArray::TYPE_UINT8_CLAMPED == 8);
|
||||
JS_STATIC_ASSERT(TypedArray::TYPE_MAX == TypedArray::TYPE_UINT8_CLAMPED + 1);
|
||||
|
||||
JS_ASSERT(type < TypedArray::TYPE_MAX);
|
||||
return SCTAG_TYPED_ARRAY_MIN + type;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
TagToArrayType(uint32_t tag)
|
||||
{
|
||||
JS_ASSERT(SCTAG_TYPED_ARRAY_MIN <= tag && tag <= SCTAG_TYPED_ARRAY_MAX);
|
||||
return tag - SCTAG_TYPED_ARRAY_MIN;
|
||||
}
|
||||
|
||||
bool
|
||||
JSStructuredCloneWriter::writeTypedArray(JSObject *obj)
|
||||
{
|
||||
@ -539,7 +526,7 @@ class AutoEnterCompartmentAndPushPrincipal : public JSAutoEnterCompartment
|
||||
|
||||
|
||||
bool
|
||||
JSStructuredCloneWriter::startWrite(const js::Value &v)
|
||||
JSStructuredCloneWriter::startWrite(const Value &v)
|
||||
{
|
||||
assertSameCompartment(context(), v);
|
||||
|
||||
@ -577,9 +564,9 @@ JSStructuredCloneWriter::startWrite(const js::Value &v)
|
||||
return out.writePair(SCTAG_DATE_OBJECT, 0) && out.writeDouble(d);
|
||||
} else if (obj->isObject() || obj->isArray()) {
|
||||
return startObject(obj);
|
||||
} else if (js_IsTypedArray(obj)) {
|
||||
} else if (obj->isTypedArray()) {
|
||||
return writeTypedArray(obj);
|
||||
} else if (js_IsArrayBuffer(obj)) {
|
||||
} else if (obj->isArrayBuffer()) {
|
||||
return writeArrayBuffer(obj);
|
||||
} else if (obj->isBoolean()) {
|
||||
return out.writePair(SCTAG_BOOLEAN_OBJECT, obj->asBoolean().unbox());
|
||||
@ -705,29 +692,66 @@ JSStructuredCloneReader::readString(uint32_t nchars)
|
||||
bool
|
||||
JSStructuredCloneReader::readTypedArray(uint32_t tag, uint32_t nelems, Value *vp)
|
||||
{
|
||||
uint32_t atype = TagToArrayType(tag);
|
||||
JSObject *obj = js_CreateTypedArray(context(), atype, nelems);
|
||||
JSObject *obj = NULL;
|
||||
|
||||
switch (tag) {
|
||||
case SCTAG_TYPED_ARRAY_INT8:
|
||||
obj = JS_NewInt8Array(context(), nelems);
|
||||
break;
|
||||
case SCTAG_TYPED_ARRAY_UINT8:
|
||||
obj = JS_NewUint8Array(context(), nelems);
|
||||
break;
|
||||
case SCTAG_TYPED_ARRAY_INT16:
|
||||
obj = JS_NewInt16Array(context(), nelems);
|
||||
break;
|
||||
case SCTAG_TYPED_ARRAY_UINT16:
|
||||
obj = JS_NewUint16Array(context(), nelems);
|
||||
break;
|
||||
case SCTAG_TYPED_ARRAY_INT32:
|
||||
obj = JS_NewInt32Array(context(), nelems);
|
||||
break;
|
||||
case SCTAG_TYPED_ARRAY_UINT32:
|
||||
obj = JS_NewUint32Array(context(), nelems);
|
||||
break;
|
||||
case SCTAG_TYPED_ARRAY_FLOAT32:
|
||||
obj = JS_NewFloat32Array(context(), nelems);
|
||||
break;
|
||||
case SCTAG_TYPED_ARRAY_FLOAT64:
|
||||
obj = JS_NewFloat64Array(context(), nelems);
|
||||
break;
|
||||
case SCTAG_TYPED_ARRAY_UINT8_CLAMPED:
|
||||
obj = JS_NewUint8ClampedArray(context(), nelems);
|
||||
break;
|
||||
default:
|
||||
JS_NOT_REACHED("unknown TypedArray type");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!obj)
|
||||
return false;
|
||||
vp->setObject(*obj);
|
||||
|
||||
JSObject *arr = TypedArray::getTypedArray(obj);
|
||||
JS_ASSERT(TypedArray::getLength(arr) == nelems);
|
||||
JS_ASSERT(TypedArray::getType(arr) == atype);
|
||||
switch (atype) {
|
||||
case TypedArray::TYPE_INT8:
|
||||
case TypedArray::TYPE_UINT8:
|
||||
case TypedArray::TYPE_UINT8_CLAMPED:
|
||||
return in.readArray((uint8_t *) TypedArray::getDataOffset(arr), nelems);
|
||||
case TypedArray::TYPE_INT16:
|
||||
case TypedArray::TYPE_UINT16:
|
||||
return in.readArray((uint16_t *) TypedArray::getDataOffset(arr), nelems);
|
||||
case TypedArray::TYPE_INT32:
|
||||
case TypedArray::TYPE_UINT32:
|
||||
case TypedArray::TYPE_FLOAT32:
|
||||
return in.readArray((uint32_t *) TypedArray::getDataOffset(arr), nelems);
|
||||
case TypedArray::TYPE_FLOAT64:
|
||||
return in.readArray((uint64_t *) TypedArray::getDataOffset(arr), nelems);
|
||||
switch (tag) {
|
||||
case SCTAG_TYPED_ARRAY_INT8:
|
||||
return in.readArray((uint8_t *) JS_GetInt8ArrayData(arr, context()), nelems);
|
||||
case SCTAG_TYPED_ARRAY_UINT8:
|
||||
return in.readArray((uint8_t *) JS_GetUint8ArrayData(arr, context()), nelems);
|
||||
case SCTAG_TYPED_ARRAY_INT16:
|
||||
return in.readArray((uint16_t *) JS_GetInt16ArrayData(arr, context()), nelems);
|
||||
case SCTAG_TYPED_ARRAY_UINT16:
|
||||
return in.readArray((uint16_t *) JS_GetUint16ArrayData(arr, context()), nelems);
|
||||
case SCTAG_TYPED_ARRAY_INT32:
|
||||
return in.readArray((uint32_t *) JS_GetInt32ArrayData(arr, context()), nelems);
|
||||
case SCTAG_TYPED_ARRAY_UINT32:
|
||||
return in.readArray((uint32_t *) JS_GetUint32ArrayData(arr, context()), nelems);
|
||||
case SCTAG_TYPED_ARRAY_FLOAT32:
|
||||
return in.readArray((uint32_t *) JS_GetFloat32ArrayData(arr, context()), nelems);
|
||||
case SCTAG_TYPED_ARRAY_FLOAT64:
|
||||
return in.readArray((uint64_t *) JS_GetFloat64ArrayData(arr, context()), nelems);
|
||||
case SCTAG_TYPED_ARRAY_UINT8_CLAMPED:
|
||||
return in.readArray((uint8_t *) JS_GetUint8ClampedArrayData(arr, context()), nelems);
|
||||
default:
|
||||
JS_NOT_REACHED("unknown TypedArray type");
|
||||
return false;
|
||||
@ -737,7 +761,7 @@ JSStructuredCloneReader::readTypedArray(uint32_t tag, uint32_t nelems, Value *vp
|
||||
bool
|
||||
JSStructuredCloneReader::readArrayBuffer(uint32_t nbytes, Value *vp)
|
||||
{
|
||||
JSObject *obj = js_CreateArrayBuffer(context(), nbytes);
|
||||
JSObject *obj = ArrayBuffer::create(context(), nbytes);
|
||||
if (!obj)
|
||||
return false;
|
||||
vp->setObject(*obj);
|
||||
|
@ -828,4 +828,282 @@ js_GetErrorMessage(void *userRef, const char *locale, const unsigned errorNumber
|
||||
extern JS_FRIEND_API(uint64_t)
|
||||
js_GetSCOffset(JSStructuredCloneWriter* writer);
|
||||
|
||||
/* Typed Array functions, implemented in jstypedarray.cpp */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace js {
|
||||
namespace ArrayBufferView {
|
||||
|
||||
enum ViewType {
|
||||
TYPE_INT8 = 0,
|
||||
TYPE_UINT8,
|
||||
TYPE_INT16,
|
||||
TYPE_UINT16,
|
||||
TYPE_INT32,
|
||||
TYPE_UINT32,
|
||||
TYPE_FLOAT32,
|
||||
TYPE_FLOAT64,
|
||||
|
||||
/*
|
||||
* Special type that is a uint8_t, but assignments are clamped to [0, 256).
|
||||
* Treat the raw data type as a uint8_t.
|
||||
*/
|
||||
TYPE_UINT8_CLAMPED,
|
||||
|
||||
TYPE_MAX
|
||||
};
|
||||
|
||||
} /* namespace ArrayBufferView */
|
||||
} /* namespace js */
|
||||
|
||||
typedef js::ArrayBufferView::ViewType JSArrayBufferViewType;
|
||||
#else
|
||||
typedef uint32_t JSArrayBufferViewType;
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Create a new typed array with nelements elements.
|
||||
*/
|
||||
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewInt8Array(JSContext *cx, uint32_t nelements);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewUint8Array(JSContext *cx, uint32_t nelements);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewUint8ClampedArray(JSContext *cx, uint32_t nelements);
|
||||
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewInt16Array(JSContext *cx, uint32_t nelements);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewUint16Array(JSContext *cx, uint32_t nelements);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewInt32Array(JSContext *cx, uint32_t nelements);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewUint32Array(JSContext *cx, uint32_t nelements);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewFloat32Array(JSContext *cx, uint32_t nelements);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewFloat64Array(JSContext *cx, uint32_t nelements);
|
||||
|
||||
/*
|
||||
* Create a new typed array and copy in values from the given object. The
|
||||
* object is used as if it were an array; that is, the new array (if
|
||||
* successfully created) will have length given by array.length, and its
|
||||
* elements will be those specified by array[0], array[1], and so on, after
|
||||
* conversion to the typed array element type.
|
||||
*/
|
||||
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewInt8ArrayFromArray(JSContext *cx, JSObject *array);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewUint8ArrayFromArray(JSContext *cx, JSObject *array);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewUint8ClampedArrayFromArray(JSContext *cx, JSObject *array);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewInt16ArrayFromArray(JSContext *cx, JSObject *array);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewUint16ArrayFromArray(JSContext *cx, JSObject *array);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewInt32ArrayFromArray(JSContext *cx, JSObject *array);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewUint32ArrayFromArray(JSContext *cx, JSObject *array);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewFloat32ArrayFromArray(JSContext *cx, JSObject *array);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewFloat64ArrayFromArray(JSContext *cx, JSObject *array);
|
||||
|
||||
/*
|
||||
* Create a new typed array using the given ArrayBuffer for storage. byteOffset
|
||||
* must not exceed (signed) INT32_MAX. The length value is optional; if -1 is
|
||||
* passed, enough elements to use up the remainder of the byte array is used as
|
||||
* the default value.
|
||||
*/
|
||||
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewInt8ArrayWithBuffer(JSContext *cx, JSObject *arrayBuffer,
|
||||
uint32_t byteOffset, int32_t length);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewUint8ArrayWithBuffer(JSContext *cx, JSObject *arrayBuffer,
|
||||
uint32_t byteOffset, int32_t length);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewUint8ClampedArrayWithBuffer(JSContext *cx, JSObject *arrayBuffer,
|
||||
uint32_t byteOffset, int32_t length);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewInt16ArrayWithBuffer(JSContext *cx, JSObject *arrayBuffer,
|
||||
uint32_t byteOffset, int32_t length);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewUint16ArrayWithBuffer(JSContext *cx, JSObject *arrayBuffer,
|
||||
uint32_t byteOffset, int32_t length);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewInt32ArrayWithBuffer(JSContext *cx, JSObject *arrayBuffer,
|
||||
uint32_t byteOffset, int32_t length);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewUint32ArrayWithBuffer(JSContext *cx, JSObject *arrayBuffer,
|
||||
uint32_t byteOffset, int32_t length);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewFloat32ArrayWithBuffer(JSContext *cx, JSObject *arrayBuffer,
|
||||
uint32_t byteOffset, int32_t length);
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_NewFloat64ArrayWithBuffer(JSContext *cx, JSObject *arrayBuffer,
|
||||
uint32_t byteOffset, int32_t length);
|
||||
|
||||
/*
|
||||
* 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
|
||||
* this test or one of the JS_Is*Array tests succeeds, then it is safe to call
|
||||
* the various accessor JSAPI calls defined below.
|
||||
*/
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
JS_IsTypedArrayObject(JSObject *obj, JSContext *cx);
|
||||
|
||||
/*
|
||||
* Test for specific typed array types (ArrayBufferView subtypes)
|
||||
*/
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
JS_IsInt8Array(JSObject *obj, JSContext *cx);
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
JS_IsUint8Array(JSObject *obj, JSContext *cx);
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
JS_IsUint8ClampedArray(JSObject *obj, JSContext *cx);
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
JS_IsInt16Array(JSObject *obj, JSContext *cx);
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
JS_IsUint16Array(JSObject *obj, JSContext *cx);
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
JS_IsInt32Array(JSObject *obj, JSContext *cx);
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
JS_IsUint32Array(JSObject *obj, JSContext *cx);
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
JS_IsFloat32Array(JSObject *obj, JSContext *cx);
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
JS_IsFloat64Array(JSObject *obj, JSContext *cx);
|
||||
|
||||
/*
|
||||
* Get the type of elements in a typed array.
|
||||
*
|
||||
* |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
|
||||
* be known that it would pass such a test: it is a typed array or a wrapper of
|
||||
* a typed array, and the unwrapping will succeed. If cx is NULL, then DEBUG
|
||||
* builds may be unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
extern JS_FRIEND_API(JSArrayBufferViewType)
|
||||
JS_GetTypedArrayType(JSObject *obj, JSContext *cx);
|
||||
|
||||
/*
|
||||
* 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(JSBool)
|
||||
JS_IsArrayBufferObject(JSObject *obj, JSContext *cx);
|
||||
|
||||
/*
|
||||
* Return the available byte length of an array buffer.
|
||||
*
|
||||
* |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. If cx is NULL, then DEBUG
|
||||
* builds may be unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
extern JS_FRIEND_API(uint32_t)
|
||||
JS_GetArrayBufferByteLength(JSObject *obj, JSContext *cx);
|
||||
|
||||
/*
|
||||
* Return a pointer to an array buffer's data. The buffer is still owned by the
|
||||
* array buffer object, and should not be modified on another thread.
|
||||
*
|
||||
* |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. If cx is NULL, then DEBUG
|
||||
* builds may be unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
extern JS_FRIEND_API(uint8_t *)
|
||||
JS_GetArrayBufferData(JSObject *obj, JSContext *cx);
|
||||
|
||||
/*
|
||||
* Return the number of elements in a typed array.
|
||||
*
|
||||
* |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
|
||||
* be known that it would pass such a test: it is a typed array or a wrapper of
|
||||
* a typed array, and the unwrapping will succeed. If cx is NULL, then DEBUG
|
||||
* builds may be unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
extern JS_FRIEND_API(uint32_t)
|
||||
JS_GetTypedArrayLength(JSObject *obj, JSContext *cx);
|
||||
|
||||
/*
|
||||
* Return the byte offset from the start of an array buffer to the start of a
|
||||
* typed array view.
|
||||
*
|
||||
* |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
|
||||
* be known that it would pass such a test: it is a typed array or a wrapper of
|
||||
* a typed array, and the unwrapping will succeed. If cx is NULL, then DEBUG
|
||||
* builds may be unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
extern JS_FRIEND_API(uint32_t)
|
||||
JS_GetTypedArrayByteOffset(JSObject *obj, JSContext *cx);
|
||||
|
||||
/*
|
||||
* Return the byte length of a typed array.
|
||||
*
|
||||
* |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
|
||||
* be known that it would pass such a test: it is a typed array or a wrapper of
|
||||
* a typed array, and the unwrapping will succeed. If cx is NULL, then DEBUG
|
||||
* builds may be unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
extern JS_FRIEND_API(uint32_t)
|
||||
JS_GetTypedArrayByteLength(JSObject *obj, JSContext *cx);
|
||||
|
||||
/*
|
||||
* More generic name for JS_GetTypedArrayByteLength to cover DataViews as well
|
||||
*/
|
||||
extern JS_FRIEND_API(uint32_t)
|
||||
JS_GetArrayBufferViewByteLength(JSObject *obj, JSContext *cx);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* |obj| must have passed a JS_Is*Array test, or somehow be known that it would
|
||||
* pass such a test: it is a typed array or a wrapper of a typed array, and the
|
||||
* unwrapping will succeed. If cx is NULL, then DEBUG builds may be unable to
|
||||
* assert when unwrapping should be disallowed.
|
||||
*/
|
||||
|
||||
extern JS_FRIEND_API(int8_t *)
|
||||
JS_GetInt8ArrayData(JSObject *obj, JSContext *cx);
|
||||
extern JS_FRIEND_API(uint8_t *)
|
||||
JS_GetUint8ArrayData(JSObject *obj, JSContext *cx);
|
||||
extern JS_FRIEND_API(uint8_t *)
|
||||
JS_GetUint8ClampedArrayData(JSObject *obj, JSContext *cx);
|
||||
extern JS_FRIEND_API(int16_t *)
|
||||
JS_GetInt16ArrayData(JSObject *obj, JSContext *cx);
|
||||
extern JS_FRIEND_API(uint16_t *)
|
||||
JS_GetUint16ArrayData(JSObject *obj, JSContext *cx);
|
||||
extern JS_FRIEND_API(int32_t *)
|
||||
JS_GetInt32ArrayData(JSObject *obj, JSContext *cx);
|
||||
extern JS_FRIEND_API(uint32_t *)
|
||||
JS_GetUint32ArrayData(JSObject *obj, JSContext *cx);
|
||||
extern JS_FRIEND_API(float *)
|
||||
JS_GetFloat32ArrayData(JSObject *obj, JSContext *cx);
|
||||
extern JS_FRIEND_API(double *)
|
||||
JS_GetFloat64ArrayData(JSObject *obj, JSContext *cx);
|
||||
|
||||
/*
|
||||
* Same as above, but for any kind of ArrayBufferView. Prefer the type-specific
|
||||
* versions when possible.
|
||||
*/
|
||||
extern JS_FRIEND_API(void *)
|
||||
JS_GetArrayBufferViewData(JSObject *obj, JSContext *cx);
|
||||
|
||||
#endif /* jsfriendapi_h___ */
|
||||
|
@ -232,7 +232,7 @@ GetPropertyOperation(JSContext *cx, jsbytecode *pc, const Value &lval, Value *vp
|
||||
}
|
||||
}
|
||||
|
||||
if (js_IsTypedArray(obj)) {
|
||||
if (obj->isTypedArray()) {
|
||||
JSObject *tarray = TypedArray::getTypedArray(obj);
|
||||
*vp = Int32Value(TypedArray::getLength(tarray));
|
||||
return true;
|
||||
|
@ -138,13 +138,13 @@ ToClampedIndex(JSContext *cx, const Value &v, int32_t length, int32_t *out)
|
||||
|
||||
/**
|
||||
* Walks up the prototype chain to find the actual ArrayBuffer data.
|
||||
* This MAY return NULL. Callers should always use js_IsArrayBuffer()
|
||||
* This MAY return NULL. Callers should always use isArrayBuffer()
|
||||
* first.
|
||||
*/
|
||||
JSObject *
|
||||
ArrayBuffer::getArrayBuffer(JSObject *obj)
|
||||
{
|
||||
while (obj && !js_IsArrayBuffer(obj))
|
||||
while (obj && !obj->isArrayBuffer())
|
||||
obj = obj->getProto();
|
||||
return obj;
|
||||
}
|
||||
@ -726,7 +726,7 @@ ArrayBuffer::obj_typeOf(JSContext *cx, JSObject *obj)
|
||||
JSObject *
|
||||
TypedArray::getTypedArray(JSObject *obj)
|
||||
{
|
||||
while (!js_IsTypedArray(obj))
|
||||
while (!obj->isTypedArray())
|
||||
obj = obj->getProto();
|
||||
return obj;
|
||||
}
|
||||
@ -751,7 +751,7 @@ class TypedArrayGetter {
|
||||
public:
|
||||
static inline bool get(JSContext *cx, JSObject *obj, jsid id, Value *vp) {
|
||||
do {
|
||||
if (js_IsTypedArray(obj)) {
|
||||
if (obj->isTypedArray()) {
|
||||
JSObject *tarray = TypedArray::getTypedArray(obj);
|
||||
if (tarray)
|
||||
*vp = Get(tarray);
|
||||
@ -995,10 +995,20 @@ template<> inline const bool ElementTypeMayBeDouble<double>() { return true; }
|
||||
|
||||
template<typename NativeType> class TypedArrayTemplate;
|
||||
|
||||
template<typename ElementType>
|
||||
static inline JSObject *
|
||||
NewArray(JSContext *cx, uint32_t nelements);
|
||||
|
||||
template<typename NativeType>
|
||||
class TypedArrayTemplate
|
||||
: public TypedArray
|
||||
{
|
||||
template<typename ElementType>
|
||||
friend JSObject *NewTypedArrayFromArray(JSContext *cx, JSObject *other);
|
||||
|
||||
template<typename ElementType>
|
||||
friend JSObject *NewArray(JSContext *cx, uint32_t nelements);
|
||||
|
||||
public:
|
||||
typedef NativeType ThisType;
|
||||
typedef TypedArrayTemplate<NativeType> ThisTypeArray;
|
||||
@ -1391,7 +1401,7 @@ class TypedArrayTemplate
|
||||
obj->setSlot(FIELD_BYTEOFFSET, Int32Value(byteOffset));
|
||||
obj->setSlot(FIELD_BYTELENGTH, Int32Value(len * sizeof(NativeType)));
|
||||
|
||||
DebugOnly<uint32_t> bufferByteLength = getBuffer(obj)->arrayBufferByteLength();
|
||||
DebugOnly<uint32_t> bufferByteLength = bufobj->arrayBufferByteLength();
|
||||
JS_ASSERT(bufferByteLength - getByteOffset(obj) >= getByteLength(obj));
|
||||
JS_ASSERT(getByteOffset(obj) <= bufferByteLength);
|
||||
JS_ASSERT(getBuffer(obj)->arrayBufferDataOffset() <= getDataOffset(obj));
|
||||
@ -1454,7 +1464,7 @@ class TypedArrayTemplate
|
||||
JSObject *dataObj = &argv[0].toObject();
|
||||
|
||||
/* (typedArray) */
|
||||
if (js_IsTypedArray(dataObj)) {
|
||||
if (dataObj->isTypedArray()) {
|
||||
JSObject *otherTypedArray = getTypedArray(dataObj);
|
||||
JS_ASSERT(otherTypedArray);
|
||||
|
||||
@ -1576,7 +1586,7 @@ class TypedArrayTemplate
|
||||
}
|
||||
|
||||
JSObject *arg0 = args[0].toObjectOrNull();
|
||||
if (js_IsTypedArray(arg0)) {
|
||||
if (arg0->isTypedArray()) {
|
||||
JSObject *src = TypedArray::getTypedArray(arg0);
|
||||
if (!src ||
|
||||
getLength(src) > getLength(tarray) - offset)
|
||||
@ -1610,56 +1620,45 @@ class TypedArrayTemplate
|
||||
|
||||
public:
|
||||
static JSObject *
|
||||
createTypedArrayWithOffsetLength(JSContext *cx, JSObject *other,
|
||||
int32_t byteOffsetInt, int32_t lengthInt)
|
||||
createTypedArrayWithBuffer(JSContext *cx, JSObject *buffer,
|
||||
int32_t byteOffsetInt, int32_t lengthInt)
|
||||
{
|
||||
JS_ASSERT(!js_IsTypedArray(other));
|
||||
uint32_t boffset = (byteOffsetInt == -1) ? 0 : uint32_t(byteOffsetInt);
|
||||
|
||||
/* Handle creation from an ArrayBuffer not ArrayBuffer.prototype. */
|
||||
if (other->isArrayBuffer()) {
|
||||
uint32_t boffset = (byteOffsetInt < 0) ? 0 : uint32_t(byteOffsetInt);
|
||||
|
||||
if (boffset > other->arrayBufferByteLength() || boffset % sizeof(NativeType) != 0) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_TYPED_ARRAY_BAD_ARGS);
|
||||
return NULL; // invalid byteOffset
|
||||
}
|
||||
|
||||
uint32_t len;
|
||||
if (lengthInt < 0) {
|
||||
len = (other->arrayBufferByteLength() - boffset) / sizeof(NativeType);
|
||||
if (len * sizeof(NativeType) != (other->arrayBufferByteLength() - boffset)) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_TYPED_ARRAY_BAD_ARGS);
|
||||
return NULL; // given byte array doesn't map exactly to sizeof(NativeType)*N
|
||||
}
|
||||
} else {
|
||||
len = (uint32_t) lengthInt;
|
||||
}
|
||||
|
||||
// Go slowly and check for overflow.
|
||||
uint32_t arrayByteLength = len*sizeof(NativeType);
|
||||
if (uint32_t(len) >= INT32_MAX / sizeof(NativeType) ||
|
||||
uint32_t(boffset) >= INT32_MAX - arrayByteLength)
|
||||
{
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_TYPED_ARRAY_BAD_ARGS);
|
||||
return NULL; // overflow occurred along the way when calculating boffset+len*sizeof(NativeType)
|
||||
}
|
||||
|
||||
if (arrayByteLength + boffset > other->arrayBufferByteLength()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_TYPED_ARRAY_BAD_ARGS);
|
||||
return NULL; // boffset+len is too big for the arraybuffer
|
||||
}
|
||||
|
||||
return createTypedArray(cx, other, boffset, len);
|
||||
if (boffset > buffer->arrayBufferByteLength() || boffset % sizeof(NativeType) != 0) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_BAD_ARGS);
|
||||
return NULL; // invalid byteOffset
|
||||
}
|
||||
|
||||
/*
|
||||
* Otherwise create a new typed array and copy len properties from the
|
||||
* object.
|
||||
*/
|
||||
uint32_t len;
|
||||
if (lengthInt == -1) {
|
||||
len = (buffer->arrayBufferByteLength() - boffset) / sizeof(NativeType);
|
||||
if (len * sizeof(NativeType) != buffer->arrayBufferByteLength() - boffset) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_BAD_ARGS);
|
||||
return NULL; // given byte array doesn't map exactly to sizeof(NativeType) * N
|
||||
}
|
||||
} else {
|
||||
len = uint32_t(lengthInt);
|
||||
}
|
||||
|
||||
// Go slowly and check for overflow.
|
||||
uint32_t arrayByteLength = len * sizeof(NativeType);
|
||||
if (len >= INT32_MAX / sizeof(NativeType) || boffset >= INT32_MAX - arrayByteLength) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_BAD_ARGS);
|
||||
return NULL; // overflow when calculating boffset + len * sizeof(NativeType)
|
||||
}
|
||||
|
||||
if (arrayByteLength + boffset > buffer->arrayBufferByteLength()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_BAD_ARGS);
|
||||
return NULL; // boffset + len is too big for the arraybuffer
|
||||
}
|
||||
|
||||
return createTypedArray(cx, buffer, boffset, len);
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
createTypedArrayFromArray(JSContext *cx, JSObject *other)
|
||||
{
|
||||
uint32_t len;
|
||||
if (!js_GetLengthProperty(cx, other, &len))
|
||||
return NULL;
|
||||
@ -1674,6 +1673,27 @@ class TypedArrayTemplate
|
||||
return obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: the offset and length arguments are ignored if an array is passed in.
|
||||
*/
|
||||
static JSObject *
|
||||
createTypedArrayWithOffsetLength(JSContext *cx, JSObject *other,
|
||||
int32_t byteOffsetInt, int32_t lengthInt)
|
||||
{
|
||||
JS_ASSERT(!other->isTypedArray());
|
||||
|
||||
if (other->isArrayBuffer()) {
|
||||
/* Handle creation from an ArrayBuffer not ArrayBuffer.prototype. */
|
||||
return createTypedArrayWithBuffer(cx, other, byteOffsetInt, lengthInt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Otherwise create a new typed array and copy len properties from
|
||||
* the object.
|
||||
*/
|
||||
return createTypedArrayFromArray(cx, other);
|
||||
}
|
||||
|
||||
static const NativeType
|
||||
getIndex(JSObject *obj, uint32_t index)
|
||||
{
|
||||
@ -2203,6 +2223,62 @@ JSFunctionSpec _typedArray::jsfuncs[] = { \
|
||||
JS_FS_END \
|
||||
}
|
||||
|
||||
template<typename ElementType>
|
||||
static inline JSObject *
|
||||
NewArray(JSContext *cx, uint32_t nelements)
|
||||
{
|
||||
JSObject *buffer = TypedArrayTemplate<ElementType>::createBufferWithSizeAndCount(cx, nelements);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
return TypedArrayTemplate<ElementType>::createTypedArray(cx, buffer, 0, nelements);
|
||||
}
|
||||
|
||||
template<typename ElementType>
|
||||
static inline JSObject *
|
||||
NewArrayWithBuffer(JSContext *cx, JSObject *arrayBuffer, int32_t byteoffset, int32_t intLength)
|
||||
{
|
||||
if (!arrayBuffer->isArrayBuffer()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_BAD_ARGS);
|
||||
return NULL; // must be arrayBuffer
|
||||
}
|
||||
|
||||
return TypedArrayTemplate<ElementType>::createTypedArrayWithBuffer(cx, arrayBuffer,
|
||||
byteoffset, intLength);
|
||||
}
|
||||
|
||||
#define IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Name,NativeType) \
|
||||
JS_FRIEND_API(JSObject *) JS_New ## Name ## Array(JSContext *cx, uint32_t nelements) \
|
||||
{ \
|
||||
MOZ_ASSERT(nelements <= INT32_MAX); \
|
||||
return NewArray<NativeType>(cx, nelements); \
|
||||
} \
|
||||
JS_FRIEND_API(JSObject *) JS_New ## Name ## ArrayFromArray(JSContext *cx, JSObject *other) \
|
||||
{ \
|
||||
return TypedArrayTemplate<NativeType>::createTypedArrayFromArray(cx, other); \
|
||||
} \
|
||||
JS_FRIEND_API(JSObject *) JS_New ## Name ## ArrayWithBuffer(JSContext *cx, \
|
||||
JSObject *arrayBuffer, uint32_t byteoffset, int32_t length) \
|
||||
{ \
|
||||
MOZ_ASSERT(byteoffset <= INT32_MAX); \
|
||||
return NewArrayWithBuffer<NativeType>(cx, arrayBuffer, byteoffset, length); \
|
||||
} \
|
||||
JS_FRIEND_API(JSBool) JS_Is ## Name ## Array(JSObject *obj, JSContext *cx) \
|
||||
{ \
|
||||
obj = UnwrapObject(obj); \
|
||||
Class *clasp = obj->getClass(); \
|
||||
return (clasp == &TypedArray::fastClasses[TypedArrayTemplate<NativeType>::ArrayTypeID()]); \
|
||||
}
|
||||
|
||||
IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Int8, int8_t)
|
||||
IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Uint8, uint8_t)
|
||||
IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Uint8Clamped, uint8_clamped)
|
||||
IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Int16, int16_t)
|
||||
IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Uint16, uint16_t)
|
||||
IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Int32, int32_t)
|
||||
IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Uint32, uint32_t)
|
||||
IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Float32, float)
|
||||
IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Float64, double)
|
||||
|
||||
#define IMPL_TYPED_ARRAY_SLOW_CLASS(_typedArray) \
|
||||
{ \
|
||||
#_typedArray, \
|
||||
@ -2409,199 +2485,190 @@ js_InitTypedArrayClasses(JSContext *cx, JSObject *obj)
|
||||
return InitArrayBufferClass(cx, global);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_IsArrayBuffer(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj);
|
||||
obj = UnwrapObject(obj);
|
||||
return obj->isArrayBuffer();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
JS_IsArrayBufferObject(JSObject *obj)
|
||||
{
|
||||
return js_IsArrayBuffer(obj);
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
bool
|
||||
IsFastTypedArrayClass(const Class *clasp)
|
||||
js::IsFastTypedArrayClass(const Class *clasp)
|
||||
{
|
||||
return &TypedArray::fastClasses[0] <= clasp &&
|
||||
clasp < &TypedArray::fastClasses[TypedArray::TYPE_MAX];
|
||||
}
|
||||
|
||||
bool
|
||||
static inline bool
|
||||
IsSlowTypedArrayClass(const Class *clasp)
|
||||
{
|
||||
return &TypedArray::slowClasses[0] <= clasp &&
|
||||
clasp < &TypedArray::slowClasses[TypedArray::TYPE_MAX];
|
||||
}
|
||||
|
||||
bool IsFastOrSlowTypedArray(JSObject *obj)
|
||||
bool
|
||||
js::IsFastOrSlowTypedArray(JSObject *obj)
|
||||
{
|
||||
Class *clasp = obj->getClass();
|
||||
return IsFastTypedArrayClass(clasp) || IsSlowTypedArrayClass(clasp);
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
/* JS Friend API */
|
||||
|
||||
uint32_t
|
||||
JS_GetArrayBufferByteLength(JSObject *obj)
|
||||
JS_FRIEND_API(JSBool)
|
||||
JS_IsArrayBufferObject(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
return obj->isArrayBuffer();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
JS_IsTypedArrayObject(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
return obj->isTypedArray();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(uint32_t)
|
||||
JS_GetArrayBufferByteLength(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isArrayBuffer());
|
||||
return obj->arrayBufferByteLength();
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
JS_GetArrayBufferData(JSObject *obj)
|
||||
JS_FRIEND_API(uint8_t *)
|
||||
JS_GetArrayBufferData(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isArrayBuffer());
|
||||
return obj->arrayBufferDataOffset();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_IsTypedArray(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj);
|
||||
obj = UnwrapObject(obj);
|
||||
Class *clasp = obj->getClass();
|
||||
return IsFastTypedArrayClass(clasp);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
js_CreateArrayBuffer(JSContext *cx, uint32_t nbytes)
|
||||
JS_NewArrayBuffer(JSContext *cx, uint32_t nbytes)
|
||||
{
|
||||
return ArrayBuffer::create(cx, nbytes);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
JS_NewArrayBuffer(JSContext *cx, uint32_t nbytes)
|
||||
{
|
||||
return js_CreateArrayBuffer(cx, nbytes);
|
||||
}
|
||||
|
||||
static inline JSObject *
|
||||
TypedArrayConstruct(JSContext *cx, int atype, unsigned argc, Value *argv)
|
||||
{
|
||||
switch (atype) {
|
||||
case TypedArray::TYPE_INT8:
|
||||
return Int8Array::create(cx, argc, argv);
|
||||
|
||||
case TypedArray::TYPE_UINT8:
|
||||
return Uint8Array::create(cx, argc, argv);
|
||||
|
||||
case TypedArray::TYPE_INT16:
|
||||
return Int16Array::create(cx, argc, argv);
|
||||
|
||||
case TypedArray::TYPE_UINT16:
|
||||
return Uint16Array::create(cx, argc, argv);
|
||||
|
||||
case TypedArray::TYPE_INT32:
|
||||
return Int32Array::create(cx, argc, argv);
|
||||
|
||||
case TypedArray::TYPE_UINT32:
|
||||
return Uint32Array::create(cx, argc, argv);
|
||||
|
||||
case TypedArray::TYPE_FLOAT32:
|
||||
return Float32Array::create(cx, argc, argv);
|
||||
|
||||
case TypedArray::TYPE_FLOAT64:
|
||||
return Float64Array::create(cx, argc, argv);
|
||||
|
||||
case TypedArray::TYPE_UINT8_CLAMPED:
|
||||
return Uint8ClampedArray::create(cx, argc, argv);
|
||||
|
||||
default:
|
||||
JS_NOT_REACHED("shouldn't have gotten here");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
js_CreateTypedArray(JSContext *cx, int atype, uint32_t nelements)
|
||||
{
|
||||
JS_ASSERT(atype >= 0 && atype < TypedArray::TYPE_MAX);
|
||||
|
||||
Value nelems = Int32Value(nelements);
|
||||
return TypedArrayConstruct(cx, atype, 1, &nelems);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
js_CreateTypedArrayWithArray(JSContext *cx, int atype, JSObject *arrayArg)
|
||||
{
|
||||
JS_ASSERT(atype >= 0 && atype < TypedArray::TYPE_MAX);
|
||||
|
||||
Value arrval = ObjectValue(*arrayArg);
|
||||
return TypedArrayConstruct(cx, atype, 1, &arrval);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
js_CreateTypedArrayWithBuffer(JSContext *cx, int atype, JSObject *bufArg,
|
||||
int byteoffset, int length)
|
||||
{
|
||||
JS_ASSERT(atype >= 0 && atype < TypedArray::TYPE_MAX);
|
||||
JS_ASSERT(bufArg && js_IsArrayBuffer(bufArg));
|
||||
JS_ASSERT_IF(byteoffset < 0, length < 0);
|
||||
|
||||
Value vals[4];
|
||||
|
||||
int argc = 1;
|
||||
vals[0].setObject(*bufArg);
|
||||
|
||||
if (byteoffset >= 0) {
|
||||
vals[argc].setInt32(byteoffset);
|
||||
argc++;
|
||||
}
|
||||
|
||||
if (length >= 0) {
|
||||
vals[argc].setInt32(length);
|
||||
argc++;
|
||||
}
|
||||
|
||||
AutoArrayRooter tvr(cx, ArrayLength(vals), vals);
|
||||
return TypedArrayConstruct(cx, atype, argc, &vals[0]);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
JS_GetTypedArrayLength(JSObject *obj)
|
||||
JS_FRIEND_API(uint32_t)
|
||||
JS_GetTypedArrayLength(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
return obj->getSlot(TypedArray::FIELD_LENGTH).toInt32();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
JS_GetTypedArrayByteOffset(JSObject *obj)
|
||||
JS_FRIEND_API(uint32_t)
|
||||
JS_GetTypedArrayByteOffset(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
return obj->getSlot(TypedArray::FIELD_BYTEOFFSET).toInt32();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
JS_GetTypedArrayByteLength(JSObject *obj)
|
||||
JS_FRIEND_API(uint32_t)
|
||||
JS_GetTypedArrayByteLength(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
return obj->getSlot(TypedArray::FIELD_BYTELENGTH).toInt32();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
JS_GetTypedArrayType(JSObject *obj)
|
||||
JS_FRIEND_API(JSArrayBufferViewType)
|
||||
JS_GetTypedArrayType(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
return obj->getSlot(TypedArray::FIELD_TYPE).toInt32();
|
||||
return static_cast<JSArrayBufferViewType>(obj->getSlot(TypedArray::FIELD_TYPE).toInt32());
|
||||
}
|
||||
|
||||
void *
|
||||
JS_GetTypedArrayData(JSObject *obj)
|
||||
JS_FRIEND_API(int8_t *)
|
||||
JS_GetInt8ArrayData(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_INT8);
|
||||
return static_cast<int8_t *>(TypedArray::getDataOffset(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(uint8_t *)
|
||||
JS_GetUint8ArrayData(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_UINT8);
|
||||
return static_cast<uint8_t *>(TypedArray::getDataOffset(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(uint8_t *)
|
||||
JS_GetUint8ClampedArrayData(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_UINT8_CLAMPED);
|
||||
return static_cast<uint8_t *>(TypedArray::getDataOffset(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(int16_t *)
|
||||
JS_GetInt16ArrayData(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_INT16);
|
||||
return static_cast<int16_t *>(TypedArray::getDataOffset(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(uint16_t *)
|
||||
JS_GetUint16ArrayData(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_UINT16);
|
||||
return static_cast<uint16_t *>(TypedArray::getDataOffset(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(int32_t *)
|
||||
JS_GetInt32ArrayData(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_INT32);
|
||||
return static_cast<int32_t *>(TypedArray::getDataOffset(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(uint32_t *)
|
||||
JS_GetUint32ArrayData(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_UINT32);
|
||||
return static_cast<uint32_t *>(TypedArray::getDataOffset(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(float *)
|
||||
JS_GetFloat32ArrayData(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_FLOAT32);
|
||||
return static_cast<float *>(TypedArray::getDataOffset(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(double *)
|
||||
JS_GetFloat64ArrayData(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_FLOAT64);
|
||||
return static_cast<double *>(TypedArray::getDataOffset(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void *)
|
||||
JS_GetArrayBufferViewData(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
return TypedArray::getDataOffset(obj);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(uint32_t)
|
||||
JS_GetArrayBufferViewByteLength(JSObject *obj, JSContext *cx)
|
||||
{
|
||||
obj = UnwrapObject(obj);
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
return obj->getSlot(TypedArray::FIELD_BYTELENGTH).toInt32();
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ namespace js {
|
||||
* TypedArray subclass, or can be created implicitly by constructing a
|
||||
* TypedArray with a size.
|
||||
*/
|
||||
struct JS_FRIEND_API(ArrayBuffer) {
|
||||
struct ArrayBuffer {
|
||||
static Class slowClass;
|
||||
static JSPropertySpec jsprops[];
|
||||
static JSFunctionSpec jsfuncs[];
|
||||
@ -177,7 +177,7 @@ struct JS_FRIEND_API(ArrayBuffer) {
|
||||
* the subclasses.
|
||||
*/
|
||||
|
||||
struct JS_FRIEND_API(TypedArray) {
|
||||
struct TypedArray {
|
||||
enum {
|
||||
TYPE_INT8 = 0,
|
||||
TYPE_UINT8,
|
||||
@ -283,79 +283,15 @@ struct JS_FRIEND_API(TypedArray) {
|
||||
static int dataOffset();
|
||||
};
|
||||
|
||||
extern bool
|
||||
IsFastTypedArrayClass(const Class *clasp);
|
||||
|
||||
extern bool
|
||||
IsSlowTypedArrayClass(const Class *clasp);
|
||||
|
||||
extern bool
|
||||
bool
|
||||
IsFastOrSlowTypedArray(JSObject *obj);
|
||||
|
||||
bool
|
||||
IsFastOrSlowTypedArrayClass(const Class *clasp);
|
||||
|
||||
bool
|
||||
IsFastTypedArrayClass(const Class *clasp);
|
||||
|
||||
} // namespace js
|
||||
|
||||
/* Friend API methods */
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_IsTypedArray(JSObject *obj);
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_IsArrayBuffer(JSObject *obj);
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
js_CreateArrayBuffer(JSContext *cx, uint32_t nbytes);
|
||||
|
||||
/*
|
||||
* Create a new typed array of type atype (one of the TypedArray
|
||||
* enumerant values above), with nelements elements.
|
||||
*/
|
||||
JS_FRIEND_API(JSObject *)
|
||||
js_CreateTypedArray(JSContext *cx, int atype, uint32_t nelements);
|
||||
|
||||
/*
|
||||
* Create a new typed array of type atype (one of the TypedArray
|
||||
* enumerant values above), and copy in values from the given JSObject,
|
||||
* which must either be a typed array or an array-like object.
|
||||
*/
|
||||
JS_FRIEND_API(JSObject *)
|
||||
js_CreateTypedArrayWithArray(JSContext *cx, int atype, JSObject *arrayArg);
|
||||
|
||||
/*
|
||||
* Create a new typed array of type atype (one of the TypedArray
|
||||
* enumerant values above), using a given ArrayBuffer for storage.
|
||||
* The byteoffset and length values are optional; if -1 is passed, an
|
||||
* offset of 0 and enough elements to use up the remainder of the byte
|
||||
* array are used as the default values.
|
||||
*/
|
||||
JS_FRIEND_API(JSObject *)
|
||||
js_CreateTypedArrayWithBuffer(JSContext *cx, int atype, JSObject *bufArg,
|
||||
int byteoffset, int length);
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
JS_IsArrayBufferObject(JSObject *obj);
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
JS_NewArrayBuffer(JSContext *cx, uint32_t nbytes);
|
||||
|
||||
JS_FRIEND_API(uint32_t)
|
||||
JS_GetArrayBufferByteLength(JSObject *obj);
|
||||
|
||||
JS_FRIEND_API(uint8_t *)
|
||||
JS_GetArrayBufferData(JSObject *obj);
|
||||
|
||||
JS_FRIEND_API(uint32_t)
|
||||
JS_GetTypedArrayLength(JSObject *obj);
|
||||
|
||||
JS_FRIEND_API(uint32_t)
|
||||
JS_GetTypedArrayByteOffset(JSObject *obj);
|
||||
|
||||
JS_FRIEND_API(uint32_t)
|
||||
JS_GetTypedArrayByteLength(JSObject *obj);
|
||||
|
||||
JS_FRIEND_API(uint32_t)
|
||||
JS_GetTypedArrayType(JSObject *obj);
|
||||
|
||||
JS_FRIEND_API(void *)
|
||||
JS_GetTypedArrayData(JSObject *obj);
|
||||
|
||||
#endif /* jstypedarray_h */
|
||||
|
@ -2398,7 +2398,7 @@ GetElementIC::update(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *
|
||||
* Since we can use type information to generate inline paths for typed
|
||||
* arrays, just don't generate these ICs with inference enabled.
|
||||
*/
|
||||
if (!f.cx->typeInferenceEnabled() && js_IsTypedArray(obj))
|
||||
if (!f.cx->typeInferenceEnabled() && obj->isTypedArray())
|
||||
return attachTypedArray(f, obj, v, id, vp);
|
||||
#endif
|
||||
|
||||
@ -2720,7 +2720,7 @@ SetElementIC::update(VMFrame &f, const Value &objval, const Value &idval)
|
||||
|
||||
#if defined JS_METHODJIT_TYPED_ARRAY
|
||||
/* Not attaching typed array stubs with linear scan allocator, see GetElementIC. */
|
||||
if (!f.cx->typeInferenceEnabled() && js_IsTypedArray(obj))
|
||||
if (!f.cx->typeInferenceEnabled() && obj->isTypedArray())
|
||||
return attachTypedArray(f, obj, key);
|
||||
#endif
|
||||
|
||||
|
@ -921,10 +921,10 @@ FileAsTypedArray(JSContext *cx, const char *pathname)
|
||||
if (fseek(file, 0, SEEK_SET) != 0) {
|
||||
JS_ReportError(cx, "can't seek start of %s", pathname);
|
||||
} else {
|
||||
obj = js_CreateTypedArray(cx, TypedArray::TYPE_UINT8, len);
|
||||
obj = JS_NewUint8Array(cx, len);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
char *buf = (char *) TypedArray::getDataOffset(TypedArray::getTypedArray(obj));
|
||||
char *buf = (char *) TypedArray::getDataOffset(obj);
|
||||
size_t cc = fread(buf, 1, len, file);
|
||||
if (cc != len) {
|
||||
JS_ReportError(cx, "can't read %s: %s", pathname,
|
||||
@ -3395,16 +3395,15 @@ Serialize(JSContext *cx, unsigned argc, jsval *vp)
|
||||
if (!JS_WriteStructuredClone(cx, v, &datap, &nbytes, NULL, NULL))
|
||||
return false;
|
||||
|
||||
JSObject *arrayobj = js_CreateTypedArray(cx, TypedArray::TYPE_UINT8, nbytes);
|
||||
if (!arrayobj) {
|
||||
JSObject *array = JS_NewUint8Array(cx, nbytes);
|
||||
if (!array) {
|
||||
JS_free(cx, datap);
|
||||
return false;
|
||||
}
|
||||
JSObject *array = TypedArray::getTypedArray(arrayobj);
|
||||
JS_ASSERT((uintptr_t(TypedArray::getDataOffset(array)) & 7) == 0);
|
||||
js_memcpy(TypedArray::getDataOffset(array), datap, nbytes);
|
||||
JS_free(cx, datap);
|
||||
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(arrayobj));
|
||||
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(array));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3413,7 +3412,7 @@ Deserialize(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
jsval v = argc > 0 ? JS_ARGV(cx, vp)[0] : JSVAL_VOID;
|
||||
JSObject *obj;
|
||||
if (JSVAL_IS_PRIMITIVE(v) || !js_IsTypedArray((obj = JSVAL_TO_OBJECT(v)))) {
|
||||
if (JSVAL_IS_PRIMITIVE(v) || !(obj = JSVAL_TO_OBJECT(v))->isTypedArray()) {
|
||||
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_INVALID_ARGS, "deserialize");
|
||||
return false;
|
||||
}
|
||||
|
@ -59,7 +59,6 @@
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jstypedarray.h"
|
||||
|
||||
#include "mozilla/dom/bindings/Utils.h"
|
||||
|
||||
@ -1606,7 +1605,8 @@ failure:
|
||||
// of the output does not exceed PR_UINT32_MAX bytes. Allocate
|
||||
// the memory and copy the elements by memcpy.
|
||||
static JSBool
|
||||
CheckTargetAndPopulate(const nsXPTType& type,
|
||||
CheckTargetAndPopulate(JSContext *cx,
|
||||
const nsXPTType& type,
|
||||
PRUint8 requiredType,
|
||||
size_t typeSize,
|
||||
uint32_t count,
|
||||
@ -1637,7 +1637,7 @@ CheckTargetAndPopulate(const nsXPTType& type,
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(*output, JS_GetTypedArrayData(tArr), byteSize);
|
||||
memcpy(*output, JS_GetArrayBufferViewData(tArr, cx), byteSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1660,11 +1660,12 @@ XPCConvert::JSTypedArray2Native(XPCCallContext& ccx,
|
||||
{
|
||||
NS_ABORT_IF_FALSE(jsArray, "bad param");
|
||||
NS_ABORT_IF_FALSE(d, "bad param");
|
||||
NS_ABORT_IF_FALSE(js_IsTypedArray(jsArray), "not a typed array");
|
||||
JSContext* cx = ccx.GetJSContext();
|
||||
NS_ABORT_IF_FALSE(JS_IsTypedArrayObject(jsArray, cx), "not a typed array");
|
||||
|
||||
// Check the actual length of the input array against the
|
||||
// given size_is.
|
||||
uint32_t len = JS_GetTypedArrayLength(jsArray);
|
||||
uint32_t len = JS_GetTypedArrayLength(jsArray, cx);
|
||||
if (len < count) {
|
||||
if (pErr)
|
||||
*pErr = NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY;
|
||||
@ -1674,66 +1675,66 @@ XPCConvert::JSTypedArray2Native(XPCCallContext& ccx,
|
||||
|
||||
void* output = nsnull;
|
||||
|
||||
switch (JS_GetTypedArrayType(jsArray)) {
|
||||
case js::TypedArray::TYPE_INT8:
|
||||
if (!CheckTargetAndPopulate(nsXPTType::T_I8, type,
|
||||
switch (JS_GetTypedArrayType(jsArray, cx)) {
|
||||
case js::ArrayBufferView::TYPE_INT8:
|
||||
if (!CheckTargetAndPopulate(cx, nsXPTType::T_I8, type,
|
||||
sizeof(int8_t), count,
|
||||
jsArray, &output, pErr)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case js::TypedArray::TYPE_UINT8:
|
||||
case js::TypedArray::TYPE_UINT8_CLAMPED:
|
||||
if (!CheckTargetAndPopulate(nsXPTType::T_U8, type,
|
||||
case js::ArrayBufferView::TYPE_UINT8:
|
||||
case js::ArrayBufferView::TYPE_UINT8_CLAMPED:
|
||||
if (!CheckTargetAndPopulate(cx, nsXPTType::T_U8, type,
|
||||
sizeof(uint8_t), count,
|
||||
jsArray, &output, pErr)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case js::TypedArray::TYPE_INT16:
|
||||
if (!CheckTargetAndPopulate(nsXPTType::T_I16, type,
|
||||
case js::ArrayBufferView::TYPE_INT16:
|
||||
if (!CheckTargetAndPopulate(cx, nsXPTType::T_I16, type,
|
||||
sizeof(int16_t), count,
|
||||
jsArray, &output, pErr)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case js::TypedArray::TYPE_UINT16:
|
||||
if (!CheckTargetAndPopulate(nsXPTType::T_U16, type,
|
||||
case js::ArrayBufferView::TYPE_UINT16:
|
||||
if (!CheckTargetAndPopulate(cx, nsXPTType::T_U16, type,
|
||||
sizeof(uint16_t), count,
|
||||
jsArray, &output, pErr)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case js::TypedArray::TYPE_INT32:
|
||||
if (!CheckTargetAndPopulate(nsXPTType::T_I32, type,
|
||||
case js::ArrayBufferView::TYPE_INT32:
|
||||
if (!CheckTargetAndPopulate(cx, nsXPTType::T_I32, type,
|
||||
sizeof(int32_t), count,
|
||||
jsArray, &output, pErr)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case js::TypedArray::TYPE_UINT32:
|
||||
if (!CheckTargetAndPopulate(nsXPTType::T_U32, type,
|
||||
case js::ArrayBufferView::TYPE_UINT32:
|
||||
if (!CheckTargetAndPopulate(cx, nsXPTType::T_U32, type,
|
||||
sizeof(uint32_t), count,
|
||||
jsArray, &output, pErr)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case js::TypedArray::TYPE_FLOAT32:
|
||||
if (!CheckTargetAndPopulate(nsXPTType::T_FLOAT, type,
|
||||
case js::ArrayBufferView::TYPE_FLOAT32:
|
||||
if (!CheckTargetAndPopulate(cx, nsXPTType::T_FLOAT, type,
|
||||
sizeof(float), count,
|
||||
jsArray, &output, pErr)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case js::TypedArray::TYPE_FLOAT64:
|
||||
if (!CheckTargetAndPopulate(nsXPTType::T_DOUBLE, type,
|
||||
case js::ArrayBufferView::TYPE_FLOAT64:
|
||||
if (!CheckTargetAndPopulate(cx, nsXPTType::T_DOUBLE, type,
|
||||
sizeof(double), count,
|
||||
jsArray, &output, pErr)) {
|
||||
return false;
|
||||
@ -1798,8 +1799,8 @@ XPCConvert::JSArray2Native(XPCCallContext& ccx, void** d, jsval s,
|
||||
|
||||
jsarray = JSVAL_TO_OBJECT(s);
|
||||
|
||||
// If this is a typed array, then do a fast conversion with memcpy.
|
||||
if (js_IsTypedArray(jsarray)) {
|
||||
// If this is a typed array, then try a fast conversion with memcpy.
|
||||
if (JS_IsTypedArrayObject(jsarray, cx)) {
|
||||
return JSTypedArray2Native(ccx, d, jsarray, count, type, pErr);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user