Merge m-c to b2g-inbound

This commit is contained in:
Wes Kocher 2014-06-11 18:50:50 -07:00
commit 6840fd7537
211 changed files with 3141 additions and 1388 deletions

View File

@ -213,7 +213,8 @@ this.ContentControl.prototype = {
let focusedAcc = Utils.AccRetrieval.getAccessibleFor( let focusedAcc = Utils.AccRetrieval.getAccessibleFor(
this.document.activeElement); this.document.activeElement);
if (focusedAcc && focusedAcc.role === Roles.ENTRY) { if (focusedAcc && this.vc.position === focusedAcc
&& focusedAcc.role === Roles.ENTRY) {
let accText = focusedAcc.QueryInterface(Ci.nsIAccessibleText); let accText = focusedAcc.QueryInterface(Ci.nsIAccessibleText);
let oldOffset = accText.caretOffset; let oldOffset = accText.caretOffset;
let newOffset = aMessage.json.offset; let newOffset = aMessage.json.offset;

View File

@ -50,7 +50,7 @@ let inputTests = [
{ {
input: "testDOMException()", input: "testDOMException()",
output: 'DOMException [SyntaxError: "An invalid or illegal string was specified"', output: 'DOMException [SyntaxError: "An invalid or illegal string was specified"',
printOutput: '[object XrayWrapper [object DOMException]]"', printOutput: '"SyntaxError: An invalid or illegal string was specified"',
inspectable: true, inspectable: true,
variablesViewLabel: "SyntaxError", variablesViewLabel: "SyntaxError",
}, },

View File

@ -2087,9 +2087,10 @@ public:
const nsAString& aTypeExtension, const nsAString& aTypeExtension,
uint32_t aNamespaceID, uint32_t aNamespaceID,
mozilla::ErrorResult& rv) = 0; mozilla::ErrorResult& rv) = 0;
virtual JSObject* virtual void
RegisterElement(JSContext* aCx, const nsAString& aName, RegisterElement(JSContext* aCx, const nsAString& aName,
const mozilla::dom::ElementRegistrationOptions& aOptions, const mozilla::dom::ElementRegistrationOptions& aOptions,
JS::MutableHandle<JSObject*> aRetval,
mozilla::ErrorResult& rv) = 0; mozilla::ErrorResult& rv) = 0;
/** /**

View File

@ -1617,12 +1617,14 @@ public:
// HasAttributes is defined inline in Element.h. // HasAttributes is defined inline in Element.h.
bool HasAttributes() const; bool HasAttributes() const;
nsDOMAttributeMap* GetAttributes(); nsDOMAttributeMap* GetAttributes();
JS::Value SetUserData(JSContext* aCx, const nsAString& aKey, void SetUserData(JSContext* aCx, const nsAString& aKey,
JS::Handle<JS::Value> aData, JS::Handle<JS::Value> aData,
nsIDOMUserDataHandler* aHandler, nsIDOMUserDataHandler* aHandler,
mozilla::ErrorResult& aError); JS::MutableHandle<JS::Value> aRetval,
JS::Value GetUserData(JSContext* aCx, const nsAString& aKey, mozilla::ErrorResult& aError);
mozilla::ErrorResult& aError); void GetUserData(JSContext* aCx, const nsAString& aKey,
JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError);
// Helper method to remove this node from its parent. This is not exposed // Helper method to remove this node from its parent. This is not exposed
// through WebIDL. // through WebIDL.

View File

@ -25,8 +25,7 @@ NS_IMPL_RELEASE_INHERITED(FileIOObject, DOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileIOObject) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileIOObject)
NS_INTERFACE_MAP_ENTRY(nsITimerCallback) NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
NS_INTERFACE_MAP_ENTRY(nsIStreamListener) NS_INTERFACE_MAP_ENTRY(nsIInputStreamCallback)
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_CLASS(FileIOObject) NS_IMPL_CYCLE_COLLECTION_CLASS(FileIOObject)
@ -35,14 +34,12 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(FileIOObject,
DOMEventTargetHelper) DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mProgressNotifier) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mProgressNotifier)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mError) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mError)
// Can't traverse mChannel because it's a multithreaded object.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FileIOObject, NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FileIOObject,
DOMEventTargetHelper) DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mProgressNotifier) NS_IMPL_CYCLE_COLLECTION_UNLINK(mProgressNotifier)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mError) NS_IMPL_CYCLE_COLLECTION_UNLINK(mError)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChannel)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_EVENT_HANDLER(FileIOObject, abort) NS_IMPL_EVENT_HANDLER(FileIOObject, abort)
@ -141,29 +138,31 @@ FileIOObject::Notify(nsITimer* aTimer)
return NS_OK; return NS_OK;
} }
// nsIStreamListener // InputStreamCallback
NS_IMETHODIMP NS_IMETHODIMP
FileIOObject::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) FileIOObject::OnInputStreamReady(nsIAsyncInputStream* aStream)
{ {
return DoOnStartRequest(aRequest, aContext); if (mReadyState != 1 || aStream != mAsyncStream) {
} return NS_OK;
}
NS_IMETHODIMP uint64_t aCount;
FileIOObject::DoOnStartRequest(nsIRequest *request, nsISupports *ctxt) nsresult rv = aStream->Available(&aCount);
{
return NS_OK;
}
NS_IMETHODIMP if (NS_SUCCEEDED(rv) && aCount) {
FileIOObject::OnDataAvailable(nsIRequest *aRequest, rv = DoReadData(aStream, aCount);
nsISupports *aContext, }
nsIInputStream *aInputStream,
uint64_t aOffset, if (NS_SUCCEEDED(rv)) {
uint32_t aCount) rv = DoAsyncWait(aStream);
{ }
nsresult rv;
rv = DoOnDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount); if (!aCount || NS_FAILED(rv)) {
NS_ENSURE_SUCCESS(rv, rv); if (rv == NS_BASE_STREAM_CLOSED) {
rv = NS_OK;
}
return OnLoadEnd(rv);
}
mTransferred += aCount; mTransferred += aCount;
@ -180,15 +179,9 @@ FileIOObject::OnDataAvailable(nsIRequest *aRequest,
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP nsresult
FileIOObject::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext, FileIOObject::OnLoadEnd(nsresult aStatus)
nsresult aStatus)
{ {
// If we're here as a result of a call from Abort(),
// simply ignore the request.
if (aRequest != mChannel)
return NS_OK;
// Cancel the progress event timer // Cancel the progress event timer
ClearProgressEventTimer(); ClearProgressEventTimer();
@ -196,8 +189,7 @@ FileIOObject::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
mReadyState = 2; mReadyState = 2;
nsString successEvent, termEvent; nsString successEvent, termEvent;
nsresult rv = DoOnStopRequest(aRequest, aContext, aStatus, nsresult rv = DoOnLoadEnd(aStatus, successEvent, termEvent);
successEvent, termEvent);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// Set the status field as appropriate // Set the status field as appropriate
@ -213,6 +205,15 @@ FileIOObject::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
return NS_OK; return NS_OK;
} }
nsresult
FileIOObject::DoAsyncWait(nsIAsyncInputStream* aStream)
{
return aStream->AsyncWait(this,
/* aFlags*/ 0,
/* aRequestedCount */ 0,
NS_GetCurrentThread());
}
void void
FileIOObject::Abort(ErrorResult& aRv) FileIOObject::Abort(ErrorResult& aRv)
{ {

View File

@ -7,12 +7,11 @@
#define FileIOObject_h__ #define FileIOObject_h__
#include "mozilla/DOMEventTargetHelper.h" #include "mozilla/DOMEventTargetHelper.h"
#include "nsIChannel.h"
#include "nsIFile.h" #include "nsIFile.h"
#include "nsIDOMFile.h" #include "nsIDOMFile.h"
#include "nsIStreamListener.h"
#include "nsITimer.h" #include "nsITimer.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsIAsyncInputStream.h"
#include "mozilla/dom/DOMError.h" #include "mozilla/dom/DOMError.h"
@ -29,7 +28,7 @@ extern const uint64_t kUnknownSize;
// A common base class for FileReader and FileSaver // A common base class for FileReader and FileSaver
class FileIOObject : public DOMEventTargetHelper, class FileIOObject : public DOMEventTargetHelper,
public nsIStreamListener, public nsIInputStreamCallback,
public nsITimerCallback public nsITimerCallback
{ {
public: public:
@ -61,26 +60,21 @@ public:
NS_DECL_NSITIMERCALLBACK NS_DECL_NSITIMERCALLBACK
NS_DECL_NSISTREAMLISTENER NS_DECL_NSIINPUTSTREAMCALLBACK
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FileIOObject, DOMEventTargetHelper) NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FileIOObject, DOMEventTargetHelper)
protected: protected:
// Implemented by the derived class to do whatever it needs to do for abort // Implemented by the derived class to do whatever it needs to do for abort
virtual void DoAbort(nsAString& aEvent) = 0; virtual void DoAbort(nsAString& aEvent) = 0;
// for onStartRequest (this has a default impl since FileReader doesn't need
// special handling virtual nsresult DoReadData(nsIAsyncInputStream* aStream, uint64_t aCount) = 0;
NS_IMETHOD DoOnStartRequest(nsIRequest *aRequest, nsISupports *aContext);
// for onStopRequest virtual nsresult DoOnLoadEnd(nsresult aStatus, nsAString& aSuccessEvent,
NS_IMETHOD DoOnStopRequest(nsIRequest *aRequest, nsISupports *aContext, nsAString& aTerminationEvent) = 0;
nsresult aStatus, nsAString& aSuccessEvent,
nsAString& aTerminationEvent) = 0; nsresult OnLoadEnd(nsresult aStatus);
// and for onDataAvailable nsresult DoAsyncWait(nsIAsyncInputStream* aStream);
NS_IMETHOD DoOnDataAvailable(nsIRequest *aRequest, nsISupports *aContext,
nsIInputStream *aInputStream, uint64_t aOffset,
uint32_t aCount) = 0;
void StartProgressEventTimer(); void StartProgressEventTimer();
void ClearProgressEventTimer(); void ClearProgressEventTimer();
@ -91,8 +85,9 @@ protected:
bool mProgressEventWasDelayed; bool mProgressEventWasDelayed;
bool mTimerIsActive; bool mTimerIsActive;
nsCOMPtr<nsIAsyncInputStream> mAsyncStream;
nsRefPtr<DOMError> mError; nsRefPtr<DOMError> mError;
nsCOMPtr<nsIChannel> mChannel;
uint16_t mReadyState; uint16_t mReadyState;

View File

@ -10,41 +10,25 @@
#include "nsDOMClassInfoID.h" #include "nsDOMClassInfoID.h"
#include "nsDOMFile.h" #include "nsDOMFile.h"
#include "nsError.h" #include "nsError.h"
#include "nsIConverterInputStream.h"
#include "nsIDocument.h"
#include "nsIFile.h" #include "nsIFile.h"
#include "nsIFileStreams.h"
#include "nsIInputStream.h"
#include "nsIMIMEService.h"
#include "nsIUnicodeDecoder.h"
#include "nsNetCID.h" #include "nsNetCID.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsLayoutCID.h"
#include "nsXPIDLString.h"
#include "nsReadableUtils.h"
#include "nsIURI.h"
#include "nsStreamUtils.h"
#include "nsXPCOM.h" #include "nsXPCOM.h"
#include "nsIDOMEventListener.h" #include "nsIDOMEventListener.h"
#include "nsJSEnvironment.h" #include "nsJSEnvironment.h"
#include "nsIScriptGlobalObject.h"
#include "nsCExternalHandlerService.h"
#include "nsIStreamConverterService.h"
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsHostObjectProtocolHandler.h"
#include "mozilla/Base64.h" #include "mozilla/Base64.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/EncodingUtils.h" #include "mozilla/dom/EncodingUtils.h"
#include "mozilla/dom/FileReaderBinding.h" #include "mozilla/dom/FileReaderBinding.h"
#include "xpcpublic.h" #include "xpcpublic.h"
#include "nsIScriptSecurityManager.h"
#include "nsDOMJSUtils.h" #include "nsDOMJSUtils.h"
#include "jsfriendapi.h" #include "jsfriendapi.h"
#include "nsITransport.h"
#include "nsIStreamTransportService.h"
using namespace mozilla; using namespace mozilla;
using namespace mozilla::dom; using namespace mozilla::dom;
@ -52,19 +36,19 @@ using namespace mozilla::dom;
#define LOADSTART_STR "loadstart" #define LOADSTART_STR "loadstart"
#define LOADEND_STR "loadend" #define LOADEND_STR "loadend"
static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID);
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMFileReader) NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMFileReader)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMFileReader, NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMFileReader,
FileIOObject) FileIOObject)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFile) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFile)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrincipal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMFileReader, NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMFileReader,
FileIOObject) FileIOObject)
tmp->mResultArrayBuffer = nullptr; tmp->mResultArrayBuffer = nullptr;
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFile) NS_IMPL_CYCLE_COLLECTION_UNLINK(mFile)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPrincipal)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@ -76,7 +60,6 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMFileReader) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMFileReader)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsIDOMFileReader) NS_INTERFACE_MAP_ENTRY(nsIDOMFileReader)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_END_INHERITING(FileIOObject) NS_INTERFACE_MAP_END_INHERITING(FileIOObject)
@ -121,14 +104,6 @@ nsDOMFileReader::~nsDOMFileReader()
nsresult nsresult
nsDOMFileReader::Init() nsDOMFileReader::Init()
{ {
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
nsCOMPtr<nsIPrincipal> principal;
if (secMan) {
secMan->GetSystemPrincipal(getter_AddRefs(principal));
}
NS_ENSURE_STATE(principal);
mPrincipal.swap(principal);
// Instead of grabbing some random global from the context stack, // Instead of grabbing some random global from the context stack,
// let's use the default one (junk scope) for now. // let's use the default one (junk scope) for now.
// We should move away from this Init... // We should move away from this Init...
@ -151,15 +126,6 @@ nsDOMFileReader::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
} }
fileReader->BindToOwner(owner); fileReader->BindToOwner(owner);
// This object is bound to a |window|,
// so reset the principal.
nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal = do_QueryInterface(owner);
if (!scriptPrincipal) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
fileReader->mPrincipal = scriptPrincipal->GetPrincipal();
return fileReader.forget(); return fileReader.forget();
} }
@ -180,12 +146,11 @@ nsDOMFileReader::GetReadyState(uint16_t *aReadyState)
return NS_OK; return NS_OK;
} }
JS::Value void
nsDOMFileReader::GetResult(JSContext* aCx, ErrorResult& aRv) nsDOMFileReader::GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv)
{ {
JS::Rooted<JS::Value> result(aCx); aRv = GetResult(aCx, aResult);
aRv = GetResult(aCx, &result);
return result;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -271,11 +236,8 @@ nsDOMFileReader::DoAbort(nsAString& aEvent)
SetDOMStringToNull(mResult); SetDOMStringToNull(mResult);
mResultArrayBuffer = nullptr; mResultArrayBuffer = nullptr;
// Non-null channel indicates a read is currently active if (mAsyncStream) {
if (mChannel) { mAsyncStream = nullptr;
// Cancel request requires an error status
mChannel->Cancel(NS_ERROR_FAILURE);
mChannel = nullptr;
} }
mFile = nullptr; mFile = nullptr;
@ -309,65 +271,14 @@ ReadFuncBinaryString(nsIInputStream* in,
} }
nsresult nsresult
nsDOMFileReader::DoOnDataAvailable(nsIRequest *aRequest, nsDOMFileReader::DoOnLoadEnd(nsresult aStatus,
nsISupports *aContext, nsAString& aSuccessEvent,
nsIInputStream *aInputStream, nsAString& aTerminationEvent)
uint64_t aOffset,
uint32_t aCount)
{ {
if (mDataFormat == FILE_AS_BINARY) {
//Continuously update our binary string as data comes in
NS_ASSERTION(mResult.Length() == aOffset,
"unexpected mResult length");
uint32_t oldLen = mResult.Length();
if (uint64_t(oldLen) + aCount > UINT32_MAX)
return NS_ERROR_OUT_OF_MEMORY;
char16_t *buf = nullptr;
mResult.GetMutableData(&buf, oldLen + aCount, fallible_t());
NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
uint32_t bytesRead = 0;
aInputStream->ReadSegments(ReadFuncBinaryString, buf + oldLen, aCount,
&bytesRead);
NS_ASSERTION(bytesRead == aCount, "failed to read data");
}
else if (mDataFormat == FILE_AS_ARRAYBUFFER) {
uint32_t bytesRead = 0;
aInputStream->Read((char*)JS_GetArrayBufferData(mResultArrayBuffer) + aOffset,
aCount, &bytesRead);
NS_ASSERTION(bytesRead == aCount, "failed to read data");
}
else {
//Update memory buffer to reflect the contents of the file
if (aOffset + aCount > UINT32_MAX) {
// PR_Realloc doesn't support over 4GB memory size even if 64-bit OS
return NS_ERROR_OUT_OF_MEMORY;
}
mFileData = (char *)moz_realloc(mFileData, aOffset + aCount);
NS_ENSURE_TRUE(mFileData, NS_ERROR_OUT_OF_MEMORY);
uint32_t bytesRead = 0;
aInputStream->Read(mFileData + aOffset, aCount, &bytesRead);
NS_ASSERTION(bytesRead == aCount, "failed to read data");
mDataLen += aCount;
}
return NS_OK;
}
nsresult
nsDOMFileReader::DoOnStopRequest(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aStatus,
nsAString& aSuccessEvent,
nsAString& aTerminationEvent)
{
// Make sure we drop all the objects that could hold files open now. // Make sure we drop all the objects that could hold files open now.
nsCOMPtr<nsIChannel> channel; nsCOMPtr<nsIAsyncInputStream> stream;
mChannel.swap(channel); mAsyncStream.swap(stream);
nsCOMPtr<nsIDOMBlob> file; nsCOMPtr<nsIDOMBlob> file;
mFile.swap(file); mFile.swap(file);
@ -409,6 +320,51 @@ nsDOMFileReader::DoOnStopRequest(nsIRequest *aRequest,
return rv; return rv;
} }
nsresult
nsDOMFileReader::DoReadData(nsIAsyncInputStream* aStream, uint64_t aCount)
{
MOZ_ASSERT(aStream);
if (mDataFormat == FILE_AS_BINARY) {
//Continuously update our binary string as data comes in
uint32_t oldLen = mResult.Length();
NS_ASSERTION(mResult.Length() == mDataLen,
"unexpected mResult length");
if (uint64_t(oldLen) + aCount > UINT32_MAX)
return NS_ERROR_OUT_OF_MEMORY;
char16_t *buf = nullptr;
mResult.GetMutableData(&buf, oldLen + aCount, fallible_t());
NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
uint32_t bytesRead = 0;
aStream->ReadSegments(ReadFuncBinaryString, buf + oldLen, aCount,
&bytesRead);
NS_ASSERTION(bytesRead == aCount, "failed to read data");
}
else if (mDataFormat == FILE_AS_ARRAYBUFFER) {
uint32_t bytesRead = 0;
aStream->Read((char*) JS_GetArrayBufferData(mResultArrayBuffer) + mDataLen,
aCount, &bytesRead);
NS_ASSERTION(bytesRead == aCount, "failed to read data");
}
else {
//Update memory buffer to reflect the contents of the file
if (mDataLen + aCount > UINT32_MAX) {
// PR_Realloc doesn't support over 4GB memory size even if 64-bit OS
return NS_ERROR_OUT_OF_MEMORY;
}
mFileData = (char *) moz_realloc(mFileData, mDataLen + aCount);
NS_ENSURE_TRUE(mFileData, NS_ERROR_OUT_OF_MEMORY);
uint32_t bytesRead = 0;
aStream->Read(mFileData + mDataLen, aCount, &bytesRead);
NS_ASSERTION(bytesRead == aCount, "failed to read data");
}
mDataLen += aCount;
return NS_OK;
}
// Helper methods // Helper methods
void void
@ -433,40 +389,55 @@ nsDOMFileReader::ReadFileContent(JSContext* aCx,
mDataFormat = aDataFormat; mDataFormat = aDataFormat;
CopyUTF16toUTF8(aCharset, mCharset); CopyUTF16toUTF8(aCharset, mCharset);
//Establish a channel with our file nsresult rv;
{
// Hold the internal URL alive only as long as necessary
// After the channel is created it will own whatever is backing
// the DOMFile.
nsDOMFileInternalUrlHolder urlHolder(mFile, mPrincipal);
nsCOMPtr<nsIURI> uri; nsCOMPtr<nsIStreamTransportService> sts =
aRv = NS_NewURI(getter_AddRefs(uri), urlHolder.mUrl); do_GetService(kStreamTransportServiceCID, &rv);
NS_ENSURE_SUCCESS_VOID(aRv.ErrorCode()); if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
nsCOMPtr<nsILoadGroup> loadGroup; return;
if (HasOrHasHadOwner()) {
if (!GetOwner()) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsIDocument* doc = GetOwner()->GetExtantDoc();
if (doc) {
loadGroup = doc->GetDocumentLoadGroup();
}
}
aRv = NS_NewChannel(getter_AddRefs(mChannel), uri, nullptr, loadGroup,
nullptr, nsIRequest::LOAD_BACKGROUND);
NS_ENSURE_SUCCESS_VOID(aRv.ErrorCode());
} }
//Obtain the total size of the file before reading nsCOMPtr<nsIInputStream> stream;
rv = mFile->GetInternalStream(getter_AddRefs(stream));
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return;
}
nsCOMPtr<nsITransport> transport;
rv = sts->CreateInputTransport(stream,
/* aStartOffset */ 0,
/* aReadLimit */ -1,
/* aCloseWhenDone */ true,
getter_AddRefs(transport));
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return;
}
nsCOMPtr<nsIInputStream> wrapper;
rv = transport->OpenInputStream(/* aFlags */ 0,
/* aSegmentSize */ 0,
/* aSegmentCount */ 0,
getter_AddRefs(wrapper));
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return;
}
MOZ_ASSERT(!mAsyncStream);
mAsyncStream = do_QueryInterface(wrapper);
MOZ_ASSERT(mAsyncStream);
mTotal = mozilla::dom::kUnknownSize; mTotal = mozilla::dom::kUnknownSize;
mFile->GetSize(&mTotal); mFile->GetSize(&mTotal);
aRv = mChannel->AsyncOpen(this, nullptr); rv = DoAsyncWait(mAsyncStream);
NS_ENSURE_SUCCESS_VOID(aRv.ErrorCode()); if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return;
}
//FileReader should be in loading state here //FileReader should be in loading state here
mReadyState = nsIDOMFileReader::LOADING; mReadyState = nsIDOMFileReader::LOADING;

View File

