зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1561357 - Implement [Serializable] for DOMException r=smaug,sfink
Skipping stack serialization here as * it's optional per the spec * no WPT test exists * Chrome doesn't support it either * not sure how it's usable when transferred to other domain. Differential Revision: https://phabricator.services.mozilla.com/D143625
This commit is contained in:
Родитель
6e33650078
Коммит
51a7018052
|
@ -19,6 +19,9 @@
|
|||
#include "mozilla/dom/DOMExceptionBinding.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
|
||||
#include "js/TypeDecls.h"
|
||||
#include "js/StructuredClone.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
|
@ -182,6 +185,12 @@ Exception::Exception(const nsACString& aMessage, nsresult aResult,
|
|||
}
|
||||
}
|
||||
|
||||
Exception::Exception(nsCString&& aMessage, nsresult aResult, nsCString&& aName)
|
||||
: mMessage(std::move(aMessage)),
|
||||
mResult(aResult),
|
||||
mName(std::move(aName)),
|
||||
mHoldingJSVal(false) {}
|
||||
|
||||
Exception::~Exception() {
|
||||
if (mHoldingJSVal) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
@ -324,6 +333,9 @@ DOMException::DOMException(nsresult aRv, const nsACString& aMessage,
|
|||
const nsACString& aName, uint16_t aCode,
|
||||
nsIStackFrame* aLocation)
|
||||
: Exception(aMessage, aRv, aName, aLocation, nullptr), mCode(aCode) {}
|
||||
DOMException::DOMException(nsresult aRv, nsCString&& aMessage,
|
||||
nsCString&& aName, uint16_t aCode)
|
||||
: Exception(std::move(aMessage), aRv, std::move(aName)), mCode(aCode) {}
|
||||
|
||||
void DOMException::ToString(JSContext* aCx, nsACString& aReturn) {
|
||||
aReturn.Truncate();
|
||||
|
@ -399,4 +411,54 @@ already_AddRefed<DOMException> DOMException::Create(
|
|||
return inst.forget();
|
||||
}
|
||||
|
||||
static bool ReadAsCString(JSContext* aCx, JSStructuredCloneReader* aReader,
|
||||
nsCString& aString) {
|
||||
JS::Rooted<JSString*> jsMessage(aCx);
|
||||
if (!JS_ReadString(aReader, &jsMessage)) {
|
||||
return false;
|
||||
}
|
||||
return AssignJSString(aCx, aString, jsMessage);
|
||||
}
|
||||
|
||||
already_AddRefed<DOMException> DOMException::ReadStructuredClone(
|
||||
JSContext* aCx, nsIGlobalObject* aGlobal,
|
||||
JSStructuredCloneReader* aReader) {
|
||||
uint32_t reserved;
|
||||
nsresult rv;
|
||||
nsCString message;
|
||||
nsCString name;
|
||||
uint16_t code;
|
||||
|
||||
if (!JS_ReadBytes(aReader, &reserved, 4) || !JS_ReadBytes(aReader, &rv, 4) ||
|
||||
!ReadAsCString(aCx, aReader, message) ||
|
||||
!ReadAsCString(aCx, aReader, name) || !JS_ReadBytes(aReader, &code, 2)) {
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
return do_AddRef(
|
||||
new DOMException(rv, std::move(message), std::move(name), code));
|
||||
}
|
||||
|
||||
bool DOMException::WriteStructuredClone(
|
||||
JSContext* aCx, JSStructuredCloneWriter* aWriter) const {
|
||||
JS::Rooted<JS::Value> messageValue(aCx);
|
||||
JS::Rooted<JS::Value> nameValue(aCx);
|
||||
if (!NonVoidByteStringToJsval(aCx, mMessage, &messageValue) ||
|
||||
!NonVoidByteStringToJsval(aCx, mName, &nameValue)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::Rooted<JSString*> message(aCx, messageValue.toString());
|
||||
JS::Rooted<JSString*> name(aCx, nameValue.toString());
|
||||
|
||||
static_assert(sizeof(nsresult) == 4);
|
||||
|
||||
// A reserved field. Use this to indicate stack serialization support etc.
|
||||
uint32_t reserved = 0;
|
||||
return JS_WriteBytes(aWriter, &reserved, 4) &&
|
||||
JS_WriteBytes(aWriter, &mResult, 4) &&
|
||||
JS_WriteString(aWriter, message) && JS_WriteString(aWriter, name) &&
|
||||
JS_WriteBytes(aWriter, &mCode, 2);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "nsString.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
|
||||
class nsIGlobalObject;
|
||||
class nsIStackFrame;
|
||||
|
||||
nsresult NS_GetNameAndMessageForDOMNSResult(nsresult aNSResult,
|
||||
|
@ -104,6 +105,7 @@ class Exception : public nsIException, public nsWrapperCache {
|
|||
Exception(const nsACString& aMessage, nsresult aResult,
|
||||
const nsACString& aName, nsIStackFrame* aLocation,
|
||||
nsISupports* aData);
|
||||
Exception(nsCString&& aMessage, nsresult aResult, nsCString&& aName);
|
||||
|
||||
protected:
|
||||
virtual ~Exception();
|
||||
|
@ -140,6 +142,8 @@ class DOMException : public Exception {
|
|||
DOMException(nsresult aRv, const nsACString& aMessage,
|
||||
const nsACString& aName, uint16_t aCode,
|
||||
nsIStackFrame* aLocation = nullptr);
|
||||
DOMException(nsresult aRv, nsCString&& aMessage, nsCString&& aName,
|
||||
uint16_t aCode);
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING_INHERITED(DOMException, Exception)
|
||||
|
||||
|
@ -171,6 +175,12 @@ class DOMException : public Exception {
|
|||
static already_AddRefed<DOMException> Create(nsresult aRv,
|
||||
const nsACString& aMessage);
|
||||
|
||||
static already_AddRefed<DOMException> ReadStructuredClone(
|
||||
JSContext* aCx, nsIGlobalObject* aGlobal,
|
||||
JSStructuredCloneReader* aReader);
|
||||
bool WriteStructuredClone(JSContext* aCx,
|
||||
JSStructuredCloneWriter* aWriter) const;
|
||||
|
||||
protected:
|
||||
virtual ~DOMException() = default;
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ enum StructuredCloneTags {
|
|||
|
||||
// IMPORTANT: Don't change the order of these enum values. You could break
|
||||
// IDB.
|
||||
EMPTY_SLOT_8,
|
||||
SCTAG_DOM_DOMEXCEPTION,
|
||||
|
||||
// IMPORTANT: Don't change the order of these enum values. You could break
|
||||
// IDB.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* http://dom.spec.whatwg.org/#exception-domexception
|
||||
* https://webidl.spec.whatwg.org/#idl-DOMException
|
||||
*
|
||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||
* liability, trademark and document use rules apply.
|
||||
|
@ -31,7 +31,7 @@ interface mixin ExceptionMembers
|
|||
readonly attribute DOMString filename;
|
||||
// Valid line numbers begin at '1'. '0' indicates unknown.
|
||||
readonly attribute unsigned long lineNumber;
|
||||
// Valid column numbers begin at 0.
|
||||
// Valid column numbers begin at 0.
|
||||
// We don't have an unambiguous indicator for unknown.
|
||||
readonly attribute unsigned long columnNumber;
|
||||
|
||||
|
@ -65,7 +65,8 @@ Exception includes ExceptionMembers;
|
|||
// XXXkhuey this is an 'exception', not an interface, but we don't have any
|
||||
// parser or codegen mechanisms for dealing with exceptions.
|
||||
[ExceptionClass,
|
||||
Exposed=(Window, Worker)]
|
||||
Exposed=(Window, Worker),
|
||||
Serializable]
|
||||
interface DOMException {
|
||||
constructor(optional DOMString message = "", optional DOMString name);
|
||||
|
||||
|
|
|
@ -729,6 +729,9 @@ JS_PUBLIC_API bool JS_ReadUint32Pair(JSStructuredCloneReader* r, uint32_t* p1,
|
|||
JS_PUBLIC_API bool JS_ReadBytes(JSStructuredCloneReader* r, void* p,
|
||||
size_t len);
|
||||
|
||||
JS_PUBLIC_API bool JS_ReadString(JSStructuredCloneReader* r,
|
||||
JS::MutableHandleString str);
|
||||
|
||||
JS_PUBLIC_API bool JS_ReadDouble(JSStructuredCloneReader* r, double* v);
|
||||
|
||||
JS_PUBLIC_API bool JS_ReadTypedArray(JSStructuredCloneReader* r,
|
||||
|
|
|
@ -477,6 +477,8 @@ struct JSStructuredCloneReader {
|
|||
// Any value passed to JS_ReadStructuredClone.
|
||||
void* closure;
|
||||
|
||||
friend bool JS_ReadString(JSStructuredCloneReader* r,
|
||||
JS::MutableHandleString str);
|
||||
friend bool JS_ReadTypedArray(JSStructuredCloneReader* r,
|
||||
MutableHandleValue vp);
|
||||
};
|
||||
|
@ -3561,6 +3563,23 @@ JS_PUBLIC_API bool JS_ReadBytes(JSStructuredCloneReader* r, void* p,
|
|||
return r->input().readBytes(p, len);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API bool JS_ReadString(JSStructuredCloneReader* r,
|
||||
MutableHandleString str) {
|
||||
uint32_t tag, data;
|
||||
if (!r->input().readPair(&tag, &data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tag == SCTAG_STRING) {
|
||||
str.set(r->readString(data));
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_ReportErrorNumberASCII(r->context(), GetErrorMessage, nullptr,
|
||||
JSMSG_SC_BAD_SERIALIZED_DATA, "expected string");
|
||||
return false;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API bool JS_ReadDouble(JSStructuredCloneReader* r, double* v) {
|
||||
return r->input().readDouble(v);
|
||||
}
|
||||
|
|
|
@ -5,15 +5,9 @@
|
|||
[Error.message: getter is ignored when cloning]
|
||||
expected: FAIL
|
||||
|
||||
[DOMException objects created by the UA can be cloned]
|
||||
expected: FAIL
|
||||
|
||||
[EvalError objects can be cloned]
|
||||
expected: FAIL
|
||||
|
||||
[DOMException objects can be cloned]
|
||||
expected: FAIL
|
||||
|
||||
[URIError objects can be cloned]
|
||||
expected: FAIL
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче