diff --git a/content/base/public/HTMLSplitOnSpacesTokenizer.h b/content/base/public/HTMLSplitOnSpacesTokenizer.h new file mode 100644 index 000000000000..8eb96b245e13 --- /dev/null +++ b/content/base/public/HTMLSplitOnSpacesTokenizer.h @@ -0,0 +1,14 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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/. */ + +#ifndef HTMLSplitOnSpacesTokenizer_h +#define HTMLSplitOnSpacesTokenizer_h + +#include "nsCharSeparatedTokenizer.h" + +typedef nsCharSeparatedTokenizerTemplate + HTMLSplitOnSpacesTokenizer; + +#endif diff --git a/content/base/public/moz.build b/content/base/public/moz.build index 7da0a383a5f3..648473f4d887 100644 --- a/content/base/public/moz.build +++ b/content/base/public/moz.build @@ -34,11 +34,13 @@ XPIDL_MODULE = 'content_base' MODULE = 'content' EXPORTS += [ + 'HTMLSplitOnSpacesTokenizer.h', 'mozFlushType.h', 'nsCaseTreatment.h', 'nsContentCID.h', 'nsContentCreatorFunctions.h', 'nsContentPolicyUtils.h', + 'nsContentTypeParser.h', 'nsContentUtils.h', 'nsCopySupport.h', 'nsDOMFile.h', diff --git a/content/base/public/nsContentTypeParser.h b/content/base/public/nsContentTypeParser.h new file mode 100644 index 000000000000..abc1042011c2 --- /dev/null +++ b/content/base/public/nsContentTypeParser.h @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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/. */ + +#ifndef nsContentTypeParser_h +#define nsContentTypeParser_h + +#include "nsAString.h" + +class nsIMIMEHeaderParam; + +class nsContentTypeParser { +public: + nsContentTypeParser(const nsAString& aString); + ~nsContentTypeParser(); + + nsresult GetParameter(const char* aParameterName, nsAString& aResult); + nsresult GetType(nsAString& aResult) + { + return GetParameter(nullptr, aResult); + } + +private: + NS_ConvertUTF16toUTF8 mString; + nsIMIMEHeaderParam* mService; +}; + +#endif + diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 9b14b311960c..93eb1cb9a4b1 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -22,11 +22,8 @@ #include "mozilla/Assertions.h" #include "mozilla/GuardObjects.h" #include "mozilla/TimeStamp.h" -#include "nsAString.h" -#include "nsCharSeparatedTokenizer.h" #include "nsContentListDeclarations.h" #include "nsMathUtils.h" -#include "nsReadableUtils.h" class imgICache; class imgIContainer; @@ -66,7 +63,6 @@ class nsIInterfaceRequestor; class nsIIOService; class nsIJSRuntimeService; class nsILineBreaker; -class nsIMIMEHeaderParam; class nsINameSpaceManager; class nsINodeInfo; class nsIObserver; @@ -106,6 +102,7 @@ template class nsCOMArray; template class nsTArray; template class nsDataHashtable; template class nsRefPtrHashtable; +template class nsReadingIterator; namespace JS { class Value; @@ -143,6 +140,11 @@ class nsIBidiKeyboard; extern const char kLoadAsData[]; +// Stolen from nsReadableUtils, but that's OK, since we can declare the same +// name multiple times. +const nsAFlatString& EmptyString(); +const nsAFlatCString& EmptyCString(); + enum EventNameType { EventNameType_None = 0x0000, EventNameType_HTML = 0x0001, @@ -811,26 +813,6 @@ public: = EmptyString(), uint32_t aLineNumber = 0, uint32_t aColumnNumber = 0); - // This overload allows passing a literal string for aCategory. - template - static nsresult ReportToConsole(uint32_t aErrorFlags, - const char (&aCategory)[N], - nsIDocument* aDocument, - PropertiesFile aFile, - const char *aMessageName, - const PRUnichar **aParams = nullptr, - uint32_t aParamsLength = 0, - nsIURI* aURI = nullptr, - const nsAFlatString& aSourceLine - = EmptyString(), - uint32_t aLineNumber = 0, - uint32_t aColumnNumber = 0) - { - nsDependentCString category(aCategory, N - 1); - return ReportToConsole(aErrorFlags, category, aDocument, aFile, - aMessageName, aParams, aParamsLength, aURI, - aSourceLine, aLineNumber, aColumnNumber); - } /** * Get the localized string named |aKey| in properties file |aFile|. @@ -1241,11 +1223,7 @@ public: * @param aResult the result. Out param. */ static void GetNodeTextContent(nsINode* aNode, bool aDeep, - nsAString& aResult) - { - aResult.Truncate(); - AppendNodeTextContent(aNode, aDeep, aResult); - } + nsAString& aResult); /** * Same as GetNodeTextContents but appends the result rather than sets it. @@ -1264,13 +1242,7 @@ public: /** * Delete strings allocated for nsContentList matches */ - static void DestroyMatchString(void* aData) - { - if (aData) { - nsString* matchString = static_cast(aData); - delete matchString; - } - } + static void DestroyMatchString(void* aData); /** * Unbinds the content from the tree and nulls it out if it's not null. @@ -1340,7 +1312,7 @@ public: bool aAllowData, uint32_t aContentPolicyType, nsISupports* aContext, - const nsACString& aMimeGuess = EmptyCString(), + const nsAFlatCString& aMimeGuess = EmptyCString(), nsISupports* aExtra = nullptr); /** @@ -2052,37 +2024,7 @@ public: */ static JSVersion ParseJavascriptVersion(const nsAString& aVersionStr); - static bool IsJavascriptMIMEType(const nsAString& aMIMEType) - { - // Table ordered from most to least likely JS MIME types. - static const char* jsTypes[] = { - "text/javascript", - "text/ecmascript", - "application/javascript", - "application/ecmascript", - "application/x-javascript", - "application/x-ecmascript", - "text/javascript1.0", - "text/javascript1.1", - "text/javascript1.2", - "text/javascript1.3", - "text/javascript1.4", - "text/javascript1.5", - "text/jscript", - "text/livescript", - "text/x-ecmascript", - "text/x-javascript", - nullptr - }; - - for (uint32_t i = 0; jsTypes[i]; ++i) { - if (aMIMEType.LowerCaseEqualsASCII(jsTypes[i])) { - return true; - } - } - - return false; - } + static bool IsJavascriptMIMEType(const nsAString& aMIMEType); static void SplitMimeType(const nsAString& aValue, nsString& aType, nsString& aParams); @@ -2263,9 +2205,6 @@ private: #endif }; -typedef nsCharSeparatedTokenizerTemplate - HTMLSplitOnSpacesTokenizer; - #define NS_HOLD_JS_OBJECTS(obj, clazz) \ nsContentUtils::HoldJSObjects(NS_CYCLE_COLLECTION_UPCAST(obj, clazz), \ NS_CYCLE_COLLECTION_PARTICIPANT(clazz)) @@ -2367,20 +2306,4 @@ public: } \ } -class nsContentTypeParser { -public: - nsContentTypeParser(const nsAString& aString); - ~nsContentTypeParser(); - - nsresult GetParameter(const char* aParameterName, nsAString& aResult); - nsresult GetType(nsAString& aResult) - { - return GetParameter(nullptr, aResult); - } - -private: - NS_ConvertUTF16toUTF8 mString; - nsIMIMEHeaderParam* mService; -}; - #endif /* nsContentUtils_h___ */ diff --git a/content/base/src/Element.cpp b/content/base/src/Element.cpp index a293f75af3f9..a616835d8685 100644 --- a/content/base/src/Element.cpp +++ b/content/base/src/Element.cpp @@ -1133,7 +1133,7 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent) // The element being removed is an ancestor of the full-screen element, // exit full-screen state. nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "DOM", OwnerDoc(), + NS_LITERAL_CSTRING("DOM"), OwnerDoc(), nsContentUtils::eDOM_PROPERTIES, "RemovedFullScreenElement"); // Fully exit full-screen. @@ -2432,7 +2432,7 @@ Element::MozRequestFullScreen() const char* error = GetFullScreenError(OwnerDoc()); if (error) { nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "DOM", OwnerDoc(), + NS_LITERAL_CSTRING("DOM"), OwnerDoc(), nsContentUtils::eDOM_PROPERTIES, error); nsRefPtr e = diff --git a/content/base/src/nsAttrValue.h b/content/base/src/nsAttrValue.h index 473bd74b82b1..3f84c77a439c 100644 --- a/content/base/src/nsAttrValue.h +++ b/content/base/src/nsAttrValue.h @@ -63,7 +63,7 @@ public: nsCheapString(nsStringBuffer* aBuf) { if (aBuf) - aBuf->ToString(aBuf->StorageSize()/2 - 1, *this); + aBuf->ToString(aBuf->StorageSize()/sizeof(PRUnichar) - 1, *this); } }; diff --git a/content/base/src/nsCSPService.cpp b/content/base/src/nsCSPService.cpp index 42e8b994bdf3..853e564aa649 100644 --- a/content/base/src/nsCSPService.cpp +++ b/content/base/src/nsCSPService.cpp @@ -299,7 +299,7 @@ CSPService::AsyncOnChannelRedirect(nsIChannel *oldChannel, const PRUnichar *formatParams[] = { NS_ConvertUTF8toUTF16(newUriSpec).get() }; if (NS_SUCCEEDED(rv)) { nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "Redirect Error", nullptr, + NS_LITERAL_CSTRING("Redirect Error"), nullptr, nsContentUtils::eDOM_PROPERTIES, "InvalidRedirectChannelWarning", formatParams, 1); diff --git a/content/base/src/nsContentListDeclarations.h b/content/base/src/nsContentListDeclarations.h index 7116ef3486f8..5890bf49e539 100644 --- a/content/base/src/nsContentListDeclarations.h +++ b/content/base/src/nsContentListDeclarations.h @@ -8,7 +8,7 @@ #include #include "nsCOMPtr.h" -#include "nsStringGlue.h" +#include "nsStringFwd.h" class nsContentList; class nsIAtom; diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index aded060e9f5b..c208ccd6f930 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -168,6 +168,8 @@ #include "nsWrapperCacheInlines.h" #include "nsXULPopupManager.h" #include "xpcprivate.h" // nsXPConnect +#include "HTMLSplitOnSpacesTokenizer.h" +#include "nsContentTypeParser.h" #ifdef IBMBIDI #include "nsIBidiKeyboard.h" @@ -4350,7 +4352,7 @@ nsContentUtils::CheckSecurityBeforeLoad(nsIURI* aURIToLoad, bool aAllowData, uint32_t aContentPolicyType, nsISupports* aContext, - const nsACString& aMimeGuess, + const nsAFlatCString& aMimeGuess, nsISupports* aExtra) { NS_PRECONDITION(aLoadingPrincipal, "Must have a loading principal here"); @@ -6490,3 +6492,52 @@ nsContentUtils::DOMWindowDumpEnabled() return true; #endif } + +void +nsContentUtils::GetNodeTextContent(nsINode* aNode, bool aDeep, nsAString& aResult) +{ + aResult.Truncate(); + AppendNodeTextContent(aNode, aDeep, aResult); +} + +void +nsContentUtils::DestroyMatchString(void* aData) +{ + if (aData) { + nsString* matchString = static_cast(aData); + delete matchString; + } +} + +bool +nsContentUtils::IsJavascriptMIMEType(const nsAString& aMIMEType) +{ + // Table ordered from most to least likely JS MIME types. + static const char* jsTypes[] = { + "text/javascript", + "text/ecmascript", + "application/javascript", + "application/ecmascript", + "application/x-javascript", + "application/x-ecmascript", + "text/javascript1.0", + "text/javascript1.1", + "text/javascript1.2", + "text/javascript1.3", + "text/javascript1.4", + "text/javascript1.5", + "text/jscript", + "text/livescript", + "text/x-ecmascript", + "text/x-javascript", + nullptr + }; + + for (uint32_t i = 0; jsTypes[i]; ++i) { + if (aMIMEType.LowerCaseEqualsASCII(jsTypes[i])) { + return true; + } + } + + return false; +} diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index fe0fb2230fe5..1caa52d7f94f 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -212,6 +212,7 @@ #include "nsIDOMLocation.h" #include "nsIHttpChannelInternal.h" #include "nsISecurityConsoleMessage.h" +#include "nsCharSeparatedTokenizer.h" using namespace mozilla; using namespace mozilla::dom; @@ -2465,7 +2466,7 @@ CSPErrorQueue::Flush(nsIDocument* aDocument) { for (uint32_t i = 0; i < mErrors.Length(); i++) { nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "CSP", aDocument, + NS_LITERAL_CSTRING("CSP"), aDocument, nsContentUtils::eSECURITY_PROPERTIES, mErrors[i]); } @@ -4498,7 +4499,7 @@ void nsDocument::ReportEmptyGetElementByIdArg() { nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "DOM", this, + NS_LITERAL_CSTRING("DOM"), this, nsContentUtils::eDOM_PROPERTIES, "EmptyGetElementByIdParam"); } @@ -6153,7 +6154,7 @@ nsDocument::GetBoxObjectFor(Element* aElement, ErrorResult& aRv) if (!mHasWarnedAboutBoxObjects && !aElement->IsXUL()) { mHasWarnedAboutBoxObjects = true; nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "BoxObjects", this, + NS_LITERAL_CSTRING("BoxObjects"), this, nsContentUtils::eDOM_PROPERTIES, "UseOfGetBoxObjectForWarning"); } @@ -9050,7 +9051,7 @@ nsIDocument::WarnOnceAbout(DeprecatedOperations aOperation, uint32_t flags = asError ? nsIScriptError::errorFlag : nsIScriptError::warningFlag; nsContentUtils::ReportToConsole(flags, - "DOM Core", this, + NS_LITERAL_CSTRING("DOM Core"), this, nsContentUtils::eDOM_PROPERTIES, kWarnings[aOperation]); } @@ -10034,7 +10035,7 @@ LogFullScreenDenied(bool aLogFailure, const char* aMessage, nsIDocument* aDoc) false); e->PostDOMEvent(); nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "DOM", aDoc, + NS_LITERAL_CSTRING("DOM"), aDoc, nsContentUtils::eDOM_PROPERTIES, aMessage); } diff --git a/content/base/src/nsMixedContentBlocker.cpp b/content/base/src/nsMixedContentBlocker.cpp index b853daaa2f29..7dd519b62e32 100644 --- a/content/base/src/nsMixedContentBlocker.cpp +++ b/content/base/src/nsMixedContentBlocker.cpp @@ -158,7 +158,7 @@ LogBlockingMixedContent(MixedContentTypes classification, const PRUnichar* strings[] = { locationSpecUTF16.get() }; nsContentUtils::ReportToConsole(nsIScriptError::errorFlag, - "Mixed Content Blocker", + NS_LITERAL_CSTRING("Mixed Content Blocker"), aRootDoc, nsContentUtils::eSECURITY_PROPERTIES, classification == eMixedDisplay ? "BlockMixedDisplayContent" : "BlockMixedActiveContent", diff --git a/content/base/src/nsObjectLoadingContent.cpp b/content/base/src/nsObjectLoadingContent.cpp index e87211a27142..a763f5a6e3e5 100644 --- a/content/base/src/nsObjectLoadingContent.cpp +++ b/content/base/src/nsObjectLoadingContent.cpp @@ -1263,7 +1263,7 @@ nsObjectLoadingContent::CheckJavaCodebase() // the exception of URIs that represent local files if (NS_URIIsLocalFile(mBaseURI) && nsScriptSecurityManager::GetStrictFileOriginPolicy() && - !NS_RelaxStrictFileOriginPolicy(mBaseURI, principalBaseURI)) { + !NS_RelaxStrictFileOriginPolicy(mBaseURI, principalBaseURI, true)) { LOG(("OBJLC [%p]: Java failed RelaxStrictFileOriginPolicy for file URI", this)); return false; diff --git a/content/base/src/nsScriptLoader.cpp b/content/base/src/nsScriptLoader.cpp index a554e2fe13c3..e23aab5d2df7 100644 --- a/content/base/src/nsScriptLoader.cpp +++ b/content/base/src/nsScriptLoader.cpp @@ -45,6 +45,7 @@ #include "mozilla/dom/Element.h" #include "nsCrossSiteListenerProxy.h" #include "nsSandboxFlags.h" +#include "nsContentTypeParser.h" #include "mozilla/CORSMode.h" #include "mozilla/Attributes.h" diff --git a/content/base/src/nsXMLHttpRequest.cpp b/content/base/src/nsXMLHttpRequest.cpp index 40a522a4ba8b..40713c2cf134 100644 --- a/content/base/src/nsXMLHttpRequest.cpp +++ b/content/base/src/nsXMLHttpRequest.cpp @@ -575,7 +575,7 @@ static void LogMessage(const char* aWarning, nsPIDOMWindow* aWindow) doc = aWindow->GetExtantDoc(); } nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "DOM", doc, + NS_LITERAL_CSTRING("DOM"), doc, nsContentUtils::eDOM_PROPERTIES, aWarning); } diff --git a/content/canvas/src/WebGLContext.cpp b/content/canvas/src/WebGLContext.cpp index 9e810a6d2a02..c2dead52a94a 100644 --- a/content/canvas/src/WebGLContext.cpp +++ b/content/canvas/src/WebGLContext.cpp @@ -1596,17 +1596,19 @@ WebGLContext::GetSupportedExtensions(JSContext *cx, Nullable< nsTArray NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLContext) NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLContext) -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_10(WebGLContext, +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_12(WebGLContext, mCanvasElement, mExtensions, mBound2DTextures, mBoundCubeMapTextures, mBoundArrayBuffer, + mBoundTransformFeedbackBuffer, mCurrentProgram, mBoundFramebuffer, mBoundRenderbuffer, mBoundVertexArray, - mActiveOcclusionQuery) + mActiveOcclusionQuery, + mActiveTransformFeedbackQuery) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLContext) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY diff --git a/content/canvas/src/WebGLContext.h b/content/canvas/src/WebGLContext.h index 27d06ebfca93..e80fc247185c 100644 --- a/content/canvas/src/WebGLContext.h +++ b/content/canvas/src/WebGLContext.h @@ -731,7 +731,10 @@ public: JS::Value GetQueryObject(JSContext* cx, WebGLQuery *query, WebGLenum pname); private: - bool ValidateTargetParameter(WebGLenum target, const char* infos); + WebGLRefPtr mActiveOcclusionQuery; + WebGLRefPtr mActiveTransformFeedbackQuery; + + bool ValidateQueryTargetParameter(WebGLenum target, const char* infos); WebGLRefPtr& GetActiveQueryByTarget(WebGLenum target); // ----------------------------------------------------------------------------- @@ -1131,7 +1134,6 @@ protected: WebGLRefPtr mBoundFramebuffer; WebGLRefPtr mBoundRenderbuffer; WebGLRefPtr mBoundVertexArray; - WebGLRefPtr mActiveOcclusionQuery; LinkedList mTextures; LinkedList mBuffers; diff --git a/content/canvas/src/WebGLContextAsyncQueries.cpp b/content/canvas/src/WebGLContextAsyncQueries.cpp index 44e2bff019c0..64726919c892 100644 --- a/content/canvas/src/WebGLContextAsyncQueries.cpp +++ b/content/canvas/src/WebGLContextAsyncQueries.cpp @@ -9,7 +9,7 @@ using namespace mozilla; /* - * We fake ANY_SAMPLES_PASSED and ANY_SAMPLES_PASSED_CONSERVATIVE with + * We fake ANY_SAMPLES_PASSED and ANY_SAMPLES_PASSED_CONSERVATIVE with * SAMPLES_PASSED on desktop. * * OpenGL ES 3.0 spec 4.1.6 @@ -27,6 +27,8 @@ GetQueryTargetEnumString(WebGLenum target) return "ANY_SAMPLES_PASSED"; case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE: return "ANY_SAMPLES_PASSED_CONSERVATIVE"; + case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + return "TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN"; default: break; } @@ -111,7 +113,7 @@ WebGLContext::BeginQuery(WebGLenum target, WebGLQuery *query) if (!IsContextStable()) return; - if (!ValidateTargetParameter(target, "beginQuery")) { + if (!ValidateQueryTargetParameter(target, "beginQuery")) { return; } @@ -165,7 +167,11 @@ WebGLContext::BeginQuery(WebGLenum target, WebGLQuery *query) MakeContextCurrent(); - gl->fBeginQuery(SimulateOcclusionQueryTarget(gl, target), query->mGLName); + if (target == LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN) { + gl->fBeginQuery(LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query->mGLName); + } else { + gl->fBeginQuery(SimulateOcclusionQueryTarget(gl, target), query->mGLName); + } GetActiveQueryByTarget(target) = query; } @@ -176,7 +182,7 @@ WebGLContext::EndQuery(WebGLenum target) if (!IsContextStable()) return; - if (!ValidateTargetParameter(target, "endQuery")) { + if (!ValidateQueryTargetParameter(target, "endQuery")) { return; } @@ -202,7 +208,11 @@ WebGLContext::EndQuery(WebGLenum target) MakeContextCurrent(); - gl->fEndQuery(SimulateOcclusionQueryTarget(gl, target)); + if (target == LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN) { + gl->fEndQuery(LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); + } else { + gl->fEndQuery(SimulateOcclusionQueryTarget(gl, target)); + } GetActiveQueryByTarget(target) = nullptr; } @@ -227,7 +237,7 @@ WebGLContext::GetQuery(WebGLenum target, WebGLenum pname) if (!IsContextStable()) return nullptr; - if (!ValidateTargetParameter(target, "getQuery")) { + if (!ValidateQueryTargetParameter(target, "getQuery")) { return nullptr; } @@ -299,6 +309,10 @@ WebGLContext::GetQueryObject(JSContext* cx, WebGLQuery *query, WebGLenum pname) MakeContextCurrent(); gl->fGetQueryObjectuiv(query->mGLName, LOCAL_GL_QUERY_RESULT, &returned); + if (query->mType == LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN) { + return JS::NumberValue(uint32_t(returned)); + } + /* * test (returned != 0) is important because ARB_occlusion_query on desktop drivers * return the number of samples drawed when the OpenGL ES extension @@ -316,23 +330,34 @@ WebGLContext::GetQueryObject(JSContext* cx, WebGLQuery *query, WebGLenum pname) } bool -WebGLContext::ValidateTargetParameter(WebGLenum target, const char* infos) +WebGLContext::ValidateQueryTargetParameter(WebGLenum target, const char* infos) { - if (target != LOCAL_GL_ANY_SAMPLES_PASSED && - target != LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE) - { - ErrorInvalidEnum("%s: target must be ANY_SAMPLES_PASSED{_CONSERVATIVE}", infos); - return false; + switch (target) { + case LOCAL_GL_ANY_SAMPLES_PASSED: + case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE: + case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + return true; } - return true; + ErrorInvalidEnum("%s: unknown query target", infos); + return false; } WebGLRefPtr& WebGLContext::GetActiveQueryByTarget(WebGLenum target) { - MOZ_ASSERT(ValidateTargetParameter(target, "private WebGLContext::GetActiveQueryByTarget")); + MOZ_ASSERT(ValidateQueryTargetParameter(target, "private WebGLContext::GetActiveQueryByTarget")); + switch (target) { + case LOCAL_GL_ANY_SAMPLES_PASSED: + case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE: + return mActiveOcclusionQuery; + case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + return mActiveTransformFeedbackQuery; + } + + MOZ_ASSERT(false, "WebGLContext::GetActiveQueryByTarget is not compatible with " + "WebGLContext::ValidateQueryTargetParameter"); return mActiveOcclusionQuery; } diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index 17d7d053b383..c6954ffb13f1 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -111,10 +111,7 @@ using namespace mozilla::dom; static const LayoutDeviceIntPoint kInvalidRefPoint = LayoutDeviceIntPoint(-1,-1); -static bool sLeftClickOnly = true; -static bool sKeyCausesActivation = true; static uint32_t sESMInstanceCount = 0; -static int32_t sChromeAccessModifier = 0, sContentAccessModifier = 0; int32_t nsEventStateManager::sUserInputEventDepth = 0; bool nsEventStateManager::sNormalLMouseEventInProcess = false; nsEventStateManager* nsEventStateManager::sActiveESM = nullptr; @@ -268,30 +265,6 @@ GetDocumentFromWindow(nsIDOMWindow *aWindow) return win ? win->GetExtantDoc() : nullptr; } -static int32_t -GetAccessModifierMaskFromPref(int32_t aItemType) -{ - int32_t accessKey = Preferences::GetInt("ui.key.generalAccessKey", -1); - switch (accessKey) { - case -1: break; // use the individual prefs - case nsIDOMKeyEvent::DOM_VK_SHIFT: return NS_MODIFIER_SHIFT; - case nsIDOMKeyEvent::DOM_VK_CONTROL: return NS_MODIFIER_CONTROL; - case nsIDOMKeyEvent::DOM_VK_ALT: return NS_MODIFIER_ALT; - case nsIDOMKeyEvent::DOM_VK_META: return NS_MODIFIER_META; - case nsIDOMKeyEvent::DOM_VK_WIN: return NS_MODIFIER_OS; - default: return 0; - } - - switch (aItemType) { - case nsIDocShellTreeItem::typeChrome: - return Preferences::GetInt("ui.key.chromeAccess", 0); - case nsIDocShellTreeItem::typeContent: - return Preferences::GetInt("ui.key.contentAccess", 0); - default: - return 0; - } -} - struct DeltaValues { DeltaValues() : deltaX(0.0), deltaY(0.0) {} @@ -681,8 +654,7 @@ nsEventStateManager::nsEventStateManager() mLClickCount(0), mMClickCount(0), mRClickCount(0), - m_haveShutdown(false), - mClickHoldContextMenu(false) + m_haveShutdown(false) { if (sESMInstanceCount == 0) { gUserInteractionTimerCallback = new nsUITimerCallback(); @@ -710,17 +682,6 @@ nsEventStateManager::UpdateUserActivityTimer(void) return NS_OK; } -static const char* kObservedPrefs[] = { - "accessibility.accesskeycausesactivation", - "nglayout.events.dispatchLeftClickOnly", - "ui.key.generalAccessKey", - "ui.key.chromeAccess", - "ui.key.contentAccess", - "ui.click_hold_context_menus", - "dom.popup_allowed_events", - nullptr -}; - nsresult nsEventStateManager::Init() { @@ -732,21 +693,8 @@ nsEventStateManager::Init() observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, true); if (sESMInstanceCount == 1) { - sKeyCausesActivation = - Preferences::GetBool("accessibility.accesskeycausesactivation", - sKeyCausesActivation); - sLeftClickOnly = - Preferences::GetBool("nglayout.events.dispatchLeftClickOnly", - sLeftClickOnly); - sChromeAccessModifier = - GetAccessModifierMaskFromPref(nsIDocShellTreeItem::typeChrome); - sContentAccessModifier = - GetAccessModifierMaskFromPref(nsIDocShellTreeItem::typeContent); + Prefs::Init(); } - Preferences::AddWeakObservers(this, kObservedPrefs); - - mClickHoldContextMenu = - Preferences::GetBool("ui.click_hold_context_menus", false); return NS_OK; } @@ -756,7 +704,7 @@ nsEventStateManager::~nsEventStateManager() if (sActiveESM == this) { sActiveESM = nullptr; } - if (mClickHoldContextMenu) + if (Prefs::ClickHoldContextMenu()) KillClickHoldTimer(); if (mDocument == sMouseOverDocument) @@ -773,6 +721,7 @@ nsEventStateManager::~nsEventStateManager() gUserInteractionTimer->Cancel(); NS_RELEASE(gUserInteractionTimer); } + Prefs::Shutdown(); WheelPrefs::Shutdown(); DeltaAccumulator::Shutdown(); } @@ -800,7 +749,6 @@ nsEventStateManager::~nsEventStateManager() nsresult nsEventStateManager::Shutdown() { - Preferences::RemoveObservers(this, kObservedPrefs); m_haveShutdown = true; return NS_OK; } @@ -810,38 +758,8 @@ nsEventStateManager::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData) { - if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) + if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) { Shutdown(); - else if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) { - if (!someData) - return NS_OK; - - nsDependentString data(someData); - if (data.EqualsLiteral("accessibility.accesskeycausesactivation")) { - sKeyCausesActivation = - Preferences::GetBool("accessibility.accesskeycausesactivation", - sKeyCausesActivation); - } else if (data.EqualsLiteral("nglayout.events.dispatchLeftClickOnly")) { - sLeftClickOnly = - Preferences::GetBool("nglayout.events.dispatchLeftClickOnly", - sLeftClickOnly); - } else if (data.EqualsLiteral("ui.key.generalAccessKey")) { - sChromeAccessModifier = - GetAccessModifierMaskFromPref(nsIDocShellTreeItem::typeChrome); - sContentAccessModifier = - GetAccessModifierMaskFromPref(nsIDocShellTreeItem::typeContent); - } else if (data.EqualsLiteral("ui.key.chromeAccess")) { - sChromeAccessModifier = - GetAccessModifierMaskFromPref(nsIDocShellTreeItem::typeChrome); - } else if (data.EqualsLiteral("ui.key.contentAccess")) { - sContentAccessModifier = - GetAccessModifierMaskFromPref(nsIDocShellTreeItem::typeContent); - } else if (data.EqualsLiteral("ui.click_hold_context_menus")) { - mClickHoldContextMenu = - Preferences::GetBool("ui.click_hold_context_menus", false); - } else if (data.EqualsLiteral("dom.popup_allowed_events")) { - nsDOMEvent::PopupAllowedEventsChanged(); - } } return NS_OK; @@ -965,7 +883,7 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext, case NS_MOUSE_BUTTON_UP: switch (static_cast(aEvent)->button) { case nsMouseEvent::eLeftButton: - if (mClickHoldContextMenu) { + if (Prefs::ClickHoldContextMenu()) { KillClickHoldTimer(); } #ifndef XP_OS2 @@ -1018,7 +936,7 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext, FlushPendingEvents(aPresContext); break; case NS_DRAGDROP_GESTURE: - if (mClickHoldContextMenu) { + if (Prefs::ClickHoldContextMenu()) { // an external drag gesture event came in, not generated internally // by Gecko. Make sure we get rid of the click-hold timer. KillClickHoldTimer(); @@ -1048,10 +966,12 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext, modifierMask |= NS_MODIFIER_OS; // Prevent keyboard scrolling while an accesskey modifier is in use. - if (modifierMask && (modifierMask == sChromeAccessModifier || - modifierMask == sContentAccessModifier)) + if (modifierMask && + (modifierMask == Prefs::ChromeAccessModifierMask() || + modifierMask == Prefs::ContentAccessModifierMask())) { HandleAccessKey(aPresContext, keyEvent, aStatus, nullptr, eAccessKeyProcessingNormal, modifierMask); + } } // then fall through... case NS_KEY_DOWN: @@ -1220,8 +1140,9 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext, return NS_OK; } -static int32_t -GetAccessModifierMask(nsISupports* aDocShell) +// static +int32_t +nsEventStateManager::GetAccessModifierMaskFor(nsISupports* aDocShell) { nsCOMPtr treeItem(do_QueryInterface(aDocShell)); if (!treeItem) @@ -1232,10 +1153,10 @@ GetAccessModifierMask(nsISupports* aDocShell) switch (itemType) { case nsIDocShellTreeItem::typeChrome: - return sChromeAccessModifier; + return Prefs::ChromeAccessModifierMask(); case nsIDocShellTreeItem::typeContent: - return sContentAccessModifier; + return Prefs::ContentAccessModifierMask(); default: return -1; // invalid modifier @@ -1314,7 +1235,7 @@ nsEventStateManager::ExecuteAccessKey(nsTArray& aAccessCharCodes, content = mAccessKeys[(start + count) % length]; frame = content->GetPrimaryFrame(); if (IsAccessKeyTarget(content, frame, accessKey)) { - bool shouldActivate = sKeyCausesActivation; + bool shouldActivate = Prefs::KeyCausesActivation(); while (shouldActivate && ++count <= length) { nsIContent *oc = mAccessKeys[(start + count) % length]; nsIFrame *of = oc->GetPrimaryFrame(); @@ -1345,25 +1266,25 @@ nsEventStateManager::GetAccessKeyLabelPrefix(nsAString& aPrefix) nsContentUtils::GetModifierSeparatorText(separator); nsCOMPtr container = mPresContext->GetContainer(); - int32_t modifier = GetAccessModifierMask(container); + int32_t modifierMask = GetAccessModifierMaskFor(container); - if (modifier & NS_MODIFIER_CONTROL) { + if (modifierMask & NS_MODIFIER_CONTROL) { nsContentUtils::GetControlText(modifierText); aPrefix.Append(modifierText + separator); } - if (modifier & NS_MODIFIER_META) { + if (modifierMask & NS_MODIFIER_META) { nsContentUtils::GetMetaText(modifierText); aPrefix.Append(modifierText + separator); } - if (modifier & NS_MODIFIER_OS) { + if (modifierMask & NS_MODIFIER_OS) { nsContentUtils::GetOSText(modifierText); aPrefix.Append(modifierText + separator); } - if (modifier & NS_MODIFIER_ALT) { + if (modifierMask & NS_MODIFIER_ALT) { nsContentUtils::GetAltText(modifierText); aPrefix.Append(modifierText + separator); } - if (modifier & NS_MODIFIER_SHIFT) { + if (modifierMask & NS_MODIFIER_SHIFT) { nsContentUtils::GetShiftText(modifierText); aPrefix.Append(modifierText + separator); } @@ -1382,7 +1303,7 @@ nsEventStateManager::HandleAccessKey(nsPresContext* aPresContext, // Alt or other accesskey modifier is down, we may need to do an accesskey if (mAccessKeys.Count() > 0 && - aModifierMask == GetAccessModifierMask(pcContainer)) { + aModifierMask == GetAccessModifierMaskFor(pcContainer)) { // Someone registered an accesskey. Find and activate it. nsAutoTArray accessCharCodes; nsContentUtils::GetAccessKeyCandidates(aEvent, accessCharCodes); @@ -1900,7 +1821,7 @@ nsEventStateManager::BeginTrackingDragGesture(nsPresContext* aPresContext, mGestureModifiers = inDownEvent->modifiers; mGestureDownButtons = inDownEvent->buttons; - if (mClickHoldContextMenu) { + if (Prefs::ClickHoldContextMenu()) { // fire off a timer to track click-hold CreateClickHoldTimer(aPresContext, inDownFrame, inDownEvent); } @@ -1990,7 +1911,7 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext, LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); if (DeprecatedAbs(pt.x - mGestureDownPoint.x) > pixelThresholdX || DeprecatedAbs(pt.y - mGestureDownPoint.y) > pixelThresholdY) { - if (mClickHoldContextMenu) { + if (Prefs::ClickHoldContextMenu()) { // stop the click-hold before we fire off the drag gesture, in case // it takes a long time KillClickHoldTimer(); @@ -5585,3 +5506,107 @@ nsEventStateManager::WheelPrefs::IsOverOnePageScrollAllowedY( return Abs(mMultiplierY[index]) >= MIN_MULTIPLIER_VALUE_ALLOWING_OVER_ONE_PAGE_SCROLL; } + +/******************************************************************/ +/* nsEventStateManager::Prefs */ +/******************************************************************/ + +bool nsEventStateManager::Prefs::sKeyCausesActivation = true; +bool nsEventStateManager::Prefs::sClickHoldContextMenu = false; +int32_t nsEventStateManager::Prefs::sGenericAccessModifierKey = -1; +int32_t nsEventStateManager::Prefs::sChromeAccessModifierMask = 0; +int32_t nsEventStateManager::Prefs::sContentAccessModifierMask = 0; + +// static +void +nsEventStateManager::Prefs::Init() +{ + DebugOnly rv = + Preferences::AddBoolVarCache(&sKeyCausesActivation, + "accessibility.accesskeycausesactivation", + sKeyCausesActivation); + MOZ_ASSERT(NS_SUCCEEDED(rv), + "Failed to observe \"accessibility.accesskeycausesactivation\""); + rv = Preferences::AddBoolVarCache(&sClickHoldContextMenu, + "ui.click_hold_context_menus", + sClickHoldContextMenu); + MOZ_ASSERT(NS_SUCCEEDED(rv), + "Failed to observe \"ui.click_hold_context_menus\""); + rv = Preferences::AddIntVarCache(&sGenericAccessModifierKey, + "ui.key.generalAccessKey", + sGenericAccessModifierKey); + MOZ_ASSERT(NS_SUCCEEDED(rv), + "Failed to observe \"ui.key.generalAccessKey\""); + rv = Preferences::AddIntVarCache(&sChromeAccessModifierMask, + "ui.key.chromeAccess", + sChromeAccessModifierMask); + MOZ_ASSERT(NS_SUCCEEDED(rv), + "Failed to observe \"ui.key.chromeAccess\""); + rv = Preferences::AddIntVarCache(&sContentAccessModifierMask, + "ui.key.contentAccess", + sContentAccessModifierMask); + MOZ_ASSERT(NS_SUCCEEDED(rv), + "Failed to observe \"ui.key.contentAccess\""); + + rv = Preferences::RegisterCallback(OnChange, "dom.popup_allowed_events"); + MOZ_ASSERT(NS_SUCCEEDED(rv), + "Failed to observe \"dom.popup_allowed_events\""); +} + +// static +int +nsEventStateManager::Prefs::OnChange(const char* aPrefName, void*) +{ + nsDependentCString prefName(aPrefName); + if (prefName.EqualsLiteral("dom.popup_allowed_events")) { + nsDOMEvent::PopupAllowedEventsChanged(); + } + return 0; +} + +// static +void +nsEventStateManager::Prefs::Shutdown() +{ + Preferences::UnregisterCallback(OnChange, "dom.popup_allowed_events"); +} + +// static +int32_t +nsEventStateManager::Prefs::ChromeAccessModifierMask() +{ + return GetAccessModifierMask(nsIDocShellTreeItem::typeChrome); +} + +// static +int32_t +nsEventStateManager::Prefs::ContentAccessModifierMask() +{ + return GetAccessModifierMask(nsIDocShellTreeItem::typeContent); +} + +// static +int32_t +nsEventStateManager::Prefs::GetAccessModifierMask(int32_t aItemType) +{ + switch (sGenericAccessModifierKey) { + case -1: break; // use the individual prefs + case nsIDOMKeyEvent::DOM_VK_SHIFT: return NS_MODIFIER_SHIFT; + case nsIDOMKeyEvent::DOM_VK_CONTROL: return NS_MODIFIER_CONTROL; + case nsIDOMKeyEvent::DOM_VK_ALT: return NS_MODIFIER_ALT; + case nsIDOMKeyEvent::DOM_VK_META: return NS_MODIFIER_META; + case nsIDOMKeyEvent::DOM_VK_WIN: return NS_MODIFIER_OS; + default: return 0; + } + + switch (aItemType) { + case nsIDocShellTreeItem::typeChrome: + return sChromeAccessModifierMask; + case nsIDocShellTreeItem::typeContent: + return sContentAccessModifierMask; + default: + return 0; + } +} + + diff --git a/content/events/src/nsEventStateManager.h b/content/events/src/nsEventStateManager.h index b0eae5f1ef39..7e19f25d5804 100644 --- a/content/events/src/nsEventStateManager.h +++ b/content/events/src/nsEventStateManager.h @@ -217,6 +217,37 @@ public: protected: friend class MouseEnterLeaveDispatcher; + /** + * Prefs class capsules preference management. + */ + class Prefs + { + public: + static bool KeyCausesActivation() { return sKeyCausesActivation; } + static bool ClickHoldContextMenu() { return sClickHoldContextMenu; } + static int32_t ChromeAccessModifierMask(); + static int32_t ContentAccessModifierMask(); + + static void Init(); + static int OnChange(const char* aPrefName, void*); + static void Shutdown(); + + private: + static bool sKeyCausesActivation; + static bool sClickHoldContextMenu; + static int32_t sGenericAccessModifierKey; + static int32_t sChromeAccessModifierMask; + static int32_t sContentAccessModifierMask; + + static int32_t GetAccessModifierMask(int32_t aItemType); + }; + + /** + * Get appropriate access modifier mask for the aDocShell. Returns -1 if + * access key isn't available. + */ + static int32_t GetAccessModifierMaskFor(nsISupports* aDocShell); + void UpdateCursor(nsPresContext* aPresContext, nsEvent* aEvent, nsIFrame* aTargetFrame, nsEventStatus* aStatus); /** * Turn a GUI mouse event into a mouse event targeted at the specified @@ -784,7 +815,6 @@ public: static void ClearGlobalActiveContent(nsEventStateManager* aClearer); // Functions used for click hold context menus - bool mClickHoldContextMenu; nsCOMPtr mClickHoldTimer; void CreateClickHoldTimer ( nsPresContext* aPresContext, nsIFrame* inDownFrame, nsGUIEvent* inMouseDownEvent ) ; diff --git a/content/html/content/src/HTMLInputElement.cpp b/content/html/content/src/HTMLInputElement.cpp index bcd271a01153..cd14f42f8514 100644 --- a/content/html/content/src/HTMLInputElement.cpp +++ b/content/html/content/src/HTMLInputElement.cpp @@ -99,6 +99,7 @@ #include "nsIColorPicker.h" #include "nsIStringEnumerator.h" +#include "HTMLSplitOnSpacesTokenizer.h" // input type=date #include "js/Date.h" diff --git a/content/html/content/src/HTMLMediaElement.cpp b/content/html/content/src/HTMLMediaElement.cpp index 6762a0a2155b..39bf5d679ec7 100644 --- a/content/html/content/src/HTMLMediaElement.cpp +++ b/content/html/content/src/HTMLMediaElement.cpp @@ -95,6 +95,7 @@ static PRLogModuleInfo* gMediaElementEventsLog; #include "mozilla/Preferences.h" #include "nsIPermissionManager.h" +#include "nsContentTypeParser.h" using namespace mozilla::layers; using mozilla::net::nsMediaFragmentURIParser; @@ -277,7 +278,7 @@ void HTMLMediaElement::ReportLoadError(const char* aMsg, uint32_t aParamCount) { nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "Media", + NS_LITERAL_CSTRING("Media"), OwnerDoc(), nsContentUtils::eDOM_PROPERTIES, aMsg, diff --git a/content/html/content/src/nsFormSubmission.cpp b/content/html/content/src/nsFormSubmission.cpp index 64dabd3e0538..a93c96b89b35 100644 --- a/content/html/content/src/nsFormSubmission.cpp +++ b/content/html/content/src/nsFormSubmission.cpp @@ -51,7 +51,7 @@ SendJSWarning(nsIDocument* aDocument, const PRUnichar** aWarningArgs, uint32_t aWarningArgsLen) { nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "HTML", aDocument, + NS_LITERAL_CSTRING("HTML"), aDocument, nsContentUtils::eFORMS_PROPERTIES, aWarningName, aWarningArgs, aWarningArgsLen); diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index 16187215fcfc..8100588afea0 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -149,7 +149,7 @@ static void ReportUseOfDeprecatedMethod(nsHTMLDocument* aDoc, const char* aWarning) { nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "DOM Events", aDoc, + NS_LITERAL_CSTRING("DOM Events"), aDoc, nsContentUtils::eDOM_PROPERTIES, aWarning); } @@ -1866,7 +1866,7 @@ nsHTMLDocument::WriteCommon(JSContext *cx, if (mExternalScriptsBeingEvaluated) { // Instead of implying a call to document.open(), ignore the call. nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "DOM Events", this, + NS_LITERAL_CSTRING("DOM Events"), this, nsContentUtils::eDOM_PROPERTIES, "DocumentWriteIgnored", nullptr, 0, @@ -1881,7 +1881,7 @@ nsHTMLDocument::WriteCommon(JSContext *cx, if (mExternalScriptsBeingEvaluated) { // Instead of implying a call to document.open(), ignore the call. nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "DOM Events", this, + NS_LITERAL_CSTRING("DOM Events"), this, nsContentUtils::eDOM_PROPERTIES, "DocumentWriteIgnored", nullptr, 0, diff --git a/content/mathml/content/src/nsMathMLElement.cpp b/content/mathml/content/src/nsMathMLElement.cpp index 03de7aba8c44..07eda2dc8399 100644 --- a/content/mathml/content/src/nsMathMLElement.cpp +++ b/content/mathml/content/src/nsMathMLElement.cpp @@ -39,7 +39,8 @@ WarnDeprecated(const PRUnichar* aDeprecatedAttribute, const PRUnichar *argv[] = { aDeprecatedAttribute, aFavoredAttribute }; return nsContentUtils:: - ReportToConsole(nsIScriptError::warningFlag, "MathML", aDocument, + ReportToConsole(nsIScriptError::warningFlag, + NS_LITERAL_CSTRING("MathML"), aDocument, nsContentUtils::eMATHML_PROPERTIES, "DeprecatedSupersededBy", argv, 2); } @@ -49,7 +50,8 @@ ReportLengthParseError(const nsString& aValue, nsIDocument* aDocument) { const PRUnichar *arg = aValue.get(); return nsContentUtils:: - ReportToConsole(nsIScriptError::errorFlag, "MathML", aDocument, + ReportToConsole(nsIScriptError::errorFlag, + NS_LITERAL_CSTRING("MathML"), aDocument, nsContentUtils::eMATHML_PROPERTIES, "LengthParsingError", &arg, 1); } @@ -62,7 +64,8 @@ ReportParseErrorNoTag(const nsString& aValue, const PRUnichar *argv[] = { aValue.get(), aAtom->GetUTF16String() }; return nsContentUtils:: - ReportToConsole(nsIScriptError::errorFlag, "MathML", aDocument, + ReportToConsole(nsIScriptError::errorFlag, + NS_LITERAL_CSTRING("MathML"), aDocument, nsContentUtils::eMATHML_PROPERTIES, "AttributeParsingErrorNoTag", argv, 2); } @@ -419,7 +422,7 @@ nsMathMLElement::ParseNumericValue(const nsString& aString, // no explicit unit, this is a number that will act as a multiplier if (!(aFlags & PARSE_SUPPRESS_WARNINGS)) { nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "MathML", aDocument, + NS_LITERAL_CSTRING("MathML"), aDocument, nsContentUtils::eMATHML_PROPERTIES, "UnitlessValuesAreDeprecated"); } diff --git a/content/media/mediasource/MediaSource.cpp b/content/media/mediasource/MediaSource.cpp index 54ed1215cee8..0b5c77e0b34f 100644 --- a/content/media/mediasource/MediaSource.cpp +++ b/content/media/mediasource/MediaSource.cpp @@ -10,6 +10,7 @@ #include "MediaSourceInputAdapter.h" #include "SourceBuffer.h" #include "SourceBufferList.h" +#include "nsContentTypeParser.h" #ifdef PR_LOGGING PRLogModuleInfo* gMediaSourceLog; diff --git a/content/media/webaudio/MediaBufferDecoder.cpp b/content/media/webaudio/MediaBufferDecoder.cpp index a9133099a1df..b912dc6ce8cf 100644 --- a/content/media/webaudio/MediaBufferDecoder.cpp +++ b/content/media/webaudio/MediaBufferDecoder.cpp @@ -902,7 +902,7 @@ WebAudioDecodeJob::OnFailure(ErrorCode aErrorCode) doc = pWindow->GetExtantDoc(); } nsContentUtils::ReportToConsole(nsIScriptError::errorFlag, - "Media", + NS_LITERAL_CSTRING("Media"), doc, nsContentUtils::eDOM_PROPERTIES, errorMessage); diff --git a/content/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp b/content/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp index 78cdd06173a9..69c638560618 100644 --- a/content/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp +++ b/content/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp @@ -158,6 +158,12 @@ SpeechTaskChild::SendAudio(const JS::Value& aData, const JS::Value& aLandmarks, MOZ_CRASH("Should never be called from child"); } +NS_IMETHODIMP +SpeechTaskChild::SendAudioNative(int16_t* aData, uint32_t aDataLen) +{ + MOZ_CRASH("Should never be called from child"); +} + void SpeechTaskChild::Pause() { diff --git a/content/media/webspeech/synth/ipc/SpeechSynthesisChild.h b/content/media/webspeech/synth/ipc/SpeechSynthesisChild.h index a4614f82c769..d1a6bd47eb04 100644 --- a/content/media/webspeech/synth/ipc/SpeechSynthesisChild.h +++ b/content/media/webspeech/synth/ipc/SpeechSynthesisChild.h @@ -78,8 +78,10 @@ public: NS_IMETHOD Setup(nsISpeechTaskCallback* aCallback, uint32_t aChannels, uint32_t aRate, uint8_t argc) MOZ_OVERRIDE; - NS_IMETHOD SendAudio (const JS::Value& aData, const JS::Value& aLandmarks, - JSContext* aCx) MOZ_OVERRIDE; + NS_IMETHOD SendAudio(const JS::Value& aData, const JS::Value& aLandmarks, + JSContext* aCx) MOZ_OVERRIDE; + + NS_IMETHOD SendAudioNative(int16_t* aData, uint32_t aDataLen) MOZ_OVERRIDE; virtual void Pause(); diff --git a/content/media/webspeech/synth/nsISpeechService.idl b/content/media/webspeech/synth/nsISpeechService.idl index 7e4e87221edd..980a860bfdc6 100644 --- a/content/media/webspeech/synth/nsISpeechService.idl +++ b/content/media/webspeech/synth/nsISpeechService.idl @@ -36,7 +36,7 @@ interface nsISpeechTaskCallback : nsISupports * A task is associated with a single utterance. It is provided by the browser * to the service in the speak() method. */ -[scriptable, builtinclass, uuid(3a60c397-7a04-4cf7-99ea-7432e7a0a1c1)] +[scriptable, builtinclass, uuid(ad59949c-2437-4b35-8eeb-d760caab75c5)] interface nsISpeechTask : nsISupports { /** @@ -61,6 +61,9 @@ interface nsISpeechTask : nsISupports [implicit_jscontext] void sendAudio(in jsval aData, in jsval aLandmarks); + [noscript] + void sendAudioNative([array, size_is(aDataLen)] in short aData, in unsigned long aDataLen); + /** * Dispatch start event. */ diff --git a/content/media/webspeech/synth/nsSpeechTask.cpp b/content/media/webspeech/synth/nsSpeechTask.cpp index c1faaf350bd0..e6868e21316c 100644 --- a/content/media/webspeech/synth/nsSpeechTask.cpp +++ b/content/media/webspeech/synth/nsSpeechTask.cpp @@ -175,31 +175,54 @@ nsSpeechTask::SendAudio(const JS::Value& aData, const JS::Value& aLandmarks, return NS_ERROR_DOM_TYPE_MISMATCH_ERR; } - uint32_t dataLength = JS_GetTypedArrayLength(tsrc); + SendAudioImpl(JS_GetInt16ArrayData(tsrc), + JS_GetTypedArrayLength(tsrc)); - if (dataLength == 0) { + return NS_OK; +} + +NS_IMETHODIMP +nsSpeechTask::SendAudioNative(int16_t* aData, uint32_t aDataLen) +{ + MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default); + + NS_ENSURE_TRUE(mStream, NS_ERROR_NOT_AVAILABLE); + NS_ENSURE_FALSE(mStream->IsDestroyed(), NS_ERROR_NOT_AVAILABLE); + NS_ENSURE_TRUE(mChannels, NS_ERROR_FAILURE); + + if (mIndirectAudio) { + NS_WARNING("Can't call SendAudio from an indirect audio speech service."); + return NS_ERROR_FAILURE; + } + + SendAudioImpl(aData, aDataLen); + + return NS_OK; +} + +void +nsSpeechTask::SendAudioImpl(int16_t* aData, uint32_t aDataLen) +{ + if (aDataLen == 0) { // XXX: We should end the track too, an undetermined bug does not allow that. mStream->Finish(); - return NS_OK; + return; } nsRefPtr samples = - SharedBuffer::Create(dataLength * sizeof(int16_t)); + SharedBuffer::Create(aDataLen * sizeof(int16_t)); int16_t* frames = static_cast(samples->Data()); - int16_t* sframes = JS_GetInt16ArrayData(tsrc); - for (uint32_t i = 0; i < dataLength; i++) { - frames[i] = sframes[i]; + for (uint32_t i = 0; i < aDataLen; i++) { + frames[i] = aData[i]; } AudioSegment segment; nsAutoTArray channelData; channelData.AppendElement(frames); - segment.AppendFrames(samples.forget(), channelData, dataLength); + segment.AppendFrames(samples.forget(), channelData, aDataLen); mStream->AppendToTrack(1, &segment); mStream->AdvanceKnownTracksTime(STREAM_TIME_MAX); - - return NS_OK; } NS_IMETHODIMP @@ -360,7 +383,7 @@ nsSpeechTask::DispatchBoundary(const nsAString& aName, nsresult nsSpeechTask::DispatchBoundaryImpl(const nsAString& aName, - float aElapsedTime, uint32_t aCharIndex) + float aElapsedTime, uint32_t aCharIndex) { MOZ_ASSERT(mUtterance); NS_ENSURE_TRUE(mUtterance->mState == SpeechSynthesisUtterance::STATE_SPEAKING, diff --git a/content/media/webspeech/synth/nsSpeechTask.h b/content/media/webspeech/synth/nsSpeechTask.h index bed2ba8b17f3..f4bf2eb71c4a 100644 --- a/content/media/webspeech/synth/nsSpeechTask.h +++ b/content/media/webspeech/synth/nsSpeechTask.h @@ -73,6 +73,8 @@ protected: private: void End(); + void SendAudioImpl(int16_t* aData, uint32_t aDataLen); + nsRefPtr mStream; nsCOMPtr mCallback; diff --git a/content/svg/content/src/SVGContentUtils.cpp b/content/svg/content/src/SVGContentUtils.cpp index 78aef2a03080..99fa00c52505 100644 --- a/content/svg/content/src/SVGContentUtils.cpp +++ b/content/svg/content/src/SVGContentUtils.cpp @@ -141,7 +141,7 @@ SVGContentUtils::ReportToConsole(nsIDocument* doc, uint32_t aParamsLength) { return nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "SVG", doc, + NS_LITERAL_CSTRING("SVG"), doc, nsContentUtils::eSVG_PROPERTIES, aWarning, aParams, aParamsLength); diff --git a/content/svg/content/src/SVGFragmentIdentifier.cpp b/content/svg/content/src/SVGFragmentIdentifier.cpp index dd7140998b06..c7996cb55fed 100644 --- a/content/svg/content/src/SVGFragmentIdentifier.cpp +++ b/content/svg/content/src/SVGFragmentIdentifier.cpp @@ -9,6 +9,7 @@ #include "mozilla/dom/SVGViewElement.h" #include "nsContentUtils.h" // for nsCharSeparatedTokenizerTemplate #include "nsSVGAnimatedTransformList.h" +#include "nsCharSeparatedTokenizer.h" using namespace mozilla; diff --git a/content/xbl/src/nsXBLContentSink.cpp b/content/xbl/src/nsXBLContentSink.cpp index 6dac5d50f09e..10f0273f08e8 100644 --- a/content/xbl/src/nsXBLContentSink.cpp +++ b/content/xbl/src/nsXBLContentSink.cpp @@ -213,7 +213,7 @@ nsXBLContentSink::ReportUnexpectedElement(nsIAtom* aElementName, const PRUnichar* params[] = { elementName.get() }; return nsContentUtils::ReportToConsole(nsIScriptError::errorFlag, - "XBL Content Sink", + NS_LITERAL_CSTRING("XBL Content Sink"), mDocument, nsContentUtils::eXBL_PROPERTIES, "UnexpectedElement", @@ -556,7 +556,7 @@ nsXBLContentSink::ConstructBinding(uint32_t aLineNumber) } } else { nsContentUtils::ReportToConsole(nsIScriptError::errorFlag, - "XBL Content Sink", nullptr, + NS_LITERAL_CSTRING("XBL Content Sink"), nullptr, nsContentUtils::eXBL_PROPERTIES, "MissingIdAttr", nullptr, 0, mDocumentURI, @@ -645,7 +645,7 @@ nsXBLContentSink::ConstructHandler(const PRUnichar **aAtts, uint32_t aLineNumber // shorthand syntax. mState = eXBL_Error; nsContentUtils::ReportToConsole(nsIScriptError::errorFlag, - "XBL Content Sink", + NS_LITERAL_CSTRING("XBL Content Sink"), mDocument, nsContentUtils::eXBL_PROPERTIES, "CommandNotInChrome", nullptr, 0, diff --git a/content/xbl/src/nsXBLPrototypeBinding.cpp b/content/xbl/src/nsXBLPrototypeBinding.cpp index cc82fbec11ca..dbd534cbe5bd 100644 --- a/content/xbl/src/nsXBLPrototypeBinding.cpp +++ b/content/xbl/src/nsXBLPrototypeBinding.cpp @@ -1621,7 +1621,7 @@ nsXBLPrototypeBinding::ResolveBaseBinding() if (!CheckTagNameWhiteList(nameSpaceID, tagName)) { const PRUnichar* params[] = { display.get() }; nsContentUtils::ReportToConsole(nsIScriptError::errorFlag, - "XBL", nullptr, + NS_LITERAL_CSTRING("XBL"), nullptr, nsContentUtils::eXBL_PROPERTIES, "InvalidExtendsBinding", params, ArrayLength(params), diff --git a/content/xbl/src/nsXBLPrototypeHandler.cpp b/content/xbl/src/nsXBLPrototypeHandler.cpp index 413d1c5a9f65..bcdd39148792 100644 --- a/content/xbl/src/nsXBLPrototypeHandler.cpp +++ b/content/xbl/src/nsXBLPrototypeHandler.cpp @@ -902,7 +902,7 @@ nsXBLPrototypeHandler::ReportKeyConflict(const PRUnichar* aKey, const PRUnichar* const PRUnichar* params[] = { aKey, aModifiers }; nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "XBL Prototype Handler", doc, + NS_LITERAL_CSTRING("XBL Prototype Handler"), doc, nsContentUtils::eXBL_PROPERTIES, aMessageName, params, ArrayLength(params), diff --git a/content/xbl/src/nsXBLService.cpp b/content/xbl/src/nsXBLService.cpp index 62ad0f1a1653..8ac8c9b064c9 100644 --- a/content/xbl/src/nsXBLService.cpp +++ b/content/xbl/src/nsXBLService.cpp @@ -90,7 +90,7 @@ IsAncestorBinding(nsIDocument* aDocument, NS_ConvertUTF8toUTF16 bindingURI(spec); const PRUnichar* params[] = { bindingURI.get() }; nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "XBL", aDocument, + NS_LITERAL_CSTRING("XBL"), aDocument, nsContentUtils::eXBL_PROPERTIES, "TooDeepBindingRecursion", params, ArrayLength(params)); @@ -331,7 +331,7 @@ nsXBLStreamListener::HandleEvent(nsIDOMEvent* aEvent) NS_WARNING("An XBL file is malformed. Did you forget the XBL namespace on the bindings tag?"); } nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "XBL", nullptr, + NS_LITERAL_CSTRING("XBL"), nullptr, nsContentUtils::eXBL_PROPERTIES, "MalformedXBL", nullptr, 0, documentURI); @@ -763,7 +763,7 @@ nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI, NS_ConvertUTF8toUTF16 baseSpecUTF16(basespec); const PRUnichar* params[] = { protoSpec.get(), baseSpecUTF16.get() }; nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "XBL", nullptr, + NS_LITERAL_CSTRING("XBL"), nullptr, nsContentUtils::eXBL_PROPERTIES, "CircularExtendsBinding", params, ArrayLength(params), diff --git a/content/xbl/test/test_bug379959.html b/content/xbl/test/test_bug379959.html index 137b28d318db..32b0e2029736 100644 --- a/content/xbl/test/test_bug379959.html +++ b/content/xbl/test/test_bug379959.html @@ -1,15 +1,15 @@ - Test for Bug 366770 + Test for Bug 379959 - - Mozilla Bug 366770 + + Mozilla Bug 379959