@ -17,14 +17,12 @@
#include "nsIJSNativeInitializer.h" #include "nsIJSNativeInitializer.h"
#include "prtime.h" #include "prtime.h"
#include "nsITimer.h" #include "nsITimer.h"
#include "nsIAsyncInputStream.h"
#include "nsIDOMFile.h" #include "nsIDOMFile.h"
#include "nsIDOMFileReader.h" #include "nsIDOMFileReader.h"
#include "nsIDOMFileList.h" #include "nsIDOMFileList.h"
#include "nsIInputStream.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsIStreamLoader.h"
#include "nsIChannel.h"
#include "FileIOObject.h" #include "FileIOObject.h"
@ -50,12 +48,11 @@ public:
// FileIOObject overrides // FileIOObject overrides
virtual void DoAbort(nsAString& aEvent) MOZ_OVERRIDE; virtual void DoAbort(nsAString& aEvent) MOZ_OVERRIDE;
NS_IMETHOD DoOnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
nsresult aStatus, nsAString& aSuccessEvent, virtual nsresult DoReadData(nsIAsyncInputStream* aStream, uint64_t aCount) MOZ_OVERRIDE;
nsAString& aTerminationEvent) MOZ_OVERRIDE;
NS_IMETHOD DoOnDataAvailable(nsIRequest* aRequest, nsISupports* aContext, virtual nsresult DoOnLoadEnd(nsresult aStatus, nsAString& aSuccessEvent,
nsIInputStream* aInputStream, uint64_t aOffset, nsAString& aTerminationEvent) MOZ_OVERRIDE;
uint32_t aCount) MOZ_OVERRIDE;
nsPIDOMWindow* GetParentObject() const nsPIDOMWindow* GetParentObject() const
{ {
@ -71,11 +68,13 @@ public:
MOZ_ASSERT(aBlob); MOZ_ASSERT(aBlob);
ReadFileContent(aCx, aBlob, EmptyString(), FILE_AS_ARRAYBUFFER, aRv); ReadFileContent(aCx, aBlob, EmptyString(), FILE_AS_ARRAYBUFFER, aRv);
} }
void ReadAsText(nsIDOMBlob* aBlob, const nsAString& aLabel, ErrorResult& aRv) void ReadAsText(nsIDOMBlob* aBlob, const nsAString& aLabel, ErrorResult& aRv)
{ {
MOZ_ASSERT(aBlob); MOZ_ASSERT(aBlob);
ReadFileContent(nullptr, aBlob, aLabel, FILE_AS_TEXT, aRv); ReadFileContent(nullptr, aBlob, aLabel, FILE_AS_TEXT, aRv);
} }
void ReadAsDataURL(nsIDOMBlob* aBlob, ErrorResult& aRv) void ReadAsDataURL(nsIDOMBlob* aBlob, ErrorResult& aRv)
{ {
MOZ_ASSERT(aBlob); MOZ_ASSERT(aBlob);
@ -86,7 +85,8 @@ public:
// Inherited ReadyState(). // Inherited ReadyState().
JS::Value GetResult(JSContext* aCx, ErrorResult& aRv); void GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv);
using FileIOObject::GetError; using FileIOObject::GetError;
@ -142,7 +142,6 @@ protected:
eDataFormat mDataFormat; eDataFormat mDataFormat;
nsString mResult; nsString mResult;
nsCOMPtr<nsIPrincipal> mPrincipal;
JS::Heap<JSObject*> mResultArrayBuffer; JS::Heap<JSObject*> mResultArrayBuffer;
}; };

View File

@ -5767,14 +5767,15 @@ nsDocument::sProcessingStack;
bool bool
nsDocument::sProcessingBaseElementQueue; nsDocument::sProcessingBaseElementQueue;
JSObject* void
nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType, nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
const ElementRegistrationOptions& aOptions, const ElementRegistrationOptions& aOptions,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& rv) ErrorResult& rv)
{ {
if (!mRegistry) { if (!mRegistry) {
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr; return;
} }
Registry::DefinitionMap& definitions = mRegistry->mCustomDefinitions; Registry::DefinitionMap& definitions = mRegistry->mCustomDefinitions;
@ -5795,7 +5796,7 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
nsCOMPtr<nsIAtom> typeAtom(do_GetAtom(lcType)); nsCOMPtr<nsIAtom> typeAtom(do_GetAtom(lcType));
if (!nsContentUtils::IsCustomElementName(typeAtom)) { if (!nsContentUtils::IsCustomElementName(typeAtom)) {
rv.Throw(NS_ERROR_DOM_SYNTAX_ERR); rv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return nullptr; return;
} }
// If there already exists a definition with the same TYPE, set ERROR to // If there already exists a definition with the same TYPE, set ERROR to
@ -5804,13 +5805,13 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
CustomElementHashKey duplicateFinder(kNameSpaceID_Unknown, typeAtom); CustomElementHashKey duplicateFinder(kNameSpaceID_Unknown, typeAtom);
if (definitions.Get(&duplicateFinder)) { if (definitions.Get(&duplicateFinder)) {
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr; return;
} }
nsIGlobalObject* sgo = GetScopeObject(); nsIGlobalObject* sgo = GetScopeObject();
if (!sgo) { if (!sgo) {
rv.Throw(NS_ERROR_UNEXPECTED); rv.Throw(NS_ERROR_UNEXPECTED);
return nullptr; return;
} }
JS::Rooted<JSObject*> global(aCx, sgo->GetGlobalJSObject()); JS::Rooted<JSObject*> global(aCx, sgo->GetGlobalJSObject());
@ -5820,7 +5821,7 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
HTMLElementBinding::GetProtoObject(aCx, global)); HTMLElementBinding::GetProtoObject(aCx, global));
if (!htmlProto) { if (!htmlProto) {
rv.Throw(NS_ERROR_OUT_OF_MEMORY); rv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr; return;
} }
int32_t namespaceID = kNameSpaceID_XHTML; int32_t namespaceID = kNameSpaceID_XHTML;
@ -5829,7 +5830,7 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
protoObject = JS_NewObject(aCx, nullptr, htmlProto, JS::NullPtr()); protoObject = JS_NewObject(aCx, nullptr, htmlProto, JS::NullPtr());
if (!protoObject) { if (!protoObject) {
rv.Throw(NS_ERROR_UNEXPECTED); rv.Throw(NS_ERROR_UNEXPECTED);
return nullptr; return;
} }
} else { } else {
// If a prototype is provided, we must check to ensure that it is from the // If a prototype is provided, we must check to ensure that it is from the
@ -5837,7 +5838,7 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
protoObject = aOptions.mPrototype; protoObject = aOptions.mPrototype;
if (JS_GetGlobalForObject(aCx, protoObject) != global) { if (JS_GetGlobalForObject(aCx, protoObject) != global) {
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr; return;
} }
// If PROTOTYPE is already an interface prototype object for any interface // If PROTOTYPE is already an interface prototype object for any interface
@ -5846,27 +5847,27 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
const js::Class* clasp = js::GetObjectClass(protoObject); const js::Class* clasp = js::GetObjectClass(protoObject);
if (IsDOMIfaceAndProtoClass(clasp)) { if (IsDOMIfaceAndProtoClass(clasp)) {
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr; return;
} }
JS::Rooted<JSPropertyDescriptor> descRoot(aCx); JS::Rooted<JSPropertyDescriptor> descRoot(aCx);
JS::MutableHandle<JSPropertyDescriptor> desc(&descRoot); JS::MutableHandle<JSPropertyDescriptor> desc(&descRoot);
if (!JS_GetPropertyDescriptor(aCx, protoObject, "constructor", desc)) { if (!JS_GetPropertyDescriptor(aCx, protoObject, "constructor", desc)) {
rv.Throw(NS_ERROR_UNEXPECTED); rv.Throw(NS_ERROR_UNEXPECTED);
return nullptr; return;
} }
// Check if non-configurable // Check if non-configurable
if (desc.isPermanent()) { if (desc.isPermanent()) {
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr; return;
} }
JS::Handle<JSObject*> svgProto( JS::Handle<JSObject*> svgProto(
SVGElementBinding::GetProtoObject(aCx, global)); SVGElementBinding::GetProtoObject(aCx, global));
if (!svgProto) { if (!svgProto) {
rv.Throw(NS_ERROR_OUT_OF_MEMORY); rv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr; return;
} }
JS::Rooted<JSObject*> protoProto(aCx, protoObject); JS::Rooted<JSObject*> protoProto(aCx, protoObject);
@ -5885,7 +5886,7 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
if (!JS_GetPrototype(aCx, protoProto, &protoProto)) { if (!JS_GetPrototype(aCx, protoProto, &protoProto)) {
rv.Throw(NS_ERROR_UNEXPECTED); rv.Throw(NS_ERROR_UNEXPECTED);
return nullptr; return;
} }
} }
} }
@ -5900,7 +5901,7 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
nsIParserService* ps = nsContentUtils::GetParserService(); nsIParserService* ps = nsContentUtils::GetParserService();
if (!ps) { if (!ps) {
rv.Throw(NS_ERROR_UNEXPECTED); rv.Throw(NS_ERROR_UNEXPECTED);
return nullptr; return;
} }
known = known =
@ -5914,13 +5915,13 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
// If BASE exists, then it cannot be an interface for a custom element. // If BASE exists, then it cannot be an interface for a custom element.
if (!known) { if (!known) {
rv.Throw(NS_ERROR_DOM_SYNTAX_ERR); rv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return nullptr; return;
} }
} else { } else {
// If NAMESPACE is SVG Namespace, set ERROR to InvalidName and stop. // If NAMESPACE is SVG Namespace, set ERROR to InvalidName and stop.
if (namespaceID == kNameSpaceID_SVG) { if (namespaceID == kNameSpaceID_SVG) {
rv.Throw(NS_ERROR_UNEXPECTED); rv.Throw(NS_ERROR_UNEXPECTED);
return nullptr; return;
} }
nameAtom = typeAtom; nameAtom = typeAtom;
@ -5929,7 +5930,8 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
nsAutoPtr<LifecycleCallbacks> callbacksHolder(new LifecycleCallbacks()); nsAutoPtr<LifecycleCallbacks> callbacksHolder(new LifecycleCallbacks());
JS::RootedValue rootedv(aCx, JS::ObjectValue(*protoObject)); JS::RootedValue rootedv(aCx, JS::ObjectValue(*protoObject));
if (!callbacksHolder->Init(aCx, rootedv)) { if (!callbacksHolder->Init(aCx, rootedv)) {
return nullptr; rv.Throw(NS_ERROR_FAILURE);
return;
} }
// Associate the definition with the custom element. // Associate the definition with the custom element.
@ -5988,8 +5990,12 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
JSFunction* constructor = JS_NewFunction(aCx, nsDocument::CustomElementConstructor, 0, JSFunction* constructor = JS_NewFunction(aCx, nsDocument::CustomElementConstructor, 0,
JSFUN_CONSTRUCTOR, JS::NullPtr(), JSFUN_CONSTRUCTOR, JS::NullPtr(),
NS_ConvertUTF16toUTF8(lcType).get()); NS_ConvertUTF16toUTF8(lcType).get());
JSObject* constructorObject = JS_GetFunctionObject(constructor); if (!constructor) {
return constructorObject; rv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
aRetval.set(JS_GetFunctionObject(constructor));
} }
void void

View File

@ -1226,9 +1226,10 @@ public:
// WebIDL bits // WebIDL bits
virtual mozilla::dom::DOMImplementation* virtual mozilla::dom::DOMImplementation*
GetImplementation(mozilla::ErrorResult& rv) MOZ_OVERRIDE; GetImplementation(mozilla::ErrorResult& rv) MOZ_OVERRIDE;
virtual JSObject* virtual void
RegisterElement(JSContext* aCx, const nsAString& aName, RegisterElement(JSContext* aCx, const nsAString& aName,
const mozilla::dom::ElementRegistrationOptions& aOptions, const mozilla::dom::ElementRegistrationOptions& aOptions,
JS::MutableHandle<JSObject*> aRetval,
mozilla::ErrorResult& rv) MOZ_OVERRIDE; mozilla::ErrorResult& rv) MOZ_OVERRIDE;
virtual mozilla::dom::StyleSheetList* StyleSheets() MOZ_OVERRIDE; virtual mozilla::dom::StyleSheetList* StyleSheets() MOZ_OVERRIDE;
virtual void SetSelectedStyleSheetSet(const nsAString& aSheetSet) MOZ_OVERRIDE; virtual void SetSelectedStyleSheetSet(const nsAString& aSheetSet) MOZ_OVERRIDE;

View File

@ -779,33 +779,33 @@ nsINode::SetUserData(const nsAString &aKey, nsIVariant *aData,
return NS_OK; return NS_OK;
} }
JS::Value void
nsINode::SetUserData(JSContext* aCx, const nsAString& aKey, nsINode::SetUserData(JSContext* aCx, const nsAString& aKey,
JS::Handle<JS::Value> aData, JS::Handle<JS::Value> aData,
nsIDOMUserDataHandler* aHandler, ErrorResult& aError) nsIDOMUserDataHandler* aHandler,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aError)
{ {
nsCOMPtr<nsIVariant> data; nsCOMPtr<nsIVariant> data;
JS::Rooted<JS::Value> dataVal(aCx, aData); aError = nsContentUtils::XPConnect()->JSValToVariant(aCx, aData, getter_AddRefs(data));
aError = nsContentUtils::XPConnect()->JSValToVariant(aCx, dataVal, getter_AddRefs(data));
if (aError.Failed()) { if (aError.Failed()) {
return JS::UndefinedValue(); return;
} }
nsCOMPtr<nsIVariant> oldData; nsCOMPtr<nsIVariant> oldData;
aError = SetUserData(aKey, data, aHandler, getter_AddRefs(oldData)); aError = SetUserData(aKey, data, aHandler, getter_AddRefs(oldData));
if (aError.Failed()) { if (aError.Failed()) {
return JS::UndefinedValue(); return;
} }
if (!oldData) { if (!oldData) {
return JS::NullValue(); aRetval.setNull();
return;
} }
JS::Rooted<JS::Value> result(aCx);
JSAutoCompartment ac(aCx, GetWrapper()); JSAutoCompartment ac(aCx, GetWrapper());
aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), oldData, aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), oldData,
&result); aRetval);
return result;
} }
nsIVariant* nsIVariant*
@ -820,19 +820,19 @@ nsINode::GetUserData(const nsAString& aKey)
return static_cast<nsIVariant*>(GetProperty(DOM_USER_DATA, key)); return static_cast<nsIVariant*>(GetProperty(DOM_USER_DATA, key));
} }
JS::Value void
nsINode::GetUserData(JSContext* aCx, const nsAString& aKey, ErrorResult& aError) nsINode::GetUserData(JSContext* aCx, const nsAString& aKey,
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError)
{ {
nsIVariant* data = GetUserData(aKey); nsIVariant* data = GetUserData(aKey);
if (!data) { if (!data) {
return JS::NullValue(); aRetval.setNull();
return;
} }
JS::Rooted<JS::Value> result(aCx);
JSAutoCompartment ac(aCx, GetWrapper()); JSAutoCompartment ac(aCx, GetWrapper());
aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), data, aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), data,
&result); aRetval);
return result;
} }
uint16_t uint16_t

View File

@ -3204,10 +3204,11 @@ nsObjectLoadingContent::GetContentDocument()
return sub_doc; return sub_doc;
} }
JS::Value void
nsObjectLoadingContent::LegacyCall(JSContext* aCx, nsObjectLoadingContent::LegacyCall(JSContext* aCx,
JS::Handle<JS::Value> aThisVal, JS::Handle<JS::Value> aThisVal,
const Sequence<JS::Value>& aArguments, const Sequence<JS::Value>& aArguments,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aRv) ErrorResult& aRv)
{ {
nsCOMPtr<nsIContent> thisContent = nsCOMPtr<nsIContent> thisContent =
@ -3221,12 +3222,12 @@ nsObjectLoadingContent::LegacyCall(JSContext* aCx,
// this is not an Xray situation by hand. // this is not an Xray situation by hand.
if (!JS_WrapObject(aCx, &obj)) { if (!JS_WrapObject(aCx, &obj)) {
aRv.Throw(NS_ERROR_UNEXPECTED); aRv.Throw(NS_ERROR_UNEXPECTED);
return JS::UndefinedValue(); return;
} }
if (nsDOMClassInfo::ObjectIsNativeWrapper(aCx, obj)) { if (nsDOMClassInfo::ObjectIsNativeWrapper(aCx, obj)) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE); aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return JS::UndefinedValue(); return;
} }
obj = thisContent->GetWrapper(); obj = thisContent->GetWrapper();
@ -3235,33 +3236,33 @@ nsObjectLoadingContent::LegacyCall(JSContext* aCx,
JS::AutoValueVector args(aCx); JS::AutoValueVector args(aCx);
if (!args.append(aArguments.Elements(), aArguments.Length())) { if (!args.append(aArguments.Elements(), aArguments.Length())) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY); aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return JS::UndefinedValue(); return;
} }
for (size_t i = 0; i < args.length(); i++) { for (size_t i = 0; i < args.length(); i++) {
if (!JS_WrapValue(aCx, args[i])) { if (!JS_WrapValue(aCx, args[i])) {
aRv.Throw(NS_ERROR_UNEXPECTED); aRv.Throw(NS_ERROR_UNEXPECTED);
return JS::UndefinedValue(); return;
} }
} }
JS::Rooted<JS::Value> thisVal(aCx, aThisVal); JS::Rooted<JS::Value> thisVal(aCx, aThisVal);
if (!JS_WrapValue(aCx, &thisVal)) { if (!JS_WrapValue(aCx, &thisVal)) {
aRv.Throw(NS_ERROR_UNEXPECTED); aRv.Throw(NS_ERROR_UNEXPECTED);
return JS::UndefinedValue(); return;
} }
nsRefPtr<nsNPAPIPluginInstance> pi; nsRefPtr<nsNPAPIPluginInstance> pi;
nsresult rv = ScriptRequestPluginInstance(aCx, getter_AddRefs(pi)); nsresult rv = ScriptRequestPluginInstance(aCx, getter_AddRefs(pi));
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
aRv.Throw(rv); aRv.Throw(rv);
return JS::UndefinedValue(); return;
} }
// if there's no plugin around for this object, throw. // if there's no plugin around for this object, throw.
if (!pi) { if (!pi) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE); aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return JS::UndefinedValue(); return;
} }
JS::Rooted<JSObject*> pi_obj(aCx); JS::Rooted<JSObject*> pi_obj(aCx);
@ -3270,23 +3271,21 @@ nsObjectLoadingContent::LegacyCall(JSContext* aCx,
rv = GetPluginJSObject(aCx, obj, pi, &pi_obj, &pi_proto); rv = GetPluginJSObject(aCx, obj, pi, &pi_obj, &pi_proto);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
aRv.Throw(rv); aRv.Throw(rv);
return JS::UndefinedValue(); return;
} }
if (!pi_obj) { if (!pi_obj) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE); aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return JS::UndefinedValue(); return;
} }
JS::Rooted<JS::Value> retval(aCx); bool ok = JS::Call(aCx, thisVal, pi_obj, args, aRetval);
bool ok = JS::Call(aCx, thisVal, pi_obj, args, &retval);
if (!ok) { if (!ok) {
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return JS::UndefinedValue(); return;
} }
Telemetry::Accumulate(Telemetry::PLUGIN_CALLED_DIRECTLY, true); Telemetry::Accumulate(Telemetry::PLUGIN_CALLED_DIRECTLY, true);
return retval;
} }
void void

View File

@ -214,9 +214,10 @@ class nsObjectLoadingContent : public nsImageLoadingContent
{ {
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
} }
JS::Value LegacyCall(JSContext* aCx, JS::Handle<JS::Value> aThisVal, void LegacyCall(JSContext* aCx, JS::Handle<JS::Value> aThisVal,
const mozilla::dom::Sequence<JS::Value>& aArguments, const mozilla::dom::Sequence<JS::Value>& aArguments,
mozilla::ErrorResult& aRv); JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aRv);
protected: protected:
/** /**

View File

@ -936,12 +936,14 @@ NS_IMETHODIMP
nsXMLHttpRequest::GetResponse(JSContext *aCx, JS::MutableHandle<JS::Value> aResult) nsXMLHttpRequest::GetResponse(JSContext *aCx, JS::MutableHandle<JS::Value> aResult)
{ {
ErrorResult rv; ErrorResult rv;
aResult.set(GetResponse(aCx, rv)); GetResponse(aCx, aResult, rv);
return rv.ErrorCode(); return rv.ErrorCode();
} }
JS::Value void
nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv) nsXMLHttpRequest::GetResponse(JSContext* aCx,
JS::MutableHandle<JS::Value> aResponse,
ErrorResult& aRv)
{ {
switch (mResponseType) { switch (mResponseType) {
case XML_HTTP_RESPONSE_TYPE_DEFAULT: case XML_HTTP_RESPONSE_TYPE_DEFAULT:
@ -951,14 +953,12 @@ nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv)
nsString str; nsString str;
aRv = GetResponseText(str); aRv = GetResponseText(str);
if (aRv.Failed()) { if (aRv.Failed()) {
return JSVAL_NULL; return;
} }
JS::Rooted<JS::Value> result(aCx); if (!xpc::StringToJsval(aCx, str, aResponse)) {
if (!xpc::StringToJsval(aCx, str, &result)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY); aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return JSVAL_NULL;
} }
return result; return;
} }
case XML_HTTP_RESPONSE_TYPE_ARRAYBUFFER: case XML_HTTP_RESPONSE_TYPE_ARRAYBUFFER:
@ -968,7 +968,8 @@ nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv)
mState & XML_HTTP_REQUEST_DONE) && mState & XML_HTTP_REQUEST_DONE) &&
!(mResponseType == XML_HTTP_RESPONSE_TYPE_CHUNKED_ARRAYBUFFER && !(mResponseType == XML_HTTP_RESPONSE_TYPE_CHUNKED_ARRAYBUFFER &&
mInLoadProgressEvent)) { mInLoadProgressEvent)) {
return JSVAL_NULL; aResponse.setNull();
return;
} }
if (!mResultArrayBuffer) { if (!mResultArrayBuffer) {
@ -977,17 +978,20 @@ nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv)
mResultArrayBuffer = mArrayBufferBuilder.getArrayBuffer(aCx); mResultArrayBuffer = mArrayBufferBuilder.getArrayBuffer(aCx);
if (!mResultArrayBuffer) { if (!mResultArrayBuffer) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY); aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return JSVAL_NULL; return;
} }
} }
return OBJECT_TO_JSVAL(mResultArrayBuffer); JS::ExposeObjectToActiveJS(mResultArrayBuffer);
aResponse.setObject(*mResultArrayBuffer);
return;
} }
case XML_HTTP_RESPONSE_TYPE_BLOB: case XML_HTTP_RESPONSE_TYPE_BLOB:
case XML_HTTP_RESPONSE_TYPE_MOZ_BLOB: case XML_HTTP_RESPONSE_TYPE_MOZ_BLOB:
{ {
if (!(mState & XML_HTTP_REQUEST_DONE)) { if (!(mState & XML_HTTP_REQUEST_DONE)) {
if (mResponseType != XML_HTTP_RESPONSE_TYPE_MOZ_BLOB) { if (mResponseType != XML_HTTP_RESPONSE_TYPE_MOZ_BLOB) {
return JSVAL_NULL; aResponse.setNull();
return;
} }
if (!mResponseBlob) { if (!mResponseBlob) {
@ -996,30 +1000,31 @@ nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv)
} }
if (!mResponseBlob) { if (!mResponseBlob) {
return JSVAL_NULL; aResponse.setNull();
return;
} }
JS::Rooted<JS::Value> result(aCx); aRv = nsContentUtils::WrapNative(aCx, mResponseBlob, aResponse);
aRv = nsContentUtils::WrapNative(aCx, mResponseBlob, &result); return;
return result;
} }
case XML_HTTP_RESPONSE_TYPE_DOCUMENT: case XML_HTTP_RESPONSE_TYPE_DOCUMENT:
{ {
if (!(mState & XML_HTTP_REQUEST_DONE) || !mResponseXML) { if (!(mState & XML_HTTP_REQUEST_DONE) || !mResponseXML) {
return JSVAL_NULL; aResponse.setNull();
return;
} }
JS::Rooted<JS::Value> result(aCx); aRv = nsContentUtils::WrapNative(aCx, mResponseXML, aResponse);
aRv = nsContentUtils::WrapNative(aCx, mResponseXML, &result); return;
return result;
} }
case XML_HTTP_RESPONSE_TYPE_JSON: case XML_HTTP_RESPONSE_TYPE_JSON:
{ {
if (!(mState & XML_HTTP_REQUEST_DONE)) { if (!(mState & XML_HTTP_REQUEST_DONE)) {
return JSVAL_NULL; aResponse.setNull();
return;
} }
if (mResultJSON == JSVAL_VOID) { if (mResultJSON.isUndefined()) {
aRv = CreateResponseParsedJSON(aCx); aRv = CreateResponseParsedJSON(aCx);
mResponseText.Truncate(); mResponseText.Truncate();
if (aRv.Failed()) { if (aRv.Failed()) {
@ -1028,16 +1033,18 @@ nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv)
// It would be nice to log the error to the console. That's hard to // It would be nice to log the error to the console. That's hard to
// do without calling window.onerror as a side effect, though. // do without calling window.onerror as a side effect, though.
JS_ClearPendingException(aCx); JS_ClearPendingException(aCx);
mResultJSON = JSVAL_NULL; mResultJSON.setNull();
} }
} }
return mResultJSON; JS::ExposeValueToActiveJS(mResultJSON);
aResponse.set(mResultJSON);
return;
} }
default: default:
NS_ERROR("Should not happen"); NS_ERROR("Should not happen");
} }
return JSVAL_NULL; aResponse.setNull();
} }
bool bool
@ -3757,10 +3764,12 @@ nsXMLHttpRequest::GetInterface(const nsIID & aIID, void **aResult)
return QueryInterface(aIID, aResult); return QueryInterface(aIID, aResult);
} }
JS::Value void
nsXMLHttpRequest::GetInterface(JSContext* aCx, nsIJSID* aIID, ErrorResult& aRv) nsXMLHttpRequest::GetInterface(JSContext* aCx, nsIJSID* aIID,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aRv)
{ {
return dom::GetInterface(aCx, this, aIID, aRv); dom::GetInterface(aCx, this, aIID, aRetval, aRv);
} }
nsXMLHttpRequestUpload* nsXMLHttpRequestUpload*

View File

@ -494,7 +494,8 @@ public:
return XMLHttpRequestResponseType(mResponseType); return XMLHttpRequestResponseType(mResponseType);
} }
void SetResponseType(XMLHttpRequestResponseType aType, ErrorResult& aRv); void SetResponseType(XMLHttpRequestResponseType aType, ErrorResult& aRv);
JS::Value GetResponse(JSContext* aCx, ErrorResult& aRv); void GetResponse(JSContext* aCx, JS::MutableHandle<JS::Value> aResponse,
ErrorResult& aRv);
void GetResponseText(nsString& aResponseText, ErrorResult& aRv); void GetResponseText(nsString& aResponseText, ErrorResult& aRv);
nsIDocument* GetResponseXML(ErrorResult& aRv); nsIDocument* GetResponseXML(ErrorResult& aRv);
@ -510,7 +511,8 @@ public:
} }
// We need a GetInterface callable from JS for chrome JS // We need a GetInterface callable from JS for chrome JS
JS::Value GetInterface(JSContext* aCx, nsIJSID* aIID, ErrorResult& aRv); void GetInterface(JSContext* aCx, nsIJSID* aIID,
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aRv);
// This creates a trusted readystatechange event, which is not cancelable and // This creates a trusted readystatechange event, which is not cancelable and
// doesn't bubble. // doesn't bubble.

View File

@ -64,7 +64,11 @@ var asciiFile = createFileWithData(testASCIIData);
var binaryFile = createFileWithData(testBinaryData); var binaryFile = createFileWithData(testBinaryData);
var fileList = document.getElementById('fileList'); var fileList = document.getElementById('fileList');
SpecialPowers.wrap(fileList).value = "/none/existing/path/fileAPI/testing"; SpecialPowers.Cu.import("resource://gre/modules/FileUtils.jsm", window);
var FU = SpecialPowers.wrap(FileUtils);
var fakeFile = FU.getDir("TmpD", [], false);
fakeFile.append("FileThatDoesntExist.abc");
SpecialPowers.wrap(fileList).value = fakeFile.path;
var nonExistingFile = fileList.files[0]; var nonExistingFile = fileList.files[0];
// Test that plain reading works and fires events as expected, both // Test that plain reading works and fires events as expected, both
@ -356,14 +360,21 @@ expectedTestCount++;
// Test reading from nonexistent files // Test reading from nonexistent files
r = new FileReader(); r = new FileReader();
var didThrow = false; var didThrow = false;
r.onerror = function (event) {
is(event.target.readyState, FileReader.DONE, "should be DONE while firing onerror");
is(event.target.error.name, "NotFoundError", "error set to NotFoundError for nonexistent files");
is(event.target.result, null, "file data should be null on aborted reads");
testHasRun();
};
try { try {
r.readAsDataURL(nonExistingFile); r.readAsDataURL(nonExistingFile);
expectedTestCount++;
} catch(ex) { } catch(ex) {
didThrow = true; didThrow = true;
} }
// Once this test passes, we should test that onerror gets called and // Once this test passes, we should test that onerror gets called and
// that the FileReader object is in the right state during that call. // that the FileReader object is in the right state during that call.
todo(!didThrow, "shouldn't throw when opening nonexistent file, should fire error instead"); is(didThrow, false, "shouldn't throw when opening nonexistent file, should fire error instead");
function getLoadHandler(expectedResult, expectedLength, testName) { function getLoadHandler(expectedResult, expectedLength, testName) {

View File

@ -1267,8 +1267,9 @@ CanvasRenderingContext2D::SetTransform(double m11, double m12,
mTarget->SetTransform(matrix); mTarget->SetTransform(matrix);
} }
JSObject* static void
MatrixToJSObject(JSContext* cx, const Matrix& matrix, ErrorResult& error) MatrixToJSObject(JSContext* cx, const Matrix& matrix,
JS::MutableHandle<JSObject*> result, ErrorResult& error)
{ {
double elts[6] = { matrix._11, matrix._12, double elts[6] = { matrix._11, matrix._12,
matrix._21, matrix._22, matrix._21, matrix._22,
@ -1278,10 +1279,9 @@ MatrixToJSObject(JSContext* cx, const Matrix& matrix, ErrorResult& error)
JS::Rooted<JS::Value> val(cx); JS::Rooted<JS::Value> val(cx);
if (!ToJSValue(cx, elts, &val)) { if (!ToJSValue(cx, elts, &val)) {
error.Throw(NS_ERROR_OUT_OF_MEMORY); error.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr; } else {
result.set(&val.toObject());
} }
return &val.toObject();
} }
static bool static bool
@ -1334,11 +1334,13 @@ CanvasRenderingContext2D::SetMozCurrentTransform(JSContext* cx,
} }
} }
JSObject* void
CanvasRenderingContext2D::GetMozCurrentTransform(JSContext* cx, CanvasRenderingContext2D::GetMozCurrentTransform(JSContext* cx,
JS::MutableHandle<JSObject*> result,
ErrorResult& error) const ErrorResult& error) const
{ {
return MatrixToJSObject(cx, mTarget ? mTarget->GetTransform() : Matrix(), error); MatrixToJSObject(cx, mTarget ? mTarget->GetTransform() : Matrix(),
result, error);
} }
void void
@ -1361,12 +1363,14 @@ CanvasRenderingContext2D::SetMozCurrentTransformInverse(JSContext* cx,
} }
} }
JSObject* void
CanvasRenderingContext2D::GetMozCurrentTransformInverse(JSContext* cx, CanvasRenderingContext2D::GetMozCurrentTransformInverse(JSContext* cx,
JS::MutableHandle<JSObject*> result,
ErrorResult& error) const ErrorResult& error) const
{ {
if (!mTarget) { if (!mTarget) {
return MatrixToJSObject(cx, Matrix(), error); MatrixToJSObject(cx, Matrix(), result, error);
return;
} }
Matrix ctm = mTarget->GetTransform(); Matrix ctm = mTarget->GetTransform();
@ -1376,7 +1380,7 @@ CanvasRenderingContext2D::GetMozCurrentTransformInverse(JSContext* cx,
ctm = Matrix(NaN, NaN, NaN, NaN, NaN, NaN); ctm = Matrix(NaN, NaN, NaN, NaN, NaN, NaN);
} }
return MatrixToJSObject(cx, ctm, error); MatrixToJSObject(cx, ctm, result, error);
} }
// //
@ -3111,10 +3115,12 @@ CanvasRenderingContext2D::SetMozDash(JSContext* cx,
} }
} }
JS::Value void
CanvasRenderingContext2D::GetMozDash(JSContext* cx, ErrorResult& error) CanvasRenderingContext2D::GetMozDash(JSContext* cx,
JS::MutableHandle<JS::Value> retval,
ErrorResult& error)
{ {
return DashArrayToJSVal(CurrentState().dash, cx, error); DashArrayToJSVal(CurrentState().dash, cx, retval, error);
} }
void void

View File

@ -388,19 +388,22 @@ public:
void Arc(double x, double y, double radius, double startAngle, void Arc(double x, double y, double radius, double startAngle,
double endAngle, bool anticlockwise, mozilla::ErrorResult& error); double endAngle, bool anticlockwise, mozilla::ErrorResult& error);
JSObject* GetMozCurrentTransform(JSContext* cx, void GetMozCurrentTransform(JSContext* cx,
mozilla::ErrorResult& error) const; JS::MutableHandle<JSObject*> result,
mozilla::ErrorResult& error) const;
void SetMozCurrentTransform(JSContext* cx, void SetMozCurrentTransform(JSContext* cx,
JS::Handle<JSObject*> currentTransform, JS::Handle<JSObject*> currentTransform,
mozilla::ErrorResult& error); mozilla::ErrorResult& error);
JSObject* GetMozCurrentTransformInverse(JSContext* cx, void GetMozCurrentTransformInverse(JSContext* cx,
mozilla::ErrorResult& error) const; JS::MutableHandle<JSObject*> result,
mozilla::ErrorResult& error) const;
void SetMozCurrentTransformInverse(JSContext* cx, void SetMozCurrentTransformInverse(JSContext* cx,
JS::Handle<JSObject*> currentTransform, JS::Handle<JSObject*> currentTransform,
mozilla::ErrorResult& error); mozilla::ErrorResult& error);
void GetFillRule(nsAString& fillRule); void GetFillRule(nsAString& fillRule);
void SetFillRule(const nsAString& fillRule); void SetFillRule(const nsAString& fillRule);
JS::Value GetMozDash(JSContext* cx, mozilla::ErrorResult& error); void GetMozDash(JSContext* cx, JS::MutableHandle<JS::Value> retval,
mozilla::ErrorResult& error);
void SetMozDash(JSContext* cx, const JS::Value& mozDash, void SetMozDash(JSContext* cx, const JS::Value& mozDash,
mozilla::ErrorResult& error); mozilla::ErrorResult& error);

View File

@ -151,18 +151,20 @@ JSValToDashArray(JSContext* cx, const JS::Value& patternArray,
} }
template<typename T> template<typename T>
JS::Value void
DashArrayToJSVal(FallibleTArray<T>& dashes, DashArrayToJSVal(FallibleTArray<T>& dashes,
JSContext* cx, mozilla::ErrorResult& rv) JSContext* cx,
JS::MutableHandle<JS::Value> retval,
mozilla::ErrorResult& rv)
{ {
if (dashes.IsEmpty()) { if (dashes.IsEmpty()) {
return JS::NullValue(); retval.setNull();
return;
} }
JS::Rooted<JS::Value> val(cx); JS::Rooted<JS::Value> val(cx);
if (!mozilla::dom::ToJSValue(cx, dashes, &val)) { if (!mozilla::dom::ToJSValue(cx, dashes, retval)) {
rv.Throw(NS_ERROR_OUT_OF_MEMORY); rv.Throw(NS_ERROR_OUT_OF_MEMORY);
} }
return val;
} }
} }

View File

@ -61,9 +61,9 @@ public:
{ {
return mHeight; return mHeight;
} }
JSObject* Data(JSContext* cx) const void GetData(JSContext* cx, JS::MutableHandle<JSObject*> aData) const
{ {
return GetDataObject(); aData.set(GetDataObject());
} }
JSObject* GetDataObject() const JSObject* GetDataObject() const
{ {

View File

@ -285,7 +285,9 @@ public:
void GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval); void GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval);
bool IsContextLost() const { return mContextStatus != ContextNotLost; } bool IsContextLost() const { return mContextStatus != ContextNotLost; }
void GetSupportedExtensions(JSContext *cx, dom::Nullable< nsTArray<nsString> > &retval); void GetSupportedExtensions(JSContext *cx, dom::Nullable< nsTArray<nsString> > &retval);
JSObject* GetExtension(JSContext* cx, const nsAString& aName, ErrorResult& rv); void GetExtension(JSContext* cx, const nsAString& aName,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& rv);
void ActiveTexture(GLenum texture); void ActiveTexture(GLenum texture);
void AttachShader(WebGLProgram* program, WebGLShader* shader); void AttachShader(WebGLProgram* program, WebGLShader* shader);
void BindAttribLocation(WebGLProgram* program, GLuint location, void BindAttribLocation(WebGLProgram* program, GLuint location,
@ -357,9 +359,10 @@ public:
dom::Nullable< nsTArray<WebGLShader*> > &retval); dom::Nullable< nsTArray<WebGLShader*> > &retval);
GLint GetAttribLocation(WebGLProgram* prog, const nsAString& name); GLint GetAttribLocation(WebGLProgram* prog, const nsAString& name);
JS::Value GetBufferParameter(GLenum target, GLenum pname); JS::Value GetBufferParameter(GLenum target, GLenum pname);
JS::Value GetBufferParameter(JSContext* /* unused */, GLenum target, void GetBufferParameter(JSContext* /* unused */, GLenum target,
GLenum pname) { GLenum pname,
return GetBufferParameter(target, pname); JS::MutableHandle<JS::Value> retval) {
retval.set(GetBufferParameter(target, pname));
} }
GLenum GetError(); GLenum GetError();
JS::Value GetFramebufferAttachmentParameter(JSContext* cx, JS::Value GetFramebufferAttachmentParameter(JSContext* cx,
@ -367,22 +370,34 @@ public:
GLenum attachment, GLenum attachment,
GLenum pname, GLenum pname,
ErrorResult& rv); ErrorResult& rv);
void GetFramebufferAttachmentParameter(JSContext* cx,
GLenum target,
GLenum attachment,
GLenum pname,
JS::MutableHandle<JS::Value> retval,
ErrorResult& rv) {
retval.set(GetFramebufferAttachmentParameter(cx, target, attachment,
pname, rv));
}
JS::Value GetProgramParameter(WebGLProgram *prog, GLenum pname); JS::Value GetProgramParameter(WebGLProgram *prog, GLenum pname);
JS::Value GetProgramParameter(JSContext* /* unused */, WebGLProgram *prog, void GetProgramParameter(JSContext* /* unused */, WebGLProgram *prog,
GLenum pname) { GLenum pname,
return GetProgramParameter(prog, pname); JS::MutableHandle<JS::Value> retval) {
retval.set(GetProgramParameter(prog, pname));
} }
void GetProgramInfoLog(WebGLProgram *prog, nsACString& retval); void GetProgramInfoLog(WebGLProgram *prog, nsACString& retval);
void GetProgramInfoLog(WebGLProgram *prog, nsAString& retval); void GetProgramInfoLog(WebGLProgram *prog, nsAString& retval);
JS::Value GetRenderbufferParameter(GLenum target, GLenum pname); JS::Value GetRenderbufferParameter(GLenum target, GLenum pname);
JS::Value GetRenderbufferParameter(JSContext* /* unused */, void GetRenderbufferParameter(JSContext* /* unused */,
GLenum target, GLenum pname) { GLenum target, GLenum pname,
return GetRenderbufferParameter(target, pname); JS::MutableHandle<JS::Value> retval) {
retval.set(GetRenderbufferParameter(target, pname));
} }
JS::Value GetShaderParameter(WebGLShader *shader, GLenum pname); JS::Value GetShaderParameter(WebGLShader *shader, GLenum pname);
JS::Value GetShaderParameter(JSContext* /* unused */, WebGLShader *shader, void GetShaderParameter(JSContext* /* unused */, WebGLShader *shader,
GLenum pname) { GLenum pname,
return GetShaderParameter(shader, pname); JS::MutableHandle<JS::Value> retval) {
retval.set(GetShaderParameter(shader, pname));
} }
already_AddRefed<WebGLShaderPrecisionFormat> already_AddRefed<WebGLShaderPrecisionFormat>
GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype); GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
@ -391,12 +406,18 @@ public:
void GetShaderSource(WebGLShader *shader, nsAString& retval); void GetShaderSource(WebGLShader *shader, nsAString& retval);
void GetShaderTranslatedSource(WebGLShader *shader, nsAString& retval); void GetShaderTranslatedSource(WebGLShader *shader, nsAString& retval);
JS::Value GetTexParameter(GLenum target, GLenum pname); JS::Value GetTexParameter(GLenum target, GLenum pname);
JS::Value GetTexParameter(JSContext * /* unused */, GLenum target, void GetTexParameter(JSContext * /* unused */, GLenum target,
GLenum pname) { GLenum pname,
return GetTexParameter(target, pname); JS::MutableHandle<JS::Value> retval) {
retval.set(GetTexParameter(target, pname));
} }
JS::Value GetUniform(JSContext* cx, WebGLProgram *prog, JS::Value GetUniform(JSContext* cx, WebGLProgram *prog,
WebGLUniformLocation *location); WebGLUniformLocation *location);
void GetUniform(JSContext* cx, WebGLProgram *prog,
WebGLUniformLocation *location,
JS::MutableHandle<JS::Value> retval) {
retval.set(GetUniform(cx, prog, location));
}
already_AddRefed<WebGLUniformLocation> already_AddRefed<WebGLUniformLocation>
GetUniformLocation(WebGLProgram *prog, const nsAString& name); GetUniformLocation(WebGLProgram *prog, const nsAString& name);
void Hint(GLenum target, GLenum mode); void Hint(GLenum target, GLenum mode);
@ -691,6 +712,10 @@ public:
bool IsQuery(WebGLQuery *query); bool IsQuery(WebGLQuery *query);
already_AddRefed<WebGLQuery> GetQuery(GLenum target, GLenum pname); already_AddRefed<WebGLQuery> GetQuery(GLenum target, GLenum pname);
JS::Value GetQueryObject(JSContext* cx, WebGLQuery *query, GLenum pname); JS::Value GetQueryObject(JSContext* cx, WebGLQuery *query, GLenum pname);
void GetQueryObject(JSContext* cx, WebGLQuery *query, GLenum pname,
JS::MutableHandle<JS::Value> retval) {
retval.set(GetQueryObject(cx, query, pname));
}
private: private:
// ANY_SAMPLES_PASSED(_CONSERVATIVE) slot // ANY_SAMPLES_PASSED(_CONSERVATIVE) slot
@ -740,7 +765,12 @@ public:
void Disable(GLenum cap); void Disable(GLenum cap);
void Enable(GLenum cap); void Enable(GLenum cap);
JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv); JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv);
JS::Value GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index); void GetParameter(JSContext* cx, GLenum pname,
JS::MutableHandle<JS::Value> retval, ErrorResult& rv) {
retval.set(GetParameter(cx, pname, rv));
}
void GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index,
JS::MutableHandle<JS::Value> retval);
bool IsEnabled(GLenum cap); bool IsEnabled(GLenum cap);
private: private:
@ -766,6 +796,11 @@ public:
JS::Value GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname, JS::Value GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
ErrorResult& rv); ErrorResult& rv);
void GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
JS::MutableHandle<JS::Value> retval,
ErrorResult& rv) {
retval.set(GetVertexAttrib(cx, index, pname, rv));
}
WebGLsizeiptr GetVertexAttribOffset(GLuint index, GLenum pname); WebGLsizeiptr GetVertexAttribOffset(GLuint index, GLenum pname);
void VertexAttrib1f(GLuint index, GLfloat x0); void VertexAttrib1f(GLuint index, GLfloat x0);

View File

@ -182,11 +182,15 @@ CompareWebGLExtensionName(const nsACString& name, const char *other)
return name.Equals(other, nsCaseInsensitiveCStringComparator()); return name.Equals(other, nsCaseInsensitiveCStringComparator());
} }
JSObject* void
WebGLContext::GetExtension(JSContext *cx, const nsAString& aName, ErrorResult& rv) WebGLContext::GetExtension(JSContext *cx, const nsAString& aName,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& rv)
{ {
if (IsContextLost()) if (IsContextLost()) {
return nullptr; aRetval.set(nullptr);
return;
}
NS_LossyConvertUTF16toASCII name(aName); NS_LossyConvertUTF16toASCII name(aName);
@ -235,12 +239,14 @@ WebGLContext::GetExtension(JSContext *cx, const nsAString& aName, ErrorResult& r
} }
if (ext == WebGLExtensionID::Unknown) { if (ext == WebGLExtensionID::Unknown) {
return nullptr; aRetval.set(nullptr);
return;
} }
// step 2: check if the extension is supported // step 2: check if the extension is supported
if (!IsExtensionSupported(cx, ext)) { if (!IsExtensionSupported(cx, ext)) {
return nullptr; aRetval.set(nullptr);
return;
} }
// step 3: if the extension hadn't been previously been created, create it now, thus enabling it // step 3: if the extension hadn't been previously been created, create it now, thus enabling it
@ -248,7 +254,7 @@ WebGLContext::GetExtension(JSContext *cx, const nsAString& aName, ErrorResult& r
EnableExtension(ext); EnableExtension(ext);
} }
return WebGLObjectAsJSObject(cx, mExtensions[ext].get(), rv); aRetval.set(WebGLObjectAsJSObject(cx, mExtensions[ext].get(), rv));
} }
void void

View File

@ -454,11 +454,14 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
return JS::NullValue(); return JS::NullValue();
} }
JS::Value void
WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index) WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index,
JS::MutableHandle<JS::Value> retval)
{ {
if (IsContextLost()) if (IsContextLost()) {
return JS::NullValue(); retval.setNull();
return;
}
MakeContextCurrent(); MakeContextCurrent();
@ -467,9 +470,11 @@ WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index)
{ {
if (index >= mGLMaxTransformFeedbackSeparateAttribs) { if (index >= mGLMaxTransformFeedbackSeparateAttribs) {
ErrorInvalidValue("getParameterIndexed: index should be less than MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", index); ErrorInvalidValue("getParameterIndexed: index should be less than MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", index);
return JS::NullValue(); retval.setNull();
return;
} }
return JS::NullValue(); // See bug 903594 retval.setNull(); // See bug 903594
return;
} }
default: default:
@ -477,7 +482,7 @@ WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index)
} }
ErrorInvalidEnumInfo("getParameterIndexed: parameter", pname); ErrorInvalidEnumInfo("getParameterIndexed: parameter", pname);
return JS::NullValue(); retval.setNull();
} }
bool bool

View File

@ -529,7 +529,8 @@ public:
return mAudioCaptured; return mAudioCaptured;
} }
JSObject* MozGetMetadata(JSContext* aCx, ErrorResult& aRv); void MozGetMetadata(JSContext* aCx, JS::MutableHandle<JSObject*> aResult,
ErrorResult& aRv);
double MozFragmentEnd(); double MozFragmentEnd();

View File