Note: In order to re-run this test correctly you need to shift-reload rather than simply reload. If you just reload we will restore the @@ -23,63 +23,74 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=366770 diff --git a/content/xml/document/src/XMLDocument.cpp b/content/xml/document/src/XMLDocument.cpp index ab0f9b9832a3..5736e52c44dd 100644 --- a/content/xml/document/src/XMLDocument.cpp +++ b/content/xml/document/src/XMLDocument.cpp @@ -279,7 +279,7 @@ static void ReportUseOfDeprecatedMethod(nsIDocument *aDoc, const char* aWarning) { nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "DOM3 Load", aDoc, + NS_LITERAL_CSTRING("DOM3 Load"), aDoc, nsContentUtils::eDOM_PROPERTIES, aWarning); } diff --git a/content/xul/document/src/XULDocument.cpp b/content/xul/document/src/XULDocument.cpp index 95c22ed0e8c2..7612b965203f 100644 --- a/content/xul/document/src/XULDocument.cpp +++ b/content/xul/document/src/XULDocument.cpp @@ -3076,7 +3076,7 @@ XULDocument::ResumeWalk() nsContentUtils::ReportToConsole( nsIScriptError::warningFlag, - "XUL Document", nullptr, + NS_LITERAL_CSTRING("XUL Document"), nullptr, nsContentUtils::eXUL_PROPERTIES, "PINotInProlog", params, ArrayLength(params), @@ -3369,7 +3369,7 @@ XULDocument::ReportMissingOverlay(nsIURI* aURI) NS_ConvertUTF8toUTF16 utfSpec(spec); const PRUnichar* params[] = { utfSpec.get() }; nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "XUL Document", this, + NS_LITERAL_CSTRING("XUL Document"), this, nsContentUtils::eXUL_PROPERTIES, "MissingOverlay", params, ArrayLength(params)); diff --git a/content/xul/document/src/nsXULContentSink.cpp b/content/xul/document/src/nsXULContentSink.cpp index 6918b9f26dd4..e6e33f1abeb4 100644 --- a/content/xul/document/src/nsXULContentSink.cpp +++ b/content/xul/document/src/nsXULContentSink.cpp @@ -56,6 +56,7 @@ #include "nsXMLContentSink.h" #include "nsIConsoleService.h" #include "nsIScriptError.h" +#include "nsContentTypeParser.h" #ifdef PR_LOGGING static PRLogModuleInfo* gLog; diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index cda0c59c3833..eae632896218 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -11983,7 +11983,7 @@ nsDocShell::GetControllerForCommand(const char * inCommand, return root->GetControllerForCommand(inCommand, outController); } -nsresult +NS_IMETHODIMP nsDocShell::IsCommandEnabled(const char * inCommand, bool* outEnabled) { NS_ENSURE_ARG_POINTER(outEnabled); @@ -11999,7 +11999,7 @@ nsDocShell::IsCommandEnabled(const char * inCommand, bool* outEnabled) return rv; } -nsresult +NS_IMETHODIMP nsDocShell::DoCommand(const char * inCommand) { nsresult rv = NS_ERROR_FAILURE; diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 454ec925afaa..8ebe45fbfcd6 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -643,8 +643,6 @@ protected: // helpers for executing commands nsresult GetControllerForCommand(const char *inCommand, nsIController** outController); - nsresult IsCommandEnabled(const char * inCommand, bool* outEnabled); - nsresult DoCommand(const char * inCommand); nsresult EnsureCommandHandler(); nsIChannel* GetCurrentDocChannel(); diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl index 3f4110922819..63d5f2d4180f 100644 --- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -42,7 +42,7 @@ interface nsIVariant; interface nsIPrivacyTransitionObserver; interface nsIReflowObserver; -[scriptable, builtinclass, uuid(b5bd6052-ec8c-45bf-b55c-409ad15cecfb)] +[scriptable, builtinclass, uuid(365e7446-6c4b-45ae-ae08-b7b401900093)] interface nsIDocShell : nsIDocShellTreeItem { /** @@ -873,4 +873,12 @@ interface nsIDocShell : nsIDocShellTreeItem * Returns false for mLSHE, true for mOSHE */ boolean getCurrentSHEntry(out nsISHEntry aEntry); + + /** + * Cherry picked parts of nsIController. + * They are here, because we want to call these functions + * from JS. + */ + boolean isCommandEnabled(in string command); + void doCommand(in string command); }; diff --git a/docshell/test/test_bug369814.html b/docshell/test/test_bug369814.html index a47b9fc72ffa..3e257f9af305 100644 --- a/docshell/test/test_bug369814.html +++ b/docshell/test/test_bug369814.html @@ -26,13 +26,9 @@ SimpleTest.waitForExplicitFinish(); // checking the results. const gLoadEventLoopCount = 100; -var Ci = SpecialPowers.Ci; - var gCurrentTest; var gTargetWindow; var gNumPokes; -var gPrefValue; - var gTestFrame; /** @@ -186,49 +182,36 @@ var gNextTest = 0; function runNextTest() { - var prefs = SpecialPowers.Cc["@mozilla.org/preferences-service;1"] - .getService(SpecialPowers.Ci.nsIPrefBranch); - if (gNextTest < gTests.length) { gCurrentTest = gTests[gNextTest++]; gNumPokes = 0; - prefs.setBoolPref("network.jar.open-unsafe-types", gCurrentTest['pref']); + SpecialPowers.pushPrefEnv({"set": [["network.jar.open-unsafe-types", gCurrentTest['pref']]]}, function() { - // Create a new frame each time, so our restictions on loads in a - // jar:-loaded iframe don't interfere with the test. - if (gTestFrame) { - document.body.removeChild(gTestFrame); - } - gTestFrame = document.createElement("iframe"); - document.body.insertBefore(gTestFrame, $("test")); + // Create a new frame each time, so our restictions on loads in a + // jar:-loaded iframe don't interfere with the test. + if (gTestFrame) { + document.body.removeChild(gTestFrame); + } + gTestFrame = document.createElement("iframe"); + document.body.insertBefore(gTestFrame, $("test")); - gCurrentTest['func'](gCurrentTest); + gCurrentTest['func'](gCurrentTest); + }); } else { - // Put back the pref value we had at test start - prefs.setBoolPref("network.jar.open-unsafe-types", gPrefValue); SimpleTest.finish(); } } function finishTest() { - var prefs = SpecialPowers.Cc["@mozilla.org/preferences-service;1"] - .getService(SpecialPowers.Ci.nsIPrefBranch); - prefs.setBoolPref("network.jar.open-unsafe-types", false); + SpecialPowers.pushPrefEnv({"set": [["network.jar.open-unsafe-types", false]]}, function() { + if (gNumPokes == 0) { + ok(true, gCurrentTest["name"] + ": no unexpected pokes"); + } - if (gNumPokes == 0) { - ok(true, gCurrentTest["name"] + ": no unexpected pokes"); - } - - runNextTest(); -} - -function startTests() -{ - var prefs = SpecialPowers.Cc["@mozilla.org/preferences-service;1"] - .getService(SpecialPowers.Ci.nsIPrefBranch); - gPrefValue = prefs.getBoolPref("network.jar.open-unsafe-types"); + runNextTest(); + }); } addLoadEvent(runNextTest); @@ -237,4 +220,3 @@ addLoadEvent(runNextTest); - diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index b5fe80ff25b8..df630fa0f090 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -2565,7 +2565,7 @@ nsDOMWindowUtils::GetOuterWindowWithId(uint64_t aWindowID, // XXX This method is deprecated. See bug 865664. nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "DOM", + NS_LITERAL_CSTRING("DOM"), nsContentUtils::GetDocumentFromCaller(), nsContentUtils::eDOM_PROPERTIES, "GetWindowWithOuterIdWarning"); diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp index b73fa2465956..ace94abc1257 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -1158,7 +1158,7 @@ nsFocusManager::SetFocusInner(nsIContent* aNewContent, int32_t aFlags, (fullscreenAncestor = nsContentUtils::GetFullscreenAncestor(contentToFocus->OwnerDoc())) && nsContentUtils::HasPluginWithUncontrolledEventDispatch(contentToFocus)) { nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "DOM", + NS_LITERAL_CSTRING("DOM"), contentToFocus->OwnerDoc(), nsContentUtils::eDOM_PROPERTIES, "FocusedWindowedPluginWhileFullScreen"); diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 495221856b0c..78236c8c37ea 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -1535,7 +1535,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindow) if (!sWarnedAboutWindowInternal) { sWarnedAboutWindowInternal = true; nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "Extensions", mDoc, + NS_LITERAL_CSTRING("Extensions"), mDoc, nsContentUtils::eDOM_PROPERTIES, "nsIDOMWindowInternalWarning"); } @@ -6204,7 +6204,7 @@ ReportUseOfDeprecatedMethod(nsGlobalWindow* aWindow, const char* aWarning) { nsCOMPtr doc = aWindow->GetExtantDoc(); nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "DOM Events", doc, + NS_LITERAL_CSTRING("DOM Events"), doc, nsContentUtils::eDOM_PROPERTIES, aWarning); } @@ -7087,7 +7087,7 @@ nsGlobalWindow::Close() // report localized error msg in JS console nsContentUtils::ReportToConsole( nsIScriptError::warningFlag, - "DOM Window", mDoc, // Better name for the category? + NS_LITERAL_CSTRING("DOM Window"), mDoc, // Better name for the category? nsContentUtils::eDOM_PROPERTIES, "WindowCloseBlockedWarning"); diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index cefe79c494de..c8019f5cc090 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -174,6 +174,7 @@ static uint32_t sForgetSkippableBeforeCC = 0; static uint32_t sPreviousSuspectedCount = 0; static uint32_t sCleanupsSinceLastGC = UINT32_MAX; static bool sNeedsFullCC = false; +static bool sNeedsGCAfterCC = false; static nsJSContext *sContextList = nullptr; static nsScriptNameSpaceManager *gNameSpaceManager; @@ -685,7 +686,8 @@ static const char js_werror_option_str[] = JS_OPTIONS_DOT_STR "werror"; static const char js_zeal_option_str[] = JS_OPTIONS_DOT_STR "gczeal"; static const char js_zeal_frequency_str[] = JS_OPTIONS_DOT_STR "gczeal.frequency"; #endif -static const char js_typeinfer_str[] = JS_OPTIONS_DOT_STR "typeinference"; +static const char js_typeinfer_content_str[] = JS_OPTIONS_DOT_STR "typeinference.content"; +static const char js_typeinfer_chrome_str[] = JS_OPTIONS_DOT_STR "typeinference.chrome"; static const char js_jit_hardening_str[] = JS_OPTIONS_DOT_STR "jit_hardening"; static const char js_memlog_option_str[] = JS_OPTIONS_DOT_STR "mem.log"; static const char js_memnotify_option_str[] = JS_OPTIONS_DOT_STR "mem.notify"; @@ -694,6 +696,7 @@ static const char js_baselinejit_content_str[] = JS_OPTIONS_DOT_STR "baselinejit static const char js_baselinejit_chrome_str[] = JS_OPTIONS_DOT_STR "baselinejit.chrome"; static const char js_baselinejit_eager_str[] = JS_OPTIONS_DOT_STR "baselinejit.unsafe_eager_compilation"; static const char js_ion_content_str[] = JS_OPTIONS_DOT_STR "ion.content"; +static const char js_ion_chrome_str[] = JS_OPTIONS_DOT_STR "ion.chrome"; static const char js_ion_eager_str[] = JS_OPTIONS_DOT_STR "ion.unsafe_eager_compilation"; static const char js_ion_parallel_compilation_str[] = JS_OPTIONS_DOT_STR "ion.parallel_compilation"; @@ -723,13 +726,17 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data) nsCOMPtr contentWindow(do_QueryInterface(global)); nsCOMPtr chromeWindow(do_QueryInterface(global)); - bool useTypeInference = !chromeWindow && contentWindow && Preferences::GetBool(js_typeinfer_str); + bool useTypeInference = Preferences::GetBool((chromeWindow || !contentWindow) ? + js_typeinfer_chrome_str : + js_typeinfer_content_str); bool useHardening = Preferences::GetBool(js_jit_hardening_str); - bool useBaselineJIT = Preferences::GetBool(chromeWindow || !contentWindow ? + bool useBaselineJIT = Preferences::GetBool((chromeWindow || !contentWindow) ? js_baselinejit_chrome_str : js_baselinejit_content_str); bool useBaselineJITEager = Preferences::GetBool(js_baselinejit_eager_str); - bool useIon = Preferences::GetBool(js_ion_content_str); + bool useIon = Preferences::GetBool((chromeWindow || !contentWindow) ? + js_ion_chrome_str : + js_ion_content_str); bool useIonEager = Preferences::GetBool(js_ion_eager_str); bool useAsmJS = Preferences::GetBool(js_asmjs_content_str); bool parallelIonCompilation = Preferences::GetBool(js_ion_parallel_compilation_str); @@ -2049,7 +2056,8 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener, // If we collected a substantial amount of cycles, poke the GC since more objects // might be unreachable now. if (sCCollectedWaitingForGC > 250 || - sLikelyShortLivingObjectsNeedingGC > 2500) { + sLikelyShortLivingObjectsNeedingGC > 2500 || + sNeedsGCAfterCC) { PokeGC(JS::gcreason::CC_WAITING); } @@ -2164,6 +2172,7 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener, sRemovedPurples = 0; sForgetSkippableBeforeCC = 0; sNeedsFullCC = false; + sNeedsGCAfterCC = false; } // static @@ -2314,6 +2323,14 @@ nsJSContext::PokeGC(JS::gcreason::Reason aReason, int aDelay) return; } + if (sCCTimer) { + // Make sure CC is called... + sNeedsFullCC = true; + // and GC after it. + sNeedsGCAfterCC = true; + return; + } + CallCreateInstance("@mozilla.org/timer;1", &sGCTimer); if (!sGCTimer) { @@ -2579,6 +2596,7 @@ mozilla::dom::StartupJSEnvironment() sLikelyShortLivingObjectsNeedingGC = 0; sPostGCEventsToConsole = false; sNeedsFullCC = false; + sNeedsGCAfterCC = false; gNameSpaceManager = nullptr; sRuntimeService = nullptr; sRuntime = nullptr; diff --git a/dom/base/nsWrapperCache.h b/dom/base/nsWrapperCache.h index 41052db84dfb..21963d71d88b 100644 --- a/dom/base/nsWrapperCache.h +++ b/dom/base/nsWrapperCache.h @@ -656,4 +656,50 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperCache, NS_WRAPPERCACHE_IID) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \ NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class) +#define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_12(_class, \ + _field1, \ + _field2, \ + _field3, \ + _field4, \ + _field5, \ + _field6, \ + _field7, \ + _field8, \ + _field9, \ + _field10, \ + _field11, \ + _field12) \ + NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field3) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field4) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field5) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field6) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field7) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field8) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field9) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field10) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field11) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field12) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \ + NS_IMPL_CYCLE_COLLECTION_UNLINK_END \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field3) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field4) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field5) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field6) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field7) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field8) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field9) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field10) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field11) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field12) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \ + NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class) + #endif /* nsWrapperCache_h___ */ diff --git a/dom/icc/src/StkCommandEvent.h b/dom/icc/src/StkCommandEvent.h index 30ac05d87b5f..feeadeb95c63 100644 --- a/dom/icc/src/StkCommandEvent.h +++ b/dom/icc/src/StkCommandEvent.h @@ -22,7 +22,6 @@ public: NS_DECL_ISUPPORTS_INHERITED NS_FORWARD_TO_NSDOMEVENT NS_DECL_NSIDOMMOZSTKCOMMANDEVENT - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(StkCommandEvent, nsDOMEvent) static already_AddRefed Create(EventTarget* aOwner, const nsAString& aMessage); diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp index aad2bde6b200..96bb12ee7101 100644 --- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -45,6 +45,7 @@ #include "ipc/IndexedDBParent.h" #include "IndexedDatabaseInlines.h" +#include "nsCharSeparatedTokenizer.h" #define FILE_COPY_BUFFER_SIZE 32768 diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 0a06f8971748..ab6275d5f70f 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -110,6 +110,8 @@ static const char BROWSER_ZOOM_TO_RECT[] = "browser-zoom-to-rect"; static const char BEFORE_FIRST_PAINT[] = "before-first-paint"; static const char DETECT_SCROLLABLE_SUBFRAME[] = "detect-scrollable-subframe"; +static bool sCpowsEnabled = false; + NS_IMETHODIMP ContentListener::HandleEvent(nsIDOMEvent* aEvent) { @@ -2339,6 +2341,11 @@ TabChild::InitRenderingState() false); } + // This state can't really change during the lifetime of the child. + sCpowsEnabled = Preferences::GetBool("browser.tabs.remote", false); + if (Preferences::GetBool("dom.ipc.cpows.force-disabled", false)) + sCpowsEnabled = false; + return true; } @@ -2469,8 +2476,10 @@ TabChild::DoSendSyncMessage(JSContext* aCx, return false; } InfallibleTArray cpows; - if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) { - return false; + if (sCpowsEnabled) { + if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) { + return false; + } } return SendSyncMessage(nsString(aMessage), data, cpows, aJSONRetVal); } @@ -2487,8 +2496,10 @@ TabChild::DoSendAsyncMessage(JSContext* aCx, return false; } InfallibleTArray cpows; - if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) { - return false; + if (sCpowsEnabled) { + if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) { + return false; + } } return SendAsyncMessage(nsString(aMessage), data, cpows); } diff --git a/dom/src/json/nsJSON.cpp b/dom/src/json/nsJSON.cpp index 5a2f85aaeaf7..31fc81e23959 100644 --- a/dom/src/json/nsJSON.cpp +++ b/dom/src/json/nsJSON.cpp @@ -49,7 +49,7 @@ static nsresult WarnDeprecatedMethod(DeprecationWarning warning) { return nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "DOM Core", nullptr, + NS_LITERAL_CSTRING("DOM Core"), nullptr, nsContentUtils::eDOM_PROPERTIES, warning == EncodeWarning ? "nsIJSONEncodeDeprecatedWarning" diff --git a/dom/webidl/WebGL2RenderingContext.webidl b/dom/webidl/WebGL2RenderingContext.webidl index 612211e2e031..5851ac49a7f1 100644 --- a/dom/webidl/WebGL2RenderingContext.webidl +++ b/dom/webidl/WebGL2RenderingContext.webidl @@ -77,6 +77,9 @@ interface WebGL2RenderingContext : WebGLRenderingContext { const GLenum TRANSFORM_FEEDBACK_BUFFER_SIZE = 0x8C85; const GLenum MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8C8B; + /* transform feedback queries */ + const GLenum TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = 0x8C88; + /* buffer objects */ void bindBufferBase(GLenum target, GLuint index, WebGLBuffer? buffer); void bindBufferRange(GLenum target, GLuint index, WebGLBuffer? buffer, diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index a5ca54d1773d..3f6835969fd4 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -292,9 +292,6 @@ LoadJSContextOptions(const char* aPrefName, void* /* aClosure */) if (GetWorkerPref(NS_LITERAL_CSTRING("werror"))) { commonOptions |= JSOPTION_WERROR; } - if (GetWorkerPref(NS_LITERAL_CSTRING("typeinference"))) { - commonOptions |= JSOPTION_TYPE_INFERENCE; - } if (GetWorkerPref(NS_LITERAL_CSTRING("asmjs"))) { commonOptions |= JSOPTION_ASMJS; } @@ -307,6 +304,9 @@ LoadJSContextOptions(const char* aPrefName, void* /* aClosure */) if (GetWorkerPref(NS_LITERAL_CSTRING("ion.content"))) { contentOptions |= JSOPTION_ION; } + if (GetWorkerPref(NS_LITERAL_CSTRING("typeinference.content"))) { + contentOptions |= JSOPTION_TYPE_INFERENCE; + } // Chrome options. uint32_t chromeOptions = commonOptions; @@ -316,6 +316,9 @@ LoadJSContextOptions(const char* aPrefName, void* /* aClosure */) if (GetWorkerPref(NS_LITERAL_CSTRING("ion.chrome"))) { chromeOptions |= JSOPTION_ION; } + if (GetWorkerPref(NS_LITERAL_CSTRING("typeinference.chrome"))) { + chromeOptions |= JSOPTION_TYPE_INFERENCE; + } #ifdef DEBUG if (GetWorkerPref(NS_LITERAL_CSTRING("strict.debug"))) { chromeOptions |= JSOPTION_EXTRA_WARNINGS; diff --git a/js/src/jit-test/tests/ion/bug904315.js b/js/src/jit-test/tests/ion/bug904315.js new file mode 100644 index 000000000000..64239408f6b2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug904315.js @@ -0,0 +1,15 @@ + +function g(o, idx, exp) { + for (var i=0; i<3000; i++) { + assertEq(o[idx], exp); + } +} +function f() { + var o = []; + for (var i=1; i<100; i++) { + o[-i] = 1; + } + g(o, 50, undefined); + g(o, -50, 1); +} +f(); diff --git a/js/src/jit-test/tests/ion/bug906035.js b/js/src/jit-test/tests/ion/bug906035.js new file mode 100644 index 000000000000..7c847aed3eff --- /dev/null +++ b/js/src/jit-test/tests/ion/bug906035.js @@ -0,0 +1,9 @@ +// |jit-test| ion-eager +function y() { return "foo,bar"; } +function x() { + var z = y().split(','); + for (var i = 0; i < z.length; i++) {} +} +gczeal(2); +Object.prototype.length = function () {}; +x(); diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 1437dbda53ad..0af7cd101277 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -3598,6 +3598,12 @@ TryAttachGetElemStub(JSContext *cx, HandleScript script, ICGetElem_Fallback *stu if (!obj->isNative() && !obj->is()) stub->noteNonNativeAccess(); + // GetElem operations which could access negative indexes generally can't + // be optimized without the potential for bailouts, as we can't statically + // determine that an object has no properties on such indexes. + if (rhs.isNumber() && rhs.toNumber() < 0) + stub->noteNegativeIndex(); + return true; } diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index 7417ead70301..2ec65bd40a48 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -2787,6 +2787,9 @@ class ICGetElem_Fallback : public ICMonitoredFallbackStub : ICMonitoredFallbackStub(ICStub::GetElem_Fallback, stubCode) { } + static const uint16_t EXTRA_NON_NATIVE = 0x1; + static const uint16_t EXTRA_NEGATIVE_INDEX = 0x2; + public: static const uint32_t MAX_OPTIMIZED_STUBS = 16; @@ -2797,10 +2800,17 @@ class ICGetElem_Fallback : public ICMonitoredFallbackStub } void noteNonNativeAccess() { - extra_ = 1; + extra_ |= EXTRA_NON_NATIVE; } bool hasNonNativeAccess() const { - return extra_; + return extra_ & EXTRA_NON_NATIVE; + } + + void noteNegativeIndex() { + extra_ |= EXTRA_NEGATIVE_INDEX; + } + bool hasNegativeIndex() const { + return extra_ & EXTRA_NEGATIVE_INDEX; } // Compiler for this stub kind. diff --git a/js/src/jit/BaselineInspector.cpp b/js/src/jit/BaselineInspector.cpp index 94ca8ad114fb..a0cd4eca4a74 100644 --- a/js/src/jit/BaselineInspector.cpp +++ b/js/src/jit/BaselineInspector.cpp @@ -303,6 +303,20 @@ BaselineInspector::hasSeenNonNativeGetElement(jsbytecode *pc) return false; } +bool +BaselineInspector::hasSeenNegativeIndexGetElement(jsbytecode *pc) +{ + if (!hasBaselineScript()) + return false; + + const ICEntry &entry = icEntryFromPC(pc); + ICStub *stub = entry.fallbackStub(); + + if (stub->isGetElem_Fallback()) + return stub->toGetElem_Fallback()->hasNegativeIndex(); + return false; +} + bool BaselineInspector::hasSeenAccessedGetter(jsbytecode *pc) { diff --git a/js/src/jit/BaselineInspector.h b/js/src/jit/BaselineInspector.h index c2772ad45035..81a09dff8706 100644 --- a/js/src/jit/BaselineInspector.h +++ b/js/src/jit/BaselineInspector.h @@ -104,6 +104,7 @@ class BaselineInspector MIRType expectedBinaryArithSpecialization(jsbytecode *pc); bool hasSeenNonNativeGetElement(jsbytecode *pc); + bool hasSeenNegativeIndexGetElement(jsbytecode *pc); bool hasSeenAccessedGetter(jsbytecode *pc); bool hasSeenDoubleResult(jsbytecode *pc); }; diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index fcf338f26719..32b83aeaa3a6 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -6433,6 +6433,8 @@ CodeGenerator::visitLoadElementHole(LLoadElementHole *lir) Register initLength = ToRegister(lir->initLength()); const ValueOperand out = ToOutValue(lir); + const MLoadElementHole *mir = lir->mir(); + // If the index is out of bounds, load |undefined|. Otherwise, load the // value. Label undefined, done; @@ -6452,6 +6454,19 @@ CodeGenerator::visitLoadElementHole(LLoadElementHole *lir) masm.jump(&done); masm.bind(&undefined); + + if (mir->needsNegativeIntCheck()) { + if (lir->index()->isConstant()) { + if (ToInt32(lir->index()) < 0 && !bailout(lir->snapshot())) + return false; + } else { + Label negative; + masm.branch32(Assembler::LessThan, ToRegister(lir->index()), Imm32(0), &negative); + if (!bailoutFrom(&negative, lir->snapshot())) + return false; + } + } + masm.moveValue(UndefinedValue(), out); masm.bind(&done); return true; diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 9eab8d3a54a2..0745e5b6cc6c 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -6465,6 +6465,11 @@ IonBuilder::getElemTryDense(bool *emitted, MDefinition *obj, MDefinition *index) if (ElementAccessHasExtraIndexedProperty(cx, obj) && failedBoundsCheck_) return true; + // Don't generate a fast path if this pc has seen negative indexes accessed, + // which will not appear to be extra indexed properties. + if (inspector->hasSeenNegativeIndexGetElement(pc)) + return true; + // Emit dense getelem variant. if (!jsop_getelem_dense(obj, index)) return false; diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 4d986080230f..a40ce0eea6d8 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -1078,6 +1078,22 @@ GenerateTypedArrayLength(JSContext *cx, MacroAssembler &masm, IonCache::StubAtta attacher.jumpNextStub(masm); } +static bool +IsCacheableArrayLength(JSContext *cx, HandleObject obj, HandlePropertyName name, + TypedOrValueRegister output) +{ + if (!obj->is()) + return false; + + if (output.type() != MIRType_Value && output.type() != MIRType_Int32) { + // The stub assumes that we always output Int32, so make sure our output + // is equipped to handle that. + return false; + } + + return true; +} + template static GetPropertyIC::NativeGetPropCacheability CanAttachNativeGetProp(typename GetPropCache::Context cx, const GetPropCache &cache, @@ -1111,7 +1127,9 @@ CanAttachNativeGetProp(typename GetPropCache::Context cx, const GetPropCache &ca return GetPropertyIC::CanAttachReadSlot; } - if (obj->is() && cx->names().length == name) { + if (cx->names().length == name && + IsCacheableArrayLength(cx, obj, name, cache.output())) + { // The array length property is non-configurable, which means both that // checking the class of the object and the name of the property is enough // and that we don't need to worry about monitoring, since we know the diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 378c15dcdb36..4beec7b7e573 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -2068,6 +2068,8 @@ LIRGenerator::visitLoadElementHole(MLoadElementHole *ins) LLoadElementHole *lir = new LLoadElementHole(useRegister(ins->elements()), useRegisterOrConstant(ins->index()), useRegister(ins->initLength())); + if (ins->needsNegativeIntCheck() && !assignSnapshot(lir)) + return false; return defineBox(lir, ins); } diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index d27a4dfd63b9..548a3be07bb7 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -4821,10 +4821,12 @@ class MLoadElementHole : public MTernaryInstruction, public SingleObjectPolicy { + bool needsNegativeIntCheck_; bool needsHoleCheck_; MLoadElementHole(MDefinition *elements, MDefinition *index, MDefinition *initLength, bool needsHoleCheck) : MTernaryInstruction(elements, index, initLength), + needsNegativeIntCheck_(true), needsHoleCheck_(needsHoleCheck) { setResultType(MIRType_Value); @@ -4854,12 +4856,16 @@ class MLoadElementHole MDefinition *initLength() const { return getOperand(2); } + bool needsNegativeIntCheck() const { + return needsNegativeIntCheck_; + } bool needsHoleCheck() const { return needsHoleCheck_; } AliasSet getAliasSet() const { return AliasSet::Load(AliasSet::Element); } + void collectRangeInfo(); }; class MStoreElementCommon diff --git a/js/src/jit/RangeAnalysis.cpp b/js/src/jit/RangeAnalysis.cpp index c1e031fb5191..d8e710996513 100644 --- a/js/src/jit/RangeAnalysis.cpp +++ b/js/src/jit/RangeAnalysis.cpp @@ -2005,6 +2005,12 @@ MInArray::collectRangeInfo() needsNegativeIntCheck_ = !index()->range() || index()->range()->lower() < 0; } +void +MLoadElementHole::collectRangeInfo() +{ + needsNegativeIntCheck_ = !index()->range() || index()->range()->lower() < 0; +} + void MMod::collectRangeInfo() { diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index d8417a135046..be5f944c3ae0 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -262,6 +262,11 @@ js::DestroyContext(JSContext *cx, DestroyContextMode mode) CancelOffThreadIonCompile(c, NULL); WaitForOffThreadParsingToFinish(rt); +#ifdef JS_WORKER_THREADS + if (rt->workerThreadState) + rt->workerThreadState->cleanup(rt); +#endif + /* Unpin all common names before final GC. */ FinishCommonNames(rt); diff --git a/js/src/jscntxtinlines.h b/js/src/jscntxtinlines.h index 6cdf75841685..eb5030185a0f 100644 --- a/js/src/jscntxtinlines.h +++ b/js/src/jscntxtinlines.h @@ -10,6 +10,7 @@ #include "jscntxt.h" #include "jsiter.h" +#include "jsworkers.h" #include "builtin/Object.h" #include "jit/IonFrames.h" diff --git a/js/src/jsmath.cpp b/js/src/jsmath.cpp index a3347d793319..67e05ccfa7ac 100644 --- a/js/src/jsmath.cpp +++ b/js/src/jsmath.cpp @@ -1101,6 +1101,8 @@ js::math_atanh(JSContext *cx, unsigned argc, Value *vp) return math_function(cx, argc, vp); } +// Math.hypot is disabled pending the resolution of spec issues (bug 896264). +#if 0 #if !HAVE_HYPOT double hypot(double x, double y) { @@ -1166,6 +1168,7 @@ js::math_hypot(JSContext *cx, unsigned argc, Value *vp) args.rval().setNumber(math_hypot_impl(math_hypot_impl(x, y), z)); return true; } +#endif #if !HAVE_TRUNC double trunc(double x) @@ -1274,7 +1277,10 @@ static const JSFunctionSpec math_static_methods[] = { JS_FN("acosh", math_acosh, 1, 0), JS_FN("asinh", math_asinh, 1, 0), JS_FN("atanh", math_atanh, 1, 0), +// Math.hypot is disabled pending the resolution of spec issues (bug 896264). +#if 0 JS_FN("hypot", math_hypot, 2, 0), +#endif JS_FN("trunc", math_trunc, 1, 0), JS_FN("sign", math_sign, 1, 0), JS_FN("cbrt", math_cbrt, 1, 0), diff --git a/js/src/jsmath.h b/js/src/jsmath.h index 3a643d546dce..8e9ccece422c 100644 --- a/js/src/jsmath.h +++ b/js/src/jsmath.h @@ -159,8 +159,11 @@ math_asinh(JSContext *cx, unsigned argc, js::Value *vp); extern bool math_atanh(JSContext *cx, unsigned argc, js::Value *vp); +// Math.hypot is disabled pending the resolution of spec issues (bug 896264). +#if 0 extern bool math_hypot(JSContext *cx, unsigned argc, Value *vp); +#endif extern bool math_trunc(JSContext *cx, unsigned argc, Value *vp); @@ -243,8 +246,11 @@ math_asinh_impl(MathCache *cache, double x); extern double math_atanh_impl(MathCache *cache, double x); +// Math.hypot is disabled pending the resolution of spec issues (bug 896264). +#if 0 extern double math_hypot_impl(double x, double y); +#endif extern double math_trunc_impl(MathCache *cache, double x); diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index fae864ede0a9..97801aedf378 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -637,7 +637,7 @@ js::XDRScript(XDRState *xdr, HandleObject enclosingScope, HandleScript enc code = ssd->data; if (natoms != 0) { script->natoms = natoms; - script->atoms = ssd->atoms(); + script->atoms = ssd->atoms(length, nsrcnotes); } } @@ -1518,26 +1518,15 @@ js::SharedScriptData::new_(ExclusiveContext *cx, uint32_t codeLength, uint32_t baseLength = codeLength + srcnotesLength; uint32_t padding = sizeof(JSAtom *) - baseLength % sizeof(JSAtom *); uint32_t length = baseLength + padding + sizeof(JSAtom *) * natoms; - JS_ASSERT(length % sizeof(JSAtom *) == 0); SharedScriptData *entry = (SharedScriptData *)cx->malloc_(length + offsetof(SharedScriptData, data)); if (!entry) return NULL; - entry->length = length; - entry->natoms = natoms; entry->marked = false; + entry->length = length; memset(entry->data + baseLength, 0, padding); - - /* - * Call constructors to initialize the storage that will be accessed as a - * HeapPtrAtom array via atoms(). - */ - HeapPtrAtom *atoms = entry->atoms(); - for (unsigned i = 0; i < natoms; ++i) - new (&atoms[i]) HeapPtrAtom(); - return entry; } @@ -1585,7 +1574,7 @@ SaveSharedScriptData(ExclusiveContext *cx, Handle script, SharedScri #endif script->code = ssd->data; - script->atoms = ssd->atoms(); + script->atoms = ssd->atoms(script->length, nsrcnotes); return true; } @@ -1929,7 +1918,7 @@ JSScript::fullyInitFromEmitter(ExclusiveContext *cx, HandleScript script, Byteco PodCopy(code + prologLength, bce->code().begin(), mainLength); if (!FinishTakingSrcNotes(cx, bce, (jssrcnote *)(code + script->length))) return false; - InitAtomMap(bce->atomIndices.getMap(), ssd->atoms()); + InitAtomMap(bce->atomIndices.getMap(), ssd->atoms(script->length, nsrcnotes)); if (!SaveSharedScriptData(cx, script, ssd, nsrcnotes)) return false; @@ -2806,7 +2795,7 @@ JSScript::markChildren(JSTracer *trc) if (IS_GC_MARKING_TRACER(trc)) { compartment()->mark(); - if (code || natoms) + if (code) MarkScriptData(trc->runtime, code); } diff --git a/js/src/jsscript.h b/js/src/jsscript.h index ee20caf4239b..a845c52d50c9 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -1427,27 +1427,22 @@ CallDestroyScriptHook(FreeOp *fop, JSScript *script); struct SharedScriptData { - uint32_t length; - uint32_t natoms; bool marked; + uint32_t length; jsbytecode data[1]; static SharedScriptData *new_(ExclusiveContext *cx, uint32_t codeLength, uint32_t srcnotesLength, uint32_t natoms); - HeapPtrAtom *atoms() { - if (!natoms) - return NULL; - return reinterpret_cast(data + length - sizeof(JSAtom *) * natoms); + HeapPtrAtom *atoms(uint32_t codeLength, uint32_t srcnotesLength) { + uint32_t length = codeLength + srcnotesLength; + return reinterpret_cast(data + length + sizeof(JSAtom *) - + length % sizeof(JSAtom *)); } static SharedScriptData *fromBytecode(const jsbytecode *bytecode) { return (SharedScriptData *)(bytecode - offsetof(SharedScriptData, data)); } - - private: - SharedScriptData() MOZ_DELETE; - SharedScriptData(const SharedScriptData&) MOZ_DELETE; }; struct ScriptBytecodeHasher diff --git a/js/src/jsworkers.cpp b/js/src/jsworkers.cpp index fde2174e0c66..3a10377accda 100644 --- a/js/src/jsworkers.cpp +++ b/js/src/jsworkers.cpp @@ -359,18 +359,33 @@ WorkerThreadState::init(JSRuntime *rt) return true; } -WorkerThreadState::~WorkerThreadState() +void +WorkerThreadState::cleanup(JSRuntime *rt) { - /* - * Join created threads first, which needs locks and condition variables - * to be intact. - */ + // Do preparatory work for shutdown before the final GC has destroyed most + // of the GC heap. + + // Join created threads, to ensure there is no in progress work. if (threads) { for (size_t i = 0; i < numThreads; i++) threads[i].destroy(); js_free(threads); + threads = NULL; + numThreads = 0; } + // Clean up any parse tasks which haven't been finished yet. + while (!parseFinishedList.empty()) { + JSScript *script = parseFinishedList[0]->script; + finishParseTaskForScript(rt, script); + } +} + +WorkerThreadState::~WorkerThreadState() +{ + JS_ASSERT(!threads); + JS_ASSERT(parseFinishedList.empty()); + if (workerLock) PR_DestroyLock(workerLock); diff --git a/js/src/jsworkers.h b/js/src/jsworkers.h index e258ad953c82..934670410285 100644 --- a/js/src/jsworkers.h +++ b/js/src/jsworkers.h @@ -30,8 +30,7 @@ namespace ion { class IonBuilder; } -#if defined(JS_THREADSAFE) && defined(JS_ION) -# define JS_WORKER_THREADS +#ifdef JS_WORKER_THREADS /* Per-runtime state for off thread work items. */ class WorkerThreadState @@ -75,6 +74,7 @@ class WorkerThreadState ~WorkerThreadState(); bool init(JSRuntime *rt); + void cleanup(JSRuntime *rt); void lock(); void unlock(); @@ -236,27 +236,31 @@ WaitForOffThreadParsingToFinish(JSRuntime *rt); class AutoLockWorkerThreadState { - WorkerThreadState &state; MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER +#ifdef JS_WORKER_THREADS + WorkerThreadState &state; + public: AutoLockWorkerThreadState(WorkerThreadState &state MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : state(state) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; -#ifdef JS_WORKER_THREADS state.lock(); -#else - (void)state; -#endif } ~AutoLockWorkerThreadState() { -#ifdef JS_WORKER_THREADS state.unlock(); -#endif } +#else + public: + AutoLockWorkerThreadState(WorkerThreadState &state + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + } +#endif }; class AutoUnlockWorkerThreadState diff --git a/js/src/tests/ecma_6/Math/hypot-approx.js b/js/src/tests/ecma_6/Math/hypot-approx.js index 1b68aad52fcd..9960d55d2ea6 100644 --- a/js/src/tests/ecma_6/Math/hypot-approx.js +++ b/js/src/tests/ecma_6/Math/hypot-approx.js @@ -1,3 +1,6 @@ +// |reftest| skip +// Math.hypot is disabled pending the resolution of spec issues (bug 896264). + for (var i = -20; i < 20; i++) assertEq(Math.hypot(+0, i), Math.abs(i)); diff --git a/js/src/tests/ecma_6/Math/hypot-exact.js b/js/src/tests/ecma_6/Math/hypot-exact.js index 6f37b6607e59..059c896ffb1a 100644 --- a/js/src/tests/ecma_6/Math/hypot-exact.js +++ b/js/src/tests/ecma_6/Math/hypot-exact.js @@ -1,3 +1,6 @@ +// |reftest| skip +// Math.hypot is disabled pending the resolution of spec issues (bug 896264). + // Properties of Math.hypot that are guaranteed by the spec. // If any argument is +∞, the result is +∞. diff --git a/js/src/vm/Runtime-inl.h b/js/src/vm/Runtime-inl.h index 1736037a16b7..7386c79d9888 100644 --- a/js/src/vm/Runtime-inl.h +++ b/js/src/vm/Runtime-inl.h @@ -74,7 +74,7 @@ ThreadDataIter::ThreadDataIter(JSRuntime *rt) #ifdef JS_WORKER_THREADS // Only allow iteration over a runtime's threads when those threads are // paused, to avoid racing when reading data from the PerThreadData. - JS_ASSERT_IF(rt->workerThreadState, rt->workerThreadState->shouldPause); + JS_ASSERT(rt->exclusiveThreadsPaused); #endif iter = rt->threadList.getFirst(); } diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index 8a2bb7bce51b..e0fbd0b1d343 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -663,6 +663,7 @@ typedef Vector ZoneVector; class AutoLockForExclusiveAccess; class AutoPauseWorkersForGC; +class ThreadDataIter; } // namespace js @@ -772,6 +773,7 @@ struct JSRuntime : public JS::shadow::Runtime, friend class js::AutoLockForExclusiveAccess; friend class js::AutoPauseWorkersForGC; + friend class js::ThreadDataIter; public: void setUsedByExclusiveThread(JS::Zone *zone); @@ -1317,6 +1319,7 @@ struct JSRuntime : public JS::shadow::Runtime, #ifdef JS_THREADSAFE # ifdef JS_ION js::WorkerThreadState *workerThreadState; +# define JS_WORKER_THREADS # endif js::SourceCompressorThread sourceCompressorThread; diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 054f667ee7b5..c96995f89fd2 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -2267,6 +2267,7 @@ public: NS_IMETHOD Unroot(void *p) { return NS_OK; } NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(XPCWrappedNative) }; + NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(XPCWrappedNative); static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; void DeleteCycleCollectable() {} diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index e57e0dd503b4..3d7acc8b20ab 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -9169,7 +9169,8 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState, (display->mDisplay == NS_STYLE_DISPLAY_INLINE_BOX) ? "NeededToWrapXULInlineBox" : "NeededToWrapXUL"; nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "FrameConstructor", mDocument, + NS_LITERAL_CSTRING("FrameConstructor"), + mDocument, nsContentUtils::eXUL_PROPERTIES, message, params, ArrayLength(params)); diff --git a/layout/generic/nsImageMap.cpp b/layout/generic/nsImageMap.cpp index 1b20d5e2dbb3..8cc50b8e7096 100644 --- a/layout/generic/nsImageMap.cpp +++ b/layout/generic/nsImageMap.cpp @@ -91,7 +91,7 @@ static void logMessage(nsIContent* aContent, nsIDocument* doc = aContent->OwnerDoc(); nsContentUtils::ReportToConsole( - aFlags, "ImageMap", doc, + aFlags, NS_LITERAL_CSTRING("ImageMap"), doc, nsContentUtils::eLAYOUT_PROPERTIES, aMessageName, nullptr, /* params */ diff --git a/layout/mathml/nsMathMLContainerFrame.cpp b/layout/mathml/nsMathMLContainerFrame.cpp index e92b6d46159e..0a1ae413a9c1 100644 --- a/layout/mathml/nsMathMLContainerFrame.cpp +++ b/layout/mathml/nsMathMLContainerFrame.cpp @@ -1523,7 +1523,7 @@ nsMathMLContainerFrame::ReportErrorToConsole(const char* errorMsgId, uint32_t aParamCount) { return nsContentUtils::ReportToConsole(nsIScriptError::errorFlag, - "MathML", mContent->OwnerDoc(), + NS_LITERAL_CSTRING("MathML"), mContent->OwnerDoc(), nsContentUtils::eMATHML_PROPERTIES, errorMsgId, aParams, aParamCount); } diff --git a/layout/style/Loader.cpp b/layout/style/Loader.cpp index add571174f19..11a3db478c42 100644 --- a/layout/style/Loader.cpp +++ b/layout/style/Loader.cpp @@ -916,7 +916,8 @@ SheetLoadData::OnStreamComplete(nsIUnicharStreamLoader* aLoader, nsCOMPtr referrer = GetReferrerURI(); nsContentUtils::ReportToConsole(errorFlag, - "CSS Loader", mLoader->mDocument, + NS_LITERAL_CSTRING("CSS Loader"), + mLoader->mDocument, nsContentUtils::eCSS_PROPERTIES, errorMessage, strings, ArrayLength(strings), diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp index 8f8a7fd0da78..d4dc8af186a3 100644 --- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -56,11 +56,6 @@ nsCSSValue::nsCSSValue(const nsString& aValue, nsCSSUnit aUnit) NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string value"); if (UnitHasStringValue()) { mValue.mString = BufferFromString(aValue).get(); - if (MOZ_UNLIKELY(!mValue.mString)) { - // XXXbz not much we can do here; just make sure that our promise of a - // non-null mValue.mString holds for string units. - mUnit = eCSSUnit_Null; - } } else { mUnit = eCSSUnit_Null; @@ -345,11 +340,6 @@ void nsCSSValue::SetStringValue(const nsString& aValue, NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string unit"); if (UnitHasStringValue()) { mValue.mString = BufferFromString(aValue).get(); - if (MOZ_UNLIKELY(!mValue.mString)) { - // XXXbz not much we can do here; just make sure that our promise of a - // non-null mValue.mString holds for string units. - mUnit = eCSSUnit_Null; - } } else mUnit = eCSSUnit_Null; } diff --git a/layout/style/nsCSSValue.h b/layout/style/nsCSSValue.h index bcc3846785ee..fecaf0dbd447 100644 --- a/layout/style/nsCSSValue.h +++ b/layout/style/nsCSSValue.h @@ -514,8 +514,8 @@ public: // Checks if this is a function value with the specified function id. bool EqualsFunction(nsCSSKeyword aFunctionId) const; - // Returns an already addrefed buffer. Can return null on allocation - // failure. + // Returns an already addrefed buffer. Guaranteed to return non-null. + // (Will abort on allocation failure.) static already_AddRefed BufferFromString(const nsString& aValue); diff --git a/layout/style/nsStyleAnimation.cpp b/layout/style/nsStyleAnimation.cpp index 71ee46b25fb3..baa602b9bda0 100644 --- a/layout/style/nsStyleAnimation.cpp +++ b/layout/style/nsStyleAnimation.cpp @@ -3402,11 +3402,6 @@ nsStyleAnimation::Value::SetUnparsedStringValue(const nsString& aString) FreeValue(); mUnit = eUnit_UnparsedString; mValue.mString = nsCSSValue::BufferFromString(aString).get(); - if (MOZ_UNLIKELY(!mValue.mString)) { - // not much we can do here; just make sure that our promise of a - // non-null mValue.mString holds for string units. - mUnit = eUnit_Null; - } } void diff --git a/mfbt/LinkedList.h b/mfbt/LinkedList.h index c29760b3e73c..8308fb3dfd93 100644 --- a/mfbt/LinkedList.h +++ b/mfbt/LinkedList.h @@ -252,8 +252,8 @@ class LinkedListElement } private: - LinkedListElement& operator=(const LinkedList& other) MOZ_DELETE; - LinkedListElement(const LinkedList& other) MOZ_DELETE; + LinkedListElement& operator=(const LinkedListElement& other) MOZ_DELETE; + LinkedListElement(const LinkedListElement& other) MOZ_DELETE; }; template @@ -361,7 +361,7 @@ class LinkedList for (slow = sentinel.next, fast1 = sentinel.next->next, fast2 = sentinel.next->next->next; - slow != sentinel && fast1 != sentinel && fast2 != sentinel; + slow != &sentinel && fast1 != &sentinel && fast2 != &sentinel; slow = slow->next, fast1 = fast2->next, fast2 = fast1->next) { MOZ_ASSERT(slow != fast1); @@ -372,7 +372,7 @@ class LinkedList for (slow = sentinel.prev, fast1 = sentinel.prev->prev, fast2 = sentinel.prev->prev->prev; - slow != sentinel && fast1 != sentinel && fast2 != sentinel; + slow != &sentinel && fast1 != &sentinel && fast2 != &sentinel; slow = slow->prev, fast1 = fast2->prev, fast2 = fast1->prev) { MOZ_ASSERT(slow != fast1); @@ -384,14 +384,14 @@ class LinkedList * isSentinel == true. */ for (const LinkedListElement* elem = sentinel.next; - elem != sentinel; + elem != &sentinel; elem = elem->next) { MOZ_ASSERT(!elem->isSentinel); } /* Check that the next/prev pointers match up. */ - const LinkedListElement* prev = sentinel; + const LinkedListElement* prev = &sentinel; const LinkedListElement* cur = sentinel.next; do { MOZ_ASSERT(cur->prev == prev); @@ -399,7 +399,7 @@ class LinkedList prev = cur; cur = cur->next; - } while (cur != sentinel); + } while (cur != &sentinel); #endif /* ifdef DEBUG */ } diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 98ed61d1ee8f..b7430818a22a 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -475,9 +475,6 @@ pref("view_source.editor.args", ""); // When true this will word-wrap plain text documents. pref("plain_text.wrap_long_lines", false); -// dispatch left clicks only to content in browser (still allows clicks to chrome/xul) -pref("nglayout.events.dispatchLeftClickOnly", true); - // whether or not to draw images while dragging pref("nglayout.enable_drag_images", true); @@ -822,10 +819,12 @@ pref("javascript.options.strict.debug", true); pref("javascript.options.baselinejit.content", true); pref("javascript.options.baselinejit.chrome", true); pref("javascript.options.ion.content", true); +pref("javascript.options.ion.chrome", false); pref("javascript.options.asmjs", true); pref("javascript.options.ion.parallel_compilation", true); pref("javascript.options.jit_hardening", true); -pref("javascript.options.typeinference", true); +pref("javascript.options.typeinference.content", true); +pref("javascript.options.typeinference.chrome", false); // This preference limits the memory usage of javascript. // If you want to change these values for your device, // please find Bug 417052 comment 17 and Bug 456721 diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h index 1949c5e42441..91afd760d4e1 100644 --- a/netwerk/base/public/nsNetUtil.h +++ b/netwerk/base/public/nsNetUtil.h @@ -1976,19 +1976,26 @@ NS_RelaxStrictFileOriginPolicy(nsIURI *aTargetURI, // inherit its source principal and be scriptable by that source. // bool sourceIsDir; - bool contained = false; + bool allowed = false; nsresult rv = sourceFile->IsDirectory(&sourceIsDir); if (NS_SUCCEEDED(rv) && sourceIsDir) { - rv = sourceFile->Contains(targetFile, true, &contained); + rv = sourceFile->Contains(targetFile, true, &allowed); } else { nsCOMPtr sourceParent; rv = sourceFile->GetParent(getter_AddRefs(sourceParent)); if (NS_SUCCEEDED(rv) && sourceParent) { - rv = sourceParent->Contains(targetFile, true, &contained); + rv = sourceParent->Equals(targetFile, &allowed); + if (NS_FAILED(rv) || !allowed) { + rv = sourceParent->Contains(targetFile, true, &allowed); + } else { + MOZ_ASSERT(aAllowDirectoryTarget, + "sourceFile->Parent == targetFile, but targetFile " + "should've been disallowed if it is a directory"); + } } } - if (NS_SUCCEEDED(rv) && contained) { + if (NS_SUCCEEDED(rv) && allowed) { return true; } diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index 636e35e92e63..c2f2865ac1cf 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -270,39 +270,39 @@ nsHttpConnectionMgr::Observe(nsISupports *subject, //----------------------------------------------------------------------------- nsresult -nsHttpConnectionMgr::AddTransaction(nsHttpTransaction *aTrans, int32_t priority) +nsHttpConnectionMgr::AddTransaction(nsHttpTransaction *trans, int32_t priority) { - LOG(("nsHttpConnectionMgr::AddTransaction [trans=%x %d]\n", aTrans, priority)); + LOG(("nsHttpConnectionMgr::AddTransaction [trans=%x %d]\n", trans, priority)); - nsRefPtr trans(aTrans); + NS_ADDREF(trans); nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgNewTransaction, priority, trans); - if (NS_SUCCEEDED(rv)) - trans.forget(); + if (NS_FAILED(rv)) + NS_RELEASE(trans); return rv; } nsresult -nsHttpConnectionMgr::RescheduleTransaction(nsHttpTransaction *aTrans, int32_t priority) +nsHttpConnectionMgr::RescheduleTransaction(nsHttpTransaction *trans, int32_t priority) { - LOG(("nsHttpConnectionMgr::RescheduleTransaction [trans=%x %d]\n", aTrans, priority)); + LOG(("nsHttpConnectionMgr::RescheduleTransaction [trans=%x %d]\n", trans, priority)); - nsRefPtr trans(aTrans); + NS_ADDREF(trans); nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgReschedTransaction, priority, trans); - if (NS_SUCCEEDED(rv)) - trans.forget(); + if (NS_FAILED(rv)) + NS_RELEASE(trans); return rv; } nsresult -nsHttpConnectionMgr::CancelTransaction(nsHttpTransaction *aTrans, nsresult reason) +nsHttpConnectionMgr::CancelTransaction(nsHttpTransaction *trans, nsresult reason) { - LOG(("nsHttpConnectionMgr::CancelTransaction [trans=%x reason=%x]\n", aTrans, reason)); + LOG(("nsHttpConnectionMgr::CancelTransaction [trans=%x reason=%x]\n", trans, reason)); - nsRefPtr trans(aTrans); + NS_ADDREF(trans); nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgCancelTransaction, static_cast(reason), trans); - if (NS_SUCCEEDED(rv)) - trans.forget(); + if (NS_FAILED(rv)) + NS_RELEASE(trans); return rv; } @@ -359,14 +359,14 @@ nsHttpConnectionMgr::GetSocketThreadTarget(nsIEventTarget **target) } nsresult -nsHttpConnectionMgr::ReclaimConnection(nsHttpConnection *aConn) +nsHttpConnectionMgr::ReclaimConnection(nsHttpConnection *conn) { - LOG(("nsHttpConnectionMgr::ReclaimConnection [conn=%x]\n", aConn)); + LOG(("nsHttpConnectionMgr::ReclaimConnection [conn=%x]\n", conn)); - nsRefPtr conn(aConn); + NS_ADDREF(conn); nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgReclaimConnection, 0, conn); - if (NS_SUCCEEDED(rv)) - conn.forget(); + if (NS_FAILED(rv)) + NS_RELEASE(conn); return rv; } @@ -405,14 +405,14 @@ nsHttpConnectionMgr::UpdateParam(nsParamName name, uint16_t value) } nsresult -nsHttpConnectionMgr::ProcessPendingQ(nsHttpConnectionInfo *aCI) +nsHttpConnectionMgr::ProcessPendingQ(nsHttpConnectionInfo *ci) { - LOG(("nsHttpConnectionMgr::ProcessPendingQ [ci=%s]\n", aCI->HashKey().get())); + LOG(("nsHttpConnectionMgr::ProcessPendingQ [ci=%s]\n", ci->HashKey().get())); - nsRefPtr ci(aCI); + NS_ADDREF(ci); nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgProcessPendingQ, 0, ci); - if (NS_SUCCEEDED(rv)) - ci.forget(); + if (NS_FAILED(rv)) + NS_RELEASE(ci); return rv; } @@ -2090,12 +2090,12 @@ nsHttpConnectionMgr::OnMsgNewTransaction(int32_t priority, void *param) { LOG(("nsHttpConnectionMgr::OnMsgNewTransaction [trans=%p]\n", param)); - nsRefPtr trans = - dont_AddRef(static_cast(param)); + nsHttpTransaction *trans = (nsHttpTransaction *) param; trans->SetPriority(priority); nsresult rv = ProcessNewTransaction(trans); if (NS_FAILED(rv)) trans->Close(rv); // for whatever its worth + NS_RELEASE(trans); } void @@ -2104,8 +2104,7 @@ nsHttpConnectionMgr::OnMsgReschedTransaction(int32_t priority, void *param) MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); LOG(("nsHttpConnectionMgr::OnMsgReschedTransaction [trans=%p]\n", param)); - nsRefPtr trans = - dont_AddRef(static_cast(param)); + nsHttpTransaction *trans = (nsHttpTransaction *) param; trans->SetPriority(priority); nsConnectionEntry *ent = LookupConnectionEntry(trans->ConnectionInfo(), @@ -2118,6 +2117,8 @@ nsHttpConnectionMgr::OnMsgReschedTransaction(int32_t priority, void *param) InsertTransactionSorted(ent->mPendingQ, trans); } } + + NS_RELEASE(trans); } void @@ -2127,8 +2128,7 @@ nsHttpConnectionMgr::OnMsgCancelTransaction(int32_t reason, void *param) LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p]\n", param)); nsresult closeCode = static_cast(reason); - nsRefPtr trans = - dont_AddRef(static_cast(param)); + nsHttpTransaction *trans = (nsHttpTransaction *) param; // // if the transaction owns a connection and the transaction is not done, // then ask the connection to close the transaction. otherwise, close the @@ -2151,14 +2151,14 @@ nsHttpConnectionMgr::OnMsgCancelTransaction(int32_t reason, void *param) } trans->Close(closeCode); } + NS_RELEASE(trans); } void nsHttpConnectionMgr::OnMsgProcessPendingQ(int32_t, void *param) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); - nsRefPtr ci = - dont_AddRef(static_cast(param)); + nsHttpConnectionInfo *ci = (nsHttpConnectionInfo *) param; if (!ci) { LOG(("nsHttpConnectionMgr::OnMsgProcessPendingQ [ci=nullptr]\n")); @@ -2177,6 +2177,8 @@ nsHttpConnectionMgr::OnMsgProcessPendingQ(int32_t, void *param) // for the specified connection info. walk the connection table... mCT.Enumerate(ProcessOneTransactionCB, this); } + + NS_RELEASE(ci); } void @@ -2214,8 +2216,7 @@ nsHttpConnectionMgr::OnMsgReclaimConnection(int32_t, void *param) MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); LOG(("nsHttpConnectionMgr::OnMsgReclaimConnection [conn=%p]\n", param)); - nsRefPtr conn = - dont_AddRef(static_cast(param)); + nsHttpConnection *conn = (nsHttpConnection *) param; // // 1) remove the connection from the active list @@ -2225,16 +2226,16 @@ nsHttpConnectionMgr::OnMsgReclaimConnection(int32_t, void *param) nsConnectionEntry *ent = LookupConnectionEntry(conn->ConnectionInfo(), conn, nullptr); - nsRefPtr ci; + nsHttpConnectionInfo *ci = nullptr; if (!ent) { // this should never happen LOG(("nsHttpConnectionMgr::OnMsgReclaimConnection ent == null\n")); MOZ_ASSERT(false, "no connection entry"); - ci = conn->ConnectionInfo(); + NS_ADDREF(ci = conn->ConnectionInfo()); } else { - ci = ent->mConnInfo; + NS_ADDREF(ci = ent->mConnInfo); // If the connection is in the active list, remove that entry // and the reference held by the mActiveConns list. @@ -2254,9 +2255,8 @@ nsHttpConnectionMgr::OnMsgReclaimConnection(int32_t, void *param) if (ent->mActiveConns.RemoveElement(conn)) { if (conn == ent->mYellowConnection) ent->OnYellowComplete(); - - // drop a reference that was held by list - conn.get()->Release(); + nsHttpConnection *temp = conn; + NS_RELEASE(temp); DecrementActiveConnCount(conn); ConditionallyStopTimeoutTick(); } @@ -2277,8 +2277,7 @@ nsHttpConnectionMgr::OnMsgReclaimConnection(int32_t, void *param) break; } - // manually add a ref to the connection when it is in the list - conn.get()->AddRef(); + NS_ADDREF(conn); ent->mIdleConns.InsertElementAt(idx, conn); mNumIdleConns++; conn->BeginIdleMonitoring(); @@ -2296,7 +2295,8 @@ nsHttpConnectionMgr::OnMsgReclaimConnection(int32_t, void *param) } } - OnMsgProcessPendingQ(0, ci.forget().get()); // releases |ci| + OnMsgProcessPendingQ(0, ci); // releases |ci| + NS_RELEASE(conn); } void @@ -2359,6 +2359,8 @@ nsHttpConnectionMgr::nsConnectionEntry::~nsConnectionEntry() { if (mSpdyPreferred) gHttpHandler->ConnMgr()->RemoveSpdyPreferredEnt(mCoalescingKey); + + NS_RELEASE(mConnInfo); } void @@ -2469,6 +2471,7 @@ nsHttpConnectionMgr::nsConnectionHandle::~nsConnectionHandle() { if (mConn) { gHttpHandler->ReclaimConnection(mConn); + NS_RELEASE(mConn); } } @@ -3094,6 +3097,7 @@ nsConnectionEntry::nsConnectionEntry(nsHttpConnectionInfo *ci) , mPreferIPv4(false) , mPreferIPv6(false) { + NS_ADDREF(mConnInfo); if (gHttpHandler->GetPipelineAggressive()) { mGreenDepth = kPipelineUnlimited; mPipelineState = PS_GREEN; diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.h b/netwerk/protocol/http/nsHttpConnectionMgr.h index da16d8b0e35a..9e539286d414 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.h +++ b/netwerk/protocol/http/nsHttpConnectionMgr.h @@ -273,7 +273,7 @@ private: nsConnectionEntry(nsHttpConnectionInfo *ci); ~nsConnectionEntry(); - nsRefPtr mConnInfo; + nsHttpConnectionInfo *mConnInfo; nsTArray mPendingQ; // pending transaction queue nsTArray mActiveConns; // active connections nsTArray mIdleConns; // idle persistent connections @@ -393,10 +393,10 @@ private: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSAHTTPCONNECTION(mConn) - nsConnectionHandle(nsHttpConnection *conn) : mConn(conn) { } + nsConnectionHandle(nsHttpConnection *conn) { NS_ADDREF(mConn = conn); } virtual ~nsConnectionHandle(); - nsRefPtr mConn; + nsHttpConnection *mConn; }; // nsHalfOpenSocket is used to hold the state of an opening TCP socket diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index d143239afd0e..2ff39548fffc 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -121,14 +121,19 @@ NewURI(const nsACString &aSpec, int32_t aDefaultPort, nsIURI **aURI) { - nsRefPtr url = new nsStandardURL(); + nsStandardURL *url = new nsStandardURL(); + if (!url) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(url); nsresult rv = url->Init(nsIStandardURL::URLTYPE_AUTHORITY, aDefaultPort, aSpec, aCharset, aBaseURI); if (NS_FAILED(rv)) { + NS_RELEASE(url); return rv; } - url.forget(aURI); + + *aURI = url; // no QI needed return NS_OK; } @@ -139,7 +144,8 @@ NewURI(const nsACString &aSpec, nsHttpHandler *gHttpHandler = nullptr; nsHttpHandler::nsHttpHandler() - : mHttpVersion(NS_HTTP_VERSION_1_1) + : mConnMgr(nullptr) + , mHttpVersion(NS_HTTP_VERSION_1_1) , mProxyHttpVersion(NS_HTTP_VERSION_1_1) , mCapabilities(NS_HTTP_ALLOW_KEEPALIVE) , mReferrerLevel(0xff) // by default we always send a referrer @@ -218,7 +224,7 @@ nsHttpHandler::~nsHttpHandler() // make sure the connection manager is shutdown if (mConnMgr) { mConnMgr->Shutdown(); - mConnMgr = nullptr; + NS_RELEASE(mConnMgr); } // Note: don't call NeckoChild::DestroyNeckoChild() here, as it's too late @@ -374,8 +380,12 @@ nsHttpHandler::InitConnectionMgr() { nsresult rv; - if (!mConnMgr) + if (!mConnMgr) { mConnMgr = new nsHttpConnectionMgr(); + if (!mConnMgr) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(mConnMgr); + } rv = mConnMgr->Init(mMaxConnections, mMaxPersistentConnectionsPerServer, diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h index e78ab1153c6a..dc419dbbe4fa 100644 --- a/netwerk/protocol/http/nsHttpHandler.h +++ b/netwerk/protocol/http/nsHttpHandler.h @@ -315,7 +315,7 @@ private: nsHttpAuthCache mPrivateAuthCache; // the connection manager - nsRefPtr mConnMgr; + nsHttpConnectionMgr *mConnMgr; // // prefs diff --git a/netwerk/protocol/http/nsHttpPipeline.cpp b/netwerk/protocol/http/nsHttpPipeline.cpp index dde16a709783..e7c04a46002b 100644 --- a/netwerk/protocol/http/nsHttpPipeline.cpp +++ b/netwerk/protocol/http/nsHttpPipeline.cpp @@ -63,7 +63,8 @@ private: //----------------------------------------------------------------------------- nsHttpPipeline::nsHttpPipeline() - : mStatus(NS_OK) + : mConnection(nullptr) + , mStatus(NS_OK) , mRequestIsPartial(false) , mResponseIsPartial(false) , mClosed(false) @@ -83,6 +84,8 @@ nsHttpPipeline::~nsHttpPipeline() // make sure we aren't still holding onto any transactions! Close(NS_ERROR_ABORT); + NS_IF_RELEASE(mConnection); + if (mPushBackBuf) free(mPushBackBuf); } @@ -407,13 +410,14 @@ nsHttpPipeline::SetConnection(nsAHttpConnection *conn) MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); MOZ_ASSERT(!mConnection, "already have a connection"); - mConnection = conn; + + NS_IF_ADDREF(mConnection = conn); } nsAHttpConnection * nsHttpPipeline::Connection() { - LOG(("nsHttpPipeline::Connection [this=%p conn=%x]\n", this, mConnection.get())); + LOG(("nsHttpPipeline::Connection [this=%p conn=%x]\n", this, mConnection)); MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); return mConnection; diff --git a/netwerk/protocol/http/nsHttpPipeline.h b/netwerk/protocol/http/nsHttpPipeline.h index 4c41a5c3a0a1..8570e83ca9d9 100644 --- a/netwerk/protocol/http/nsHttpPipeline.h +++ b/netwerk/protocol/http/nsHttpPipeline.h @@ -52,7 +52,7 @@ private: // overload of nsAHttpTransaction::QueryPipeline() nsHttpPipeline *QueryPipeline(); - nsRefPtr mConnection; + nsAHttpConnection *mConnection; nsTArray mRequestQ; // array of transactions nsTArray mResponseQ; // array of transactions nsresult mStatus; diff --git a/netwerk/protocol/http/nsHttpTransaction.cpp b/netwerk/protocol/http/nsHttpTransaction.cpp index b1a160387843..2f0519e9be29 100644 --- a/netwerk/protocol/http/nsHttpTransaction.cpp +++ b/netwerk/protocol/http/nsHttpTransaction.cpp @@ -82,6 +82,8 @@ LogHeaders(const char *lineStart) nsHttpTransaction::nsHttpTransaction() : mCallbacksLock("transaction mCallbacks lock") , mRequestSize(0) + , mConnection(nullptr) + , mConnInfo(nullptr) , mRequestHead(nullptr) , mResponseHead(nullptr) , mContentLength(-1) @@ -135,6 +137,9 @@ nsHttpTransaction::~nsHttpTransaction() // Force the callbacks to be released right now mCallbacks = nullptr; + NS_IF_RELEASE(mConnection); + NS_IF_RELEASE(mConnInfo); + delete mResponseHead; delete mForTakeResponseHead; delete mChunkedDecoder; @@ -227,7 +232,7 @@ nsHttpTransaction::Init(uint32_t caps, !activityDistributorActive); if (NS_FAILED(rv)) return rv; - mConnInfo = cinfo; + NS_ADDREF(mConnInfo = cinfo); mCallbacks = callbacks; mConsumerTarget = target; mCaps = caps; @@ -403,7 +408,8 @@ nsHttpTransaction::TakeSubTransactions( void nsHttpTransaction::SetConnection(nsAHttpConnection *conn) { - mConnection = conn; + NS_IF_RELEASE(mConnection); + NS_IF_ADDREF(mConnection = conn); if (conn) { MOZ_EVENT_TRACER_EXEC(static_cast(this), @@ -818,8 +824,8 @@ nsHttpTransaction::Close(nsresult reason) mTimings.responseEnd.IsNull() && !mTimings.responseStart.IsNull()) mTimings.responseEnd = TimeStamp::Now(); - if (relConn) - mConnection = nullptr; + if (relConn && mConnection) + NS_RELEASE(mConnection); mStatus = reason; mTransactionDone = true; // forcibly flag the transaction as complete @@ -952,7 +958,7 @@ nsHttpTransaction::Restart() // clear old connection state... mSecurityInfo = 0; - mConnection = nullptr; + NS_IF_RELEASE(mConnection); // disable pipelining for the next attempt in case pipelining caused the // reset. this is being overly cautious since we don't know if pipelining diff --git a/netwerk/protocol/http/nsHttpTransaction.h b/netwerk/protocol/http/nsHttpTransaction.h index 3b5913d561f5..f0b61a2f44f2 100644 --- a/netwerk/protocol/http/nsHttpTransaction.h +++ b/netwerk/protocol/http/nsHttpTransaction.h @@ -180,11 +180,10 @@ private: nsCOMPtr mRequestStream; uint64_t mRequestSize; - nsRefPtr mConnInfo; - nsRefPtr mConnection; - + nsAHttpConnection *mConnection; // hard ref + nsHttpConnectionInfo *mConnInfo; // hard ref nsHttpRequestHead *mRequestHead; // weak ref - nsHttpResponseHead *mResponseHead; // owning ref + nsHttpResponseHead *mResponseHead; // hard ref nsAHttpSegmentReader *mReader; nsAHttpSegmentWriter *mWriter; diff --git a/parser/html/nsHtml5StreamParser.cpp b/parser/html/nsHtml5StreamParser.cpp index e71bf879eb6e..b3187694f882 100644 --- a/parser/html/nsHtml5StreamParser.cpp +++ b/parser/html/nsHtml5StreamParser.cpp @@ -1494,7 +1494,7 @@ nsHtml5StreamParser::ContinueAfterScripts(nsHtml5Tokenizer* aTokenizer, mTokenizer->setLineNumber(speculation->GetStartLineNumber()); nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - "DOM Events", + NS_LITERAL_CSTRING("DOM Events"), mExecutor->GetDocument(), nsContentUtils::eDOM_PROPERTIES, "SpeculationFailed", diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp index 4a9a0e3e7e1a..2bcaf0bf591f 100644 --- a/parser/html/nsHtml5TreeOpExecutor.cpp +++ b/parser/html/nsHtml5TreeOpExecutor.cpp @@ -887,7 +887,7 @@ nsHtml5TreeOpExecutor::MaybeComplainAboutCharset(const char* aMsgId, mAlreadyComplainedAboutCharset = true; nsContentUtils::ReportToConsole(aError ? nsIScriptError::errorFlag : nsIScriptError::warningFlag, - "HTML parser", + NS_LITERAL_CSTRING("HTML parser"), mDocument, nsContentUtils::eHTMLPARSER_PROPERTIES, aMsgId, @@ -905,7 +905,7 @@ nsHtml5TreeOpExecutor::ComplainAboutBogusProtocolCharset(nsIDocument* aDoc) "How come we already managed to complain?"); mAlreadyComplainedAboutCharset = true; nsContentUtils::ReportToConsole(nsIScriptError::errorFlag, - "HTML parser", + NS_LITERAL_CSTRING("HTML parser"), aDoc, nsContentUtils::eHTMLPARSER_PROPERTIES, "EncProtocolUnsupported"); diff --git a/testing/marionette/client/marionette/marionette.py b/testing/marionette/client/marionette/marionette.py index 30e312eaec5e..d363f4d6e999 100644 --- a/testing/marionette/client/marionette/marionette.py +++ b/testing/marionette/client/marionette/marionette.py @@ -456,7 +456,7 @@ class Marionette(object): self.instance = instance_class(host=self.host, port=self.port, bin=self.bin, profile=self.profile, app_args=app_args) self.instance.start() - assert(self.wait_for_port()) + assert(self.wait_for_port()), "Timed out waiting for port!" if emulator: self.emulator = Emulator(homedir=homedir, @@ -469,14 +469,14 @@ class Marionette(object): res=emulator_res) self.emulator.start() self.port = self.emulator.setup_port_forwarding(self.port) - assert(self.emulator.wait_for_port()) + assert(self.emulator.wait_for_port()), "Timed out waiting for port!" if connectToRunningEmulator: self.emulator = Emulator(homedir=homedir, logcat_dir=self.logcat_dir) self.emulator.connect() self.port = self.emulator.setup_port_forwarding(self.port) - assert(self.emulator.wait_for_port()) + assert(self.emulator.wait_for_port()), "Timed out waiting for port!" self.client = MarionetteClient(self.host, self.port) diff --git a/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py b/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py index a7013c7f329a..c71af93821c0 100644 --- a/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py +++ b/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py @@ -6,9 +6,10 @@ import multiprocessing import sys import time +# psutil will raise NotImplementedError if the platform is not supported. try: import psutil -except ImportError: +except (ImportError, NotImplementedError): psutil = None from collections import ( diff --git a/toolkit/components/printing/content/printUtils.js b/toolkit/components/printing/content/printUtils.js index 66948922b5fc..ab9e25927331 100644 --- a/toolkit/components/printing/content/printUtils.js +++ b/toolkit/components/printing/content/printUtils.js @@ -218,9 +218,9 @@ var PrintUtils = { // Set the original window as an active window so any mozPrintCallbacks can // run without delayed setTimeouts. - var docShell = originalWindow.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShell); + var docShell = originalWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIWebNavigation) + .QueryInterface(Components.interfaces.nsIDocShell); docShell.isActive = true; // show the toolbar after we go into print preview mode so diff --git a/toolkit/content/browser-child.js b/toolkit/content/browser-child.js index 78f189bba829..6a3f4a94ffb8 100644 --- a/toolkit/content/browser-child.js +++ b/toolkit/content/browser-child.js @@ -186,6 +186,23 @@ let SecurityUI = { } }; +let ControllerCommands = { + init: function () { + addMessageListener("ControllerCommands:Do", this); + }, + + receiveMessage: function(message) { + switch(message.name) { + case "ControllerCommands:Do": + if (docShell.isCommandEnabled(message.data)) + docShell.doCommand(message.data); + break; + } + } +} + +ControllerCommands.init() + addEventListener("DOMTitleChanged", function (aEvent) { let document = content.document; switch (aEvent.type) { diff --git a/toolkit/content/widgets/remote-browser.xml b/toolkit/content/widgets/remote-browser.xml index f2f9f0b89a50..8a52b40a250c 100644 --- a/toolkit/content/widgets/remote-browser.xml +++ b/toolkit/content/widgets/remote-browser.xml @@ -101,12 +101,18 @@ this.messageManager.addMessageListener("ImageDocumentLoaded", this); this.messageManager.loadFrameScript("chrome://global/content/browser-child.js", true); this.webProgress._init(); + + let jsm = "resource://gre/modules/RemoteController.jsm"; + let RemoteController = Components.utils.import(jsm, {}).RemoteController; + this._controller = new RemoteController(this); + this.controllers.appendController(this._controller); ]]> diff --git a/toolkit/modules/RemoteController.jsm b/toolkit/modules/RemoteController.jsm new file mode 100644 index 000000000000..aa3183456149 --- /dev/null +++ b/toolkit/modules/RemoteController.jsm @@ -0,0 +1,58 @@ +// -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +this.EXPORTED_SYMBOLS = ["RemoteController"]; + +const Ci = Components.interfaces; +const Cc = Components.classes; +const Cu = Components.utils; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +function RemoteController(browser) +{ + this._browser = browser; +} + +RemoteController.prototype = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIController]), + + isCommandEnabled: function(aCommand) { + // We can't synchronously ask content if a command is enabled, + // so we always pretend is. + // The right way forward would be to never use nsIController + // to ask if something in content is enabled. Maybe even + // by replacing the nsIController architecture by something else. + // See bug 905768. + return true; + }, + + supportsCommand: function(aCommand) { + // Optimize the lookup a bit. + if (!aCommand.startsWith("cmd_")) + return false; + + // For now only support the commands used in "browser-context.inc" + let commands = [ + "cmd_copyLink", + "cmd_copyImage", + "cmd_undo", + "cmd_cut", + "cmd_copy", + "cmd_paste", + "cmd_delete", + "cmd_selectAll", + "cmd_switchTextDirection" + ]; + + return commands.indexOf(aCommand) >= 0; + }, + + doCommand: function(aCommand) { + this._browser.messageManager.sendAsyncMessage("ControllerCommands:Do", aCommand); + }, + + onEvent: function () {} +}; diff --git a/toolkit/modules/moz.build b/toolkit/modules/moz.build index f60dd1c9ffc0..c28d4dbaa6c5 100644 --- a/toolkit/modules/moz.build +++ b/toolkit/modules/moz.build @@ -21,6 +21,7 @@ EXTRA_JS_MODULES += [ 'PrivateBrowsingUtils.jsm', 'Promise.jsm', 'PropertyListUtils.jsm', + 'RemoteController.jsm', 'RemoteSecurityUI.jsm', 'RemoteWebNavigation.jsm', 'RemoteWebProgress.jsm', diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm index 267605cbda45..81e68f1d0bd1 100644 --- a/widget/cocoa/nsNativeThemeCocoa.mm +++ b/widget/cocoa/nsNativeThemeCocoa.mm @@ -2329,7 +2329,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, BOOL isHorizontal = (aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL); BOOL isRolledOver = CheckBooleanAttr(GetParentScrollbarFrame(aFrame), nsGkAtoms::hover); - if (!isRolledOver) { + if (!nsCocoaFeatures::OnMountainLionOrLater() || !isRolledOver) { if (isHorizontal) { macRect.origin.y += 4; macRect.size.height -= 4; @@ -2375,6 +2375,20 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, if (nsLookAndFeel::UseOverlayScrollbars() && CheckBooleanAttr(GetParentScrollbarFrame(aFrame), nsGkAtoms::hover)) { BOOL isHorizontal = (aWidgetType == NS_THEME_SCROLLBAR_TRACK_HORIZONTAL); + if (!nsCocoaFeatures::OnMountainLionOrLater()) { + // On OSX 10.7, scrollbars don't grow when hovered. The adjustments + // below were obtained by trial and error. + if (isHorizontal) { + macRect.origin.y += 2.0; + } else { + if (aFrame->StyleVisibility()->mDirection != + NS_STYLE_DIRECTION_RTL) { + macRect.origin.x += 3.0; + } else { + macRect.origin.x -= 1.0; + } + } + } const BOOL isOnTopOfDarkBackground = IsDarkBackground(aFrame); CUIDraw([NSWindow coreUIRenderer], macRect, cgContext, (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys: diff --git a/xpcom/base/nsAgg.h b/xpcom/base/nsAgg.h index ca7d6f4fa087..6c5fe76859eb 100644 --- a/xpcom/base/nsAgg.h +++ b/xpcom/base/nsAgg.h @@ -92,6 +92,7 @@ public: \ return &_class::NS_CYCLE_COLLECTION_INNERNAME; \ } \ }; \ +NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class); \ static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; // Put this in your class's constructor: diff --git a/xpcom/glue/nsCycleCollectionParticipant.h b/xpcom/glue/nsCycleCollectionParticipant.h index cf418e4da195..d8a4af719622 100644 --- a/xpcom/glue/nsCycleCollectionParticipant.h +++ b/xpcom/glue/nsCycleCollectionParticipant.h @@ -232,6 +232,12 @@ public: #define NS_CYCLE_COLLECTION_UPCAST(obj, clazz) \ NS_CYCLE_COLLECTION_CLASSNAME(clazz)::Upcast(obj) +#ifdef DEBUG +#define NS_CHECK_FOR_RIGHT_PARTICIPANT(_ptr) _ptr->CheckForRightParticipant() +#else +#define NS_CHECK_FOR_RIGHT_PARTICIPANT(_ptr) +#endif + // The default implementation of this class template is empty, because it // should never be used: see the partial specializations below. template nsISupports *s = static_cast(p); MOZ_ASSERT(NS_CYCLE_COLLECTION_CLASSNAME(T)::CheckForRightISupports(s), "not the nsISupports pointer we expect"); - return NS_CYCLE_COLLECTION_CLASSNAME(T)::Downcast(s); + T *rval = NS_CYCLE_COLLECTION_CLASSNAME(T)::Downcast(s); + NS_CHECK_FOR_RIGHT_PARTICIPANT(rval); + return rval; } }; @@ -432,6 +440,21 @@ T* DowncastCCParticipant(void *p) // Helpers for implementing a concrete nsCycleCollectionParticipant /////////////////////////////////////////////////////////////////////////////// +// If a class defines a participant, then QIing an instance of that class to +// nsXPCOMCycleCollectionParticipant should produce that participant. +#ifdef DEBUG +#define NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \ + virtual void CheckForRightParticipant() \ + { \ + nsXPCOMCycleCollectionParticipant *p; \ + CallQueryInterface(this, &p); \ + MOZ_ASSERT(p == &NS_CYCLE_COLLECTION_INNERNAME, \ + #_class " should QI to its own CC participant"); \ + } +#else +#define NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) +#endif + #define NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base) \ public: \ NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb); \ @@ -483,6 +506,7 @@ class NS_CYCLE_COLLECTION_INNERCLASS \ NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \ NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class) \ }; \ +NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \ static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; \ NOT_INHERITED_CANT_OVERRIDE @@ -504,6 +528,7 @@ private: NS_IMETHOD_(bool) CanSkipThisReal(void *p); \ NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class) \ }; \ +NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \ static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; \ NOT_INHERITED_CANT_OVERRIDE @@ -518,6 +543,7 @@ class NS_CYCLE_COLLECTION_INNERCLASS NS_IMETHOD_(void) Trace(void *p, const TraceCallbacks &cb, void *closure); \ NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class) \ }; \ +NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \ static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; \ NOT_INHERITED_CANT_OVERRIDE @@ -536,6 +562,7 @@ private: NS_IMETHOD_(bool) CanSkipThisReal(void *p); \ NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class) \ }; \ +NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \ static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; \ NOT_INHERITED_CANT_OVERRIDE @@ -554,6 +581,7 @@ class NS_CYCLE_COLLECTION_INNERCLASS NS_IMETHOD_(bool) CanSkipThisReal(void *p); \ NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class) \ }; \ +NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \ static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; #define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(_class) \ @@ -581,6 +609,7 @@ public: \ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class) \ NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class) \ }; \ +NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \ static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; #define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(_class, \ @@ -592,6 +621,7 @@ public: \ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY_NO_UNLINK(_class, _base_class) \ NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class) \ }; \ +NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \ static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; #define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(_class, \ @@ -603,6 +633,7 @@ class NS_CYCLE_COLLECTION_INNERCLASS NS_IMETHOD_(void) Trace(void *p, const TraceCallbacks &cb, void *closure); \ NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class) \ }; \ +NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \ static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; // Cycle collector participant declarations.