@ -1673,18 +1673,20 @@ HTMLMediaElement::BuildObjectFromTags(nsCStringHashKey::KeyType aKey,
return PL_DHASH_NEXT; return PL_DHASH_NEXT;
} }
JSObject* void
HTMLMediaElement::MozGetMetadata(JSContext* cx, ErrorResult& aRv) HTMLMediaElement::MozGetMetadata(JSContext* cx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{ {
if (mReadyState < nsIDOMHTMLMediaElement::HAVE_METADATA) { if (mReadyState < nsIDOMHTMLMediaElement::HAVE_METADATA) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr; return;
} }
JS::Rooted<JSObject*> tags(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr())); JS::Rooted<JSObject*> tags(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));
if (!tags) { if (!tags) {
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return nullptr; return;
} }
if (mTags) { if (mTags) {
MetadataIterCx iter = {cx, tags, false}; MetadataIterCx iter = {cx, tags, false};
@ -1692,19 +1694,19 @@ HTMLMediaElement::MozGetMetadata(JSContext* cx, ErrorResult& aRv)
if (iter.error) { if (iter.error) {
NS_WARNING("couldn't create metadata object!"); NS_WARNING("couldn't create metadata object!");
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return nullptr; return;
} }
} }
return tags; aRetval.set(tags);
} }
NS_IMETHODIMP NS_IMETHODIMP
HTMLMediaElement::MozGetMetadata(JSContext* cx, JS::MutableHandle<JS::Value> aValue) HTMLMediaElement::MozGetMetadata(JSContext* cx, JS::MutableHandle<JS::Value> aValue)
{ {
ErrorResult rv; ErrorResult rv;
JS::Rooted<JSObject*> obj(cx);
JSObject* obj = MozGetMetadata(cx, rv); MozGetMetadata(cx, &obj, rv);
if (!rv.Failed()) { if (!rv.Failed()) {
MOZ_ASSERT(obj); MOZ_ASSERT(obj);
aValue.setObject(*obj); aValue.setObject(*obj);

View File

@ -426,7 +426,8 @@ PropertyNodeList::GetValues(JSContext* aCx, nsTArray<JS::Value >& aResult,
JSAutoCompartment ac(aCx, wrapper); JSAutoCompartment ac(aCx, wrapper);
uint32_t length = mElements.Length(); uint32_t length = mElements.Length();
for (uint32_t i = 0; i < length; ++i) { for (uint32_t i = 0; i < length; ++i) {
JS::Value v = mElements.ElementAt(i)->GetItemValue(aCx, wrapper, aError); JS::Rooted<JS::Value> v(aCx);
mElements.ElementAt(i)->GetItemValue(aCx, wrapper, &v, aError);
if (aError.Failed()) { if (aError.Failed()) {
return; return;
} }

View File

@ -3041,33 +3041,31 @@ nsGenericHTMLFormElementWithState::NodeInfoChanged(nsINodeInfo* aOldNodeInfo)
mStateKey.SetIsVoid(true); mStateKey.SetIsVoid(true);
} }
JS::Value void
nsGenericHTMLElement::GetItemValue(JSContext* aCx, JSObject* aScope, nsGenericHTMLElement::GetItemValue(JSContext* aCx, JSObject* aScope,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aError) ErrorResult& aError)
{ {
JS::Rooted<JSObject*> scope(aCx, aScope); JS::Rooted<JSObject*> scope(aCx, aScope);
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop)) { if (!HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop)) {
return JS::NullValue(); aRetval.setNull();
return;
} }
if (ItemScope()) { if (ItemScope()) {
JS::Rooted<JS::Value> v(aCx); JS::Rooted<JS::Value> v(aCx);
JSAutoCompartment ac(aCx, scope); JSAutoCompartment ac(aCx, scope);
if (!mozilla::dom::WrapObject(aCx, this, &v)) { if (!mozilla::dom::WrapObject(aCx, this, aRetval)) {
aError.Throw(NS_ERROR_FAILURE); aError.Throw(NS_ERROR_FAILURE);
return JS::UndefinedValue();
} }
return v; return;
} }
nsString string; nsString string;
GetItemValueText(string); GetItemValueText(string);
JS::Rooted<JS::Value> v(aCx); if (!xpc::NonVoidStringToJsval(aCx, string, aRetval)) {
if (!xpc::NonVoidStringToJsval(aCx, string, &v)) {
aError.Throw(NS_ERROR_FAILURE); aError.Throw(NS_ERROR_FAILURE);
return JS::UndefinedValue();
} }
return v;
} }
NS_IMETHODIMP NS_IMETHODIMP

View File

@ -124,11 +124,13 @@ public:
return GetTokenList(nsGkAtoms::itemprop); return GetTokenList(nsGkAtoms::itemprop);
} }
mozilla::dom::HTMLPropertiesCollection* Properties(); mozilla::dom::HTMLPropertiesCollection* Properties();
JS::Value GetItemValue(JSContext* aCx, JSObject* aScope, void GetItemValue(JSContext* aCx, JSObject* aScope,
mozilla::ErrorResult& aError); JS::MutableHandle<JS::Value> aRetval,
JS::Value GetItemValue(JSContext* aCx, mozilla::ErrorResult& aError) mozilla::ErrorResult& aError);
void GetItemValue(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError)
{ {
return GetItemValue(aCx, GetWrapperPreserveColor(), aError); GetItemValue(aCx, GetWrapperPreserveColor(), aRetval, aError);
} }
void SetItemValue(JSContext* aCx, JS::Value aValue, void SetItemValue(JSContext* aCx, JS::Value aValue,
mozilla::ErrorResult& aError); mozilla::ErrorResult& aError);

View File

@ -2244,15 +2244,17 @@ nsHTMLDocument::ResolveName(const nsAString& aName, nsWrapperCache **aCache)
return nullptr; return nullptr;
} }
JSObject* void
nsHTMLDocument::NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound, nsHTMLDocument::NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& rv) ErrorResult& rv)
{ {
nsWrapperCache* cache; nsWrapperCache* cache;
nsISupports* supp = ResolveName(aName, &cache); nsISupports* supp = ResolveName(aName, &cache);
if (!supp) { if (!supp) {
aFound = false; aFound = false;
return nullptr; aRetval.set(nullptr);
return;
} }
JS::Rooted<JS::Value> val(cx); JS::Rooted<JS::Value> val(cx);
@ -2260,10 +2262,10 @@ nsHTMLDocument::NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
// here? // here?
if (!dom::WrapObject(cx, supp, cache, nullptr, &val)) { if (!dom::WrapObject(cx, supp, cache, nullptr, &val)) {
rv.Throw(NS_ERROR_OUT_OF_MEMORY); rv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr; return;
} }
aFound = true; aFound = true;
return &val.toObject(); aRetval.set(&val.toObject());
} }
bool bool

View File

@ -174,8 +174,9 @@ public:
void SetDomain(const nsAString& aDomain, mozilla::ErrorResult& rv); void SetDomain(const nsAString& aDomain, mozilla::ErrorResult& rv);
void GetCookie(nsAString& aCookie, mozilla::ErrorResult& rv); void GetCookie(nsAString& aCookie, mozilla::ErrorResult& rv);
void SetCookie(const nsAString& aCookie, mozilla::ErrorResult& rv); void SetCookie(const nsAString& aCookie, mozilla::ErrorResult& rv);
JSObject* NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound, void NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
mozilla::ErrorResult& rv); JS::MutableHandle<JSObject*> aRetval,
mozilla::ErrorResult& rv);
bool NameIsEnumerable(const nsAString& aName); bool NameIsEnumerable(const nsAString& aName);
void GetSupportedNames(unsigned, nsTArray<nsString>& aNames); void GetSupportedNames(unsigned, nsTArray<nsString>& aNames);
nsGenericHTMLElement *GetBody(); nsGenericHTMLElement *GetBody();

View File

@ -99,8 +99,10 @@ MediaKeyMessageEvent::Constructor(const GlobalObject& aGlobal,
return e.forget(); return e.forget();
} }
JSObject* void
MediaKeyMessageEvent::GetMessage(JSContext* cx, ErrorResult& aRv) MediaKeyMessageEvent::GetMessage(JSContext* cx,
JS::MutableHandle<JSObject*> aMessage,
ErrorResult& aRv)
{ {
if (!mMessage) { if (!mMessage) {
mMessage = Uint8Array::Create(cx, mMessage = Uint8Array::Create(cx,
@ -109,12 +111,12 @@ MediaKeyMessageEvent::GetMessage(JSContext* cx, ErrorResult& aRv)
mRawMessage.Elements()); mRawMessage.Elements());
if (!mMessage) { if (!mMessage) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY); aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr; return;
} }
mRawMessage.Clear(); mRawMessage.Clear();
} }
JS::ExposeObjectToActiveJS(mMessage); JS::ExposeObjectToActiveJS(mMessage);
return mMessage; aMessage.set(mMessage);
} }
void void

View File

@ -50,7 +50,9 @@ public:
const MediaKeyMessageEventInit& aEventInitDict, const MediaKeyMessageEventInit& aEventInitDict,
ErrorResult& aRv); ErrorResult& aRv);
JSObject* GetMessage(JSContext* cx, ErrorResult& aRv); void GetMessage(JSContext* cx,
JS::MutableHandle<JSObject*> aMessage,
ErrorResult& aRv);
void GetDestinationURL(nsString& aRetVal) const; void GetDestinationURL(nsString& aRetVal) const;

View File

@ -94,8 +94,10 @@ MediaKeyNeededEvent::GetInitDataType(nsString& aRetVal) const
aRetVal = mInitDataType; aRetVal = mInitDataType;
} }
JSObject* void
MediaKeyNeededEvent::GetInitData(JSContext* cx, ErrorResult& aRv) MediaKeyNeededEvent::GetInitData(JSContext* cx,
JS::MutableHandle<JSObject*> aData,
ErrorResult& aRv)
{ {
if (mRawInitData.Length()) { if (mRawInitData.Length()) {
mInitData = Uint8Array::Create(cx, mInitData = Uint8Array::Create(cx,
@ -104,14 +106,14 @@ MediaKeyNeededEvent::GetInitData(JSContext* cx, ErrorResult& aRv)
mRawInitData.Elements()); mRawInitData.Elements());
if (!mInitData) { if (!mInitData) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY); aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr; return;
} }
mRawInitData.Clear(); mRawInitData.Clear();
} }
if (mInitData) { if (mInitData) {
JS::ExposeObjectToActiveJS(mInitData); JS::ExposeObjectToActiveJS(mInitData);
} }
return mInitData; aData.set(mInitData);
} }
} // namespace dom } // namespace dom

View File

@ -51,7 +51,9 @@ public:
void GetInitDataType(nsString& aRetVal) const; void GetInitDataType(nsString& aRetVal) const;
JSObject* GetInitData(JSContext* cx, ErrorResult& aRv); void GetInitData(JSContext* cx,
JS::MutableHandle<JSObject*> aData,
ErrorResult& aRv);
private: private:
nsTArray<uint8_t> mRawInitData; nsTArray<uint8_t> mRawInitData;
}; };

View File

@ -192,21 +192,25 @@ AudioBuffer::SetRawChannelContents(uint32_t aChannel, float* aContents)
PodCopy(JS_GetFloat32ArrayData(mJSChannels[aChannel]), aContents, mLength); PodCopy(JS_GetFloat32ArrayData(mJSChannels[aChannel]), aContents, mLength);
} }
JSObject* void
AudioBuffer::GetChannelData(JSContext* aJSContext, uint32_t aChannel, AudioBuffer::GetChannelData(JSContext* aJSContext, uint32_t aChannel,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv) ErrorResult& aRv)
{ {
if (aChannel >= NumberOfChannels()) { if (aChannel >= NumberOfChannels()) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return nullptr; return;
} }
if (!RestoreJSChannelData(aJSContext)) { if (!RestoreJSChannelData(aJSContext)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY); aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr; return;
} }
return mJSChannels[aChannel]; if (mJSChannels[aChannel]) {
JS::ExposeObjectToActiveJS(mJSChannels[aChannel]);
}
aRetval.set(mJSChannels[aChannel]);
} }
static already_AddRefed<ThreadSharedFloatArrayBufferList> static already_AddRefed<ThreadSharedFloatArrayBufferList>

View File

@ -74,8 +74,9 @@ public:
* If mSharedChannels is non-null, copies its contents to * If mSharedChannels is non-null, copies its contents to
* new Float32Arrays in mJSChannels. Returns a Float32Array. * new Float32Arrays in mJSChannels. Returns a Float32Array.
*/ */
JSObject* GetChannelData(JSContext* aJSContext, uint32_t aChannel, void GetChannelData(JSContext* aJSContext, uint32_t aChannel,
ErrorResult& aRv); JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv);
void CopyFromChannel(const Float32Array& aDestination, uint32_t aChannelNumber, void CopyFromChannel(const Float32Array& aDestination, uint32_t aChannelNumber,
uint32_t aStartInChannel, ErrorResult& aRv); uint32_t aStartInChannel, ErrorResult& aRv);

View File

@ -27,9 +27,12 @@ public:
virtual JSObject* WrapObject(JSContext *aCx) MOZ_OVERRIDE; virtual JSObject* WrapObject(JSContext *aCx) MOZ_OVERRIDE;
JSObject* GetCurve(JSContext* aCx) const void GetCurve(JSContext* aCx, JS::MutableHandle<JSObject*> aRetval) const
{ {
return mCurve; if (mCurve) {
JS::ExposeObjectToActiveJS(mCurve);
}
aRetval.set(mCurve);
} }
void SetCurve(const Nullable<Float32Array>& aData); void SetCurve(const Nullable<Float32Array>& aData);

View File

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=4 sw=4 tw=80 et: */ /* vim: set ts=4 sw=4 tw=80 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -29,6 +29,7 @@
#endif #endif
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIContentInlines.h"
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsIDOMDocument.h" #include "nsIDOMDocument.h"
#include "nsIDOMElement.h" #include "nsIDOMElement.h"
@ -336,6 +337,18 @@ CheckPingURI(nsIURI* uri, nsIContent* content)
typedef void (* ForEachPingCallback)(void *closure, nsIContent *content, typedef void (* ForEachPingCallback)(void *closure, nsIContent *content,
nsIURI *uri, nsIIOService *ios); nsIURI *uri, nsIIOService *ios);
static bool
IsElementAnchor(nsIContent* aContent)
{
// Make sure we are dealing with either an <A> or <AREA> element in the HTML
// or XHTML namespace.
if (!aContent->IsHTML()) {
return false;
}
nsIAtom* nameAtom = aContent->Tag();
return nameAtom == nsGkAtoms::a || nameAtom == nsGkAtoms::area;
}
static void static void
ForEachPing(nsIContent *content, ForEachPingCallback callback, void *closure) ForEachPing(nsIContent *content, ForEachPingCallback callback, void *closure)
{ {
@ -346,10 +359,7 @@ ForEachPing(nsIContent *content, ForEachPingCallback callback, void *closure)
// Make sure we are dealing with either an <A> or <AREA> element in the HTML // Make sure we are dealing with either an <A> or <AREA> element in the HTML
// or XHTML namespace. // or XHTML namespace.
if (!content->IsHTML()) if (!IsElementAnchor(content))
return;
nsIAtom *nameAtom = content->Tag();
if (nameAtom != nsGkAtoms::a && nameAtom != nsGkAtoms::area)
return; return;
nsCOMPtr<nsIAtom> pingAtom = do_GetAtom("ping"); nsCOMPtr<nsIAtom> pingAtom = do_GetAtom("ping");
@ -9080,6 +9090,11 @@ nsDocShell::InternalLoad(nsIURI * aURI,
if (!newDoc || newDoc->IsInitialDocument()) { if (!newDoc || newDoc->IsInitialDocument()) {
isNewWindow = true; isNewWindow = true;
aFlags |= INTERNAL_LOAD_FLAGS_FIRST_LOAD; aFlags |= INTERNAL_LOAD_FLAGS_FIRST_LOAD;
// set opener object to null for noreferrer
if (aFlags & INTERNAL_LOAD_FLAGS_NO_OPENER) {
piNewWin->SetOpenerWindow(nullptr, false);
}
} }
} }
@ -12634,6 +12649,18 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent,
} }
} }
uint32_t flags = INTERNAL_LOAD_FLAGS_NONE;
if (IsElementAnchor(aContent)) {
MOZ_ASSERT(aContent->IsHTML());
if (aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::rel,
NS_LITERAL_STRING("noreferrer"),
aContent->IsInHTMLDocument() ?
eIgnoreCase : eCaseMatters)) {
flags |= INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER |
INTERNAL_LOAD_FLAGS_NO_OPENER;
}
}
// Get the owner document of the link that was clicked, this will be // Get the owner document of the link that was clicked, this will be
// the document that the link is in, or the last document that the // the document that the link is in, or the last document that the
// link was in. From that document, we'll get the URI to use as the // link was in. From that document, we'll get the URI to use as the
@ -12684,7 +12711,7 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent,
referer, // Referer URI referer, // Referer URI
aContent->NodePrincipal(), // Owner is our node's aContent->NodePrincipal(), // Owner is our node's
// principal // principal
INTERNAL_LOAD_FLAGS_NONE, flags,
target.get(), // Window target target.get(), // Window target
NS_LossyConvertUTF16toASCII(typeHint).get(), NS_LossyConvertUTF16toASCII(typeHint).get(),
aFileName, // Download as file aFileName, // Download as file

View File

@ -114,6 +114,7 @@ interface nsIDocShell : nsIDocShellTreeItem
const long INTERNAL_LOAD_FLAGS_IS_SRCDOC = 0x40; const long INTERNAL_LOAD_FLAGS_IS_SRCDOC = 0x40;
const long INTERNAL_LOAD_FLAGS_FIXUP_SCHEME_TYPOS = 0x80; const long INTERNAL_LOAD_FLAGS_FIXUP_SCHEME_TYPOS = 0x80;
const long INTERNAL_LOAD_FLAGS_NO_OPENER = 0x100;
/** /**
* Loads the given URI. This method is identical to loadURI(...) except * Loads the given URI. This method is identical to loadURI(...) except

View File

@ -0,0 +1,20 @@
function handleRequest(request, response) {
response.setHeader("Content-Type", "text/html");
response.setHeader("Cache-Control", "no-cache");
response.write("<body onload='");
if (!request.hasHeader('Referer')) {
response.write("window.parent.onloadCount++;");
}
if (request.queryString == "newwindow") {
response.write("if (window.opener) { window.opener.parent.onloadCount++; window.opener.parent.doNextStep(); }");
response.write("if (!window.opener) window.close();");
response.write("'>");
} else {
response.write("window.parent.doNextStep();'>");
}
response.write(request.method + " " + Date.now());
response.write("</body>");
}

View File

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html>
<body onload="window.parent.onloadCount++">
<a href="bug530396-noref.sjs" rel="noreferrer" id="target1">bug530396-noref.sjs</a>
<a href="bug530396-noref.sjs?newwindow" rel="noreferrer" id="target2" target="newwindow">bug530396-noref.sjs with new window</a>
</body>
</html>

View File

@ -60,6 +60,9 @@ support-files = file_bug511449.html
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_bug529119-2.html] [test_bug529119-2.html]
skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(debug-only failure) b2g-desktop(Bug 931116, b2g desktop specific, initial triage) skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(debug-only failure) b2g-desktop(Bug 931116, b2g desktop specific, initial triage)
[test_bug530396.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Timeouts on B2G desktop
support-files = bug530396-noref.sjs bug530396-subframe.html
[test_bug540462.html] [test_bug540462.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_bug551225.html] [test_bug551225.html]

View File

@ -0,0 +1,56 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=530396
-->
<head>
<title>Test for Bug 530396</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=530396">Mozilla Bug 530396</a>
<p>
<iframe id="testFrame" src="http://mochi.test:8888/tests/docshell/test/bug530396-subframe.html"></iframe>
<pre id="test">
<script class="testbody" type="text/javascript">
// NOTE: If we ever make subframes do bfcache stuff, this test will need to be
// modified accordingly! It assumes that subframes do NOT get bfcached.
var onloadCount = 0;
var step = 0;
var gTestFrame = document.getElementById('testFrame');
SimpleTest.waitForExplicitFinish();
addLoadEvent(doNextStep);
function doNextStep() {
++step;
switch (step) {
case 1:
is(onloadCount, 1, "Loaded initial page");
sendMouseEvent({type: "click"}, "target2", gTestFrame.contentWindow);
window.setTimeout(doNextStep, 1000);
break;
case 2:
is(onloadCount, 1, "opener must be null");
sendMouseEvent({type: "click"}, "target1", gTestFrame.contentWindow);
break;
case 3:
is(onloadCount, 2, "don't send referrer with rel=referrer");
SimpleTest.finish();
break;
}
}
</script>
</pre>
</html>

View File

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Activity.h" #include "Activity.h"
#include "mozilla/dom/ToJSValue.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsDOMClassInfo.h" #include "nsDOMClassInfo.h"
#include "nsIConsoleService.h" #include "nsIConsoleService.h"
@ -67,7 +67,7 @@ Activity::Initialize(nsPIDOMWindow* aWindow,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
JS::Rooted<JS::Value> optionsValue(aCx); JS::Rooted<JS::Value> optionsValue(aCx);
if (!aOptions.ToObject(aCx, &optionsValue)) { if (!ToJSValue(aCx, aOptions, &optionsValue)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }

View File

@ -21,7 +21,14 @@ function convertAppsArray(aApps, aWindow) {
let apps = new aWindow.Array(); let apps = new aWindow.Array();
for (let i = 0; i < aApps.length; i++) { for (let i = 0; i < aApps.length; i++) {
let app = aApps[i]; let app = aApps[i];
apps.push(createApplicationObject(aWindow, app)); // Our application objects are JS-implemented XPCOM objects with DOM_OBJECT
// set in classinfo. These objects are reflector-per-scope, so as soon as we
// pass them to content, we'll end up with a new object in content. But from
// this code, they _appear_ to be chrome objects, and so the Array Xray code
// vetos the attempt to define a chrome-privileged object on a content Array.
// Very carefully waive Xrays so that this can keep working until we convert
// mozApps to WebIDL in bug 899322.
Cu.waiveXrays(apps)[i] = createApplicationObject(aWindow, app);
} }
return apps; return apps;

View File

@ -697,7 +697,7 @@ Console::ProfileMethod(JSContext* aCx, const nsAString& aAction,
} }
JS::Rooted<JS::Value> eventValue(aCx); JS::Rooted<JS::Value> eventValue(aCx);
if (!event.ToObject(aCx, &eventValue)) { if (!ToJSValue(aCx, event, &eventValue)) {
return; return;
} }
@ -1111,7 +1111,7 @@ Console::ProcessCallData(ConsoleCallData* aData)
JSAutoCompartment ac2(cx, xpc::GetJunkScope()); JSAutoCompartment ac2(cx, xpc::GetJunkScope());
JS::Rooted<JS::Value> eventValue(cx); JS::Rooted<JS::Value> eventValue(cx);
if (!event.ToObject(cx, &eventValue)) { if (!ToJSValue(cx, event, &eventValue)) {
return; return;
} }
@ -1485,7 +1485,7 @@ Console::StartTimer(JSContext* aCx, const JS::Value& aName,
RootedDictionary<ConsoleTimerError> error(aCx); RootedDictionary<ConsoleTimerError> error(aCx);
JS::Rooted<JS::Value> value(aCx); JS::Rooted<JS::Value> value(aCx);
if (!error.ToObject(aCx, &value)) { if (!ToJSValue(aCx, error, &value)) {
return JS::UndefinedValue(); return JS::UndefinedValue();
} }
@ -1517,7 +1517,7 @@ Console::StartTimer(JSContext* aCx, const JS::Value& aName,
timer.mStarted = aTimestamp; timer.mStarted = aTimestamp;
JS::Rooted<JS::Value> value(aCx); JS::Rooted<JS::Value> value(aCx);
if (!timer.ToObject(aCx, &value)) { if (!ToJSValue(aCx, timer, &value)) {
return JS::UndefinedValue(); return JS::UndefinedValue();
} }
@ -1551,7 +1551,7 @@ Console::StopTimer(JSContext* aCx, const JS::Value& aName,
timer.mDuration = aTimestamp - entry; timer.mDuration = aTimestamp - entry;
JS::Rooted<JS::Value> value(aCx); JS::Rooted<JS::Value> value(aCx);
if (!timer.ToObject(aCx, &value)) { if (!ToJSValue(aCx, timer, &value)) {
return JS::UndefinedValue(); return JS::UndefinedValue();
} }
@ -1599,7 +1599,7 @@ Console::IncreaseCounter(JSContext* aCx, const ConsoleStackEntry& aFrame,
RootedDictionary<ConsoleCounterError> error(aCx); RootedDictionary<ConsoleCounterError> error(aCx);
JS::Rooted<JS::Value> value(aCx); JS::Rooted<JS::Value> value(aCx);
if (!error.ToObject(aCx, &value)) { if (!ToJSValue(aCx, error, &value)) {
return JS::UndefinedValue(); return JS::UndefinedValue();
} }
@ -1615,7 +1615,7 @@ Console::IncreaseCounter(JSContext* aCx, const ConsoleStackEntry& aFrame,
data.mCount = count; data.mCount = count;
JS::Rooted<JS::Value> value(aCx); JS::Rooted<JS::Value> value(aCx);
if (!data.ToObject(aCx, &value)) { if (!ToJSValue(aCx, data, &value)) {
return JS::UndefinedValue(); return JS::UndefinedValue();
} }

View File

@ -55,8 +55,9 @@ Crypto::WrapObject(JSContext* aCx)
return CryptoBinding::Wrap(aCx, this); return CryptoBinding::Wrap(aCx, this);
} }
JSObject * void
Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray, Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv) ErrorResult& aRv)
{ {
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Called on the wrong thread"); NS_ABORT_IF_FALSE(NS_IsMainThread(), "Called on the wrong thread");
@ -76,17 +77,18 @@ Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
break; break;
default: default:
aRv.Throw(NS_ERROR_DOM_TYPE_MISMATCH_ERR); aRv.Throw(NS_ERROR_DOM_TYPE_MISMATCH_ERR);
return nullptr; return;
} }
aArray.ComputeLengthAndData(); aArray.ComputeLengthAndData();
uint32_t dataLen = aArray.Length(); uint32_t dataLen = aArray.Length();
if (dataLen == 0) { if (dataLen == 0) {
NS_WARNING("ArrayBufferView length is 0, cannot continue"); NS_WARNING("ArrayBufferView length is 0, cannot continue");
return view; aRetval.set(view);
return;
} else if (dataLen > 65536) { } else if (dataLen > 65536) {
aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR); aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
return nullptr; return;
} }
uint8_t* data = aArray.Data(); uint8_t* data = aArray.Data();
@ -98,7 +100,7 @@ Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
if (!cc->SendGetRandomValues(dataLen, &randomValues) || if (!cc->SendGetRandomValues(dataLen, &randomValues) ||
randomValues.Length() == 0) { randomValues.Length() == 0) {
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return nullptr; return;
} }
NS_ASSERTION(dataLen == randomValues.Length(), NS_ASSERTION(dataLen == randomValues.Length(),
"Invalid length returned from parent process!"); "Invalid length returned from parent process!");
@ -108,14 +110,14 @@ Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
if (!buf) { if (!buf) {
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return nullptr; return;
} }
memcpy(data, buf, dataLen); memcpy(data, buf, dataLen);
NS_Free(buf); NS_Free(buf);
} }
return view; aRetval.set(view);
} }
SubtleCrypto* SubtleCrypto*

View File

@ -41,8 +41,9 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Crypto) NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Crypto)
JSObject * void
GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray, GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv); ErrorResult& aRv);
SubtleCrypto* SubtleCrypto*

View File

@ -83,7 +83,7 @@ DOMRequest::GetReadyState(nsAString& aReadyState)
NS_IMETHODIMP NS_IMETHODIMP
DOMRequest::GetResult(JS::MutableHandle<JS::Value> aResult) DOMRequest::GetResult(JS::MutableHandle<JS::Value> aResult)
{ {
aResult.set(Result()); GetResult(nullptr, aResult);
return NS_OK; return NS_OK;
} }

View File

@ -49,11 +49,12 @@ public:
: DOMRequestReadyState::Pending; : DOMRequestReadyState::Pending;
} }
JS::Value Result(JSContext* = nullptr) const void GetResult(JSContext*, JS::MutableHandle<JS::Value> aRetval) const
{ {
NS_ASSERTION(mDone || mResult == JSVAL_VOID, NS_ASSERTION(mDone || mResult == JSVAL_VOID,
"Result should be undefined when pending"); "Result should be undefined when pending");
return mResult; JS::ExposeValueToActiveJS(mResult);
aRetval.set(mResult);
} }
DOMError* GetError() const DOMError* GetError() const

View File

@ -1,52 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict"
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
this.EXPORTED_SYMBOLS = ["ObjectWrapper"];
// Makes sure that we expose correctly chrome JS objects to content.
const TypedArrayThings = [
"Int8Array",
"Uint8Array",
"Uint8ClampedArray",
"Int16Array",
"Uint16Array",
"Int32Array",
"Uint32Array",
"Float32Array",
"Float64Array",
];
this.ObjectWrapper = {
getObjectKind: function objWrapper_getObjectKind(aObject) {
if (aObject === null || aObject === undefined) {
return "primitive";
} else if (Array.isArray(aObject)) {
return "array";
} else if (aObject instanceof Ci.nsIDOMFile) {
return "file";
} else if (aObject instanceof Ci.nsIDOMBlob) {
return "blob";
} else if (aObject instanceof Date) {
return "date";
} else if (TypedArrayThings.indexOf(aObject.constructor.name) !== -1) {
return aObject.constructor.name;
} else if (typeof aObject == "object") {
return "object";
} else {
return "primitive";
}
},
wrap: function objWrapper_wrap(aObject, aCtxt) {
dump("-*- ObjectWrapper is deprecated. Use Components.utils.cloneInto() instead.\n");
return Cu.cloneInto(aObject, aCtxt, { cloneFunctions: true });
}
}

View File

@ -137,7 +137,6 @@ EXTRA_COMPONENTS += [
EXTRA_JS_MODULES += [ EXTRA_JS_MODULES += [
'DOMRequestHelper.jsm', 'DOMRequestHelper.jsm',
'IndexedDBHelper.jsm', 'IndexedDBHelper.jsm',
'ObjectWrapper.jsm',
] ]
FAIL_ON_WARNINGS = True FAIL_ON_WARNINGS = True

View File

@ -59,6 +59,7 @@
#include "nsCCUncollectableMarker.h" #include "nsCCUncollectableMarker.h"
#include "mozilla/dom/workers/Workers.h" #include "mozilla/dom/workers/Workers.h"
#include "mozilla/dom/MessagePortList.h" #include "mozilla/dom/MessagePortList.h"
#include "mozilla/dom/ToJSValue.h"
#include "nsJSPrincipals.h" #include "nsJSPrincipals.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/Debug.h" #include "mozilla/Debug.h"
@ -3928,45 +3929,48 @@ nsGlobalWindow::GetRealTop(nsIDOMWindow** aTop)
return GetTopImpl(outer, aTop, /* aScriptable = */ false); return GetTopImpl(outer, aTop, /* aScriptable = */ false);
} }
JSObject* void
nsGlobalWindow::GetContent(JSContext* aCx, ErrorResult& aError) nsGlobalWindow::GetContent(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aError)
{ {
FORWARD_TO_OUTER_OR_THROW(GetContent, (aCx, aError), aError, nullptr); FORWARD_TO_OUTER_OR_THROW(GetContent, (aCx, aRetval, aError), aError, );
nsCOMPtr<nsIDOMWindow> content = GetContentInternal(aError); nsCOMPtr<nsIDOMWindow> content = GetContentInternal(aError);
if (aError.Failed()) { if (aError.Failed()) {
return nullptr; return;
} }
if (content) { if (content) {
JS::Rooted<JS::Value> val(aCx); JS::Rooted<JS::Value> val(aCx);
aError = nsContentUtils::WrapNative(aCx, content, &val); aError = nsContentUtils::WrapNative(aCx, content, &val);
if (aError.Failed()) { if (aError.Failed()) {
return nullptr; return;
} }
return &val.toObject(); aRetval.set(&val.toObject());
return;
} }
if (!nsContentUtils::IsCallerChrome() || !IsChromeWindow()) { if (!nsContentUtils::IsCallerChrome() || !IsChromeWindow()) {
aError.Throw(NS_ERROR_FAILURE); aError.Throw(NS_ERROR_FAILURE);
return nullptr; return;
} }
// Something tries to get .content on a ChromeWindow, try to fetch the CPOW. // Something tries to get .content on a ChromeWindow, try to fetch the CPOW.
nsCOMPtr<nsIDocShellTreeOwner> treeOwner = GetTreeOwner(); nsCOMPtr<nsIDocShellTreeOwner> treeOwner = GetTreeOwner();
if (!treeOwner) { if (!treeOwner) {
aError.Throw(NS_ERROR_FAILURE); aError.Throw(NS_ERROR_FAILURE);
return nullptr; return;
} }
JS::Rooted<JS::Value> val(aCx, JS::NullValue()); JS::Rooted<JS::Value> val(aCx, JS::NullValue());
aError = treeOwner->GetContentWindow(aCx, &val); aError = treeOwner->GetContentWindow(aCx, &val);
if (aError.Failed()) { if (aError.Failed()) {
return nullptr; return;
} }
return val.toObjectOrNull(); aRetval.set(val.toObjectOrNull());
} }
already_AddRefed<nsIDOMWindow> already_AddRefed<nsIDOMWindow>
@ -4034,7 +4038,8 @@ NS_IMETHODIMP
nsGlobalWindow::GetScriptableContent(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) nsGlobalWindow::GetScriptableContent(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
{ {
ErrorResult rv; ErrorResult rv;
JS::Rooted<JSObject*> content(aCx, GetContent(aCx, rv)); JS::Rooted<JSObject*> content(aCx);
GetContent(aCx, &content, rv);
if (!rv.Failed()) { if (!rv.Failed()) {
aVal.setObjectOrNull(content); aVal.setObjectOrNull(content);
} }
@ -4502,17 +4507,17 @@ nsGlobalWindow::GetOpenerWindow(ErrorResult& aError)
return nullptr; return nullptr;
} }
JS::Value void
nsGlobalWindow::GetOpener(JSContext* aCx, ErrorResult& aError) nsGlobalWindow::GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aError)
{ {
nsCOMPtr<nsIDOMWindow> opener = GetOpenerWindow(aError); nsCOMPtr<nsIDOMWindow> opener = GetOpenerWindow(aError);
if (aError.Failed() || !opener) { if (aError.Failed() || !opener) {
return JS::NullValue(); aRetval.setNull();
return;
} }
JS::Rooted<JS::Value> val(aCx); aError = nsContentUtils::WrapNative(aCx, opener, aRetval);
aError = nsContentUtils::WrapNative(aCx, opener, &val);
return val;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -4520,7 +4525,7 @@ nsGlobalWindow::GetScriptableOpener(JSContext* aCx,
JS::MutableHandle<JS::Value> aOpener) JS::MutableHandle<JS::Value> aOpener)
{ {
ErrorResult rv; ErrorResult rv;
aOpener.set(GetOpener(aCx, rv)); GetOpener(aCx, aOpener, rv);
return rv.ErrorCode(); return rv.ErrorCode();
} }
@ -5825,7 +5830,7 @@ nsGlobalWindow::DispatchResizeEvent(const nsIntSize& aSize)
detail.mWidth = aSize.width; detail.mWidth = aSize.width;
detail.mHeight = aSize.height; detail.mHeight = aSize.height;
JS::Rooted<JS::Value> detailValue(cx); JS::Rooted<JS::Value> detailValue(cx);
if (!detail.ToObject(cx, &detailValue)) { if (!ToJSValue(cx, detail, &detailValue)) {
return false; return false;
} }
@ -9109,10 +9114,11 @@ nsGlobalWindow::ShowModalDialog(const nsAString& aUrl, nsIVariant* aArgument,
return retVal.forget(); return retVal.forget();
} }
JS::Value void
nsGlobalWindow::ShowModalDialog(JSContext* aCx, const nsAString& aUrl, nsGlobalWindow::ShowModalDialog(JSContext* aCx, const nsAString& aUrl,
JS::Handle<JS::Value> aArgument, JS::Handle<JS::Value> aArgument,
const nsAString& aOptions, const nsAString& aOptions,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aError) ErrorResult& aError)
{ {
nsCOMPtr<nsIVariant> args; nsCOMPtr<nsIVariant> args;
@ -9120,23 +9126,22 @@ nsGlobalWindow::ShowModalDialog(JSContext* aCx, const nsAString& aUrl,
aArgument, aArgument,
getter_AddRefs(args)); getter_AddRefs(args));
if (aError.Failed()) { if (aError.Failed()) {
return JS::UndefinedValue(); return;
} }
nsCOMPtr<nsIVariant> retVal = ShowModalDialog(aUrl, args, aOptions, aError); nsCOMPtr<nsIVariant> retVal = ShowModalDialog(aUrl, args, aOptions, aError);
if (aError.Failed()) { if (aError.Failed()) {
return JS::UndefinedValue(); return;
} }
JS::Rooted<JS::Value> result(aCx); JS::Rooted<JS::Value> result(aCx);
if (retVal) { if (retVal) {
aError = nsContentUtils::XPConnect()->VariantToJS(aCx, aError = nsContentUtils::XPConnect()->VariantToJS(aCx,
FastGetGlobalJSObject(), FastGetGlobalJSObject(),
retVal, &result); retVal, aRetval);
} else { } else {
result = JS::NullValue(); aRetval.setNull();
} }
return result;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -10584,10 +10589,12 @@ nsGlobalWindow::GetInterface(const nsIID & aIID, void **aSink)
return *aSink ? NS_OK : NS_ERROR_NO_INTERFACE; return *aSink ? NS_OK : NS_ERROR_NO_INTERFACE;
} }
JS::Value void
nsGlobalWindow::GetInterface(JSContext* aCx, nsIJSID* aIID, ErrorResult& aError) nsGlobalWindow::GetInterface(JSContext* aCx, nsIJSID* aIID,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aError)
{ {
return dom::GetInterface(aCx, this, aIID, aError); dom::GetInterface(aCx, this, aIID, aRetval, aError);
} }
void void
@ -12097,7 +12104,8 @@ nsGlobalWindow::RunTimeoutHandler(nsTimeout* aTimeout,
// Hold strong ref to ourselves while we call the callback. // Hold strong ref to ourselves while we call the callback.
nsCOMPtr<nsISupports> me(static_cast<nsIDOMWindow *>(this)); nsCOMPtr<nsISupports> me(static_cast<nsIDOMWindow *>(this));
ErrorResult ignored; ErrorResult ignored;
callback->Call(me, handler->GetArgs(), ignored); JS::Rooted<JS::Value> ignoredVal(CycleCollectedJSRuntime::Get()->Runtime());
callback->Call(me, handler->GetArgs(), &ignoredVal, ignored);
} }
// We ignore any failures from calling EvaluateString() on the context or // We ignore any failures from calling EvaluateString() on the context or
@ -13622,28 +13630,29 @@ NS_IMPL_ADDREF_INHERITED(nsGlobalModalWindow, nsGlobalWindow)
NS_IMPL_RELEASE_INHERITED(nsGlobalModalWindow, nsGlobalWindow) NS_IMPL_RELEASE_INHERITED(nsGlobalModalWindow, nsGlobalWindow)
JS::Value void
nsGlobalWindow::GetDialogArguments(JSContext* aCx, ErrorResult& aError) nsGlobalWindow::GetDialogArguments(JSContext* aCx,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aError)
{ {
FORWARD_TO_OUTER_OR_THROW(GetDialogArguments, (aCx, aError), aError, FORWARD_TO_OUTER_OR_THROW(GetDialogArguments, (aCx, aRetval, aError),
JS::UndefinedValue()); aError, );
MOZ_ASSERT(IsModalContentWindow(), MOZ_ASSERT(IsModalContentWindow(),
"This should only be called on modal windows!"); "This should only be called on modal windows!");
if (!mDialogArguments) { if (!mDialogArguments) {
MOZ_ASSERT(mIsClosed, "This window should be closed!"); MOZ_ASSERT(mIsClosed, "This window should be closed!");
return JS::UndefinedValue(); aRetval.setUndefined();
return;
} }
// This does an internal origin check, and returns undefined if the subject // This does an internal origin check, and returns undefined if the subject
// does not subsumes the origin of the arguments. // does not subsumes the origin of the arguments.
JS::Rooted<JSObject*> wrapper(aCx, GetWrapper()); JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
JSAutoCompartment ac(aCx, wrapper); JSAutoCompartment ac(aCx, wrapper);
JS::Rooted<JS::Value> args(aCx);
mDialogArguments->Get(aCx, wrapper, nsContentUtils::SubjectPrincipal(), mDialogArguments->Get(aCx, wrapper, nsContentUtils::SubjectPrincipal(),
&args, aError); aRetval, aError);
return args;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -13657,23 +13666,25 @@ nsGlobalModalWindow::GetDialogArguments(nsIVariant **aArguments)
return mDialogArguments->Get(nsContentUtils::SubjectPrincipal(), aArguments); return mDialogArguments->Get(nsContentUtils::SubjectPrincipal(), aArguments);
} }
JS::Value void
nsGlobalWindow::GetReturnValue(JSContext* aCx, ErrorResult& aError) nsGlobalWindow::GetReturnValue(JSContext* aCx,
JS::MutableHandle<JS::Value> aReturnValue,
ErrorResult& aError)
{ {
FORWARD_TO_OUTER_OR_THROW(GetReturnValue, (aCx, aError), aError, FORWARD_TO_OUTER_OR_THROW(GetReturnValue, (aCx, aReturnValue, aError),
JS::UndefinedValue()); aError, );
MOZ_ASSERT(IsModalContentWindow(), MOZ_ASSERT(IsModalContentWindow(),
"This should only be called on modal windows!"); "This should only be called on modal windows!");
JS::Rooted<JS::Value> returnValue(aCx);
if (mReturnValue) { if (mReturnValue) {
JS::Rooted<JSObject*> wrapper(aCx, GetWrapper()); JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
JSAutoCompartment ac(aCx, wrapper); JSAutoCompartment ac(aCx, wrapper);
mReturnValue->Get(aCx, wrapper, nsContentUtils::SubjectPrincipal(), mReturnValue->Get(aCx, wrapper, nsContentUtils::SubjectPrincipal(),
&returnValue, aError); aReturnValue, aError);
} else {
aReturnValue.setUndefined();
} }
return returnValue;
} }
NS_IMETHODIMP NS_IMETHODIMP

View File

@ -837,7 +837,8 @@ public:
protected: protected:
nsIDOMWindow* GetOpenerWindow(mozilla::ErrorResult& aError); nsIDOMWindow* GetOpenerWindow(mozilla::ErrorResult& aError);
public: public:
JS::Value GetOpener(JSContext* aCx, mozilla::ErrorResult& aError); void GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError);
void SetOpener(JSContext* aCx, JS::Handle<JS::Value> aOpener, void SetOpener(JSContext* aCx, JS::Handle<JS::Value> aOpener,
mozilla::ErrorResult& aError); mozilla::ErrorResult& aError);
using nsIDOMWindow::GetParent; using nsIDOMWindow::GetParent;
@ -867,7 +868,11 @@ public:
void Prompt(const nsAString& aMessage, const nsAString& aInitial, void Prompt(const nsAString& aMessage, const nsAString& aInitial,
nsAString& aReturn, mozilla::ErrorResult& aError); nsAString& aReturn, mozilla::ErrorResult& aError);
void Print(mozilla::ErrorResult& aError); void Print(mozilla::ErrorResult& aError);
JS::Value ShowModalDialog(JSContext* aCx, const nsAString& aUrl, JS::Handle<JS::Value> aArgument, const nsAString& aOptions, mozilla::ErrorResult& aError); void ShowModalDialog(JSContext* aCx, const nsAString& aUrl,
JS::Handle<JS::Value> aArgument,
const nsAString& aOptions,
JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError);
void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage, void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
const nsAString& aTargetOrigin, const nsAString& aTargetOrigin,
const mozilla::dom::Optional<mozilla::dom::Sequence<JS::Value > >& aTransfer, const mozilla::dom::Optional<mozilla::dom::Sequence<JS::Value > >& aTransfer,
@ -986,13 +991,17 @@ public:
const nsAString& aOptions, const nsAString& aOptions,
const mozilla::dom::Sequence<JS::Value>& aExtraArgument, const mozilla::dom::Sequence<JS::Value>& aExtraArgument,
mozilla::ErrorResult& aError); mozilla::ErrorResult& aError);
JSObject* GetContent(JSContext* aCx, mozilla::ErrorResult& aError); void GetContent(JSContext* aCx,
JSObject* Get_content(JSContext* aCx, mozilla::ErrorResult& aError) JS::MutableHandle<JSObject*> aRetval,
mozilla::ErrorResult& aError);
void Get_content(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
mozilla::ErrorResult& aError)
{ {
if (mDoc) { if (mDoc) {
mDoc->WarnOnceAbout(nsIDocument::eWindow_Content); mDoc->WarnOnceAbout(nsIDocument::eWindow_Content);
} }
return GetContent(aCx, aError); GetContent(aCx, aRetval, aError);
} }
// ChromeWindow bits. Do NOT call these unless your window is in // ChromeWindow bits. Do NOT call these unless your window is in
@ -1017,13 +1026,16 @@ public:
mozilla::dom::Element* aPanel, mozilla::dom::Element* aPanel,
mozilla::ErrorResult& aError); mozilla::ErrorResult& aError);
JS::Value GetDialogArguments(JSContext* aCx, mozilla::ErrorResult& aError); void GetDialogArguments(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
JS::Value GetReturnValue(JSContext* aCx, mozilla::ErrorResult& aError); mozilla::ErrorResult& aError);
void GetReturnValue(JSContext* aCx, JS::MutableHandle<JS::Value> aReturnValue,
mozilla::ErrorResult& aError);
void SetReturnValue(JSContext* aCx, JS::Handle<JS::Value> aReturnValue, void SetReturnValue(JSContext* aCx, JS::Handle<JS::Value> aReturnValue,
mozilla::ErrorResult& aError); mozilla::ErrorResult& aError);
JS::Value GetInterface(JSContext* aCx, nsIJSID* aIID, void GetInterface(JSContext* aCx, nsIJSID* aIID,
mozilla::ErrorResult& aError); JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError);
protected: protected:
// Array of idle observers that are notified of idle events. // Array of idle observers that are notified of idle events.

View File

@ -96,50 +96,46 @@ nsHistory::GetLength(ErrorResult& aRv) const
return len >= 0 ? len : 0; return len >= 0 ? len : 0;
} }
JS::Value void
nsHistory::GetState(JSContext* aCx, ErrorResult& aRv) const nsHistory::GetState(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv) const
{ {
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow)); nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
if (!win) { if (!win) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE); aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return;
return JS::UndefinedValue();
} }
if (!win->HasActiveDocument()) { if (!win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
return JS::UndefinedValue();
} }
nsCOMPtr<nsIDocument> doc = nsCOMPtr<nsIDocument> doc =
do_QueryInterface(win->GetExtantDoc()); do_QueryInterface(win->GetExtantDoc());
if (!doc) { if (!doc) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE); aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return;
return JS::UndefinedValue();
} }
nsCOMPtr<nsIVariant> variant; nsCOMPtr<nsIVariant> variant;
doc->GetStateObject(getter_AddRefs(variant)); doc->GetStateObject(getter_AddRefs(variant));
if (variant) { if (variant) {
JS::Rooted<JS::Value> jsData(aCx); aRv = variant->GetAsJSVal(aResult);
aRv = variant->GetAsJSVal(&jsData);
if (aRv.Failed()) { if (aRv.Failed()) {
return JS::UndefinedValue(); return;
} }
if (!JS_WrapValue(aCx, &jsData)) { if (!JS_WrapValue(aCx, aResult)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY); aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return JS::UndefinedValue();
} }
return jsData; return;
} }
return JS::NullValue(); aResult.setNull();
} }
void void

View File

@ -37,7 +37,8 @@ public:
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE; virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
uint32_t GetLength(mozilla::ErrorResult& aRv) const; uint32_t GetLength(mozilla::ErrorResult& aRv) const;
JS::Value GetState(JSContext* aCx, mozilla::ErrorResult& aRv) const; void GetState(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
mozilla::ErrorResult& aRv) const;
void Go(int32_t aDelta, mozilla::ErrorResult& aRv); void Go(int32_t aDelta, mozilla::ErrorResult& aRv);
void Back(mozilla::ErrorResult& aRv); void Back(mozilla::ErrorResult& aRv);
void Forward(mozilla::ErrorResult& aRv); void Forward(mozilla::ErrorResult& aRv);

View File

@ -884,25 +884,22 @@ QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp)
return true; return true;
} }
JS::Value void
GetInterfaceImpl(JSContext* aCx, nsIInterfaceRequestor* aRequestor, GetInterfaceImpl(JSContext* aCx, nsIInterfaceRequestor* aRequestor,
nsWrapperCache* aCache, nsIJSID* aIID, ErrorResult& aError) nsWrapperCache* aCache, nsIJSID* aIID,
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError)
{ {
const nsID* iid = aIID->GetID(); const nsID* iid = aIID->GetID();
nsRefPtr<nsISupports> result; nsRefPtr<nsISupports> result;
aError = aRequestor->GetInterface(*iid, getter_AddRefs(result)); aError = aRequestor->GetInterface(*iid, getter_AddRefs(result));
if (aError.Failed()) { if (aError.Failed()) {
return JS::NullValue(); return;
} }
JS::Rooted<JS::Value> v(aCx, JSVAL_NULL); if (!WrapObject(aCx, result, iid, aRetval)) {
if (!WrapObject(aCx, result, iid, &v)) {
aError.Throw(NS_ERROR_FAILURE); aError.Throw(NS_ERROR_FAILURE);
return JS::NullValue();
} }
return v;
} }
bool bool

View File

@ -1649,15 +1649,17 @@ WantsQueryInterface
} }
}; };
JS::Value void
GetInterfaceImpl(JSContext* aCx, nsIInterfaceRequestor* aRequestor, GetInterfaceImpl(JSContext* aCx, nsIInterfaceRequestor* aRequestor,
nsWrapperCache* aCache, nsIJSID* aIID, ErrorResult& aError); nsWrapperCache* aCache, nsIJSID* aIID,
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError);
template<class T> template<class T>
JS::Value void
GetInterface(JSContext* aCx, T* aThis, nsIJSID* aIID, ErrorResult& aError) GetInterface(JSContext* aCx, T* aThis, nsIJSID* aIID,
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError)
{ {
return GetInterfaceImpl(aCx, aThis, aThis, aIID, aError); GetInterfaceImpl(aCx, aThis, aThis, aIID, aRetval, aError);
} }
bool bool

View File

@ -2143,10 +2143,9 @@ class MethodDefiner(PropertyDefiner):
accessor = "genericCrossOriginMethod" accessor = "genericCrossOriginMethod"
elif self.descriptor.needsSpecialGenericOps(): elif self.descriptor.needsSpecialGenericOps():
if m.get("returnsPromise", False): if m.get("returnsPromise", False):
raise TypeError("%s returns a Promise but needs " accessor = "genericPromiseReturningMethod"
"special generic ops?" % else:
accessor) accessor = "genericMethod"
accessor = "genericMethod"
elif m.get("returnsPromise", False): elif m.get("returnsPromise", False):
accessor = "GenericPromiseReturningBindingMethod" accessor = "GenericPromiseReturningBindingMethod"
else: else:
@ -5444,7 +5443,7 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
False) False)
if type.isDictionary(): if type.isDictionary():
return (wrapAndSetPtr("%s.ToObject(cx, ${jsvalHandle})" % result), return (wrapAndSetPtr("%s.ToObjectInternal(cx, ${jsvalHandle})" % result),
False) False)
if type.isDate(): if type.isDate():
@ -5594,8 +5593,10 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
1) A CGThing for the type of the return value, or None if there is no need 1) A CGThing for the type of the return value, or None if there is no need
for a return value. for a return value.
2) A boolean indicating whether the return value is passed as an out 2) A value indicating the kind of ourparam to pass the value as. Valid
parameter. options are None to not pass as an out param at all, "ref" (to pass a
reference as an out param), and "ptr" (to pass a pointer as an out
param).
3) A CGThing for a tracer for the return value, or None if no tracing is 3) A CGThing for a tracer for the return value, or None if no tracing is
needed. needed.
@ -5605,23 +5606,23 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
""" """
if returnType is None or returnType.isVoid(): if returnType is None or returnType.isVoid():
# Nothing to declare # Nothing to declare
return None, False, None, None return None, None, None, None
if returnType.isPrimitive() and returnType.tag() in builtinNames: if returnType.isPrimitive() and returnType.tag() in builtinNames:
result = CGGeneric(builtinNames[returnType.tag()]) result = CGGeneric(builtinNames[returnType.tag()])
if returnType.nullable(): if returnType.nullable():
result = CGTemplatedType("Nullable", result) result = CGTemplatedType("Nullable", result)
return result, False, None, None return result, None, None, None
if returnType.isDOMString(): if returnType.isDOMString():
if isMember: if isMember:
return CGGeneric("nsString"), True, None, None return CGGeneric("nsString"), "ref", None, None
return CGGeneric("DOMString"), True, None, None return CGGeneric("DOMString"), "ref", None, None
if returnType.isByteString(): if returnType.isByteString():
return CGGeneric("nsCString"), True, None, None return CGGeneric("nsCString"), "ref", None, None
if returnType.isEnum(): if returnType.isEnum():
result = CGGeneric(returnType.unroll().inner.identifier.name) result = CGGeneric(returnType.unroll().inner.identifier.name)
if returnType.nullable(): if returnType.nullable():
result = CGTemplatedType("Nullable", result) result = CGTemplatedType("Nullable", result)
return result, False, None, None return result, None, None, None
if returnType.isGeckoInterface(): if returnType.isGeckoInterface():
result = CGGeneric(descriptorProvider.getDescriptor( result = CGGeneric(descriptorProvider.getDescriptor(
returnType.unroll().inner.identifier.name).nativeType) returnType.unroll().inner.identifier.name).nativeType)
@ -5632,14 +5633,18 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
result = CGTemplatedType("nsRefPtr", result) result = CGTemplatedType("nsRefPtr", result)
else: else:
result = CGWrapper(result, post="*") result = CGWrapper(result, post="*")
return result, False, None, None return result, None, None, None
if returnType.isCallback(): if returnType.isCallback():
name = returnType.unroll().identifier.name name = returnType.unroll().identifier.name
return CGGeneric("nsRefPtr<%s>" % name), False, None, None return CGGeneric("nsRefPtr<%s>" % name), None, None, None
if returnType.isAny(): if returnType.isAny():
return CGGeneric("JS::Value"), False, None, None if isMember:
return CGGeneric("JS::Value"), None, None, None
return CGGeneric("JS::Rooted<JS::Value>"), "ptr", None, "cx"
if returnType.isObject() or returnType.isSpiderMonkeyInterface(): if returnType.isObject() or returnType.isSpiderMonkeyInterface():
return CGGeneric("JSObject*"), False, None, None if isMember:
return CGGeneric("JSObject*"), None, None, None
return CGGeneric("JS::Rooted<JSObject*>"), "ptr", None, "cx"
if returnType.isSequence(): if returnType.isSequence():
nullable = returnType.nullable() nullable = returnType.nullable()
if nullable: if nullable:
@ -5659,7 +5664,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
result = CGTemplatedType("nsTArray", result) result = CGTemplatedType("nsTArray", result)
if nullable: if nullable:
result = CGTemplatedType("Nullable", result) result = CGTemplatedType("Nullable", result)
return result, True, rooter, None return result, "ref", rooter, None
if returnType.isMozMap(): if returnType.isMozMap():
nullable = returnType.nullable() nullable = returnType.nullable()
if nullable: if nullable:
@ -5679,7 +5684,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
result = CGTemplatedType("MozMap", result) result = CGTemplatedType("MozMap", result)
if nullable: if nullable:
result = CGTemplatedType("Nullable", result) result = CGTemplatedType("Nullable", result)
return result, True, rooter, None return result, "ref", rooter, None
if returnType.isDictionary(): if returnType.isDictionary():
nullable = returnType.nullable() nullable = returnType.nullable()
dictName = CGDictionary.makeDictionaryName(returnType.unroll().inner) dictName = CGDictionary.makeDictionaryName(returnType.unroll().inner)
@ -5694,7 +5699,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
if nullable: if nullable:
result = CGTemplatedType("Nullable", result) result = CGTemplatedType("Nullable", result)
resultArgs = None resultArgs = None
return result, True, None, resultArgs return result, "ref", None, resultArgs
if returnType.isUnion(): if returnType.isUnion():
result = CGGeneric(CGUnionStruct.unionTypeName(returnType.unroll(), True)) result = CGGeneric(CGUnionStruct.unionTypeName(returnType.unroll(), True))
if not isMember and typeNeedsRooting(returnType): if not isMember and typeNeedsRooting(returnType):
@ -5707,12 +5712,12 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
if returnType.nullable(): if returnType.nullable():
result = CGTemplatedType("Nullable", result) result = CGTemplatedType("Nullable", result)
resultArgs = None resultArgs = None
return result, True, None, resultArgs return result, "ref", None, resultArgs
if returnType.isDate(): if returnType.isDate():
result = CGGeneric("Date") result = CGGeneric("Date")
if returnType.nullable(): if returnType.nullable():
result = CGTemplatedType("Nullable", result) result = CGTemplatedType("Nullable", result)
return result, False, None, None return result, None, None, None
raise TypeError("Don't know how to declare return value for %s" % raise TypeError("Don't know how to declare return value for %s" %
returnType) returnType)
@ -5801,8 +5806,13 @@ class CGCallGenerator(CGThing):
args.append(arg) args.append(arg)
# Return values that go in outparams go here # Return values that go in outparams go here
if resultOutParam: if resultOutParam is not None:
args.append(CGGeneric("result")) if resultOutParam is "ref":
args.append(CGGeneric("result"))
else:
assert resultOutParam is "ptr"
args.append(CGGeneric("&result"))
if isFallible: if isFallible:
args.append(CGGeneric("rv")) args.append(CGGeneric("rv"))
args.extend(CGGeneric(arg) for arg in argsPost) args.extend(CGGeneric(arg) for arg in argsPost)
@ -6904,6 +6914,53 @@ class CGGenericMethod(CGAbstractBindingMethod):
return ok; return ok;
""")) """))
class CGGenericPromiseReturningMethod(CGAbstractBindingMethod):
"""
A class for generating the C++ code for an IDL method that returns a Promise.
Does not handle cross-origin this.
"""
def __init__(self, descriptor):
args = [Argument('JSContext*', 'cx'),
Argument('unsigned', 'argc'),
Argument('JS::Value*', 'vp')]
unwrapFailureCode = dedent("""
ThrowInvalidThis(cx, args, GetInvalidThisErrorForMethod(%%(securityError)s), "%s");\n
return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
args.rval());\n""" %
descriptor.interface.identifier.name)
name = "genericPromiseReturningMethod"
customCallArgs = dedent("""
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
// Make sure to save the callee before someone maybe messes with rval().
JS::Rooted<JSObject*> callee(cx, &args.callee());
""")
CGAbstractBindingMethod.__init__(self, descriptor, name,
args,
callArgs=customCallArgs,
unwrapFailureCode=unwrapFailureCode)
def generate_code(self):
return CGGeneric(dedent("""
const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
MOZ_ASSERT(info->type() == JSJitInfo::Method);
JSJitMethodOp method = info->method;
bool ok = method(cx, obj, self, JSJitMethodCallArgs(args));
if (ok) {
#ifdef DEBUG
AssertReturnTypeMatchesJitinfo(info, args.rval());
#endif
return true;
}
MOZ_ASSERT(info->returnType() == JSVAL_TYPE_OBJECT);
return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
args.rval());
"""))
class CGSpecializedMethod(CGAbstractStaticMethod): class CGSpecializedMethod(CGAbstractStaticMethod):
""" """
@ -10153,7 +10210,8 @@ class CGDescriptor(CGThing):
# These are set to true if at least one non-static # These are set to true if at least one non-static
# method/getter/setter or jsonifier exist on the interface. # method/getter/setter or jsonifier exist on the interface.
(hasMethod, hasGetter, hasLenientGetter, hasSetter, hasJsonifier, (hasMethod, hasGetter, hasLenientGetter, hasSetter, hasJsonifier,
hasLenientSetter) = False, False, False, False, False, False hasLenientSetter,
hasPromiseReturningMethod) = False, False, False, False, False, False, False
crossOriginMethods, crossOriginGetters, crossOriginSetters = set(), set(), set() crossOriginMethods, crossOriginGetters, crossOriginSetters = set(), set(), set()
for n in descriptor.interface.namedConstructors: for n in descriptor.interface.namedConstructors:
cgThings.append(CGClassConstructor(descriptor, n, cgThings.append(CGClassConstructor(descriptor, n,
@ -10176,6 +10234,8 @@ class CGDescriptor(CGThing):
specializedMethod = CGSpecializedMethod(descriptor, m) specializedMethod = CGSpecializedMethod(descriptor, m)
cgThings.append(specializedMethod) cgThings.append(specializedMethod)
if m.returnsPromise(): if m.returnsPromise():
if descriptor.needsSpecialGenericOps():
hasPromiseReturningMethod = True
cgThings.append(CGMethodPromiseWrapper(descriptor, specializedMethod)) cgThings.append(CGMethodPromiseWrapper(descriptor, specializedMethod))
cgThings.append(CGMemberJITInfo(descriptor, m)) cgThings.append(CGMemberJITInfo(descriptor, m))
if m.getExtendedAttribute("CrossOriginCallable"): if m.getExtendedAttribute("CrossOriginCallable"):
@ -10234,6 +10294,8 @@ class CGDescriptor(CGThing):
cgThings.append(CGMemberJITInfo(descriptor, jsonifierMethod)) cgThings.append(CGMemberJITInfo(descriptor, jsonifierMethod))
if hasMethod: if hasMethod:
cgThings.append(CGGenericMethod(descriptor)) cgThings.append(CGGenericMethod(descriptor))
if hasPromiseReturningMethod:
cgThings.append(CGGenericPromiseReturningMethod(descriptor))
if len(crossOriginMethods): if len(crossOriginMethods):
cgThings.append(CGGenericMethod(descriptor, cgThings.append(CGGenericMethod(descriptor,
allowCrossOriginThis=True)) allowCrossOriginThis=True))
@ -10600,7 +10662,7 @@ class CGDictionary(CGThing):
return Init(cx, json); return Init(cx, json);
""")) """))
def toObjectMethod(self): def toObjectInternalMethod(self):
body = "" body = ""
if self.needToInitIds: if self.needToInitIds:
body += fill( body += fill(
@ -10617,7 +10679,7 @@ class CGDictionary(CGThing):
body += fill( body += fill(
""" """
// Per spec, we define the parent's members first // Per spec, we define the parent's members first
if (!${dictName}::ToObject(cx, rval)) { if (!${dictName}::ToObjectInternal(cx, rval)) {
return false; return false;
} }
JS::Rooted<JSObject*> obj(cx, &rval.toObject()); JS::Rooted<JSObject*> obj(cx, &rval.toObject());
@ -10640,7 +10702,7 @@ class CGDictionary(CGThing):
for m in self.memberInfo) for m in self.memberInfo)
body += "\nreturn true;\n" body += "\nreturn true;\n"
return ClassMethod("ToObject", "bool", [ return ClassMethod("ToObjectInternal", "bool", [
Argument('JSContext*', 'cx'), Argument('JSContext*', 'cx'),
Argument('JS::MutableHandle<JS::Value>', 'rval'), Argument('JS::MutableHandle<JS::Value>', 'rval'),
], const=True, body=body) ], const=True, body=body)
@ -10726,11 +10788,11 @@ class CGDictionary(CGThing):
methods.append(self.initMethod()) methods.append(self.initMethod())
methods.append(self.initFromJSONMethod()) methods.append(self.initFromJSONMethod())
try: try:
methods.append(self.toObjectMethod()) methods.append(self.toObjectInternalMethod())
except MethodNotNewObjectError: except MethodNotNewObjectError:
# If we can't have a ToObject() because one of our members can only # If we can't have a ToObjectInternal() because one of our members
# be returned from [NewObject] methods, then just skip generating # can only be returned from [NewObject] methods, then just skip
# ToObject(). # generating ToObjectInternal().
pass pass
methods.append(self.traceDictionaryMethod()) methods.append(self.traceDictionaryMethod())
@ -11521,15 +11583,26 @@ class CGNativeMember(ClassMethod):
return ("already_AddRefed<%s>" % type.unroll().identifier.name, return ("already_AddRefed<%s>" % type.unroll().identifier.name,
"nullptr", "return ${declName}.forget();\n") "nullptr", "return ${declName}.forget();\n")
if type.isAny(): if type.isAny():
return "JS::Value", "JS::UndefinedValue()", "return ${declName};\n" if isMember:
# No need for a third element in the isMember case
return "JS::Value", None, None
# Outparam
return "void", "", "aRetVal.set(${declName});\n"
if type.isObject(): if type.isObject():
return "JSObject*", "nullptr", "return ${declName};\n" if isMember:
# No need for a third element in the isMember case
return "JSObject*", None, None
return "void", "", "aRetVal.set(${declName});\n"
if type.isSpiderMonkeyInterface(): if type.isSpiderMonkeyInterface():
if isMember:
# No need for a third element in the isMember case
return "JSObject*", None, None
if type.nullable(): if type.nullable():
returnCode = "return ${declName}.IsNull() ? nullptr : ${declName}.Value().Obj();\n" returnCode = "${declName}.IsNull() ? nullptr : ${declName}.Value().Obj();\n"
else: else:
returnCode = "return ${declName}.Obj();\n" returnCode = "${declName}.Obj();\n"
return "JSObject*", "nullptr", returnCode return "void", "", "aRetVal.set(%s);\n" % returnCode
if type.isSequence(): if type.isSequence():
# If we want to handle sequence-of-sequences return values, we're # If we want to handle sequence-of-sequences return values, we're
# going to need to fix example codegen to not produce nsTArray<void> # going to need to fix example codegen to not produce nsTArray<void>
@ -11619,6 +11692,11 @@ class CGNativeMember(ClassMethod):
args.append(Argument("%s&" % args.append(Argument("%s&" %
CGUnionStruct.unionTypeDecl(returnType, True), CGUnionStruct.unionTypeDecl(returnType, True),
"aRetVal")) "aRetVal"))
elif returnType.isAny():
args.append(Argument("JS::MutableHandle<JS::Value>", "aRetVal"))
elif returnType.isObject() or returnType.isSpiderMonkeyInterface():
args.append(Argument("JS::MutableHandle<JSObject*>", "aRetVal"))
# And the ErrorResult # And the ErrorResult
if 'infallible' not in self.extendedAttrs: if 'infallible' not in self.extendedAttrs:
# Use aRv so it won't conflict with local vars named "rv" # Use aRv so it won't conflict with local vars named "rv"
@ -11797,6 +11875,9 @@ class CGNativeMember(ClassMethod):
return Argument(decl.define(), arg.identifier.name) return Argument(decl.define(), arg.identifier.name)
def arguments(self):
return self.member.signatures()[0][1]
class CGExampleMethod(CGNativeMember): class CGExampleMethod(CGNativeMember):
def __init__(self, descriptor, method, signature, isConstructor, breakAfter=True): def __init__(self, descriptor, method, signature, isConstructor, breakAfter=True):
@ -13498,14 +13579,16 @@ class CGEventGetter(CGNativeMember):
if (${memberName}) { if (${memberName}) {
JS::ExposeObjectToActiveJS(${memberName}); JS::ExposeObjectToActiveJS(${memberName});
} }
return ${memberName}; aRetVal.set(${memberName});
return;
""", """,
memberName=memberName) memberName=memberName)
if type.isAny(): if type.isAny():
return fill( return fill(
""" """
JS::ExposeValueToActiveJS(${memberName}); JS::ExposeValueToActiveJS(${memberName});
return ${memberName}; aRetVal.set(${memberName});
return;
""", """,
memberName=memberName) memberName=memberName)
if type.isUnion(): if type.isUnion():
@ -13562,9 +13645,9 @@ class CGEventMethod(CGNativeMember):
def declare(self, cgClass): def declare(self, cgClass):
self.args = list(self.originalArgs) self.args = list(self.originalArgs)
self.args.insert(0, Argument("mozilla::dom::EventTarget*", "aOwner")) self.args.insert(0, Argument("mozilla::dom::EventTarget*", "aOwner"))
constructorForNativeCaller = CGNativeMember.declare(self, cgClass) + "\n" constructorForNativeCaller = CGNativeMember.declare(self, cgClass)
self.args = list(self.originalArgs) self.args = list(self.originalArgs)
if needCx(None, self.descriptorProvider.interface.members, [], True): if needCx(None, self.arguments(), [], True):
self.args.insert(0, Argument("JSContext*", "aCx")) self.args.insert(0, Argument("JSContext*", "aCx"))
self.args.insert(0, Argument("const GlobalObject&", "aGlobal")) self.args.insert(0, Argument("const GlobalObject&", "aGlobal"))
self.args.append(Argument('ErrorResult&', 'aRv')) self.args.append(Argument('ErrorResult&', 'aRv'))
@ -13615,7 +13698,7 @@ class CGEventMethod(CGNativeMember):
""", """,
arg0=self.args[0].name, arg0=self.args[0].name,
arg1=self.args[1].name) arg1=self.args[1].name)
if needCx(None, self.descriptorProvider.interface.members, [], True): if needCx(None, self.arguments(), [], True):
self.args.insert(0, Argument("JSContext*", "aCx")) self.args.insert(0, Argument("JSContext*", "aCx"))
self.args.insert(0, Argument("const GlobalObject&", "aGlobal")) self.args.insert(0, Argument("const GlobalObject&", "aGlobal"))
self.args.append(Argument('ErrorResult&', 'aRv')) self.args.append(Argument('ErrorResult&', 'aRv'))

View File

@ -209,7 +209,7 @@ ToJSValue(JSContext* aCx,
const T& aArgument, const T& aArgument,
JS::MutableHandle<JS::Value> aValue) JS::MutableHandle<JS::Value> aValue)
{ {
return aArgument.ToObject(aCx, aValue); return aArgument.ToObjectInternal(aCx, aValue);
} }
// Accept existing JS values (which may not be same-compartment with us // Accept existing JS values (which may not be same-compartment with us

View File

@ -450,7 +450,7 @@ public:
void PassMozMapOfNullableArrayBuffers(const MozMap<Nullable<ArrayBuffer> >&); void PassMozMapOfNullableArrayBuffers(const MozMap<Nullable<ArrayBuffer> >&);
void PassVariadicTypedArray(const Sequence<Float32Array>&); void PassVariadicTypedArray(const Sequence<Float32Array>&);
void PassVariadicNullableTypedArray(const Sequence<Nullable<Float32Array> >&); void PassVariadicNullableTypedArray(const Sequence<Nullable<Float32Array> >&);
JSObject* ReceiveUint8Array(JSContext*); void ReceiveUint8Array(JSContext*, JS::MutableHandle<JSObject*>);
// DOMString types // DOMString types
void PassString(const nsAString&); void PassString(const nsAString&);
@ -523,7 +523,7 @@ public:
void PassOptionalNullableMozMapOfNullableMozMapOfAny(JSContext*, const Optional<Nullable<MozMap<Nullable<MozMap<JS::Value>>>>>&); void PassOptionalNullableMozMapOfNullableMozMapOfAny(JSContext*, const Optional<Nullable<MozMap<Nullable<MozMap<JS::Value>>>>>&);
void PassOptionalNullableMozMapOfNullableSequenceOfAny(JSContext*, const Optional<Nullable<MozMap<Nullable<Sequence<JS::Value>>>>>&); void PassOptionalNullableMozMapOfNullableSequenceOfAny(JSContext*, const Optional<Nullable<MozMap<Nullable<Sequence<JS::Value>>>>>&);
void PassOptionalNullableSequenceOfNullableMozMapOfAny(JSContext*, const Optional<Nullable<Sequence<Nullable<MozMap<JS::Value>>>>>&); void PassOptionalNullableSequenceOfNullableMozMapOfAny(JSContext*, const Optional<Nullable<Sequence<Nullable<MozMap<JS::Value>>>>>&);
JS::Value ReceiveAny(JSContext*); void ReceiveAny(JSContext*, JS::MutableHandle<JS::Value>);
// object types // object types
void PassObject(JSContext*, JS::Handle<JSObject*>); void PassObject(JSContext*, JS::Handle<JSObject*>);
@ -539,8 +539,8 @@ public:
void PassOptionalNullableSequenceOfNullableSequenceOfObject(JSContext*, const Optional<Nullable<Sequence<Nullable<Sequence<JSObject*> > > > >&); void PassOptionalNullableSequenceOfNullableSequenceOfObject(JSContext*, const Optional<Nullable<Sequence<Nullable<Sequence<JSObject*> > > > >&);
void PassOptionalNullableSequenceOfNullableSequenceOfNullableObject(JSContext*, const Optional<Nullable<Sequence<Nullable<Sequence<JSObject*> > > > >&); void PassOptionalNullableSequenceOfNullableSequenceOfNullableObject(JSContext*, const Optional<Nullable<Sequence<Nullable<Sequence<JSObject*> > > > >&);
void PassMozMapOfObject(JSContext*, const MozMap<JSObject*>&); void PassMozMapOfObject(JSContext*, const MozMap<JSObject*>&);
JSObject* ReceiveObject(JSContext*); void ReceiveObject(JSContext*, JS::MutableHandle<JSObject*>);
JSObject* ReceiveNullableObject(JSContext*); void ReceiveNullableObject(JSContext*, JS::MutableHandle<JSObject*>);
// Union types // Union types
void PassUnion(JSContext*, const ObjectOrLong& arg); void PassUnion(JSContext*, const ObjectOrLong& arg);
@ -767,7 +767,7 @@ public:
TestInterface* PutForwardsAttr(); TestInterface* PutForwardsAttr();
TestInterface* PutForwardsAttr2(); TestInterface* PutForwardsAttr2();
TestInterface* PutForwardsAttr3(); TestInterface* PutForwardsAttr3();
JS::Value JsonifierShouldSkipThis(JSContext*); void GetJsonifierShouldSkipThis(JSContext*, JS::MutableHandle<JS::Value>);
void SetJsonifierShouldSkipThis(JSContext*, JS::Rooted<JS::Value>&); void SetJsonifierShouldSkipThis(JSContext*, JS::Rooted<JS::Value>&);
TestParentInterface* JsonifierShouldSkipThis2(); TestParentInterface* JsonifierShouldSkipThis2();
void SetJsonifierShouldSkipThis2(TestParentInterface&); void SetJsonifierShouldSkipThis2(TestParentInterface&);

View File

@ -429,30 +429,34 @@ BluetoothAdapter::StopDiscovery(ErrorResult& aRv)
return StartStopDiscovery(false, aRv); return StartStopDiscovery(false, aRv);
} }
JS::Value void
BluetoothAdapter::GetDevices(JSContext* aContext, ErrorResult& aRv) BluetoothAdapter::GetDevices(JSContext* aContext,
JS::MutableHandle<JS::Value> aDevices,
ErrorResult& aRv)
{ {
if (!mJsDeviceAddresses) { if (!mJsDeviceAddresses) {
BT_WARNING("Devices not yet set!\n"); BT_WARNING("Devices not yet set!\n");
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return JS::NullValue(); return;
} }
JS::ExposeObjectToActiveJS(mJsDeviceAddresses); JS::ExposeObjectToActiveJS(mJsDeviceAddresses);
return JS::ObjectValue(*mJsDeviceAddresses); aDevices.setObject(*mJsDeviceAddresses);
} }
JS::Value void
BluetoothAdapter::GetUuids(JSContext* aContext, ErrorResult& aRv) BluetoothAdapter::GetUuids(JSContext* aContext,
JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv)
{ {
if (!mJsUuids) { if (!mJsUuids) {
BT_WARNING("UUIDs not yet set!\n"); BT_WARNING("UUIDs not yet set!\n");
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return JS::NullValue(); return;
} }
JS::ExposeObjectToActiveJS(mJsUuids); JS::ExposeObjectToActiveJS(mJsUuids);
return JS::ObjectValue(*mJsUuids); aUuids.setObject(*mJsUuids);
} }
already_AddRefed<DOMRequest> already_AddRefed<DOMRequest>

View File

@ -83,8 +83,10 @@ public:
return mDiscoverableTimeout; return mDiscoverableTimeout;
} }
JS::Value GetDevices(JSContext* aContext, ErrorResult& aRv); void GetDevices(JSContext* aContext, JS::MutableHandle<JS::Value> aDevices,
JS::Value GetUuids(JSContext* aContext, ErrorResult& aRv); ErrorResult& aRv);
void GetUuids(JSContext* aContext, JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv);
already_AddRefed<mozilla::dom::DOMRequest> already_AddRefed<mozilla::dom::DOMRequest>
SetName(const nsAString& aName, ErrorResult& aRv); SetName(const nsAString& aName, ErrorResult& aRv);

View File

@ -206,30 +206,34 @@ BluetoothDevice::Notify(const BluetoothSignal& aData)
} }
} }
JS::Value void
BluetoothDevice::GetUuids(JSContext* aCx, ErrorResult& aRv) BluetoothDevice::GetUuids(JSContext* aContext,
JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv)
{ {
if (!mJsUuids) { if (!mJsUuids) {
BT_WARNING("UUIDs not yet set!"); BT_WARNING("UUIDs not yet set!");
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return JS::NullValue(); return;
} }
JS::ExposeObjectToActiveJS(mJsUuids); JS::ExposeObjectToActiveJS(mJsUuids);
return JS::ObjectValue(*mJsUuids); aUuids.setObject(*mJsUuids);
} }
JS::Value void
BluetoothDevice::GetServices(JSContext* aCx, ErrorResult& aRv) BluetoothDevice::GetServices(JSContext* aCx,
JS::MutableHandle<JS::Value> aServices,
ErrorResult& aRv)
{ {
if (!mJsServices) { if (!mJsServices) {
BT_WARNING("Services not yet set!"); BT_WARNING("Services not yet set!");
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return JS::Value(JSVAL_NULL); return;
} }
JS::ExposeObjectToActiveJS(mJsServices); JS::ExposeObjectToActiveJS(mJsServices);
return JS::ObjectValue(*mJsServices); aServices.setObject(*mJsServices);
} }
JSObject* JSObject*

View File

@ -66,8 +66,10 @@ public:
return mConnected; return mConnected;
} }
JS::Value GetUuids(JSContext* aContext, ErrorResult& aRv); void GetUuids(JSContext* aContext, JS::MutableHandle<JS::Value> aUuids,
JS::Value GetServices(JSContext* aContext, ErrorResult& aRv); ErrorResult& aRv);
void GetServices(JSContext* aContext, JS::MutableHandle<JS::Value> aServices,
ErrorResult& aRv);
nsISupports* nsISupports*
ToISupports() ToISupports()

View File

@ -457,30 +457,34 @@ BluetoothAdapter::StopDiscovery(ErrorResult& aRv)
return StartStopDiscovery(false, aRv); return StartStopDiscovery(false, aRv);
} }
JS::Value void
BluetoothAdapter::GetDevices(JSContext* aContext, ErrorResult& aRv) BluetoothAdapter::GetDevices(JSContext* aContext,
JS::MutableHandle<JS::Value> aDevices,
ErrorResult& aRv)
{ {
if (!mJsDeviceAddresses) { if (!mJsDeviceAddresses) {
BT_WARNING("Devices not yet set!\n"); BT_WARNING("Devices not yet set!\n");
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return JS::NullValue(); return;
} }
JS::ExposeObjectToActiveJS(mJsDeviceAddresses); JS::ExposeObjectToActiveJS(mJsDeviceAddresses);
return JS::ObjectValue(*mJsDeviceAddresses); aDevices.setObject(*mJsDeviceAddresses);
} }
JS::Value void
BluetoothAdapter::GetUuids(JSContext* aContext, ErrorResult& aRv) BluetoothAdapter::GetUuids(JSContext* aContext,
JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv)
{ {
if (!mJsUuids) { if (!mJsUuids) {
BT_WARNING("UUIDs not yet set!\n"); BT_WARNING("UUIDs not yet set!\n");
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return JS::NullValue(); return;
} }
JS::ExposeObjectToActiveJS(mJsUuids); JS::ExposeObjectToActiveJS(mJsUuids);
return JS::ObjectValue(*mJsUuids); aUuids.setObject(*mJsUuids);
} }
already_AddRefed<DOMRequest> already_AddRefed<DOMRequest>

View File

@ -90,8 +90,10 @@ public:
return mDiscoverableTimeout; return mDiscoverableTimeout;
} }
JS::Value GetDevices(JSContext* aContext, ErrorResult& aRv); void GetDevices(JSContext* aContext, JS::MutableHandle<JS::Value> aDevices,
JS::Value GetUuids(JSContext* aContext, ErrorResult& aRv); ErrorResult& aRv);
void GetUuids(JSContext* aContext, JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv);
already_AddRefed<mozilla::dom::DOMRequest> already_AddRefed<mozilla::dom::DOMRequest>
SetName(const nsAString& aName, ErrorResult& aRv); SetName(const nsAString& aName, ErrorResult& aRv);

View File

@ -206,30 +206,34 @@ BluetoothDevice::Notify(const BluetoothSignal& aData)
} }
} }
JS::Value void
BluetoothDevice::GetUuids(JSContext* aCx, ErrorResult& aRv) BluetoothDevice::GetUuids(JSContext* aContext,
JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv)
{ {
if (!mJsUuids) { if (!mJsUuids) {
BT_WARNING("UUIDs not yet set!"); BT_WARNING("UUIDs not yet set!");
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return JS::NullValue(); return;
} }
JS::ExposeObjectToActiveJS(mJsUuids); JS::ExposeObjectToActiveJS(mJsUuids);
return JS::ObjectValue(*mJsUuids); aUuids.setObject(*mJsUuids);
} }
JS::Value void
BluetoothDevice::GetServices(JSContext* aCx, ErrorResult& aRv) BluetoothDevice::GetServices(JSContext* aCx,
JS::MutableHandle<JS::Value> aServices,
ErrorResult& aRv)
{ {
if (!mJsServices) { if (!mJsServices) {
BT_WARNING("Services not yet set!"); BT_WARNING("Services not yet set!");
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return JS::Value(JSVAL_NULL); return;
} }
JS::ExposeObjectToActiveJS(mJsServices); JS::ExposeObjectToActiveJS(mJsServices);
return JS::ObjectValue(*mJsServices); aServices.setObject(*mJsServices);
} }
JSObject* JSObject*

View File

@ -66,8 +66,10 @@ public:
return mConnected; return mConnected;
} }
JS::Value GetUuids(JSContext* aContext, ErrorResult& aRv); void GetUuids(JSContext* aContext, JS::MutableHandle<JS::Value> aUuids,
JS::Value GetServices(JSContext* aContext, ErrorResult& aRv); ErrorResult& aRv);
void GetServices(JSContext* aContext, JS::MutableHandle<JS::Value> aServices,
ErrorResult& aRv);
nsISupports* nsISupports*
ToISupports() ToISupports()

View File

@ -15,6 +15,7 @@
#include "BrowserElementParent.h" #include "BrowserElementParent.h"
#include "mozilla/EventDispatcher.h" #include "mozilla/EventDispatcher.h"
#include "mozilla/dom/HTMLIFrameElement.h" #include "mozilla/dom/HTMLIFrameElement.h"
#include "mozilla/dom/ToJSValue.h"
#include "nsIDOMCustomEvent.h" #include "nsIDOMCustomEvent.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
#include "nsVariant.h" #include "nsVariant.h"
@ -160,7 +161,7 @@ BrowserElementParent::DispatchOpenWindowEvent(Element* aOpenerFrameElement,
JS::Rooted<JSObject*> global(cx, sgo->GetGlobalJSObject()); JS::Rooted<JSObject*> global(cx, sgo->GetGlobalJSObject());
JSAutoCompartment ac(cx, global); JSAutoCompartment ac(cx, global);
if (!detail.ToObject(cx, &val)) { if (!ToJSValue(cx, detail, &val)) {
MOZ_CRASH("Failed to convert dictionary to JS::Value due to OOM."); MOZ_CRASH("Failed to convert dictionary to JS::Value due to OOM.");
return BrowserElementParent::OPEN_WINDOW_IGNORED; return BrowserElementParent::OPEN_WINDOW_IGNORED;
} }
@ -332,7 +333,7 @@ NS_IMETHODIMP DispatchAsyncScrollEventRunnable::Run()
JSAutoCompartment ac(cx, globalJSObject); JSAutoCompartment ac(cx, globalJSObject);
JS::Rooted<JS::Value> val(cx); JS::Rooted<JS::Value> val(cx);
if (!detail.ToObject(cx, &val)) { if (!ToJSValue(cx, detail, &val)) {
MOZ_CRASH("Failed to convert dictionary to JS::Value due to OOM."); MOZ_CRASH("Failed to convert dictionary to JS::Value due to OOM.");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }

View File

@ -293,10 +293,12 @@ CameraCapabilities::ExposureCompensationStep() const
return mExposureCompensationStep; return mExposureCompensationStep;
} }
JS::Value void
CameraCapabilities::RecorderProfiles(JSContext* aCx) const CameraCapabilities::GetRecorderProfiles(JSContext* aCx,
JS::MutableHandle<JS::Value> aRetval) const
{ {
return mRecorderProfiles; JS::ExposeValueToActiveJS(mRecorderProfiles);
aRetval.set(mRecorderProfiles);
} }
void void

View File

@ -71,7 +71,7 @@ public:
double MinExposureCompensation() const; double MinExposureCompensation() const;
double MaxExposureCompensation() const; double MaxExposureCompensation() const;
double ExposureCompensationStep() const; double ExposureCompensationStep() const;
JS::Value RecorderProfiles(JSContext* cx) const; void GetRecorderProfiles(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval) const;
void GetIsoModes(nsTArray<nsString>& aRetVal) const; void GetIsoModes(nsTArray<nsString>& aRetVal) const;
protected: protected:

View File

@ -7,6 +7,7 @@
#ifndef mozilla_dom_RsaKeyAlgorithm_h #ifndef mozilla_dom_RsaKeyAlgorithm_h
#define mozilla_dom_RsaKeyAlgorithm_h #define mozilla_dom_RsaKeyAlgorithm_h
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/KeyAlgorithm.h" #include "mozilla/dom/KeyAlgorithm.h"
#include "js/TypeDecls.h" #include "js/TypeDecls.h"
@ -35,10 +36,16 @@ public:
return mModulusLength; return mModulusLength;
} }
JSObject* PublicExponent(JSContext* cx) const void GetPublicExponent(JSContext* cx, JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aError) const
{ {
TypedArrayCreator<Uint8Array> creator(mPublicExponent); TypedArrayCreator<Uint8Array> creator(mPublicExponent);
return creator.Create(cx); JSObject* retval = creator.Create(cx);
if (!retval) {
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
} else {
aRetval.set(retval);
}
} }
virtual bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const MOZ_OVERRIDE; virtual bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const MOZ_OVERRIDE;

View File

@ -129,7 +129,8 @@ DataStoreDB::UpgradeSchema()
AutoSafeJSContext cx; AutoSafeJSContext cx;
ErrorResult error; ErrorResult error;
JS::Rooted<JS::Value> result(cx, mRequest->GetResult(error)); JS::Rooted<JS::Value> result(cx);
mRequest->GetResult(&result, error);
if (NS_WARN_IF(error.Failed())) { if (NS_WARN_IF(error.Failed())) {
return error.ErrorCode(); return error.ErrorCode();
} }
@ -190,7 +191,8 @@ DataStoreDB::DatabaseOpened()
AutoSafeJSContext cx; AutoSafeJSContext cx;
ErrorResult error; ErrorResult error;
JS::Rooted<JS::Value> result(cx, mRequest->GetResult(error)); JS::Rooted<JS::Value> result(cx);
mRequest->GetResult(&result, error);
if (NS_WARN_IF(error.Failed())) { if (NS_WARN_IF(error.Failed())) {
return error.ErrorCode(); return error.ErrorCode();
} }

View File

@ -10,6 +10,7 @@
#include "DataStoreService.h" #include "DataStoreService.h"
#include "mozilla/dom/DataStoreBinding.h" #include "mozilla/dom/DataStoreBinding.h"
#include "mozilla/dom/indexedDB/IDBObjectStore.h" #include "mozilla/dom/indexedDB/IDBObjectStore.h"
#include "mozilla/dom/ToJSValue.h"
#include "nsIDOMEvent.h" #include "nsIDOMEvent.h"
namespace mozilla { namespace mozilla {
@ -57,7 +58,7 @@ DataStoreRevision::AddRevision(JSContext* aCx,
} }
JS::Rooted<JS::Value> value(aCx); JS::Rooted<JS::Value> value(aCx);
if (!data.ToObject(aCx, &value)) { if (!ToJSValue(aCx, data, &value)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }

View File

@ -587,7 +587,8 @@ public:
AutoSafeJSContext cx; AutoSafeJSContext cx;
ErrorResult error; ErrorResult error;
JS::Rooted<JS::Value> result(cx, mRequest->GetResult(error)); JS::Rooted<JS::Value> result(cx);
mRequest->GetResult(cx, &result, error);
if (NS_WARN_IF(error.Failed())) { if (NS_WARN_IF(error.Failed())) {
return error.ErrorCode(); return error.ErrorCode();
} }

View File

@ -34,11 +34,12 @@ TextEncoder::Init(const nsAString& aEncoding, ErrorResult& aRv)
mEncoder = EncodingUtils::EncoderForEncoding(mEncoding); mEncoder = EncodingUtils::EncoderForEncoding(mEncoding);
} }
JSObject* void
TextEncoder::Encode(JSContext* aCx, TextEncoder::Encode(JSContext* aCx,
JS::Handle<JSObject*> aObj, JS::Handle<JSObject*> aObj,
const nsAString& aString, const nsAString& aString,
const bool aStream, const bool aStream,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv) ErrorResult& aRv)
{ {
// Run the steps of the encoding algorithm. // Run the steps of the encoding algorithm.
@ -48,7 +49,7 @@ TextEncoder::Encode(JSContext* aCx,
nsresult rv = mEncoder->GetMaxLength(data, srcLen, &maxLen); nsresult rv = mEncoder->GetMaxLength(data, srcLen, &maxLen);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
aRv.Throw(rv); aRv.Throw(rv);
return nullptr; return;
} }
// Need a fallible allocator because the caller may be a content // Need a fallible allocator because the caller may be a content
// and the content can specify the length of the string. // and the content can specify the length of the string.
@ -56,7 +57,7 @@ TextEncoder::Encode(JSContext* aCx,
nsAutoArrayPtr<char> buf(new (fallible) char[maxLen + 1]); nsAutoArrayPtr<char> buf(new (fallible) char[maxLen + 1]);
if (!buf) { if (!buf) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY); aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr; return;
} }
int32_t dstLen = maxLen; int32_t dstLen = maxLen;
@ -80,14 +81,14 @@ TextEncoder::Encode(JSContext* aCx,
reinterpret_cast<uint8_t*>(buf.get())); reinterpret_cast<uint8_t*>(buf.get()));
if (!outView) { if (!outView) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY); aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr; return;
} }
} }
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
aRv.Throw(rv); aRv.Throw(rv);
} }
return outView; aRetval.set(outView);
} }
void void

View File

@ -46,12 +46,13 @@ public:
return TextEncoderBinding::Wrap(aCx, this, aTookOwnership); return TextEncoderBinding::Wrap(aCx, this, aTookOwnership);
} }
JSObject* Encode(JSContext* aCx, void Encode(JSContext* aCx,
JS::Handle<JSObject*> aObj, JS::Handle<JSObject*> aObj,
const nsAString& aString, const nsAString& aString,
const TextEncodeOptions& aOptions, const TextEncodeOptions& aOptions,
ErrorResult& aRv) { JS::MutableHandle<JSObject*> aRetval,
return TextEncoder::Encode(aCx, aObj, aString, aOptions.mStream, aRv); ErrorResult& aRv) {
TextEncoder::Encode(aCx, aObj, aString, aOptions.mStream, aRetval, aRv);
} }
protected: protected:
@ -85,13 +86,15 @@ public:
* If the streaming option is false, then the encoding * If the streaming option is false, then the encoding
* algorithm state will get reset. If set to true then * algorithm state will get reset. If set to true then
* the previous encoding is reused/continued. * the previous encoding is reused/continued.
* @return JSObject* The Uint8Array wrapped in a JS object. * @return JSObject* The Uint8Array wrapped in a JS object. Returned via
* the aRetval out param.
*/ */
JSObject* Encode(JSContext* aCx, void Encode(JSContext* aCx,
JS::Handle<JSObject*> aObj, JS::Handle<JSObject*> aObj,
const nsAString& aString, const nsAString& aString,
const bool aStream, const bool aStream,
ErrorResult& aRv); JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv);
private: private:
nsCString mEncoding; nsCString mEncoding;

View File

@ -640,27 +640,27 @@ DataTransfer::MozGetDataAt(const nsAString& aFormat, uint32_t aIndex,
return NS_OK; return NS_OK;
} }
JS::Value void
DataTransfer::MozGetDataAt(JSContext* aCx, const nsAString& aFormat, DataTransfer::MozGetDataAt(JSContext* aCx, const nsAString& aFormat,
uint32_t aIndex, mozilla::ErrorResult& aRv) uint32_t aIndex,
JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aRv)
{ {
nsCOMPtr<nsIVariant> data; nsCOMPtr<nsIVariant> data;
aRv = MozGetDataAt(aFormat, aIndex, getter_AddRefs(data)); aRv = MozGetDataAt(aFormat, aIndex, getter_AddRefs(data));
if (aRv.Failed()) { if (aRv.Failed()) {
return JS::UndefinedValue(); return;
} }
if (!data) { if (!data) {
return JS::NullValue(); return;
} }
JS::Rooted<JS::Value> result(aCx); JS::Rooted<JS::Value> result(aCx);
if (!VariantToJsval(aCx, data, &result)) { if (!VariantToJsval(aCx, data, aRetval)) {
aRv = NS_ERROR_FAILURE; aRv = NS_ERROR_FAILURE;
return JS::UndefinedValue(); return;
} }
return result;
} }
NS_IMETHODIMP NS_IMETHODIMP

View File

@ -164,8 +164,9 @@ public:
void MozSetDataAt(JSContext* aCx, const nsAString& aFormat, void MozSetDataAt(JSContext* aCx, const nsAString& aFormat,
JS::Handle<JS::Value> aData, uint32_t aIndex, JS::Handle<JS::Value> aData, uint32_t aIndex,
mozilla::ErrorResult& aRv); mozilla::ErrorResult& aRv);
JS::Value MozGetDataAt(JSContext* aCx, const nsAString& aFormat, void MozGetDataAt(JSContext* aCx, const nsAString& aFormat,
uint32_t aIndex, mozilla::ErrorResult& aRv); uint32_t aIndex, JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aRv);
bool MozUserCancelled() bool MozUserCancelled()
{ {
return mUserCancelled; return mUserCancelled;

View File

@ -18,6 +18,7 @@
#include "nsDOMJSUtils.h" #include "nsDOMJSUtils.h"
#include "WorkerPrivate.h" #include "WorkerPrivate.h"
#include "mozilla/ContentEvents.h" #include "mozilla/ContentEvents.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/HoldDropJSObjects.h" #include "mozilla/HoldDropJSObjects.h"
#include "mozilla/JSEventHandler.h" #include "mozilla/JSEventHandler.h"
#include "mozilla/Likely.h" #include "mozilla/Likely.h"
@ -155,7 +156,7 @@ JSEventHandler::HandleEvent(nsIDOMEvent* aEvent)
ThreadsafeAutoJSContext cx; ThreadsafeAutoJSContext cx;
error.Construct(cx); error.Construct(cx);
error.Value() = scriptEvent->Error(cx); scriptEvent->GetError(cx, &error.Value());
} else { } else {
msgOrEvent.SetAsEvent() = aEvent->InternalDOMEvent(); msgOrEvent.SetAsEvent() = aEvent->InternalDOMEvent();
} }
@ -210,8 +211,8 @@ JSEventHandler::HandleEvent(nsIDOMEvent* aEvent)
MOZ_ASSERT(mTypedHandler.Type() == TypedEventHandler::eNormal); MOZ_ASSERT(mTypedHandler.Type() == TypedEventHandler::eNormal);
ErrorResult rv; ErrorResult rv;
nsRefPtr<EventHandlerNonNull> handler = mTypedHandler.NormalEventHandler(); nsRefPtr<EventHandlerNonNull> handler = mTypedHandler.NormalEventHandler();
JS::Value retval = JS::Rooted<JS::Value> retval(CycleCollectedJSRuntime::Get()->Runtime());
handler->Call(mTarget, *(aEvent->InternalDOMEvent()), rv); handler->Call(mTarget, *(aEvent->InternalDOMEvent()), &retval, rv);
if (rv.Failed()) { if (rv.Failed()) {
return rv.ErrorCode(); return rv.ErrorCode();
} }

View File

@ -66,18 +66,19 @@ NS_IMETHODIMP
MessageEvent::GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData) MessageEvent::GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData)
{ {
ErrorResult rv; ErrorResult rv;
aData.set(GetData(aCx, rv)); GetData(aCx, aData, rv);
return rv.ErrorCode(); return rv.ErrorCode();
} }
JS::Value void
MessageEvent::GetData(JSContext* aCx, ErrorResult& aRv) MessageEvent::GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData,
ErrorResult& aRv)
{ {
JS::Rooted<JS::Value> data(aCx, mData); JS::ExposeValueToActiveJS(mData);
if (!JS_WrapValue(aCx, &data)) { aData.set(mData);
if (!JS_WrapValue(aCx, aData)) {
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
} }
return data;
} }
NS_IMETHODIMP NS_IMETHODIMP

View File

@ -46,7 +46,8 @@ public:
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE; virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
JS::Value GetData(JSContext* aCx, ErrorResult& aRv); void GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData,
ErrorResult& aRv);
void GetSource(Nullable<OwningWindowProxyOrMessagePort>& aValue) const; void GetSource(Nullable<OwningWindowProxyOrMessagePort>& aValue) const;

View File

@ -610,14 +610,16 @@ IDBCursor::GetSource(OwningIDBObjectStoreOrIDBIndex& aSource) const
} }
} }
JS::Value void
IDBCursor::GetKey(JSContext* aCx, ErrorResult& aRv) IDBCursor::GetKey(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mKey.IsUnset() || !mHaveValue); MOZ_ASSERT(!mKey.IsUnset() || !mHaveValue);
if (!mHaveValue) { if (!mHaveValue) {
return JSVAL_VOID; aResult.setUndefined();
return;
} }
if (!mHaveCachedKey) { if (!mHaveCachedKey) {
@ -627,21 +629,26 @@ IDBCursor::GetKey(JSContext* aCx, ErrorResult& aRv)
} }
aRv = mKey.ToJSVal(aCx, mCachedKey); aRv = mKey.ToJSVal(aCx, mCachedKey);
ENSURE_SUCCESS(aRv, JSVAL_VOID); if (NS_WARN_IF(aRv.Failed())) {
return;
}
mHaveCachedKey = true; mHaveCachedKey = true;
} }
return mCachedKey; JS::ExposeValueToActiveJS(mCachedKey);
aResult.set(mCachedKey);
} }
JS::Value void
IDBCursor::GetPrimaryKey(JSContext* aCx, ErrorResult& aRv) IDBCursor::GetPrimaryKey(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
if (!mHaveValue) { if (!mHaveValue) {
return JSVAL_VOID; aResult.setUndefined();
return;
} }
if (!mHaveCachedPrimaryKey) { if (!mHaveCachedPrimaryKey) {
@ -655,22 +662,27 @@ IDBCursor::GetPrimaryKey(JSContext* aCx, ErrorResult& aRv)
MOZ_ASSERT(!key.IsUnset()); MOZ_ASSERT(!key.IsUnset());
aRv = key.ToJSVal(aCx, mCachedPrimaryKey); aRv = key.ToJSVal(aCx, mCachedPrimaryKey);
ENSURE_SUCCESS(aRv, JSVAL_VOID); if (NS_WARN_IF(aRv.Failed())) {
return;
}
mHaveCachedPrimaryKey = true; mHaveCachedPrimaryKey = true;
} }
return mCachedPrimaryKey; JS::ExposeValueToActiveJS(mCachedPrimaryKey);
aResult.set(mCachedPrimaryKey);
} }
JS::Value void
IDBCursor::GetValue(JSContext* aCx, ErrorResult& aRv) IDBCursor::GetValue(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mType == OBJECTSTORE || mType == INDEXOBJECT); MOZ_ASSERT(mType == OBJECTSTORE || mType == INDEXOBJECT);
if (!mHaveValue) { if (!mHaveValue) {
return JSVAL_VOID; aResult.setUndefined();
return;
} }
if (!mHaveCachedValue) { if (!mHaveCachedValue) {
@ -682,7 +694,7 @@ IDBCursor::GetValue(JSContext* aCx, ErrorResult& aRv)
JS::Rooted<JS::Value> val(aCx); JS::Rooted<JS::Value> val(aCx);
if (!IDBObjectStore::DeserializeValue(aCx, mCloneReadInfo, &val)) { if (!IDBObjectStore::DeserializeValue(aCx, mCloneReadInfo, &val)) {
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR); aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
return JSVAL_VOID; return;
} }
mCloneReadInfo.mCloneBuffer.clear(); mCloneReadInfo.mCloneBuffer.clear();
@ -691,7 +703,8 @@ IDBCursor::GetValue(JSContext* aCx, ErrorResult& aRv)
mHaveCachedValue = true; mHaveCachedValue = true;
} }
return mCachedValue; JS::ExposeValueToActiveJS(mCachedValue);
aResult.set(mCachedValue);
} }
void void

View File

@ -184,11 +184,13 @@ public:
IDBCursorDirection IDBCursorDirection
GetDirection() const; GetDirection() const;
JS::Value void
GetKey(JSContext* aCx, ErrorResult& aRv); GetKey(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv);
JS::Value void
GetPrimaryKey(JSContext* aCx, ErrorResult& aRv); GetPrimaryKey(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv);
already_AddRefed<IDBRequest> already_AddRefed<IDBRequest>
Update(JSContext* aCx, JS::Handle<JS::Value> aValue, ErrorResult& aRv); Update(JSContext* aCx, JS::Handle<JS::Value> aValue, ErrorResult& aRv);
@ -202,8 +204,9 @@ public:
already_AddRefed<IDBRequest> already_AddRefed<IDBRequest>
Delete(JSContext* aCx, ErrorResult& aRv); Delete(JSContext* aCx, ErrorResult& aRv);
JS::Value void
GetValue(JSContext* aCx, ErrorResult& aRv); GetValue(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv);
protected: protected:
IDBCursor(); IDBCursor();

View File

@ -826,24 +826,30 @@ IDBIndex::WrapObject(JSContext* aCx)
return IDBIndexBinding::Wrap(aCx, this); return IDBIndexBinding::Wrap(aCx, this);
} }
JS::Value void
IDBIndex::GetKeyPath(JSContext* aCx, ErrorResult& aRv) IDBIndex::GetKeyPath(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv)
{ {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (!mCachedKeyPath.isUndefined()) { if (!mCachedKeyPath.isUndefined()) {
return mCachedKeyPath; JS::ExposeValueToActiveJS(mCachedKeyPath);
aResult.set(mCachedKeyPath);
return;
} }
aRv = GetKeyPath().ToJSVal(aCx, mCachedKeyPath); aRv = GetKeyPath().ToJSVal(aCx, mCachedKeyPath);
ENSURE_SUCCESS(aRv, JSVAL_VOID); if (NS_WARN_IF(aRv.Failed())) {
return;
}
if (mCachedKeyPath.isGCThing()) { if (mCachedKeyPath.isGCThing()) {
mozilla::HoldJSObjects(this); mozilla::HoldJSObjects(this);
mRooted = true; mRooted = true;
} }
return mCachedKeyPath; JS::ExposeValueToActiveJS(mCachedKeyPath);
aResult.set(mCachedKeyPath);
} }
already_AddRefed<IDBRequest> already_AddRefed<IDBRequest>

View File

@ -176,8 +176,9 @@ public:
return mObjectStore; return mObjectStore;
} }
JS::Value void
GetKeyPath(JSContext* aCx, ErrorResult& aRv); GetKeyPath(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv);
bool bool
MultiEntry() const MultiEntry() const

View File

@ -164,8 +164,9 @@ IDBKeyRange::WrapObject(JSContext* aCx)
return IDBKeyRangeBinding::Wrap(aCx, this); return IDBKeyRangeBinding::Wrap(aCx, this);
} }
JS::Value void
IDBKeyRange::GetLower(JSContext* aCx, ErrorResult& aRv) IDBKeyRange::GetLower(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -177,17 +178,19 @@ IDBKeyRange::GetLower(JSContext* aCx, ErrorResult& aRv)
aRv = Lower().ToJSVal(aCx, mCachedLowerVal); aRv = Lower().ToJSVal(aCx, mCachedLowerVal);
if (aRv.Failed()) { if (aRv.Failed()) {
return JS::UndefinedValue(); return;
} }
mHaveCachedLowerVal = true; mHaveCachedLowerVal = true;
} }
return mCachedLowerVal; JS::ExposeValueToActiveJS(mCachedLowerVal);
aResult.set(mCachedLowerVal);
} }
JS::Value void
IDBKeyRange::GetUpper(JSContext* aCx, ErrorResult& aRv) IDBKeyRange::GetUpper(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -199,13 +202,14 @@ IDBKeyRange::GetUpper(JSContext* aCx, ErrorResult& aRv)
aRv = Upper().ToJSVal(aCx, mCachedUpperVal); aRv = Upper().ToJSVal(aCx, mCachedUpperVal);
if (aRv.Failed()) { if (aRv.Failed()) {
return JS::UndefinedValue(); return;
} }
mHaveCachedUpperVal = true; mHaveCachedUpperVal = true;
} }
return mCachedUpperVal; JS::ExposeValueToActiveJS(mCachedUpperVal);
aResult.set(mCachedUpperVal);
} }
// static // static

View File

@ -156,11 +156,13 @@ public:
return mGlobal; return mGlobal;
} }
JS::Value void
GetLower(JSContext* aCx, ErrorResult& aRv); GetLower(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv);
JS::Value void
GetUpper(JSContext* aCx, ErrorResult& aRv); GetUpper(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv);
bool bool
LowerOpen() const LowerOpen() const

View File

@ -2622,24 +2622,30 @@ IDBObjectStore::WrapObject(JSContext* aCx)
return IDBObjectStoreBinding::Wrap(aCx, this); return IDBObjectStoreBinding::Wrap(aCx, this);
} }
JS::Value void
IDBObjectStore::GetKeyPath(JSContext* aCx, ErrorResult& aRv) IDBObjectStore::GetKeyPath(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv)
{ {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (!mCachedKeyPath.isUndefined()) { if (!mCachedKeyPath.isUndefined()) {
return mCachedKeyPath; JS::ExposeValueToActiveJS(mCachedKeyPath);
aResult.set(mCachedKeyPath);
return;
} }
aRv = GetKeyPath().ToJSVal(aCx, mCachedKeyPath); aRv = GetKeyPath().ToJSVal(aCx, mCachedKeyPath);
ENSURE_SUCCESS(aRv, JSVAL_VOID); if (NS_WARN_IF(aRv.Failed())) {
return;
}
if (mCachedKeyPath.isGCThing()) { if (mCachedKeyPath.isGCThing()) {
mozilla::HoldJSObjects(this); mozilla::HoldJSObjects(this);
mRooted = true; mRooted = true;
} }
return mCachedKeyPath; JS::ExposeValueToActiveJS(mCachedKeyPath);
aResult.set(mCachedKeyPath);
} }
already_AddRefed<DOMStringList> already_AddRefed<DOMStringList>

View File

@ -282,8 +282,9 @@ public:
aName.Assign(mName); aName.Assign(mName);
} }
JS::Value void
GetKeyPath(JSContext* aCx, ErrorResult& aRv); GetKeyPath(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv);
already_AddRefed<DOMStringList> already_AddRefed<DOMStringList>
GetIndexNames(ErrorResult& aRv); GetIndexNames(ErrorResult& aRv);

View File

@ -326,8 +326,9 @@ IDBRequest::WrapObject(JSContext* aCx)
return IDBRequestBinding::Wrap(aCx, this); return IDBRequestBinding::Wrap(aCx, this);
} }
JS::Value void
IDBRequest::GetResult(mozilla::ErrorResult& aRv) const IDBRequest::GetResult(JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv) const
{ {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -336,7 +337,8 @@ IDBRequest::GetResult(mozilla::ErrorResult& aRv) const
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
} }
return mResultVal; JS::ExposeValueToActiveJS(mResultVal);
aResult.set(mResultVal);
} }
mozilla::dom::DOMError* mozilla::dom::DOMError*

View File

@ -131,13 +131,14 @@ public:
return GetOwner(); return GetOwner();
} }
JS::Value void
GetResult(ErrorResult& aRv) const; GetResult(JS::MutableHandle<JS::Value> aResult, ErrorResult& aRv) const;
JS::Value void
GetResult(JSContext* aCx, ErrorResult& aRv) const GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv) const
{ {
return GetResult(aRv); GetResult(aResult, aRv);
} }
IDBTransaction* IDBTransaction*

View File

@ -408,7 +408,8 @@ IndexedDBDatabaseParent::HandleRequestEvent(nsIDOMEvent* aEvent,
AutoSafeJSContext cx; AutoSafeJSContext cx;
ErrorResult error; ErrorResult error;
JS::Rooted<JS::Value> result(cx, mOpenRequest->GetResult(cx, error)); JS::Rooted<JS::Value> result(cx);
mOpenRequest->GetResult(cx, &result, error);
ENSURE_SUCCESS(error, error.ErrorCode()); ENSURE_SUCCESS(error, error.ErrorCode());
MOZ_ASSERT(!result.isPrimitive()); MOZ_ASSERT(!result.isPrimitive());

View File

@ -10,6 +10,7 @@
#include "mozilla/dom/MozClirModeEvent.h" #include "mozilla/dom/MozClirModeEvent.h"
#include "mozilla/dom/MozEmergencyCbModeEvent.h" #include "mozilla/dom/MozEmergencyCbModeEvent.h"
#include "mozilla/dom/MozOtaStatusEvent.h" #include "mozilla/dom/MozOtaStatusEvent.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/USSDReceivedEvent.h" #include "mozilla/dom/USSDReceivedEvent.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/Services.h" #include "mozilla/Services.h"
@ -605,7 +606,7 @@ MobileConnection::SetCallForwardingOption(const MozCallForwardingOptions& aOptio
AutoSafeJSContext cx; AutoSafeJSContext cx;
JS::Rooted<JS::Value> options(cx); JS::Rooted<JS::Value> options(cx);
if (!aOptions.ToObject(cx, &options)) { if (!ToJSValue(cx, aOptions, &options)) {
aRv.Throw(NS_ERROR_TYPE_ERR); aRv.Throw(NS_ERROR_TYPE_ERR);
return nullptr; return nullptr;
} }
@ -636,7 +637,7 @@ MobileConnection::GetCallBarringOption(const MozCallBarringOptions& aOptions,
AutoSafeJSContext cx; AutoSafeJSContext cx;
JS::Rooted<JS::Value> options(cx); JS::Rooted<JS::Value> options(cx);
if (!aOptions.ToObject(cx, &options)) { if (!ToJSValue(cx, aOptions, &options)) {
aRv.Throw(NS_ERROR_TYPE_ERR); aRv.Throw(NS_ERROR_TYPE_ERR);
return nullptr; return nullptr;
} }
@ -667,7 +668,7 @@ MobileConnection::SetCallBarringOption(const MozCallBarringOptions& aOptions,
AutoSafeJSContext cx; AutoSafeJSContext cx;
JS::Rooted<JS::Value> options(cx); JS::Rooted<JS::Value> options(cx);
if (!aOptions.ToObject(cx, &options)) { if (!ToJSValue(cx, aOptions, &options)) {
aRv.Throw(NS_ERROR_TYPE_ERR); aRv.Throw(NS_ERROR_TYPE_ERR);
return nullptr; return nullptr;
} }
@ -698,7 +699,7 @@ MobileConnection::ChangeCallBarringPassword(const MozCallBarringOptions& aOption
AutoSafeJSContext cx; AutoSafeJSContext cx;
JS::Rooted<JS::Value> options(cx); JS::Rooted<JS::Value> options(cx);
if (!aOptions.ToObject(cx, &options)) { if (!ToJSValue(cx, aOptions, &options)) {
aRv.Throw(NS_ERROR_TYPE_ERR); aRv.Throw(NS_ERROR_TYPE_ERR);
return nullptr; return nullptr;
} }

View File

@ -60,46 +60,28 @@ public:
return mTnf; return mTnf;
} }
JSObject* GetType(JSContext* cx) const void GetType(JSContext* cx, JS::MutableHandle<JSObject*> retval) const
{ {
if (mType) { if (mType) {
return GetTypeObject(); JS::ExposeObjectToActiveJS(mType);
} else {
return nullptr;
} }
} retval.set(mType);
JSObject* GetTypeObject() const
{
JS::ExposeObjectToActiveJS(mType);
return mType;
} }
JSObject* GetId(JSContext* cx) const void GetId(JSContext* cx, JS::MutableHandle<JSObject*> retval) const
{ {
if (mId) { if (mId) {
return GetIdObject(); JS::ExposeObjectToActiveJS(mId);
} else {
return nullptr;
} }
} retval.set(mId);
JSObject* GetIdObject() const
{
JS::ExposeObjectToActiveJS(mId);
return mId;
} }
JSObject* GetPayload(JSContext* cx) const void GetPayload(JSContext* cx, JS::MutableHandle<JSObject*> retval) const
{ {
if (mPayload) { if (mPayload) {
return GetPayloadObject(); JS::ExposeObjectToActiveJS(mPayload);
} else {
return nullptr;
} }
} retval.set(mPayload);
JSObject* GetPayloadObject() const
{
JS::ExposeObjectToActiveJS(mPayload);
return mPayload;
} }
private: private:

View File

@ -17,7 +17,6 @@ const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/ObjectWrapper.jsm");
XPCOMUtils.defineLazyServiceGetter(this, XPCOMUtils.defineLazyServiceGetter(this,
"appsService", "appsService",

View File

@ -219,8 +219,8 @@ WrapperPromiseCallback::Call(JSContext* aCx,
// If invoking callback threw an exception, run resolver's reject with the // If invoking callback threw an exception, run resolver's reject with the
// thrown exception as argument and the synchronous flag set. // thrown exception as argument and the synchronous flag set.
JS::Rooted<JS::Value> retValue(aCx, JS::Rooted<JS::Value> retValue(aCx);
mCallback->Call(value, rv, CallbackObject::eRethrowExceptions)); mCallback->Call(value, &retValue, rv, CallbackObject::eRethrowExceptions);
rv.WouldReportJSException(); rv.WouldReportJSException();

View File

@ -9,7 +9,6 @@ let Ci = Components.interfaces;
let Cu = Components.utils; let Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/ObjectWrapper.jsm");
this.EXPORTED_SYMBOLS = ["SettingsDB", "SETTINGSDB_NAME", "SETTINGSSTORE_NAME"]; this.EXPORTED_SYMBOLS = ["SettingsDB", "SETTINGSDB_NAME", "SETTINGSSTORE_NAME"];
@ -18,6 +17,18 @@ function debug(s) {
if (DEBUG) dump("-*- SettingsDB: " + s + "\n"); if (DEBUG) dump("-*- SettingsDB: " + s + "\n");
} }
const TYPED_ARRAY_THINGS = new Set([
"Int8Array",
"Uint8Array",
"Uint8ClampedArray",
"Int16Array",
"Uint16Array",
"Int32Array",
"Uint32Array",
"Float32Array",
"Float64Array",
]);
this.SETTINGSDB_NAME = "settings"; this.SETTINGSDB_NAME = "settings";
this.SETTINGSDB_VERSION = 4; this.SETTINGSDB_VERSION = 4;
this.SETTINGSSTORE_NAME = "settings"; this.SETTINGSSTORE_NAME = "settings";
@ -176,9 +187,29 @@ SettingsDB.prototype = {
return aValue return aValue
}, },
getObjectKind: function(aObject) {
if (aObject === null || aObject === undefined) {
return "primitive";
} else if (Array.isArray(aObject)) {
return "array";
} else if (aObject instanceof Ci.nsIDOMFile) {
return "file";
} else if (aObject instanceof Ci.nsIDOMBlob) {
return "blob";
} else if (aObject.constructor.name == "Date") {
return "date";
} else if (TYPED_ARRAY_THINGS.has(aObject.constructor.name)) {
return aObject.constructor.name;
} else if (typeof aObject == "object") {
return "object";
} else {
return "primitive";
}
},
// Makes sure any property that is a data: uri gets converted to a Blob. // Makes sure any property that is a data: uri gets converted to a Blob.
prepareValue: function(aObject) { prepareValue: function(aObject) {
let kind = ObjectWrapper.getObjectKind(aObject); let kind = this.getObjectKind(aObject);
if (kind == "array") { if (kind == "array") {
let res = []; let res = [];
aObject.forEach(function(aObj) { aObject.forEach(function(aObj) {

View File

@ -17,7 +17,6 @@ Cu.import("resource://gre/modules/SettingsQueue.jsm");
Cu.import("resource://gre/modules/SettingsDB.jsm"); Cu.import("resource://gre/modules/SettingsDB.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/ObjectWrapper.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "cpmm", XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1", "@mozilla.org/childprocessmessagemanager;1",
@ -197,6 +196,13 @@ SettingsLock.prototype = {
}, },
_serializePreservingBinaries: function _serializePreservingBinaries(aObject) { _serializePreservingBinaries: function _serializePreservingBinaries(aObject) {
function needsUUID(aValue) {
if (!aValue || !aValue.constructor) {
return false;
}
return (aValue.constructor.name == "Date") || (aValue instanceof Ci.nsIDOMFile) ||
(aValue instanceof Ci.nsIDOMBlob);
}
// We need to serialize settings objects, otherwise they can change between // We need to serialize settings objects, otherwise they can change between
// the set() call and the enqueued request being processed. We can't simply // the set() call and the enqueued request being processed. We can't simply
// parse(stringify(obj)) because that breaks things like Blobs, Files and // parse(stringify(obj)) because that breaks things like Blobs, Files and
@ -206,8 +212,7 @@ SettingsLock.prototype = {
let binaries = Object.create(null); let binaries = Object.create(null);
let stringified = JSON.stringify(aObject, function(key, value) { let stringified = JSON.stringify(aObject, function(key, value) {
value = manager._settingsDB.prepareValue(value); value = manager._settingsDB.prepareValue(value);
let kind = ObjectWrapper.getObjectKind(value); if (needsUUID(value)) {
if (kind == "file" || kind == "blob" || kind == "date") {
let uuid = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator) let uuid = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator)
.generateUUID().toString(); .generateUUID().toString();
binaries[uuid] = value; binaries[uuid] = value;

Some files were not shown because too many files have changed in this diff Show More