diff --git a/CLOBBER b/CLOBBER index c9cf3ca2da40..eaa1f125c045 100644 --- a/CLOBBER +++ b/CLOBBER @@ -22,5 +22,4 @@ # changes to stick? As of bug 928195, this shouldn't be necessary! Please # don't change CLOBBER for WebIDL changes any more. -Bug 1100184 - Lots of file moves from the /netwerk flattening and zero faith -in the build system to properly handle them. +Bug 1115998 - (DOMString or sequence) needs binding flush (Bug 1103153) diff --git a/accessible/base/RelationType.h b/accessible/base/RelationType.h index b3c14e19f8c0..17b40352b1f4 100644 --- a/accessible/base/RelationType.h +++ b/accessible/base/RelationType.h @@ -12,7 +12,7 @@ namespace mozilla { namespace a11y { -MOZ_BEGIN_ENUM_CLASS(RelationType) +enum class RelationType { /** * This object is labelled by a target object. @@ -131,7 +131,7 @@ MOZ_BEGIN_ENUM_CLASS(RelationType) LAST = CONTAINING_APPLICATION -MOZ_END_ENUM_CLASS(RelationType) +}; } // namespace a11y } // namespace mozilla diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index f7d3a2c70502..825d806bb609 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 872ba95cc99d..4eefd6a91aec 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index a8944db01e5d..8c04ddede377 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 8771e12ed79b..153752ecc70d 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 872ba95cc99d..4eefd6a91aec 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 868db93faf75..dbb9fd296d67 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index ae899cd92e30..37fe74c814dd 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 338b8ad4c0d7..e42c66259b72 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "e45c5dbdcfc2d598c889dfbea72fa11157422afe", + "git_revision": "917b6c36717fddc6e71ffc1ec249633c8044c93c", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "ecc956a2747963c2db6edf513cd3a8a75ca8884a", + "revision": "3033c2214b5863d8ac50d2067b34c5cb02fb054d", "repo_path": "integration/gaia-central" } diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 35af55566cc8..b89f8433b225 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 7117e308ca6a..e1f3880f4662 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 8bd6e3bc2305..d9e82dafb972 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index d24b438df8d2..aad2ff0689dc 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/browser/base/content/test/general/browser_windowactivation.js b/browser/base/content/test/general/browser_windowactivation.js index ab686287377b..481d80818d51 100644 --- a/browser/base/content/test/general/browser_windowactivation.js +++ b/browser/base/content/test/general/browser_windowactivation.js @@ -84,6 +84,14 @@ function test() { } }); + window.messageManager.addMessageListener("Test:ActivateEvent", function(message) { + ok(message.data.ok, "Test:ActivateEvent"); + }); + + window.messageManager.addMessageListener("Test:DeactivateEvent", function(message) { + ok(message.data.ok, "Test:DeactivateEvent"); + }); + browser1.addEventListener("load", check, true); browser2.addEventListener("load", check, true); browser1.contentWindow.location = testPage; @@ -132,6 +140,25 @@ function childFunction() sendAsyncMessage("Test:FocusReceived", { }); }, false); + var windowGotActivate = false; + var windowGotDeactivate = false; + addEventListener("activate", function() { + sendAsyncMessage("Test:ActivateEvent", { ok: !windowGotActivate }); + windowGotActivate = false; + }); + + addEventListener("deactivate", function() { + sendAsyncMessage("Test:DeactivateEvent", { ok: !windowGotDeactivate }); + windowGotDeactivate = false; + }); + content.addEventListener("activate", function() { + windowGotActivate = true;; + }); + + content.addEventListener("deactivate", function() { + windowGotDeactivate = true; + }); + content.setInterval(function () { if (!expectingResponse) { return; diff --git a/browser/base/content/test/social/browser.ini b/browser/base/content/test/social/browser.ini index 34622de1cdea..fa86776729b7 100644 --- a/browser/base/content/test/social/browser.ini +++ b/browser/base/content/test/social/browser.ini @@ -31,6 +31,7 @@ skip-if = e10s # Bug 1053965 "cw.ensureSnippetsMapThen is not a function", also [browser_addons.js] [browser_blocklist.js] [browser_share.js] +skip-if = true # bug 1115131 [browser_social_activation.js] skip-if = e10s # Bug 933103 synthesizeMouseAtCenter not e10s friendly [browser_social_chatwindow.js] diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index dde489d71b0b..fc02c48a29f2 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -3620,7 +3620,8 @@ nsresult nsContentUtils::DispatchEvent(nsIDocument* aDoc, nsISupports* aTarget, const nsAString& aEventName, bool aCanBubble, bool aCancelable, - bool aTrusted, bool *aDefaultAction) + bool aTrusted, bool *aDefaultAction, + bool aOnlyChromeDispatch) { nsCOMPtr event; nsCOMPtr target; @@ -3628,6 +3629,7 @@ nsContentUtils::DispatchEvent(nsIDocument* aDoc, nsISupports* aTarget, aCancelable, aTrusted, getter_AddRefs(event), getter_AddRefs(target)); NS_ENSURE_SUCCESS(rv, rv); + event->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = aOnlyChromeDispatch; bool dummy; return target->DispatchEvent(event, aDefaultAction ? aDefaultAction : &dummy); @@ -3664,6 +3666,17 @@ nsContentUtils::DispatchChromeEvent(nsIDocument *aDoc, return rv; } +nsresult +nsContentUtils::DispatchEventOnlyToChrome(nsIDocument* aDoc, + nsISupports* aTarget, + const nsAString& aEventName, + bool aCanBubble, bool aCancelable, + bool* aDefaultAction) +{ + return DispatchEvent(aDoc, aTarget, aEventName, aCanBubble, aCancelable, + true, aDefaultAction, true); +} + /* static */ Element* nsContentUtils::MatchElementId(nsIContent *aContent, const nsIAtom* aId) diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 34a95c6519f7..4cbff1d26506 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -987,7 +987,10 @@ public: /** * This method creates and dispatches a trusted event to the chrome - * event handler. + * event handler (the parent object of the DOM Window in the event target + * chain). Note, chrome event handler is used even if aTarget is a chrome + * object. Use DispatchEventOnlyToChrome if the normal event dispatching is + * wanted in case aTarget is a chrome object. * Works only with events which can be created by calling * nsIDOMDocument::CreateEvent() with parameter "Events". * @param aDocument The document which will be used to create the event, @@ -1007,6 +1010,32 @@ public: bool aCancelable, bool *aDefaultAction = nullptr); + + /** + * This method creates and dispatches a trusted event. + * If aTarget is not a chrome object, the nearest chrome object in the + * propagation path will be used as the start of the event target chain. + * This method is different than DispatchChromeEvent, which always dispatches + * events to chrome event handler. DispatchEventOnlyToChrome works like + * DispatchTrustedEvent in the case aTarget is a chrome object. + * Works only with events which can be created by calling + * nsIDOMDocument::CreateEvent() with parameter "Events". + * @param aDoc The document which will be used to create the event. + * @param aTarget The target of the event, should be QIable to + * nsIDOMEventTarget. + * @param aEventName The name of the event. + * @param aCanBubble Whether the event can bubble. + * @param aCancelable Is the event cancelable. + * @param aDefaultAction Set to true if default action should be taken, + * see nsIDOMEventTarget::DispatchEvent. + */ + static nsresult DispatchEventOnlyToChrome(nsIDocument* aDoc, + nsISupports* aTarget, + const nsAString& aEventName, + bool aCanBubble, + bool aCancelable, + bool *aDefaultAction = nullptr); + /** * Determines if an event attribute name (such as onclick) is valid for * a given element type. Types are from the EventNameType enumeration @@ -1252,7 +1281,7 @@ public: * @param aDiscoverMode Set to eRecurseIntoChildren to descend recursively * into children. */ - enum TextContentDiscoverMode MOZ_ENUM_TYPE(uint8_t) { + enum TextContentDiscoverMode : uint8_t { eRecurseIntoChildren, eDontRecurseIntoChildren }; @@ -2046,7 +2075,7 @@ public: */ static bool IsAutocompleteEnabled(nsIDOMHTMLInputElement* aInput); - enum AutocompleteAttrState MOZ_ENUM_TYPE(uint8_t) + enum AutocompleteAttrState : uint8_t { eAutocompleteAttrState_Unknown = 1, eAutocompleteAttrState_Invalid, @@ -2253,7 +2282,8 @@ private: bool aCanBubble, bool aCancelable, bool aTrusted, - bool *aDefaultAction = nullptr); + bool *aDefaultAction = nullptr, + bool aOnlyChromeDispatch = false); static void InitializeModifierStrings(); diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp index 5e001d9f73cc..3e028ae197c1 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -1145,11 +1145,12 @@ nsFocusManager::ActivateOrDeactivate(nsPIDOMWindow* aWindow, bool aActive) aWindow->ActivateOrDeactivate(aActive); // Send the activate event. - nsContentUtils::DispatchTrustedEvent(aWindow->GetExtantDoc(), - aWindow, - aActive ? NS_LITERAL_STRING("activate") : - NS_LITERAL_STRING("deactivate"), - true, true, nullptr); + nsContentUtils::DispatchEventOnlyToChrome(aWindow->GetExtantDoc(), + aWindow, + aActive ? + NS_LITERAL_STRING("activate") : + NS_LITERAL_STRING("deactivate"), + true, true, nullptr); // Look for any remote child frames, iterate over them and send the activation notification. nsContentUtils::CallOnAllRemoteChildren(aWindow, ActivateOrDeactivateChild, diff --git a/dom/bindings/BindingDeclarations.h b/dom/bindings/BindingDeclarations.h index 38ef6ce3ffc6..5b84610e9a15 100644 --- a/dom/bindings/BindingDeclarations.h +++ b/dom/bindings/BindingDeclarations.h @@ -461,7 +461,7 @@ GetWrapperCache(const SmartPtr& aObject) return GetWrapperCache(aObject.get()); } -struct ParentObject { +struct MOZ_STACK_CLASS ParentObject { template ParentObject(T* aObject) : mObject(aObject), @@ -482,7 +482,9 @@ struct ParentObject { mUseXBLScope(false) {} - nsISupports* const mObject; + // We don't want to make this an nsCOMPtr because of performance reasons, but + // it's safe because ParentObject is a stack class. + nsISupports* const MOZ_NON_OWNING_REF mObject; nsWrapperCache* const mWrapperCache; bool mUseXBLScope; }; diff --git a/dom/broadcastchannel/BroadcastChannel.cpp b/dom/broadcastchannel/BroadcastChannel.cpp index c3f4101cbbfa..1a526b5921e9 100644 --- a/dom/broadcastchannel/BroadcastChannel.cpp +++ b/dom/broadcastchannel/BroadcastChannel.cpp @@ -187,7 +187,7 @@ public: MOZ_ASSERT(mActor); } - NS_IMETHODIMP Run() + NS_IMETHODIMP Run() MOZ_OVERRIDE { MOZ_ASSERT(mActor); if (mActor->IsActorDestroyed()) { @@ -221,7 +221,7 @@ public: return NS_OK; } - NS_IMETHODIMP Cancel() + NS_IMETHODIMP Cancel() MOZ_OVERRIDE { mActor = nullptr; return NS_OK; @@ -247,13 +247,13 @@ public: MOZ_ASSERT(mBC); } - NS_IMETHODIMP Run() + NS_IMETHODIMP Run() MOZ_OVERRIDE { mBC->Shutdown(); return NS_OK; } - NS_IMETHODIMP Cancel() + NS_IMETHODIMP Cancel() MOZ_OVERRIDE { mBC = nullptr; return NS_OK; @@ -278,7 +278,7 @@ public: MOZ_ASSERT(mActor); } - NS_IMETHODIMP Run() + NS_IMETHODIMP Run() MOZ_OVERRIDE { MOZ_ASSERT(mActor); if (!mActor->IsActorDestroyed()) { @@ -287,7 +287,7 @@ public: return NS_OK; } - NS_IMETHODIMP Cancel() + NS_IMETHODIMP Cancel() MOZ_OVERRIDE { mActor = nullptr; return NS_OK; diff --git a/dom/broadcastchannel/BroadcastChannelChild.h b/dom/broadcastchannel/BroadcastChannelChild.h index 8f7a22092625..011d2c5a110d 100644 --- a/dom/broadcastchannel/BroadcastChannelChild.h +++ b/dom/broadcastchannel/BroadcastChannelChild.h @@ -42,7 +42,7 @@ private: ~BroadcastChannelChild(); - void ActorDestroy(ActorDestroyReason aWhy); + virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; // This raw pointer is actually the parent object. // It's set to null when the parent object is deleted. diff --git a/dom/camera/CameraPreferences.cpp b/dom/camera/CameraPreferences.cpp index afe78342b650..0c8d4fc2fa13 100644 --- a/dom/camera/CameraPreferences.cpp +++ b/dom/camera/CameraPreferences.cpp @@ -37,7 +37,6 @@ StaticRefPtr CameraPreferences::sObserver; NS_IMPL_ISUPPORTS(CameraPreferences, nsIObserver); #endif -#ifdef CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT /* static */ nsresult CameraPreferences::UpdatePref(const char* aPref, nsresult& aVal) @@ -49,7 +48,6 @@ CameraPreferences::UpdatePref(const char* aPref, nsresult& aVal) } return rv; } -#endif /* static */ nsresult @@ -156,7 +154,6 @@ CameraPreferences::PreferenceChanged(const char* aPref, void* aClosure) nsresult rv; switch (p.mValueType) { case kPrefValueIsNsResult: - #ifdef CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT { nsresult& v = *p.mValue.mAsNsResult; rv = UpdatePref(aPref, v); @@ -165,7 +162,6 @@ CameraPreferences::PreferenceChanged(const char* aPref, void* aClosure) } } break; - #endif case kPrefValueIsUint32: { @@ -331,7 +327,6 @@ CameraPreferences::GetPref(const char* aPref, nsACString& aVal) return true; } -#ifdef CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT /* static */ bool CameraPreferences::GetPref(const char* aPref, nsresult& aVal) @@ -359,7 +354,6 @@ CameraPreferences::GetPref(const char* aPref, nsresult& aVal) aVal = v; return true; } -#endif /* static */ bool diff --git a/dom/camera/CameraPreferences.h b/dom/camera/CameraPreferences.h index 3d260a3f31af..7fd09aeb40a5 100644 --- a/dom/camera/CameraPreferences.h +++ b/dom/camera/CameraPreferences.h @@ -12,13 +12,6 @@ #include "mozilla/StaticPtr.h" #endif -#if defined(MOZ_HAVE_CXX11_STRONG_ENUMS) || defined(MOZ_HAVE_CXX11_ENUM_TYPE) -// Older compilers that don't support strongly-typed enums -// just typedef uint32_t to nsresult, which results in conflicting -// overloaded members in CameraPreferences. -#define CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT -#endif - namespace mozilla { template class StaticAutoPtr; @@ -38,9 +31,7 @@ public: static void Shutdown(); static bool GetPref(const char* aPref, nsACString& aVal); -#ifdef CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT static bool GetPref(const char* aPref, nsresult& aVal); -#endif static bool GetPref(const char* aPref, uint32_t& aVal); static bool GetPref(const char* aPref, bool& aVal); @@ -49,9 +40,7 @@ protected: static uint32_t PrefToIndex(const char* aPref); static void PreferenceChanged(const char* aPref, void* aClosure); -#ifdef CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT static nsresult UpdatePref(const char* aPref, nsresult& aVar); -#endif static nsresult UpdatePref(const char* aPref, uint32_t& aVar); static nsresult UpdatePref(const char* aPref, nsACString& aVar); static nsresult UpdatePref(const char* aPref, bool& aVar); diff --git a/dom/events/EventListenerManager.h b/dom/events/EventListenerManager.h index a71b861486c3..bcd1f034bb11 100644 --- a/dom/events/EventListenerManager.h +++ b/dom/events/EventListenerManager.h @@ -162,7 +162,7 @@ public: nsString mTypeString; // for non-main-threads uint16_t mEventType; - enum ListenerType MOZ_ENUM_TYPE(uint8_t) + enum ListenerType : uint8_t { eNativeListener = 0, eJSEventListener, diff --git a/dom/events/EventStateManager.h b/dom/events/EventStateManager.h index 3b509f0a8a5a..73de63a3eaac 100644 --- a/dom/events/EventStateManager.h +++ b/dom/events/EventStateManager.h @@ -429,7 +429,7 @@ protected: /** * Computes the default action for the aEvent with the prefs. */ - enum Action MOZ_ENUM_TYPE(uint8_t) + enum Action : uint8_t { ACTION_NONE = 0, ACTION_SCROLL, diff --git a/dom/media/PeerConnection.js b/dom/media/PeerConnection.js index f388d52973ab..6350afd58a66 100644 --- a/dom/media/PeerConnection.js +++ b/dom/media/PeerConnection.js @@ -323,13 +323,24 @@ RTCPeerConnection.prototype = { init: function(win) { this._win = win; }, __init: function(rtcConfig) { + this._winID = this._win.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID; + if (!rtcConfig.iceServers || !Services.prefs.getBoolPref("media.peerconnection.use_document_iceservers")) { rtcConfig.iceServers = JSON.parse(Services.prefs.getCharPref("media.peerconnection.default_iceservers")); } - this._winID = this._win.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID; + // Normalize iceServers input + rtcConfig.iceServers.forEach(server => { + if (typeof server.urls === "string") { + server.urls = [server.urls]; + } else if (!server.urls && server.url) { + // TODO: Remove support for legacy iceServer.url eventually (Bug 1116766) + server.urls = [server.url]; + this.logWarning("RTCIceServer.url is deprecated! Use urls instead.", null, 0); + } + }); this._mustValidateRTCConfiguration(rtcConfig, "RTCPeerConnection constructor passed invalid RTCConfiguration"); if (_globalPCList._networkdown || !this._win.navigator.onLine) { @@ -432,10 +443,11 @@ RTCPeerConnection.prototype = { }, /** - * An RTCConfiguration looks like this: + * An RTCConfiguration may look like this: * - * { "iceServers": [ { url:"stun:stun.example.org" }, - * { url:"turn:turn.example.org", + * { "iceServers": [ { urls: "stun:stun.example.org", }, + * { url: "stun:stun.example.org", }, // deprecated version + * { urls: ["turn:turn1.x.org", "turn:turn2.x.org"], * username:"jib", credential:"mypass"} ] } * * WebIDL normalizes structure for us, so we test well-formed stun/turn urls, @@ -456,27 +468,29 @@ RTCPeerConnection.prototype = { }; rtcConfig.iceServers.forEach(server => { - if (!server.url) { - throw new this._win.DOMException(msg + " - missing url", "InvalidAccessError"); + if (!server.urls) { + throw new this._win.DOMException(msg + " - missing urls", "InvalidAccessError"); } - let url = nicerNewURI(server.url); - if (url.scheme in { turn:1, turns:1 }) { - if (!server.username) { - throw new this._win.DOMException(msg + " - missing username: " + server.url, - "InvalidAccessError"); + server.urls.forEach(urlStr => { + let url = nicerNewURI(urlStr); + if (url.scheme in { turn:1, turns:1 }) { + if (!server.username) { + throw new this._win.DOMException(msg + " - missing username: " + urlStr, + "InvalidAccessError"); + } + if (!server.credential) { + throw new this._win.DOMException(msg + " - missing credential: " + urlStr, + "InvalidAccessError"); + } } - if (!server.credential) { - throw new this._win.DOMException(msg + " - missing credential: " + server.url, - "InvalidAccessError"); + else if (!(url.scheme in { stun:1, stuns:1 })) { + throw new this._win.DOMException(msg + " - improper scheme: " + url.scheme, + "SyntaxError"); } - } - else if (!(url.scheme in { stun:1, stuns:1 })) { - throw new this._win.DOMException(msg + " - improper scheme: " + url.scheme, - "SyntaxError"); - } - if (url.scheme in { stuns:1, turns:1 }) { - this.logWarning(url.scheme.toUpperCase() + " is not yet supported.", null, 0); - } + if (url.scheme in { stuns:1, turns:1 }) { + this.logWarning(url.scheme.toUpperCase() + " is not yet supported.", null, 0); + } + }); }); }, diff --git a/dom/media/tests/mochitest/test_peerConnection_bug825703.html b/dom/media/tests/mochitest/test_peerConnection_bug825703.html index 84d43efbf2e2..9b5e729a9a85 100644 --- a/dom/media/tests/mochitest/test_peerConnection_bug825703.html +++ b/dom/media/tests/mochitest/test_peerConnection_bug825703.html @@ -14,78 +14,66 @@ title: "RTCConfiguration valid/invalid permutations" }); - makePC = function (config, expect_success) { - var exception = null; - var pc = null; - - try { - pc = new mozRTCPeerConnection(config); - } catch (e) { - exception = e; - } - if (pc !== null) { - pc.close(); - } - pc = null - - if (expect_success) { - ok(!exception, "mozRTCPeerConnection(" + - JSON.stringify(config) + ") succeeds"); - } else { - ok(exception, "mozRTCPeerConnection(" + - JSON.stringify(config) + ") throws"); - } + makePC = (config, expected_error) => { + var exception; + try { + new mozRTCPeerConnection(config).close(); + } catch (e) { + exception = e; + } + is((exception? exception.name : "success"), expected_error || "success", + "mozRTCPeerConnection(" + JSON.stringify(config) + ")"); } // This is a test of the iceServers parsing code + readable errors runNetworkTest(function () { - var pcs = null; var exception = null; - var config; try { - pcs = new mozRTCPeerConnection(); + new mozRTCPeerConnection().close(); } catch (e) { exception = e; } ok(!exception, "mozRTCPeerConnection() succeeds"); - if (pcs !== null) { - pcs.close(); - } - pcs = null; exception = null; - makePC(1, false); + makePC(); - makePC({}, true); + makePC(1, "TypeError"); - makePC({ iceServers: [] }, true); + makePC({}); - makePC({ iceServers: [{ url:"" }] }, false); + makePC({ iceServers: [] }); + + makePC({ iceServers: [{ urls:"" }] }, "SyntaxError"); makePC({ iceServers: [ - { url:"stun:127.0.0.1" }, - { url:"stuns:localhost", foo:"" }, - { url:"turn:[::1]:3478", username:"p", credential:"p" }, - { url:"turns:localhost:3478?transport=udp", username:"p", credential:"p" } - ]}, true); + { urls:"stun:127.0.0.1" }, + { urls:"stun:localhost", foo:"" }, + { urls: ["stun:127.0.0.1", "stun:localhost"] }, + { urls:"stuns:localhost", foo:"" }, + { urls:"turn:[::1]:3478", username:"p", credential:"p" }, + { urls:"turn:localhost:3478?transport=udp", username:"p", credential:"p" }, + { urls: ["turn:[::1]:3478", "turn:localhost"], username:"p", credential:"p" }, + { urls:"turns:localhost:3478?transport=udp", username:"p", credential:"p" }, + { url:"stun:localhost", foo:"" }, + { url:"turn:localhost", username:"p", credential:"p" } + ]}); - makePC({ iceServers: [{ url:"turns:localhost:3478", username:"p" }] }, false); + makePC({ iceServers: [{ urls: ["stun:127.0.0.1", ""] }] }, "SyntaxError"); - makePC({ iceServers: [{ url:"turns:localhost:3478", credential:"p" }] }, false); + makePC({ iceServers: [{ urls:"turns:localhost:3478", username:"p" }] }, "InvalidAccessError"); - makePC({ iceServers: [{ url:"http:0.0.0.0" }] }, false); + makePC({ iceServers: [{ url:"turns:localhost:3478", credential:"p" }] }, "InvalidAccessError"); + + makePC({ iceServers: [{ urls:"http:0.0.0.0" }] }, "SyntaxError"); try { - pcs = new mozRTCPeerConnection({ iceServers: [{ url:"http:0.0.0.0" }] }); + new mozRTCPeerConnection({ iceServers: [{ url:"http:0.0.0.0" }] }).close(); } catch (e) { - ok(e.message.indexOf("http") > 0, - "mozRTCPeerConnection() constructor has readable exceptions"); + ok(e.message.indexOf("http") > 0, + "mozRTCPeerConnection() constructor has readable exceptions"); } - if (pcs !== null) { - pcs.close(); - } - pcs = null; networkTestFinished(); }); diff --git a/dom/media/webaudio/AudioEventTimeline.h b/dom/media/webaudio/AudioEventTimeline.h index bd9a385d2407..f97c20d55a57 100644 --- a/dom/media/webaudio/AudioEventTimeline.h +++ b/dom/media/webaudio/AudioEventTimeline.h @@ -23,7 +23,7 @@ namespace dom { // This is an internal helper class and should not be used outside of this header. struct AudioTimelineEvent { - enum Type MOZ_ENUM_TYPE(uint32_t) { + enum Type : uint32_t { SetValue, LinearRamp, ExponentialRamp, diff --git a/dom/network/NetworkStatsDB.jsm b/dom/network/NetworkStatsDB.jsm index dbc5f3c9e591..103588c9ee55 100644 --- a/dom/network/NetworkStatsDB.jsm +++ b/dom/network/NetworkStatsDB.jsm @@ -48,18 +48,33 @@ NetworkStatsDB.prototype = { return this.newTxn(txn_type, store_name, callback, successCb, errorCb); }, + /** + * The onupgradeneeded handler of the IDBOpenDBRequest. + * This function is called in IndexedDBHelper open() method. + * + * @param {IDBTransaction} aTransaction + * {IDBDatabase} aDb + * {64-bit integer} aOldVersion The version number on local storage. + * {64-bit integer} aNewVersion The version number to be upgraded to. + * + * @note Be careful with the database upgrade pattern. + * Because IndexedDB operations are performed asynchronously, we must + * apply a recursive approach instead of an iterative approach while + * upgrading versions. + */ upgradeSchema: function upgradeSchema(aTransaction, aDb, aOldVersion, aNewVersion) { if (DEBUG) { debug("upgrade schema from: " + aOldVersion + " to " + aNewVersion + " called!"); } let db = aDb; let objectStore; - for (let currVersion = aOldVersion; currVersion < aNewVersion; currVersion++) { - if (currVersion == 0) { - /** - * Create the initial database schema. - */ + // An array of upgrade functions for each version. + let upgradeSteps = [ + function upgrade0to1() { + if (DEBUG) debug("Upgrade 0 to 1: Create object stores and indexes."); + + // Create the initial database schema. objectStore = db.createObjectStore(DEPRECATED_STORE_NAME, { keyPath: ["connectionType", "timestamp"] }); objectStore.createIndex("connectionType", "connectionType", { unique: false }); objectStore.createIndex("timestamp", "timestamp", { unique: false }); @@ -67,10 +82,18 @@ NetworkStatsDB.prototype = { objectStore.createIndex("txBytes", "txBytes", { unique: false }); objectStore.createIndex("rxTotalBytes", "rxTotalBytes", { unique: false }); objectStore.createIndex("txTotalBytes", "txTotalBytes", { unique: false }); - if (DEBUG) { - debug("Created object stores and indexes"); - } - } else if (currVersion == 2) { + + upgradeNextVersion(); + }, + + function upgrade1to2() { + if (DEBUG) debug("Upgrade 1 to 2: Do nothing."); + upgradeNextVersion(); + }, + + function upgrade2to3() { + if (DEBUG) debug("Upgrade 2 to 3: Add keyPath appId to object store."); + // In order to support per-app traffic data storage, the original // objectStore needs to be replaced by a new objectStore with new // key path ("appId") and new index ("appId"). @@ -99,11 +122,13 @@ NetworkStatsDB.prototype = { objectStore.createIndex("rxTotalBytes", "rxTotalBytes", { unique: false }); objectStore.createIndex("txTotalBytes", "txTotalBytes", { unique: false }); - if (DEBUG) { - debug("Created object stores and indexes for version 3"); - } - } else if (currVersion == 3) { - // Delete redundent indexes (leave "network" only). + upgradeNextVersion(); + }, + + function upgrade3to4() { + if (DEBUG) debug("Upgrade 3 to 4: Delete redundant indexes."); + + // Delete redundant indexes (leave "network" only). objectStore = aTransaction.objectStore(DEPRECATED_STORE_NAME); if (objectStore.indexNames.contains("appId")) { objectStore.deleteIndex("appId"); @@ -127,10 +152,12 @@ NetworkStatsDB.prototype = { objectStore.deleteIndex("txTotalBytes"); } - if (DEBUG) { - debug("Deleted redundent indexes for version 4"); - } - } else if (currVersion == 4) { + upgradeNextVersion(); + }, + + function upgrade4to5() { + if (DEBUG) debug("Upgrade 4 to 5: Create object store for alarms."); + // In order to manage alarms, it is necessary to use a global counter // (totalBytes) that will increase regardless of the system reboot. objectStore = aTransaction.objectStore(DEPRECATED_STORE_NAME); @@ -143,6 +170,8 @@ NetworkStatsDB.prototype = { objectStore.openCursor().onsuccess = function(event) { let cursor = event.target.result; if (!cursor){ + // upgrade4to5 completed now. + upgradeNextVersion(); return; } @@ -188,11 +217,11 @@ NetworkStatsDB.prototype = { objectStore = db.createObjectStore(ALARMS_STORE_NAME, { keyPath: "id", autoIncrement: true }); objectStore.createIndex("alarm", ['networkId','threshold'], { unique: false }); objectStore.createIndex("manifestURL", "manifestURL", { unique: false }); + }, + + function upgrade5to6() { + if (DEBUG) debug("Upgrade 5 to 6: Add keyPath serviceType to object store."); - if (DEBUG) { - debug("Created alarms store for version 5"); - } - } else if (currVersion == 5) { // In contrast to "per-app" traffic data, "system-only" traffic data // refers to data which can not be identified by any applications. // To further support "system-only" data storage, the data can be @@ -209,6 +238,8 @@ NetworkStatsDB.prototype = { let cursor = event.target.result; if (!cursor) { db.deleteObjectStore(DEPRECATED_STORE_NAME); + // upgrade5to6 completed now. + upgradeNextVersion(); return; } @@ -217,11 +248,11 @@ NetworkStatsDB.prototype = { newObjectStore.put(newStats); cursor.continue(); }; + }, + + function upgrade6to7() { + if (DEBUG) debug("Upgrade 6 to 7: Replace alarm threshold by relativeThreshold."); - if (DEBUG) { - debug("Added new key 'serviceType' for version 6"); - } - } else if (currVersion == 6) { // Replace threshold attribute of alarm index by relativeThreshold in alarms DB. // Now alarms are indexed by relativeThreshold, which is the threshold relative // to current system stats. @@ -239,6 +270,7 @@ NetworkStatsDB.prototype = { alarmsStore.openCursor().onsuccess = function(event) { let cursor = event.target.result; if (!cursor) { + upgrade6to7_updateTotalBytes(); return; } @@ -250,75 +282,132 @@ NetworkStatsDB.prototype = { cursor.continue(); } - // Previous versions save accumulative totalBytes, increasing althought the system - // reboots or resets stats. But is necessary to reset the total counters when reset - // through 'clearInterfaceStats'. - let statsStore = aTransaction.objectStore(STATS_STORE_NAME); - let networks = []; - // Find networks stored in the database. - statsStore.index("network").openKeyCursor(null, "nextunique").onsuccess = function(event) { - let cursor = event.target.result; - if (cursor) { - networks.push(cursor.key); - cursor.continue(); - return; - } + function upgrade6to7_updateTotalBytes() { + if (DEBUG) debug("Upgrade 6 to 7: Update TotalBytes."); + // Previous versions save accumulative totalBytes, increasing although the system + // reboots or resets stats. But is necessary to reset the total counters when reset + // through 'clearInterfaceStats'. + let statsStore = aTransaction.objectStore(STATS_STORE_NAME); + let networks = []; - networks.forEach(function(network) { - let lowerFilter = [0, "", network, 0]; - let upperFilter = [0, "", network, ""]; - let range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false); + // Find networks stored in the database. + statsStore.index("network").openKeyCursor(null, "nextunique").onsuccess = function(event) { + let cursor = event.target.result; - // Find number of samples for a given network. - statsStore.count(range).onsuccess = function(event) { - // If there are more samples than the max allowed, there is no way to know - // when does reset take place. - if (event.target.result >= VALUES_MAX_LENGTH) { - return; - } + // Store each network into an array. + if (cursor) { + networks.push(cursor.key); + cursor.continue(); + return; + } - let last = null; - // Reset detected if the first sample totalCounters are different than bytes - // counters. If so, the total counters should be recalculated. - statsStore.openCursor(range).onsuccess = function(event) { - let cursor = event.target.result; - if (!cursor) { + // Start to deal with each network. + let pending = networks.length; + + if (pending === 0) { + // Found no records of network. upgrade6to7 completed now. + upgradeNextVersion(); + return; + } + + networks.forEach(function(network) { + let lowerFilter = [0, "", network, 0]; + let upperFilter = [0, "", network, ""]; + let range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false); + + // Find number of samples for a given network. + statsStore.count(range).onsuccess = function(event) { + let recordCount = event.target.result; + + // If there are more samples than the max allowed, there is no way to know + // when does reset take place. + if (recordCount === 0 || recordCount >= VALUES_MAX_LENGTH) { + pending--; + if (pending === 0) { + upgradeNextVersion(); + } return; } - if (!last) { - if (cursor.value.rxTotalBytes == cursor.value.rxBytes && - cursor.value.txTotalBytes == cursor.value.txBytes) { + + let last = null; + // Reset detected if the first sample totalCounters are different than bytes + // counters. If so, the total counters should be recalculated. + statsStore.openCursor(range).onsuccess = function(event) { + let cursor = event.target.result; + if (!cursor) { + pending--; + if (pending === 0) { + upgradeNextVersion(); + } + return; + } + if (!last) { + if (cursor.value.rxTotalBytes == cursor.value.rxBytes && + cursor.value.txTotalBytes == cursor.value.txBytes) { + pending--; + if (pending === 0) { + upgradeNextVersion(); + } + return; + } + + cursor.value.rxTotalBytes = cursor.value.rxBytes; + cursor.value.txTotalBytes = cursor.value.txBytes; + cursor.update(cursor.value); + last = cursor.value; + cursor.continue(); return; } - cursor.value.rxTotalBytes = cursor.value.rxBytes; - cursor.value.txTotalBytes = cursor.value.txBytes; + // Recalculate the total counter for last / current sample + cursor.value.rxTotalBytes = last.rxTotalBytes + cursor.value.rxBytes; + cursor.value.txTotalBytes = last.txTotalBytes + cursor.value.txBytes; cursor.update(cursor.value); last = cursor.value; cursor.continue(); - return; } - - // Recalculate the total counter for last / current sample - cursor.value.rxTotalBytes = last.rxTotalBytes + cursor.value.rxBytes; - cursor.value.txTotalBytes = last.txTotalBytes + cursor.value.txBytes; - cursor.update(cursor.value); - last = cursor.value; - cursor.continue(); } - } - }, this); - }; - } else if (currVersion == 7) { + }, this); // end of networks.forEach() + }; // end of statsStore.index("network").openKeyCursor().onsuccess callback + } // end of function upgrade6to7_updateTotalBytes + }, + + function upgrade7to8() { + if (DEBUG) debug("Upgrade 7 to 8: Create index serviceType."); + // Create index for 'ServiceType' in order to make it retrievable. let statsStore = aTransaction.objectStore(STATS_STORE_NAME); statsStore.createIndex("serviceType", "serviceType", { unique: false }); + }, + ]; - if (DEBUG) { - debug("Create index of 'serviceType' for version 8"); - } + let index = aOldVersion; + let outer = this; + + function upgradeNextVersion() { + if (index == aNewVersion) { + debug("Upgrade finished."); + return; + } + + try { + var i = index++; + if (DEBUG) debug("Upgrade step: " + i + "\n"); + upgradeSteps[i].call(outer); + } catch (ex) { + dump("Caught exception " + ex); + throw ex; + return; } } + + if (aNewVersion > upgradeSteps.length) { + debug("No migration steps for the new version!"); + aTransaction.abort(); + return; + } + + upgradeNextVersion(); }, importData: function importData(aStats) { diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index 0fd634003cb0..3720cc8e7cc4 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -1557,6 +1557,10 @@ nsPluginHost::ClearSiteData(nsIPluginTag* plugin, const nsACString& domain, nsPluginTag* tag = static_cast(plugin); + if (!tag->IsEnabled()) { + return NS_ERROR_NOT_AVAILABLE; + } + // We only ensure support for clearing Flash site data for now. // We will also attempt to clear data for any plugin that happens // to be loaded already. diff --git a/dom/svg/SVGCircleElement.cpp b/dom/svg/SVGCircleElement.cpp index 9bc447dfdd1d..deac6112db1c 100644 --- a/dom/svg/SVGCircleElement.cpp +++ b/dom/svg/SVGCircleElement.cpp @@ -90,8 +90,7 @@ SVGCircleElement::GetGeometryBounds(Rect* aBounds, Float aStrokeWidth, if (r <= 0.f) { // Rendering of the element is disabled - aBounds->MoveTo(x, y); - aBounds->SetEmpty(); + *aBounds = Rect(aTransform * Point(x, y), Size()); return true; } diff --git a/dom/svg/SVGEllipseElement.cpp b/dom/svg/SVGEllipseElement.cpp index 47dc8eb3f91d..a0ae35bb6111 100644 --- a/dom/svg/SVGEllipseElement.cpp +++ b/dom/svg/SVGEllipseElement.cpp @@ -101,8 +101,7 @@ SVGEllipseElement::GetGeometryBounds(Rect* aBounds, Float aStrokeWidth, if (rx <= 0.f || ry <= 0.f) { // Rendering of the element is disabled - aBounds->MoveTo(x, y); - aBounds->SetEmpty(); + *aBounds = Rect(aTransform * Point(x, y), Size()); return true; } diff --git a/dom/svg/SVGImageElement.cpp b/dom/svg/SVGImageElement.cpp index 863e96f234fd..31cde149d927 100644 --- a/dom/svg/SVGImageElement.cpp +++ b/dom/svg/SVGImageElement.cpp @@ -226,6 +226,23 @@ SVGImageElement::IsAttributeMapped(const nsIAtom* name) const /* For the purposes of the update/invalidation logic pretend to be a rectangle. */ +bool +SVGImageElement::GetGeometryBounds(Rect* aBounds, Float aStrokeWidth, + const Matrix& aTransform) +{ + Rect rect; + GetAnimatedLengthValues(&rect.x, &rect.y, &rect.width, + &rect.height, nullptr); + + if (rect.IsEmpty()) { + // Rendering of the element disabled + rect.SetEmpty(); // Make sure width/height are zero and not negative + } + + *aBounds = aTransform.TransformBounds(rect); + return true; +} + TemporaryRef SVGImageElement::BuildPath(PathBuilder* aBuilder) { diff --git a/dom/svg/SVGImageElement.h b/dom/svg/SVGImageElement.h index 0494df94a8c7..c083c28d260f 100644 --- a/dom/svg/SVGImageElement.h +++ b/dom/svg/SVGImageElement.h @@ -53,6 +53,8 @@ public: NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const MOZ_OVERRIDE; // nsSVGPathGeometryElement methods: + virtual bool GetGeometryBounds(Rect* aBounds, Float aStrokeWidth, + const Matrix& aTransform) MOZ_OVERRIDE; virtual TemporaryRef BuildPath(PathBuilder* aBuilder) MOZ_OVERRIDE; // nsSVGSVGElement methods: diff --git a/dom/svg/SVGPreserveAspectRatio.h b/dom/svg/SVGPreserveAspectRatio.h index e1e6a5cbb3eb..43ce2426d63f 100644 --- a/dom/svg/SVGPreserveAspectRatio.h +++ b/dom/svg/SVGPreserveAspectRatio.h @@ -17,7 +17,7 @@ namespace mozilla { // Alignment Types -enum SVGAlign MOZ_ENUM_TYPE(uint8_t) { +enum SVGAlign : uint8_t { SVG_PRESERVEASPECTRATIO_UNKNOWN = 0, SVG_PRESERVEASPECTRATIO_NONE = 1, SVG_PRESERVEASPECTRATIO_XMINYMIN = 2, @@ -37,7 +37,7 @@ const uint16_t SVG_ALIGN_MIN_VALID = SVG_PRESERVEASPECTRATIO_NONE; const uint16_t SVG_ALIGN_MAX_VALID = SVG_PRESERVEASPECTRATIO_XMAXYMAX; // Meet-or-slice Types -enum SVGMeetOrSlice MOZ_ENUM_TYPE(uint8_t) { +enum SVGMeetOrSlice : uint8_t { SVG_MEETORSLICE_UNKNOWN = 0, SVG_MEETORSLICE_MEET = 1, SVG_MEETORSLICE_SLICE = 2 diff --git a/dom/svg/SVGRectElement.cpp b/dom/svg/SVGRectElement.cpp index 5b00e54b3117..8bd69f458e3e 100644 --- a/dom/svg/SVGRectElement.cpp +++ b/dom/svg/SVGRectElement.cpp @@ -122,7 +122,8 @@ SVGRectElement::GetGeometryBounds(Rect* aBounds, Float aStrokeWidth, if (rect.IsEmpty()) { // Rendering of the element disabled rect.SetEmpty(); // Make sure width/height are zero and not negative - *aBounds = rect; // We still want the x/y position from 'rect' + // We still want the x/y position from 'rect' + *aBounds = aTransform.TransformBounds(rect); return true; } diff --git a/dom/svg/SVGSVGElement.cpp b/dom/svg/SVGSVGElement.cpp index 61b09878f5ce..ef61c8582641 100644 --- a/dom/svg/SVGSVGElement.cpp +++ b/dom/svg/SVGSVGElement.cpp @@ -1247,5 +1247,33 @@ SVGSVGElement::ClearTransformProperty() return UnsetProperty(nsGkAtoms::transform); } +int32_t +SVGSVGElement::GetIntrinsicWidth() +{ + if (mLengthAttributes[ATTR_WIDTH].IsPercentage()) { + return -1; + } + // Passing |this| as a SVGSVGElement* invokes the variant of GetAnimValue + // that uses the passed argument as the context, but that's fine since we + // know the length isn't a percentage so the context won't be used (and we + // need to pass the element to be able to resolve em/ex units). + float width = mLengthAttributes[ATTR_WIDTH].GetAnimValue(this); + return nsSVGUtils::ClampToInt(width); +} + +int32_t +SVGSVGElement::GetIntrinsicHeight() +{ + if (mLengthAttributes[ATTR_HEIGHT].IsPercentage()) { + return -1; + } + // Passing |this| as a SVGSVGElement* invokes the variant of GetAnimValue + // that uses the passed argument as the context, but that's fine since we + // know the length isn't a percentage so the context won't be used (and we + // need to pass the element to be able to resolve em/ex units). + float height = mLengthAttributes[ATTR_HEIGHT].GetAnimValue(this); + return nsSVGUtils::ClampToInt(height); +} + } // namespace dom } // namespace mozilla diff --git a/dom/svg/SVGSVGElement.h b/dom/svg/SVGSVGElement.h index 30591581218d..34176ce26e00 100644 --- a/dom/svg/SVGSVGElement.h +++ b/dom/svg/SVGSVGElement.h @@ -147,6 +147,15 @@ public: // public helpers: + /** + * Returns -1 if the width/height is a percentage, else returns the user unit + * length clamped to fit in a int32_t. + * XXX see bug 1112533 comment 3 - we should fix drawImage so that we can + * change these methods to make zero the error flag for percentages. + */ + int32_t GetIntrinsicWidth(); + int32_t GetIntrinsicHeight(); + /** * Returns true if this element has a base/anim value for its "viewBox" * attribute that defines a viewBox rectangle with finite values, or diff --git a/dom/webidl/RTCConfiguration.webidl b/dom/webidl/RTCConfiguration.webidl index 7553fcb4da9b..02e7c8e465e8 100644 --- a/dom/webidl/RTCConfiguration.webidl +++ b/dom/webidl/RTCConfiguration.webidl @@ -8,7 +8,8 @@ */ dictionary RTCIceServer { - DOMString url; + (DOMString or sequence) urls; + DOMString url; //deprecated DOMString? credential = null; DOMString? username = null; }; diff --git a/gfx/2d/SVGTurbulenceRenderer-inl.h b/gfx/2d/SVGTurbulenceRenderer-inl.h index b784bd8a4738..006f842e383b 100644 --- a/gfx/2d/SVGTurbulenceRenderer-inl.h +++ b/gfx/2d/SVGTurbulenceRenderer-inl.h @@ -125,8 +125,11 @@ SVGTurbulenceRenderer::InitFromSeed(int32_t float gradient[4][sBSize][2]; for (int32_t k = 0; k < 4; k++) { for (int32_t i = 0; i < sBSize; i++) { - float a = float((rand.Next() % (sBSize + sBSize)) - sBSize) / sBSize; - float b = float((rand.Next() % (sBSize + sBSize)) - sBSize) / sBSize; + float a, b; + do { + a = float((rand.Next() % (sBSize + sBSize)) - sBSize) / sBSize; + b = float((rand.Next() % (sBSize + sBSize)) - sBSize) / sBSize; + } while (a == 0 && b == 0); float s = sqrt(a * a + b * b); gradient[k][i][0] = a / s; gradient[k][i][1] = b / s; diff --git a/gfx/layers/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index 63e1d3e60465..28b1bb8778ea 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -1050,6 +1050,7 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion, return; } + nsIntSize oldSize = mSize; UpdateRenderTarget(); // Failed to create a render target or the view. @@ -1069,7 +1070,13 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion, nsIntRect intRect = nsIntRect(nsIntPoint(0, 0), mSize); // Sometimes the invalid region is larger than we want to draw. nsIntRegion invalidRegionSafe; - invalidRegionSafe.And(aInvalidRegion, intRect); + + if (mSize != oldSize) { + invalidRegionSafe = intRect; + } else { + invalidRegionSafe.And(aInvalidRegion, intRect); + } + nsIntRect invalidRect = invalidRegionSafe.GetBounds(); mInvalidRect = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height); mInvalidRegion = invalidRegionSafe; diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index 6ec0ed99745f..3271af05dc8f 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -239,7 +239,7 @@ private: DECL_GFX_PREF(Live, "image.high_quality_downscaling.min_factor", ImageHQDownscalingMinFactor, uint32_t, 1000); DECL_GFX_PREF(Live, "image.high_quality_upscaling.max_size", ImageHQUpscalingMaxSize, uint32_t, 20971520); DECL_GFX_PREF(Once, "image.mem.decode_bytes_at_a_time", ImageMemDecodeBytesAtATime, uint32_t, 200000); - DECL_GFX_PREF(Live, "image.mem.decodeondraw", ImageMemDecodeOnDraw, bool, false); + DECL_GFX_PREF(Live, "image.mem.decodeondraw", ImageMemDecodeOnDraw, bool, true); DECL_GFX_PREF(Live, "image.mem.discardable", ImageMemDiscardable, bool, false); DECL_GFX_PREF(Once, "image.mem.surfacecache.discard_factor", ImageMemSurfaceCacheDiscardFactor, uint32_t, 1); DECL_GFX_PREF(Once, "image.mem.surfacecache.max_size_kb", ImageMemSurfaceCacheMaxSizeKB, uint32_t, 100 * 1024); diff --git a/image/src/SVGDocumentWrapper.cpp b/image/src/SVGDocumentWrapper.cpp index b7d086b243a8..dc2d6d894ab5 100644 --- a/image/src/SVGDocumentWrapper.cpp +++ b/image/src/SVGDocumentWrapper.cpp @@ -68,45 +68,6 @@ SVGDocumentWrapper::DestroyViewer() } } -bool -SVGDocumentWrapper::GetWidthOrHeight(Dimension aDimension, - int32_t& aResult) -{ - SVGSVGElement* rootElem = GetRootSVGElem(); - NS_ABORT_IF_FALSE(rootElem, "root elem missing or of wrong type"); - - // Get the width or height SVG object - nsRefPtr domAnimLength; - if (aDimension == eWidth) { - domAnimLength = rootElem->Width(); - } else { - NS_ABORT_IF_FALSE(aDimension == eHeight, "invalid dimension"); - domAnimLength = rootElem->Height(); - } - NS_ENSURE_TRUE(domAnimLength, false); - - // Get the animated value from the object - nsRefPtr domLength = domAnimLength->AnimVal(); - NS_ENSURE_TRUE(domLength, false); - - // Check if it's a percent value (and fail if so) - uint16_t unitType; - nsresult rv = domLength->GetUnitType(&unitType); - NS_ENSURE_SUCCESS(rv, false); - if (unitType == nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE) { - return false; - } - - // Non-percent value - woot! Grab it & return it. - float floatLength; - rv = domLength->GetValue(&floatLength); - NS_ENSURE_SUCCESS(rv, false); - - aResult = nsSVGUtils::ClampToInt(floatLength); - - return true; -} - nsIFrame* SVGDocumentWrapper::GetRootLayoutFrame() { diff --git a/image/src/SVGDocumentWrapper.h b/image/src/SVGDocumentWrapper.h index 4904592b0eed..81923768a428 100644 --- a/image/src/SVGDocumentWrapper.h +++ b/image/src/SVGDocumentWrapper.h @@ -52,21 +52,6 @@ public: eHeight }; - /** - * Looks up the value of the wrapped SVG document's |width| or |height| - * attribute in CSS pixels, and returns it by reference. If the document has - * a percent value for the queried attribute, then this method fails - * (returns false). - * - * @param aDimension Indicates whether the width or height is desired. - * @param[out] aResult If this method succeeds, then this outparam will be - populated with the width or height in CSS pixels. - * @return false to indicate failure, if the queried attribute has a - * percent value. Otherwise, true. - * - */ - bool GetWidthOrHeight(Dimension aDimension, int32_t& aResult); - /** * Returns the wrapped document, or nullptr on failure. (No AddRef.) */ diff --git a/image/src/VectorImage.cpp b/image/src/VectorImage.cpp index df5cb642c336..76d62500ff2a 100644 --- a/image/src/VectorImage.cpp +++ b/image/src/VectorImage.cpp @@ -472,17 +472,14 @@ NS_IMETHODIMP VectorImage::GetWidth(int32_t* aWidth) { if (mError || !mIsFullyLoaded) { - *aWidth = 0; - return NS_ERROR_FAILURE; + *aWidth = -1; + } else { + SVGSVGElement* rootElem = mSVGDocumentWrapper->GetRootSVGElem(); + MOZ_ASSERT(rootElem, "Should have a root SVG elem, since we finished " + "loading without errors"); + *aWidth = rootElem->GetIntrinsicWidth(); } - - if (!mSVGDocumentWrapper->GetWidthOrHeight(SVGDocumentWrapper::eWidth, - *aWidth)) { - *aWidth = 0; - return NS_ERROR_FAILURE; - } - - return NS_OK; + return *aWidth >= 0 ? NS_OK : NS_ERROR_FAILURE; } //****************************************************************************** @@ -541,17 +538,14 @@ NS_IMETHODIMP VectorImage::GetHeight(int32_t* aHeight) { if (mError || !mIsFullyLoaded) { - *aHeight = 0; - return NS_ERROR_FAILURE; + *aHeight = -1; + } else { + SVGSVGElement* rootElem = mSVGDocumentWrapper->GetRootSVGElem(); + MOZ_ASSERT(rootElem, "Should have a root SVG elem, since we finished " + "loading without errors"); + *aHeight = rootElem->GetIntrinsicHeight(); } - - if (!mSVGDocumentWrapper->GetWidthOrHeight(SVGDocumentWrapper::eHeight, - *aHeight)) { - *aHeight = 0; - return NS_ERROR_FAILURE; - } - - return NS_OK; + return *aHeight >= 0 ? NS_OK : NS_ERROR_FAILURE; } //****************************************************************************** @@ -663,17 +657,20 @@ VectorImage::GetFrame(uint32_t aWhichFrame, if (aWhichFrame > FRAME_MAX_VALUE) return nullptr; - if (mError) + if (mError || !mIsFullyLoaded) return nullptr; // Look up height & width // ---------------------- - nsIntSize imageIntSize; - if (!mSVGDocumentWrapper->GetWidthOrHeight(SVGDocumentWrapper::eWidth, - imageIntSize.width) || - !mSVGDocumentWrapper->GetWidthOrHeight(SVGDocumentWrapper::eHeight, - imageIntSize.height)) { - // We'll get here if our SVG doc has a percent-valued width or height. + SVGSVGElement* svgElem = mSVGDocumentWrapper->GetRootSVGElem(); + MOZ_ASSERT(svgElem, "Should have a root SVG elem, since we finished " + "loading without errors"); + nsIntSize imageIntSize(svgElem->GetIntrinsicWidth(), + svgElem->GetIntrinsicHeight()); + + if (imageIntSize.IsEmpty()) { + // We'll get here if our SVG doc has a percent-valued or negative width or + // height. return nullptr; } diff --git a/intl/build/moz.build b/intl/build/moz.build index b5ea4aeea918..26bae09dd299 100644 --- a/intl/build/moz.build +++ b/intl/build/moz.build @@ -9,9 +9,8 @@ SOURCES += [ ] FINAL_LIBRARY = 'xul' +CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS'] LOCAL_INCLUDES += [ - '../icu/source/common', - '../icu/source/i18n', '../locale', '../lwbrk', '../strres', diff --git a/intl/locale/mac/moz.build b/intl/locale/mac/moz.build index 277cf2fba306..226a516f38f0 100644 --- a/intl/locale/mac/moz.build +++ b/intl/locale/mac/moz.build @@ -11,10 +11,9 @@ UNIFIED_SOURCES += [ ] FINAL_LIBRARY = 'xul' +CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS'] LOCAL_INCLUDES += [ '..', - '../../icu/source/common', - '../../icu/source/i18n', ] FAIL_ON_WARNINGS = True diff --git a/ipc/nfc/Nfc.cpp b/ipc/nfc/Nfc.cpp index 04f6fca4298c..62b96d5ab564 100644 --- a/ipc/nfc/Nfc.cpp +++ b/ipc/nfc/Nfc.cpp @@ -1,5 +1,5 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim: set sw=4 ts=8 et ft=cpp: */ +/* vim: set sw=2 ts=8 et ft=cpp: */ /* 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/. */ @@ -22,88 +22,86 @@ #include "jsfriendapi.h" #include "mozilla/ArrayUtils.h" +#include "mozilla/ipc/UnixSocketConnector.h" #include "nsThreadUtils.h" // For NS_IsMainThread. using namespace mozilla::ipc; namespace { -const char* NFC_SOCKET_NAME = "/dev/socket/nfcd"; +static const char NFC_SOCKET_NAME[] = "/dev/socket/nfcd"; // Network port to connect to for adb forwarded sockets when doing // desktop development. -const uint32_t NFC_TEST_PORT = 6400; +static const uint32_t NFC_TEST_PORT = 6400; -class SendNfcSocketDataTask : public nsRunnable +class SendNfcSocketDataTask MOZ_FINAL : public nsRunnable { public: - SendNfcSocketDataTask(NfcConsumer* aConsumer, UnixSocketRawData* aRawData) - : mConsumer(aConsumer), mRawData(aRawData) - { } + SendNfcSocketDataTask(NfcConsumer* aConsumer, UnixSocketRawData* aRawData) + : mConsumer(aConsumer) + , mRawData(aRawData) + { } - NS_IMETHOD Run() - { - MOZ_ASSERT(NS_IsMainThread()); + NS_IMETHOD Run() + { + MOZ_ASSERT(NS_IsMainThread()); - if (!mConsumer || - mConsumer->GetConnectionStatus() != SOCKET_CONNECTED) { - // Probably shuting down. - delete mRawData; - return NS_OK; - } - - mConsumer->SendSocketData(mRawData); - return NS_OK; + if (!mConsumer || + mConsumer->GetConnectionStatus() != SOCKET_CONNECTED) { + // Probably shuting down. + return NS_OK; } + mConsumer->SendSocketData(mRawData.forget()); + return NS_OK; + } + private: - NfcConsumer* mConsumer; - UnixSocketRawData* mRawData; + NfcConsumer* mConsumer; + nsAutoPtr mRawData; }; -class NfcConnector : public mozilla::ipc::UnixSocketConnector +class NfcConnector MOZ_FINAL : public mozilla::ipc::UnixSocketConnector { public: - NfcConnector() - {} + NfcConnector() + { } - virtual ~NfcConnector() - {} - - virtual int Create(); - virtual bool CreateAddr(bool aIsServer, - socklen_t& aAddrSize, - sockaddr_any& aAddr, - const char* aAddress); - virtual bool SetUp(int aFd); - virtual bool SetUpListenSocket(int aFd); - virtual void GetSocketAddr(const sockaddr_any& aAddr, - nsAString& aAddrStr); + int Create() MOZ_OVERRIDE; + bool CreateAddr(bool aIsServer, + socklen_t& aAddrSize, + sockaddr_any& aAddr, + const char* aAddress) MOZ_OVERRIDE; + bool SetUp(int aFd) MOZ_OVERRIDE; + bool SetUpListenSocket(int aFd) MOZ_OVERRIDE; + void GetSocketAddr(const sockaddr_any& aAddr, + nsAString& aAddrStr) MOZ_OVERRIDE; }; int NfcConnector::Create() { - MOZ_ASSERT(!NS_IsMainThread()); + MOZ_ASSERT(!NS_IsMainThread()); - int fd = -1; + int fd = -1; #if defined(MOZ_WIDGET_GONK) - fd = socket(AF_LOCAL, SOCK_STREAM, 0); + fd = socket(AF_LOCAL, SOCK_STREAM, 0); #else - // If we can't hit a local loopback, fail later in connect. - fd = socket(AF_INET, SOCK_STREAM, 0); + // If we can't hit a local loopback, fail later in connect. + fd = socket(AF_INET, SOCK_STREAM, 0); #endif - if (fd < 0) { - NS_WARNING("Could not open nfc socket!"); - return -1; - } + if (fd < 0) { + NS_WARNING("Could not open nfc socket!"); + return -1; + } - if (!SetUp(fd)) { - NS_WARNING("Could not set up socket!"); - } - return fd; + if (!SetUp(fd)) { + NS_WARNING("Could not set up socket!"); + } + return fd; } bool @@ -112,56 +110,56 @@ NfcConnector::CreateAddr(bool aIsServer, sockaddr_any& aAddr, const char* aAddress) { - // We never open nfc socket as server. - MOZ_ASSERT(!aIsServer); - uint32_t af; + // We never open nfc socket as server. + MOZ_ASSERT(!aIsServer); + uint32_t af; #if defined(MOZ_WIDGET_GONK) - af = AF_LOCAL; + af = AF_LOCAL; #else - af = AF_INET; + af = AF_INET; #endif - switch (af) { - case AF_LOCAL: - aAddr.un.sun_family = af; - if(strlen(aAddress) > sizeof(aAddr.un.sun_path)) { - NS_WARNING("Address too long for socket struct!"); - return false; - } - strcpy((char*)&aAddr.un.sun_path, aAddress); - aAddrSize = strlen(aAddress) + offsetof(struct sockaddr_un, sun_path) + 1; - break; - case AF_INET: - aAddr.in.sin_family = af; - aAddr.in.sin_port = htons(NFC_TEST_PORT); - aAddr.in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - aAddrSize = sizeof(sockaddr_in); - break; - default: - NS_WARNING("Socket type not handled by connector!"); - return false; + switch (af) { + case AF_LOCAL: + aAddr.un.sun_family = af; + if(strlen(aAddress) > sizeof(aAddr.un.sun_path)) { + NS_WARNING("Address too long for socket struct!"); + return false; } - return true; + strcpy((char*)&aAddr.un.sun_path, aAddress); + aAddrSize = strlen(aAddress) + offsetof(struct sockaddr_un, sun_path) + 1; + break; + case AF_INET: + aAddr.in.sin_family = af; + aAddr.in.sin_port = htons(NFC_TEST_PORT); + aAddr.in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + aAddrSize = sizeof(sockaddr_in); + break; + default: + NS_WARNING("Socket type not handled by connector!"); + return false; + } + return true; } bool NfcConnector::SetUp(int aFd) { - // Nothing to do here. - return true; + // Nothing to do here. + return true; } bool NfcConnector::SetUpListenSocket(int aFd) { - // Nothing to do here. - return true; + // Nothing to do here. + return true; } void NfcConnector::GetSocketAddr(const sockaddr_any& aAddr, nsAString& aAddrStr) { - MOZ_CRASH("This should never be called!"); + MOZ_CRASH("This should never be called!"); } } // anonymous namespace @@ -170,66 +168,71 @@ namespace mozilla { namespace ipc { NfcConsumer::NfcConsumer(NfcSocketListener* aListener) - : mListener(aListener) - , mShutdown(false) + : mListener(aListener) + , mShutdown(false) { - mAddress = NFC_SOCKET_NAME; + mAddress = NFC_SOCKET_NAME; - ConnectSocket(new NfcConnector(), mAddress.get()); + Connect(new NfcConnector(), mAddress.get()); } void NfcConsumer::Shutdown() { - MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(NS_IsMainThread()); - mShutdown = true; - CloseSocket(); + mShutdown = true; + Close(); } bool NfcConsumer::PostToNfcDaemon(const uint8_t* aData, size_t aSize) { - MOZ_ASSERT(!NS_IsMainThread()); + MOZ_ASSERT(!NS_IsMainThread()); - UnixSocketRawData* raw = new UnixSocketRawData(aData, aSize); - nsRefPtr task = new SendNfcSocketDataTask(this, raw); - NS_DispatchToMainThread(task); - return true; + UnixSocketRawData* raw = new UnixSocketRawData(aData, aSize); + nsRefPtr task = new SendNfcSocketDataTask(this, raw); + NS_DispatchToMainThread(task); + return true; } void NfcConsumer::ReceiveSocketData(nsAutoPtr& aData) { - MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(NS_IsMainThread()); - if (mListener) { - mListener->ReceiveSocketData(aData); - } + if (mListener) { + mListener->ReceiveSocketData(aData); + } } void NfcConsumer::OnConnectSuccess() { - // Nothing to do here. - CHROMIUM_LOG("NFC: %s\n", __FUNCTION__); + // Nothing to do here. + CHROMIUM_LOG("NFC: %s\n", __FUNCTION__); } void NfcConsumer::OnConnectError() { - CHROMIUM_LOG("NFC: %s\n", __FUNCTION__); - CloseSocket(); + CHROMIUM_LOG("NFC: %s\n", __FUNCTION__); + Close(); } void NfcConsumer::OnDisconnect() { - CHROMIUM_LOG("NFC: %s\n", __FUNCTION__); - if (!mShutdown) { - ConnectSocket(new NfcConnector(), mAddress.get(), - GetSuggestedConnectDelayMs()); - } + CHROMIUM_LOG("NFC: %s\n", __FUNCTION__); + if (!mShutdown) { + Connect(new NfcConnector(), mAddress.get(), GetSuggestedConnectDelayMs()); + } +} + +ConnectionOrientedSocketIO* +NfcConsumer::GetIO() +{ + return PrepareAccept(new NfcConnector()); } } // namespace ipc diff --git a/ipc/nfc/Nfc.h b/ipc/nfc/Nfc.h index 56cbd9600e2a..8f0b9683fb5d 100644 --- a/ipc/nfc/Nfc.h +++ b/ipc/nfc/Nfc.h @@ -9,7 +9,7 @@ #ifndef mozilla_ipc_Nfc_h #define mozilla_ipc_Nfc_h 1 -#include +#include namespace mozilla { namespace ipc { @@ -20,21 +20,23 @@ public: virtual void ReceiveSocketData(nsAutoPtr& aData) = 0; }; -class NfcConsumer : public mozilla::ipc::UnixSocketConsumer +class NfcConsumer MOZ_FINAL : public mozilla::ipc::StreamSocket { public: NfcConsumer(NfcSocketListener* aListener); - virtual ~NfcConsumer() { } void Shutdown(); bool PostToNfcDaemon(const uint8_t* aData, size_t aSize); -private: - virtual void ReceiveSocketData(nsAutoPtr& aData); + ConnectionOrientedSocketIO* GetIO() MOZ_OVERRIDE; - virtual void OnConnectSuccess(); - virtual void OnConnectError(); - virtual void OnDisconnect(); +private: + void ReceiveSocketData( + nsAutoPtr& aData) MOZ_OVERRIDE; + + void OnConnectSuccess() MOZ_OVERRIDE; + void OnConnectError() MOZ_OVERRIDE; + void OnDisconnect() MOZ_OVERRIDE; private: NfcSocketListener* mListener; diff --git a/js/src/configure.in b/js/src/configure.in index 854427fea800..5beb3dc6bb1e 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -3052,18 +3052,6 @@ MOZ_ARG_WITH_STRING(wrap-malloc, [ --with-wrap-malloc=DIR Location of malloc wrapper library], WRAP_LDFLAGS="${WRAP_LDFLAGS} $withval") -dnl ======================================================== -dnl = Use compacting GC -dnl ======================================================== -dnl Compact the heap by moving GC things when doing a shrinking colletion. -MOZ_ARG_ENABLE_BOOL(gccompacting, -[ --enable-gccompacting Compact the heap by moving GC things], - JSGC_COMPACTING=1, - JSGC_COMPACTING= ) -if test -n "$JSGC_COMPACTING"; then - AC_DEFINE(JSGC_COMPACTING) -fi - dnl ======================================================== dnl = Use a smaller chunk size for GC chunks dnl ======================================================== diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 6068a14968fb..4f3ea5f61f11 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -3257,6 +3257,8 @@ EmitDestructuringDeclsWithEmitter(ExclusiveContext *cx, BytecodeEmitter *bce, JS MOZ_ASSERT(element->pn_kid->isKind(PNK_NAME)); target = element->pn_kid; } + if (target->isKind(PNK_ASSIGN)) + target = target->pn_left; if (target->isKind(PNK_NAME)) { if (!EmitName(cx, bce, prologOp, target)) return false; @@ -3276,6 +3278,8 @@ EmitDestructuringDeclsWithEmitter(ExclusiveContext *cx, BytecodeEmitter *bce, JS ParseNode *target = member->isKind(PNK_MUTATEPROTO) ? member->pn_kid : member->pn_right; + if (target->isKind(PNK_ASSIGN)) + target = target->pn_left; if (target->isKind(PNK_NAME)) { if (!EmitName(cx, bce, prologOp, target)) return false; @@ -3341,7 +3345,7 @@ EmitDestructuringOpsHelper(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode * lhs expression. (Same post-condition as EmitDestructuringOpsHelper) */ static bool -EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, VarEmitOption emitOption) +EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *target, VarEmitOption emitOption) { MOZ_ASSERT(emitOption != DefineVars); @@ -3349,10 +3353,12 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, // destructuring initialiser-form, call ourselves to handle it, then pop // the matched value. Otherwise emit an lvalue bytecode sequence followed // by an assignment op. - if (pn->isKind(PNK_SPREAD)) - pn = pn->pn_kid; - if (pn->isKind(PNK_ARRAY) || pn->isKind(PNK_OBJECT)) { - if (!EmitDestructuringOpsHelper(cx, bce, pn, emitOption)) + if (target->isKind(PNK_SPREAD)) + target = target->pn_kid; + else if (target->isKind(PNK_ASSIGN)) + target = target->pn_left; + if (target->isKind(PNK_ARRAY) || target->isKind(PNK_OBJECT)) { + if (!EmitDestructuringOpsHelper(cx, bce, target, emitOption)) return false; if (emitOption == InitializeVars) { // Per its post-condition, EmitDestructuringOpsHelper has left the @@ -3363,15 +3369,15 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, } else if (emitOption == PushInitialValues) { // The lhs is a simple name so the to-be-destructured value is // its initial value and there is nothing to do. - MOZ_ASSERT(pn->getOp() == JSOP_SETLOCAL || pn->getOp() == JSOP_INITLEXICAL); - MOZ_ASSERT(pn->pn_dflags & PND_BOUND); + MOZ_ASSERT(target->getOp() == JSOP_SETLOCAL || target->getOp() == JSOP_INITLEXICAL); + MOZ_ASSERT(target->pn_dflags & PND_BOUND); } else { - switch (pn->getKind()) { + switch (target->getKind()) { case PNK_NAME: - if (!BindNameToSlot(cx, bce, pn)) + if (!BindNameToSlot(cx, bce, target)) return false; - switch (pn->getOp()) { + switch (target->getOp()) { case JSOP_SETNAME: case JSOP_STRICTSETNAME: case JSOP_SETGNAME: @@ -3388,11 +3394,11 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, // but the operands are on the stack in the wrong order for // JSOP_SETPROP, so we have to add a JSOP_SWAP. jsatomid atomIndex; - if (!bce->makeAtomIndex(pn->pn_atom, &atomIndex)) + if (!bce->makeAtomIndex(target->pn_atom, &atomIndex)) return false; - if (!pn->isOp(JSOP_SETCONST)) { - bool global = pn->isOp(JSOP_SETGNAME) || pn->isOp(JSOP_STRICTSETGNAME); + if (!target->isOp(JSOP_SETCONST)) { + bool global = target->isOp(JSOP_SETGNAME) || target->isOp(JSOP_STRICTSETGNAME); JSOp bindOp = global ? JSOP_BINDGNAME : JSOP_BINDNAME; if (!EmitIndex32(cx, bindOp, atomIndex, bce)) return false; @@ -3400,7 +3406,7 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, return false; } - if (!EmitIndexOp(cx, pn->getOp(), atomIndex, bce)) + if (!EmitIndexOp(cx, target->getOp(), atomIndex, bce)) return false; break; } @@ -3408,7 +3414,7 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, case JSOP_SETLOCAL: case JSOP_SETARG: case JSOP_INITLEXICAL: - if (!EmitVarOp(cx, pn, pn->getOp(), bce)) + if (!EmitVarOp(cx, target, target->getOp(), bce)) return false; break; @@ -3427,12 +3433,12 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, // In `[a.x] = [b]`, per spec, `b` is evaluated before `a`. Then we // need a property set -- but the operands are on the stack in the // wrong order for JSOP_SETPROP, so we have to add a JSOP_SWAP. - if (!EmitTree(cx, bce, pn->pn_expr)) + if (!EmitTree(cx, bce, target->pn_expr)) return false; if (Emit1(cx, bce, JSOP_SWAP) < 0) return false; JSOp setOp = bce->sc->strict ? JSOP_STRICTSETPROP : JSOP_SETPROP; - if (!EmitAtomOp(cx, pn, setOp, bce)) + if (!EmitAtomOp(cx, target, setOp, bce)) return false; break; } @@ -3443,14 +3449,14 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, // `[a[x]] = [b]`, is handled much the same way. The JSOP_SWAP // is emitted by EmitElemOperands. JSOp setOp = bce->sc->strict ? JSOP_STRICTSETELEM : JSOP_SETELEM; - if (!EmitElemOp(cx, pn, setOp, bce)) + if (!EmitElemOp(cx, target, setOp, bce)) return false; break; } case PNK_CALL: - MOZ_ASSERT(pn->pn_xflags & PNX_SETCALL); - if (!EmitTree(cx, bce, pn)) + MOZ_ASSERT(target->pn_xflags & PNX_SETCALL); + if (!EmitTree(cx, bce, target)) return false; // Pop the call return value. Below, we pop the RHS too, balancing @@ -3500,6 +3506,33 @@ EmitIteratorNext(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn=nullp return true; } +/** + * EmitDefault will check if the value on top of the stack is "undefined". + * If so, it will replace that value on the stack with the value defined by |defaultExpr|. + */ +static bool +EmitDefault(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *defaultExpr) +{ + if (Emit1(cx, bce, JSOP_DUP) < 0) // VALUE VALUE + return false; + if (Emit1(cx, bce, JSOP_UNDEFINED) < 0) // VALUE VALUE UNDEFINED + return false; + if (Emit1(cx, bce, JSOP_STRICTEQ) < 0) // VALUE EQL? + return false; + // Emit source note to enable ion compilation. + if (NewSrcNote(cx, bce, SRC_IF) < 0) + return false; + ptrdiff_t jump = EmitJump(cx, bce, JSOP_IFEQ, 0); // VALUE + if (jump < 0) + return false; + if (Emit1(cx, bce, JSOP_POP) < 0) // . + return false; + if (!EmitTree(cx, bce, defaultExpr)) // DEFAULTVALUE + return false; + SetJumpOffsetAt(bce, jump); + return true; +} + static bool EmitDestructuringOpsArrayHelper(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pattern, VarEmitOption emitOption) @@ -3526,7 +3559,14 @@ EmitDestructuringOpsArrayHelper(ExclusiveContext *cx, BytecodeEmitter *bce, Pars * current property name "label" on the left of a colon in the object * initializer. */ - if (member->isKind(PNK_SPREAD)) { + ParseNode *pndefault = nullptr; + ParseNode *elem = member; + if (elem->isKind(PNK_ASSIGN)) { + pndefault = elem->pn_right; + elem = elem->pn_left; + } + + if (elem->isKind(PNK_SPREAD)) { /* Create a new array with the rest of the iterator */ ptrdiff_t off = EmitN(cx, bce, JSOP_NEWARRAY, 3); // ... OBJ? ITER ARRAY if (off < 0) @@ -3581,8 +3621,11 @@ EmitDestructuringOpsArrayHelper(ExclusiveContext *cx, BytecodeEmitter *bce, Pars return false; } + if (pndefault && !EmitDefault(cx, bce, pndefault)) + return false; + // Destructure into the pattern the element contains. - ParseNode *subpattern = member; + ParseNode *subpattern = elem; if (subpattern->isKind(PNK_ELISION)) { // The value destructuring into an elision just gets ignored. if (Emit1(cx, bce, JSOP_POP) < 0) // ... OBJ? ITER @@ -3684,6 +3727,12 @@ EmitDestructuringOpsObjectHelper(ExclusiveContext *cx, BytecodeEmitter *bce, Par if (needsGetElem && !EmitElemOpBase(cx, bce, JSOP_GETELEM)) // ... OBJ PROP return false; + if (subpattern->isKind(PNK_ASSIGN)) { + if (!EmitDefault(cx, bce, subpattern->pn_right)) + return false; + subpattern = subpattern->pn_left; + } + // Destructure PROP per this member's subpattern. int32_t depthBefore = bce->stackDepth; if (!EmitDestructuringLHS(cx, bce, subpattern, emitOption)) diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 2c1e3efc7526..a57ae2464813 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -3385,6 +3385,8 @@ Parser::checkDestructuringObject(BindData *d MOZ_ASSERT(member->isKind(PNK_COLON) || member->isKind(PNK_SHORTHAND)); expr = member->pn_right; } + if (expr->isKind(PNK_ASSIGN)) + expr = expr->pn_left; bool ok; if (expr->isKind(PNK_ARRAY) || expr->isKind(PNK_OBJECT)) { @@ -3429,6 +3431,8 @@ Parser::checkDestructuringArray(BindData *da report(ParseError, false, target, JSMSG_BAD_DESTRUCT_TARGET); return false; } + } else if (target->isKind(PNK_ASSIGN)) { + target = target->pn_left; } bool ok; diff --git a/js/src/gc/GCInternals.h b/js/src/gc/GCInternals.h index 0a718a9ac32b..15b85f26dae4 100644 --- a/js/src/gc/GCInternals.h +++ b/js/src/gc/GCInternals.h @@ -143,7 +143,6 @@ void CheckHashTablesAfterMovingGC(JSRuntime *rt); #endif -#ifdef JSGC_COMPACTING struct MovingTracer : JSTracer { explicit MovingTracer(JSRuntime *rt) : JSTracer(rt, Visit, TraceWeakMapKeysValues) {} @@ -152,7 +151,6 @@ struct MovingTracer : JSTracer { return trc->callback == Visit; } }; -#endif } /* namespace gc */ } /* namespace js */ diff --git a/js/src/gc/GCRuntime.h b/js/src/gc/GCRuntime.h index 1b836747ff3a..f71effabace4 100644 --- a/js/src/gc/GCRuntime.h +++ b/js/src/gc/GCRuntime.h @@ -34,11 +34,8 @@ struct FinalizePhase; class MarkingValidator; struct AutoPrepareForTracing; class AutoTraceSession; - -#ifdef JSGC_COMPACTING struct ArenasToUpdate; struct MovingTracer; -#endif class ChunkPool { @@ -297,11 +294,7 @@ class GCRuntime bool isHeapMajorCollecting() { return heapState == js::MajorCollecting; } bool isHeapMinorCollecting() { return heapState == js::MinorCollecting; } bool isHeapCollecting() { return isHeapMajorCollecting() || isHeapMinorCollecting(); } -#ifdef JSGC_COMPACTING bool isHeapCompacting() { return isHeapMajorCollecting() && state() == COMPACT; } -#else - bool isHeapCompacting() { return false; } -#endif bool triggerGC(JS::gcreason::Reason reason); void maybeAllocTriggerZoneGC(Zone *zone, const AutoLockGC &lock); @@ -437,11 +430,9 @@ class GCRuntime void disableGenerationalGC(); void enableGenerationalGC(); -#ifdef JSGC_COMPACTING void disableCompactingGC(); void enableCompactingGC(); bool isCompactingGCEnabled(); -#endif void setGrayRootsTracer(JSTraceDataOp traceOp, void *data); bool addBlackRootsTracer(JSTraceDataOp traceOp, void *data); @@ -604,19 +595,17 @@ class GCRuntime void assertBackgroundSweepingFinished(); bool shouldCompact(); bool compactPhase(bool lastGC); -#ifdef JSGC_COMPACTING void sweepTypesAfterCompacting(Zone *zone); void sweepZoneAfterCompacting(Zone *zone); ArenaHeader *relocateArenas(); - void updateAllCellPointersParallel(ArenasToUpdate &source); - void updateAllCellPointersSerial(MovingTracer *trc, ArenasToUpdate &source); + void updateAllCellPointersParallel(MovingTracer *trc); + void updateAllCellPointersSerial(MovingTracer *trc); void updatePointersToRelocatedCells(); void releaseRelocatedArenas(ArenaHeader *relocatedList); void releaseRelocatedArenasWithoutUnlocking(ArenaHeader *relocatedList, const AutoLockGC& lock); #ifdef DEBUG void protectRelocatedArenas(ArenaHeader *relocatedList); void unprotectRelocatedArenas(ArenaHeader *relocatedList); -#endif #endif void finishCollection(); @@ -811,13 +800,11 @@ class GCRuntime */ unsigned generationalDisabled; -#ifdef JSGC_COMPACTING /* * Some code cannot tolerate compacting GC so it can be disabled with this * counter. */ unsigned compactingDisabled; -#endif /* * This is true if we are in the middle of a brain transplant (e.g., @@ -918,9 +905,7 @@ class GCRuntime size_t noGCOrAllocationCheck; -#ifdef JSGC_COMPACTING ArenaHeader* relocatedArenasToRelease; -#endif #endif diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h index f18d82cd9325..6e53c16948be 100644 --- a/js/src/gc/Heap.h +++ b/js/src/gc/Heap.h @@ -642,10 +642,8 @@ struct ArenaHeader void unmarkAll(); -#ifdef JSGC_COMPACTING size_t countUsedCells(); size_t countFreeCells(); -#endif }; static_assert(ArenaZoneOffset == offsetof(ArenaHeader, zone), "The hardcoded API zone offset must match the actual offset."); diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 94500b5ee718..9f8b71600987 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -161,18 +161,14 @@ CheckMarkedThing(JSTracer *trc, T **thingp) T *thing = *thingp; MOZ_ASSERT(*thingp); -#ifdef JSGC_COMPACTING thing = MaybeForwarded(thing); -#endif /* This function uses data that's not available in the nursery. */ if (IsInsideNursery(thing)) return; -#ifdef JSGC_COMPACTING MOZ_ASSERT_IF(!MovingTracer::IsMovingTracer(trc) && !Nursery::IsMinorCollectionTracer(trc), !IsForwarded(*thingp)); -#endif /* * Permanent atoms are not associated with this runtime, but will be ignored @@ -184,13 +180,8 @@ CheckMarkedThing(JSTracer *trc, T **thingp) Zone *zone = thing->zoneFromAnyThread(); JSRuntime *rt = trc->runtime(); -#ifdef JSGC_COMPACTING MOZ_ASSERT_IF(!MovingTracer::IsMovingTracer(trc), CurrentThreadCanAccessZone(zone)); MOZ_ASSERT_IF(!MovingTracer::IsMovingTracer(trc), CurrentThreadCanAccessRuntime(rt)); -#else - MOZ_ASSERT(CurrentThreadCanAccessZone(zone)); - MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt)); -#endif MOZ_ASSERT(zone->runtimeFromAnyThread() == trc->runtime()); MOZ_ASSERT(trc->hasTracingDetails()); @@ -437,10 +428,8 @@ IsMarkedFromAnyThread(T **thingp) Zone *zone = (*thingp)->asTenured().zoneFromAnyThread(); if (!zone->isCollectingFromAnyThread() || zone->isGCFinished()) return true; -#ifdef JSGC_COMPACTING if (zone->isGCCompacting() && IsForwarded(*thingp)) *thingp = Forwarded(*thingp); -#endif return (*thingp)->asTenured().isMarked(); } @@ -481,12 +470,10 @@ IsAboutToBeFinalizedFromAnyThread(T **thingp) return false; return !thing->asTenured().isMarked(); } -#ifdef JSGC_COMPACTING else if (zone->isGCCompacting() && IsForwarded(thing)) { *thingp = Forwarded(thing); return false; } -#endif return false; } @@ -504,11 +491,10 @@ UpdateIfRelocated(JSRuntime *rt, T **thingp) return *thingp; } -#ifdef JSGC_COMPACTING Zone *zone = (*thingp)->zone(); if (zone->isGCCompacting() && IsForwarded(*thingp)) *thingp = Forwarded(*thingp); -#endif + return *thingp; } @@ -1815,10 +1801,8 @@ GCMarker::processMarkStackTop(SliceBudget &budget) // Global objects all have the same trace hook. That hook is safe without barriers // if the global has no custom trace hook of its own, or has been moved to a different // compartment, and so can't have one. - MOZ_ASSERT_IF(runtime()->gc.isIncrementalGCEnabled() && - !(clasp->trace == JS_GlobalObjectTraceHook && - (!obj->compartment()->options().getTrace() || - !obj->isOwnGlobal())), + MOZ_ASSERT_IF(!(clasp->trace == JS_GlobalObjectTraceHook && + (!obj->compartment()->options().getTrace() || !obj->isOwnGlobal())), clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS); if (clasp->trace == InlineTypedObject::obj_trace) goto scan_typed_obj; diff --git a/js/src/jit-test/tests/basic/destructuring-default.js b/js/src/jit-test/tests/basic/destructuring-default.js new file mode 100644 index 000000000000..d5d22d412a38 --- /dev/null +++ b/js/src/jit-test/tests/basic/destructuring-default.js @@ -0,0 +1,166 @@ + +load(libdir + 'asserts.js'); +load(libdir + 'eqArrayHelper.js'); + +var arrayPattern = '[a = 1, b = 2, c = 3, d = 4, e = 5, f = 6]'; +var objectPattern = '{0: a = 1, 1: b = 2, 2: c = 3, 3: d = 4, 4: e = 5, 5: f = 6}'; +var nestedPattern = '{a: a = 1, b: [b = 2] = [], c: {c: [c]} = {c: [3]}, d: {d, e} = {d: 4, e: 5}, f: f = 6}'; + +function testAll(fn) { + assertEqArray(fn(arrayPattern, []), [1, 2, 3, 4, 5, 6]); + assertEqArray(fn(arrayPattern, [2, 3, 4, 5, 6, 7, 8, 9]), [2, 3, 4, 5, 6, 7]); + assertEqArray(fn(arrayPattern, [undefined, 0, false, null, "", undefined]), [1, 0, false, null, "", 6]); + assertEqArray(fn(arrayPattern, [0, false]), [0, false, 3, 4, 5, 6]); + + assertEqArray(fn(objectPattern, []), [1, 2, 3, 4, 5, 6]); + assertEqArray(fn(objectPattern, [2, 3, 4, 5, 6, 7, 8, 9]), [2, 3, 4, 5, 6, 7]); + assertEqArray(fn(objectPattern, [undefined, 0, false, null, "", undefined]), [1, 0, false, null, "", 6]); + assertEqArray(fn(objectPattern, [0, false]), [0, false, 3, 4, 5, 6]); + + assertEqArray(fn(nestedPattern, {}), [1, 2, 3, 4, 5, 6]); + assertEqArray(fn(nestedPattern, {a: 2, b: [], c: undefined}), [2, 2, 3, 4, 5, 6]); + assertEqArray(fn(nestedPattern, {a: undefined, b: [3], c: {c: [4]}}), [1, 3, 4, 4, 5, 6]); + assertEqArray(fn(nestedPattern, {a: undefined, b: [3], c: {c: [4]}, d: {d: 5, e: 6}}), [1, 3, 4, 5, 6, 6]); +} + +function testVar(pattern, input) { + return new Function('input', + 'var ' + pattern + ' = input;' + + 'return [a, b, c, d, e, f];' + )(input); +} +testAll(testVar); + +function testLet(pattern, input) { + return new Function('input', + 'let ' + pattern + ' = input;' + + 'return [a, b, c, d, e, f];' + )(input); +} +testAll(testLet); + +function testConst(pattern, input) { + return new Function('input', + 'const ' + pattern + ' = input;' + + 'return [a, b, c, d, e, f];' + )(input); +} +testAll(testConst); + +function testGlobal(pattern, input) { + return new Function('input', + '(' + pattern + ') = input;' + + 'return [a, b, c, d, e, f];' + )(input); +} +testAll(testGlobal); + +function testClosure(pattern, input) { + return new Function('input', + 'var rest; (function () {' + + '(' + pattern + ') = input;' + + '})();' + + 'return [a, b, c, d, e, f];' + )(input); +} +testAll(testClosure); + +function testArgument(pattern, input) { + return new Function('input', + 'return (function (' + pattern + ') {' + + 'return [a, b, c, d, e, f]; })(input);' + )(input); +} +testAll(testArgument); + +function testArgumentFunction(pattern, input) { + return new Function(pattern, + 'return [a, b, c, d, e, f];' + )(input); +} +// XXX: ES6 requires the `Function` constructor to accept arbitrary +// `BindingElement`s as formal parameters. See Bug 1037939. +// Once fixed, please update the assertions below. +assertThrowsInstanceOf(() => testAll(testArgumentFunction), SyntaxError); + +function testThrow(pattern, input) { + return new Function('input', + 'try { throw input }' + + 'catch(' + pattern + ') {' + + 'return [a, b, c, d, e, f]; }' + )(input); +} +testAll(testThrow); + +// XXX: Support for let blocks and expressions will be removed in bug 1023609. +// However, they test a special code path in destructuring assignment so having +// these tests here for now seems like a good idea. +function testLetBlock(pattern, input) { + return new Function('input', + 'let (' + pattern + ' = input)' + + '{ return [a, b, c, d, e, f]; }' + )(input); +} +testAll(testLetBlock); + +function testLetExpression(pattern, input) { + return new Function('input', + 'return (let (' + pattern + ' = input) [a, b, c, d, e, f]);' + )(input); +} +testAll(testLetExpression); + +// test global const +const [ca = 1, cb = 2] = []; +assertEq(ca, 1); +assertEq(cb, 2); + +const {a: {a: cc = 3} = {a: undefined}} = {}; +assertEq(cc, 3); + +// test that the assignment happens in source order +var a = undefined, b = undefined, c = undefined; +({a: a = 1, c: c = 2, b: b = 3}) = { + get a() { + assertEq(a, undefined); + assertEq(c, undefined); + assertEq(b, undefined); + return undefined; + }, + get b() { + assertEq(a, 1); + assertEq(c, 2); + assertEq(b, undefined); + return 4; + }, + get c() { + assertEq(a, 1); + assertEq(c, undefined); + assertEq(b, undefined); + return undefined; + } +}; +assertEq(b, 4); + +assertThrowsInstanceOf(() => { var {a: {a} = null} = {}; }, TypeError); +assertThrowsInstanceOf(() => { var [[a] = 2] = []; }, TypeError); + +// destructuring assignment might have duplicate variable names. +var [a = 1, a = 2] = [3]; +assertEq(a, 2); + +// assignment to properties of default params +[a = {y: 2}, a.x = 1] = []; +assertEq(typeof a, 'object'); +assertEq(a.x, 1); +assertEq(a.y, 2); + +// defaults are evaluated even if there is no binding +var evaled = false; +({a: {} = (evaled = true, null)}) = {}; +assertEq(evaled, true); +evaled = false; +assertThrowsInstanceOf(() => { [[] = (evaled = true, 2)] = [] }, TypeError); +assertEq(evaled, true); + +assertThrowsInstanceOf(() => new Function('var [...rest = defaults] = [];'), SyntaxError); diff --git a/js/src/jit-test/tests/ion/simd-bug1123631.js b/js/src/jit-test/tests/ion/simd-bug1123631.js new file mode 100644 index 000000000000..38309f6b15cb --- /dev/null +++ b/js/src/jit-test/tests/ion/simd-bug1123631.js @@ -0,0 +1,9 @@ +if (!this.hasOwnProperty("SIMD")) + quit(); + +var float64x2 = SIMD.float64x2; +function test() { + var a = float64x2(1, 2); +} +test(); +test(); diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 15afa27b5783..6147b13e54a9 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -2530,9 +2530,8 @@ IonBuilder::inlineConstructSimdObject(CallInfo &callInfo, SimdTypeDescr *descr) case SimdTypeDescr::TYPE_FLOAT32: simdType = MIRType_Float32x4; break; - default: - MOZ_CRASH("Unknown SIMD kind when generating MSimdBox instruction."); - return InliningStatus_NotInlined; + case SimdTypeDescr::TYPE_FLOAT64: + return InliningStatus_NotInlined; // :TODO: NYI (Bug 1124205) } // We do not inline SIMD constructors if the number of arguments does not diff --git a/js/src/js-config.h.in b/js/src/js-config.h.in index b7a7e1a9f3cd..e7e3e1ed2562 100644 --- a/js/src/js-config.h.in +++ b/js/src/js-config.h.in @@ -31,9 +31,6 @@ /* Define to 1 if SpiderMonkey should use small chunks. */ #undef JS_GC_SMALL_CHUNK_SIZE -/* Define to 1 if SpiderMonkey should use Compacting GC. */ -#undef JSGC_COMPACTING - /* Define to 1 if the header is present and useable. See jscpucfg.h. */ #undef JS_HAVE_ENDIAN_H diff --git a/js/src/jsapi-tests/testPersistentRooted.cpp b/js/src/jsapi-tests/testPersistentRooted.cpp index ea8f7d960e0f..3ebdb592aba7 100644 --- a/js/src/jsapi-tests/testPersistentRooted.cpp +++ b/js/src/jsapi-tests/testPersistentRooted.cpp @@ -21,7 +21,7 @@ int BarkWhenTracedClass::finalizeCount; int BarkWhenTracedClass::traceCount; const JSClass BarkWhenTracedClass::class_ = { - "BarkWhenTracedClass", 0, + "BarkWhenTracedClass", JSCLASS_IMPLEMENTS_BARRIERS, nullptr, nullptr, nullptr, diff --git a/js/src/jsapi-tests/testWeakMap.cpp b/js/src/jsapi-tests/testWeakMap.cpp index a337bcc3ec63..b49967e9cbf1 100644 --- a/js/src/jsapi-tests/testWeakMap.cpp +++ b/js/src/jsapi-tests/testWeakMap.cpp @@ -66,10 +66,6 @@ checkSize(JS::HandleObject map, uint32_t expected) } END_TEST(testWeakMap_basicOperations) -// TODO: this test stores object pointers in a private slot which is not marked -// and so doesn't work with compacting GC. -#ifndef JSGC_COMPACTING - BEGIN_TEST(testWeakMap_keyDelegates) { JS_SetGCParameter(rt, JSGC_MODE, JSGC_MODE_INCREMENTAL); @@ -253,5 +249,3 @@ checkSize(JS::HandleObject map, uint32_t expected) return true; } END_TEST(testWeakMap_keyDelegates) - -#endif diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index b267be3d0ca2..d579615db44c 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -649,8 +649,6 @@ JSCompartment::sweepCrossCompartmentWrappers() } } -#ifdef JSGC_COMPACTING - void JSCompartment::fixupAfterMovingGC() { fixupGlobal(); @@ -667,8 +665,6 @@ JSCompartment::fixupGlobal() global_.set(MaybeForwarded(global)); } -#endif // JSGC_COMPACTING - void JSCompartment::purge() { diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index c6968cd45e22..732c445859f9 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -398,12 +398,10 @@ struct JSCompartment void purge(); void clearTables(); -#ifdef JSGC_COMPACTING void fixupInitialShapeTable(); void fixupNewTypeObjectTable(js::types::NewTypeObjectTable &table); void fixupAfterMovingGC(); void fixupGlobal(); -#endif bool hasObjectMetadataCallback() const { return objectMetadataCallback; } void setObjectMetadataCallback(js::ObjectMetadataCallback callback); diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 16d279e6c584..2680f0902f62 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -1112,9 +1112,7 @@ GCRuntime::GCRuntime(JSRuntime *rt) : sliceBudget(SliceBudget::Unlimited), incrementalAllowed(true), generationalDisabled(0), -#ifdef JSGC_COMPACTING compactingDisabled(0), -#endif manipulatingDeadZones(false), objectsMarkedInDeadZones(0), poked(false), @@ -1134,9 +1132,7 @@ GCRuntime::GCRuntime(JSRuntime *rt) : #ifdef DEBUG inUnsafeRegion(0), noGCOrAllocationCheck(0), -#ifdef JSGC_COMPACTING relocatedArenasToRelease(nullptr), -#endif #endif lock(nullptr), lockOwner(nullptr), @@ -1930,15 +1926,9 @@ ArenaLists::allocateFromArenaInner(JS::Zone *zone, ArenaHeader *aheader, AllocKi bool GCRuntime::shouldCompact() { -#ifdef JSGC_COMPACTING return invocationKind == GC_SHRINK && isCompactingGCEnabled(); -#else - return false; -#endif } -#ifdef JSGC_COMPACTING - void GCRuntime::disableCompactingGC() { @@ -2373,13 +2363,19 @@ namespace gc { struct ArenasToUpdate { - explicit ArenasToUpdate(JSRuntime *rt); + enum KindsToUpdate { + FOREGROUND = 1, + BACKGROUND = 2, + ALL = FOREGROUND | BACKGROUND + }; + ArenasToUpdate(JSRuntime *rt, KindsToUpdate kinds); bool done() { return initialized && arena == nullptr; } ArenaHeader* next(); ArenaHeader *getArenasToUpdate(AutoLockHelperThreadState& lock, unsigned max); private: bool initialized; + KindsToUpdate kinds; GCZonesIter zone; // Current zone to process, unless zone.done() unsigned kind; // Current alloc kind to process ArenaHeader *arena; // Next arena to process @@ -2390,16 +2386,25 @@ struct ArenasToUpdate bool ArenasToUpdate::shouldProcessKind(unsigned kind) { MOZ_ASSERT(kind < FINALIZE_LIMIT); - return - kind != FINALIZE_FAT_INLINE_STRING && - kind != FINALIZE_STRING && - kind != FINALIZE_EXTERNAL_STRING && - kind != FINALIZE_SYMBOL; + if (kind == FINALIZE_FAT_INLINE_STRING || + kind == FINALIZE_STRING || + kind == FINALIZE_EXTERNAL_STRING || + kind == FINALIZE_SYMBOL) + { + return false; + } + + if (kind > FINALIZE_OBJECT_LAST || js::gc::IsBackgroundFinalized(AllocKind(kind))) + return (kinds & BACKGROUND) != 0; + else + return (kinds & FOREGROUND) != 0; } -ArenasToUpdate::ArenasToUpdate(JSRuntime *rt) - : initialized(false), zone(rt, SkipAtoms) -{} +ArenasToUpdate::ArenasToUpdate(JSRuntime *rt, KindsToUpdate kinds) + : initialized(false), kinds(kinds), zone(rt, SkipAtoms) +{ + MOZ_ASSERT(kinds && !(kinds & ~ALL)); +} ArenaHeader * ArenasToUpdate::next() @@ -2526,20 +2531,23 @@ UpdateCellPointersTask::run() } // namespace js void -GCRuntime::updateAllCellPointersParallel(ArenasToUpdate &source) +GCRuntime::updateAllCellPointersParallel(MovingTracer *trc) { AutoDisableProxyCheck noProxyCheck(rt); // These checks assert when run in parallel. const size_t minTasks = 2; const size_t maxTasks = 8; unsigned taskCount = Min(Max(HelperThreadState().cpuCount / 2, minTasks), - maxTasks); + maxTasks) + 1; UpdateCellPointersTask updateTasks[maxTasks]; + ArenasToUpdate fgArenas(rt, ArenasToUpdate::FOREGROUND); + ArenasToUpdate bgArenas(rt, ArenasToUpdate::BACKGROUND); AutoLockHelperThreadState lock; unsigned i; - for (i = 0; i < taskCount && !source.done(); ++i) { - updateTasks[i].init(rt, &source, lock); + for (i = 0; i < taskCount && !bgArenas.done(); ++i) { + ArenasToUpdate *source = i == 0 ? &fgArenas : &bgArenas; + updateTasks[i].init(rt, source, lock); startTask(updateTasks[i], gcstats::PHASE_COMPACT_UPDATE_CELLS); } unsigned tasksStarted = i; @@ -2549,9 +2557,10 @@ GCRuntime::updateAllCellPointersParallel(ArenasToUpdate &source) } void -GCRuntime::updateAllCellPointersSerial(MovingTracer *trc, ArenasToUpdate &source) +GCRuntime::updateAllCellPointersSerial(MovingTracer *trc) { - while (ArenaHeader *arena = source.next()) + ArenasToUpdate allArenas(rt, ArenasToUpdate::ALL); + while (ArenaHeader *arena = allArenas.next()) UpdateCellPointers(trc, arena); } @@ -2580,11 +2589,10 @@ GCRuntime::updatePointersToRelocatedCells() // Iterate through all cells that can contain JSObject pointers to update // them. Since updating each cell is independent we try to parallelize this // as much as possible. - ArenasToUpdate source(rt); if (CanUseExtraThreads()) - updateAllCellPointersParallel(source); + updateAllCellPointersParallel(&trc); else - updateAllCellPointersSerial(&trc, source); + updateAllCellPointersSerial(&trc); // Mark roots to update them. { @@ -2697,12 +2705,10 @@ GCRuntime::releaseRelocatedArenasWithoutUnlocking(ArenaHeader *relocatedList, co } } -#endif // JSGC_COMPACTING - void GCRuntime::releaseHeldRelocatedArenas() { -#if defined(JSGC_COMPACTING) && defined(DEBUG) +#ifdef DEBUG // In debug mode we don't release relocated arenas straight away. Instead // we protect them and hold onto them until the next GC sweep phase to catch // any pointers to them that didn't get forwarded. @@ -5462,9 +5468,6 @@ GCRuntime::endSweepPhase(bool lastGC) bool GCRuntime::compactPhase(bool lastGC) { -#ifndef JSGC_COMPACTING - MOZ_CRASH(); -#else gcstats::AutoPhase ap(stats, gcstats::PHASE_COMPACT); if (isIncremental) { @@ -5529,8 +5532,6 @@ GCRuntime::compactPhase(bool lastGC) } } #endif - -#endif // JSGC_COMPACTING return true; } @@ -5690,7 +5691,6 @@ GCRuntime::resetIncrementalGC(const char *reason) break; } -#ifdef JSGC_COMPACTING case COMPACT: { { gcstats::AutoPhase ap(stats, gcstats::PHASE_WAIT_BACKGROUND_THREAD); @@ -5706,7 +5706,6 @@ GCRuntime::resetIncrementalGC(const char *reason) invocationKind = oldInvocationKind; break; } -#endif default: MOZ_CRASH("Invalid incremental GC state"); @@ -6394,7 +6393,7 @@ GCRuntime::onOutOfMallocMemory(const AutoLockGC &lock) { // Release any relocated arenas we may be holding on to, without releasing // the GC lock. -#if defined(JSGC_COMPACTING) && defined(DEBUG) +#ifdef DEBUG unprotectRelocatedArenas(relocatedArenasToRelease); releaseRelocatedArenasWithoutUnlocking(relocatedArenasToRelease, lock); relocatedArenasToRelease = nullptr; @@ -7115,19 +7114,13 @@ JS::IsIncrementalGCEnabled(JSRuntime *rt) JS_PUBLIC_API(void) JS::DisableCompactingGC(JSRuntime *rt) { -#ifdef JSGC_COMPACTING rt->gc.disableCompactingGC(); -#endif } JS_PUBLIC_API(bool) JS::IsCompactingGCEnabled(JSRuntime *rt) { -#ifdef JSGC_COMPACTING return rt->gc.isCompactingGCEnabled(); -#else - return false; -#endif } JS_PUBLIC_API(bool) diff --git a/js/src/jsgc.h b/js/src/jsgc.h index 0bd8f37e1982..7cb3c6ed1649 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -454,11 +454,9 @@ class ArenaList { return *this; } -#ifdef JSGC_COMPACTING ArenaHeader *removeRemainingArenas(ArenaHeader **arenap, const AutoLockGC &lock); ArenaHeader *pickArenasToRelocate(JSRuntime *runtime); ArenaHeader *relocateArenas(ArenaHeader *toRelocate, ArenaHeader *relocated); -#endif }; /* @@ -785,9 +783,7 @@ class ArenaLists MOZ_ASSERT(freeLists[kind].isEmpty()); } -#ifdef JSGC_COMPACTING ArenaHeader *relocateArenas(ArenaHeader *relocatedList); -#endif void queueForegroundObjectsForSweep(FreeOp *fop); void queueForegroundThingsForSweep(FreeOp *fop); @@ -1270,9 +1266,7 @@ inline void CheckGCThingAfterMovingGC(T *t) { MOZ_ASSERT_IF(t, !IsInsideNursery(t)); -#ifdef JSGC_COMPACTING MOZ_ASSERT_IF(t, !IsForwarded(t)); -#endif } inline void @@ -1429,16 +1423,11 @@ struct AutoDisableProxyCheck struct AutoDisableCompactingGC { -#ifdef JSGC_COMPACTING explicit AutoDisableCompactingGC(JSRuntime *rt); ~AutoDisableCompactingGC(); private: gc::GCRuntime &gc; -#else - explicit AutoDisableCompactingGC(JSRuntime *rt) {} - ~AutoDisableCompactingGC() {} -#endif }; void diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 8900558dc1be..0ea1d8d0dfa3 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -4891,8 +4891,6 @@ JSCompartment::sweepNewTypeObjectTable(NewTypeObjectTable &table) } } -#ifdef JSGC_COMPACTING - void JSCompartment::fixupNewTypeObjectTable(NewTypeObjectTable &table) { @@ -4966,8 +4964,6 @@ TypeObject::fixupAfterMovingGC() } } -#endif // JSGC_COMPACTING - #ifdef JSGC_HASH_TABLE_CHECKS void diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index 3d10cbae2961..b8b1d46751cb 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -293,7 +293,7 @@ public: }; /* Flags and other state stored in TypeSet::flags */ -enum MOZ_ENUM_TYPE(uint32_t) { +enum : uint32_t { TYPE_FLAG_UNDEFINED = 0x1, TYPE_FLAG_NULL = 0x2, TYPE_FLAG_BOOLEAN = 0x4, @@ -352,7 +352,7 @@ enum MOZ_ENUM_TYPE(uint32_t) { typedef uint32_t TypeFlags; /* Flags and other state stored in TypeObject::flags */ -enum MOZ_ENUM_TYPE(uint32_t) { +enum : uint32_t { /* Whether this type object is associated with some allocation site. */ OBJECT_FLAG_FROM_ALLOCATION_SITE = 0x1, @@ -925,10 +925,7 @@ class TypeNewScript void trace(JSTracer *trc); void sweep(); - -#ifdef JSGC_COMPACTING void fixupAfterMovingGC(); -#endif void registerNewObject(PlainObject *res); void unregisterNewObject(PlainObject *res); @@ -1241,9 +1238,7 @@ struct TypeObject : public gc::TenuredCell flags_ |= generation << OBJECT_FLAG_GENERATION_SHIFT; } -#ifdef JSGC_COMPACTING void fixupAfterMovingGC(); -#endif size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const; diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 6eea5ebb399e..9dc13a923a68 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -1232,32 +1232,10 @@ NewObject(ExclusiveContext *cx, types::TypeObject *type_, JSObject *parent, gc:: obj = nobj; } - /* - * This will cancel an already-running incremental GC from doing any more - * slices, and it will prevent any future incremental GCs. - */ bool globalWithoutCustomTrace = clasp->trace == JS_GlobalObjectTraceHook && !cx->compartment()->options().getTrace(); - if (clasp->trace && - !globalWithoutCustomTrace && - !(clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS)) - { - if (!cx->shouldBeJSContext()) - return nullptr; - JSRuntime *rt = cx->asJSContext()->runtime(); - rt->gc.disallowIncrementalGC(); - -#ifdef DEBUG - if (rt->gc.gcMode() == JSGC_MODE_INCREMENTAL) { - fprintf(stderr, - "The class %s has a trace hook but does not declare the\n" - "JSCLASS_IMPLEMENTS_BARRIERS flag. Please ensure that it correctly\n" - "implements write barriers and then set the flag.\n", - clasp->name); - MOZ_CRASH(); - } -#endif - } + if (clasp->trace && !globalWithoutCustomTrace) + MOZ_RELEASE_ASSERT(clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS); probes::CreateObject(cx, obj); return obj; @@ -2928,13 +2906,18 @@ js::NonProxyLookupOwnProperty(JSContext *cx, LookupGenericOp lookup, MaybeRooted::template downcastHandle(obj); bool done; - if (!LookupOwnPropertyInline(cx, nobj, id, objp, propp, &done)) + if (!LookupOwnPropertyInline(cx, nobj, id, propp, &done)) return false; if (!done) { objp.set(nullptr); propp.set(nullptr); return true; } + + if (propp) + objp.set(obj); + else + objp.set(nullptr); } if (!propp) diff --git a/js/src/jspropertytree.cpp b/js/src/jspropertytree.cpp index 9a3d005c4b71..8dcb4b6ebbd4 100644 --- a/js/src/jspropertytree.cpp +++ b/js/src/jspropertytree.cpp @@ -235,8 +235,6 @@ Shape::finalize(FreeOp *fop) fop->delete_(kids.toHash()); } -#ifdef JSGC_COMPACTING - void Shape::fixupDictionaryShapeAfterMovingGC() { @@ -322,8 +320,6 @@ Shape::fixupAfterMovingGC() fixupShapeTreeAfterMovingGC(); } -#endif // JSGC_COMPACTING - void ShapeGetterSetterRef::mark(JSTracer *trc) { diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index be8894f126ea..15e83e6e752e 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -20,8 +20,7 @@ #include "js/TypeDecls.h" -#if (defined(JS_GC_ZEAL)) || \ - (defined(JSGC_COMPACTING) && defined(DEBUG)) +#if (defined(JS_GC_ZEAL)) || defined(DEBUG) # define JSGC_HASH_TABLE_CHECKS #endif diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 35fdc2047490..59a6ef3a5f2a 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -357,6 +357,12 @@ ShellInterruptCallback(JSContext *cx) if (!gServiceInterrupt) return true; + // Reset gServiceInterrupt. CancelExecution or InterruptIf will set it to + // true to distinguish watchdog or user triggered interrupts. + // Do this first to prevent other interrupts that may occur while the + // user-supplied callback is executing from re-entering the handler. + gServiceInterrupt = false; + bool result; RootedValue interruptFunc(cx, *gInterruptFunc); if (!interruptFunc.isNull()) { @@ -379,10 +385,6 @@ ShellInterruptCallback(JSContext *cx) if (!result && gExitCode == 0) gExitCode = EXITCODE_TIMEOUT; - // Reset gServiceInterrupt. CancelExecution or InterruptIf will set it to - // true to distinguish watchdog or user triggered interrupts. - gServiceInterrupt = false; - return result; } diff --git a/js/src/tests/js1_8_5/extensions/reflect-parse.js b/js/src/tests/js1_8_5/extensions/reflect-parse.js index 7e7d73c22594..d3cade96f0e1 100644 --- a/js/src/tests/js1_8_5/extensions/reflect-parse.js +++ b/js/src/tests/js1_8_5/extensions/reflect-parse.js @@ -112,6 +112,11 @@ function compOfBlock(left, right) Pattern({ type: "ComprehensionBlock", left: le function arrPatt(elts) Pattern({ type: "ArrayPattern", elements: elts }) function objPatt(elts) Pattern({ type: "ObjectPattern", properties: elts }) +function assignElem(target, defaultExpr = null, targetIdent = typeof target == 'string' ? ident(target) : target) defaultExpr ? aExpr('=', targetIdent, defaultExpr) : targetIdent +function assignProp(property, target, defaultExpr = null, shorthand = !target, targetProp = target || ident(property)) Pattern({ + type: "Property", key: ident(property), shorthand, + value: defaultExpr ? aExpr('=', targetProp, defaultExpr) : targetProp }) + function localSrc(src) "(function(){ " + src + " })" function localPatt(patt) program([exprStmt(funExpr(null, [], blockStmt([patt])))]) function blockSrc(src) "(function(){ { " + src + " } })" @@ -235,7 +240,7 @@ assertDecl("function f(a,b,c) { function b() { } }", funDecl(ident("f"), [ident("a"),ident("b"),ident("c")], blockStmt([funDecl(ident("b"), [], blockStmt([]))]))); assertDecl("function f(a,[x,y]) { function a() { } }", funDecl(ident("f"), - [ident("a"), arrPatt([ident("x"), ident("y")])], + [ident("a"), arrPatt([assignElem("x"), assignElem("y")])], blockStmt([funDecl(ident("a"), [], blockStmt([]))]))); // Bug 632027: array holes should reflect as null @@ -269,7 +274,7 @@ assertExpr("a => b => a", arrowExpr([ident("a")], arrowExpr([ident("b")], ident( assertExpr("a => {}", arrowExpr([ident("a")], blockStmt([]))); assertExpr("a => ({})", arrowExpr([ident("a")], objExpr([]))); assertExpr("(a, b, c) => {}", arrowExpr([ident("a"), ident("b"), ident("c")], blockStmt([]))); -assertExpr("([a, b]) => {}", arrowExpr([arrPatt([ident("a"), ident("b")])], blockStmt([]))); +assertExpr("([a, b]) => {}", arrowExpr([arrPatt([assignElem("a"), assignElem("b")])], blockStmt([]))); assertExpr("(++x)", updExpr("++", ident("x"), true)); assertExpr("(x++)", updExpr("++", ident("x"), false)); assertExpr("(+x)", unExpr("+", ident("x"))); @@ -566,9 +571,9 @@ assertStmt("function f() { var x = 42; var x = 43; }", varDecl([{ id: ident("x"), init: lit(43) }])]))); -assertDecl("var {x:y} = foo;", varDecl([{ id: objPatt([{ key: ident("x"), value: ident("y"), shorthand: false }]), +assertDecl("var {x:y} = foo;", varDecl([{ id: objPatt([assignProp("x", ident("y"))]), init: ident("foo") }])); -assertDecl("var {x} = foo;", varDecl([{ id: objPatt([{ key: ident("x"), value: ident("x"), shorthand: true }]), +assertDecl("var {x} = foo;", varDecl([{ id: objPatt([assignProp("x")]), init: ident("foo") }])); // Bug 632030: redeclarations between var and funargs, var and function @@ -581,16 +586,16 @@ assertProg("f.p = 1; var f; f.p; function f(){}", funDecl(ident("f"), [], blockStmt([]))]); // global let is var -assertGlobalDecl("let {x:y} = foo;", varDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]), +assertGlobalDecl("let {x:y} = foo;", varDecl([{ id: objPatt([assignProp("x", ident("y"))]), init: ident("foo") }])); // function-global let is let -assertLocalDecl("let {x:y} = foo;", letDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]), +assertLocalDecl("let {x:y} = foo;", letDecl([{ id: objPatt([assignProp("x", ident("y"))]), init: ident("foo") }])); // block-local let is let -assertBlockDecl("let {x:y} = foo;", letDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]), +assertBlockDecl("let {x:y} = foo;", letDecl([{ id: objPatt([assignProp("x", ident("y"))]), init: ident("foo") }])); -assertDecl("const {x:y} = foo;", constDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]), +assertDecl("const {x:y} = foo;", constDecl([{ id: objPatt([assignProp("x", ident("y"))]), init: ident("foo") }])); @@ -670,16 +675,23 @@ function testParamPatternCombinations(makePattSrc, makePattPatt) { } testParamPatternCombinations(function(n) ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "}"), - function(n) (objPatt([{ key: ident("a" + n), value: ident("x" + n) }, - { key: ident("b" + n), value: ident("y" + n) }, - { key: ident("c" + n), value: ident("z" + n) }]))); + function(n) (objPatt([assignProp("a" + n, ident("x" + n)), + assignProp("b" + n, ident("y" + n)), + assignProp("c" + n, ident("z" + n))]))); + +testParamPatternCombinations(function(n) ("{a" + n + ":x" + n + " = 10," + "b" + n + ":y" + n + " = 10," + "c" + n + ":z" + n + " = 10}"), + function(n) (objPatt([assignProp("a" + n, ident("x" + n), lit(10)), + assignProp("b" + n, ident("y" + n), lit(10)), + assignProp("c" + n, ident("z" + n), lit(10))]))); testParamPatternCombinations(function(n) ("[x" + n + "," + "y" + n + "," + "z" + n + "]"), - function(n) (arrPatt([ident("x" + n), ident("y" + n), ident("z" + n)]))); + function(n) (arrPatt([assignElem("x" + n), assignElem("y" + n), assignElem("z" + n)]))); testParamPatternCombinations(function(n) ("[a" + n + ", ..." + "b" + n + "]"), - function(n) (arrPatt([ident("a" + n), spread(ident("b" + n))]))); + function(n) (arrPatt([assignElem("a" + n), spread(ident("b" + n))]))); +testParamPatternCombinations(function(n) ("[a" + n + ", " + "b" + n + " = 10]"), + function(n) (arrPatt([assignElem("a" + n), assignElem("b" + n, lit(10))]))); // destructuring variable declarations @@ -712,19 +724,28 @@ function testVarPatternCombinations(makePattSrc, makePattPatt) { } testVarPatternCombinations(function (n) ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "} = 0"), - function (n) ({ id: objPatt([{ key: ident("a" + n), value: ident("x" + n) }, - { key: ident("b" + n), value: ident("y" + n) }, - { key: ident("c" + n), value: ident("z" + n) }]), + function (n) ({ id: objPatt([assignProp("a" + n, ident("x" + n)), + assignProp("b" + n, ident("y" + n)), + assignProp("c" + n, ident("z" + n))]), + init: lit(0) })); + +testVarPatternCombinations(function (n) ("{a" + n + ":x" + n + " = 10," + "b" + n + ":y" + n + " = 10," + "c" + n + ":z" + n + " = 10} = 0"), + function (n) ({ id: objPatt([assignProp("a" + n, ident("x" + n), lit(10)), + assignProp("b" + n, ident("y" + n), lit(10)), + assignProp("c" + n, ident("z" + n), lit(10))]), init: lit(0) })); testVarPatternCombinations(function(n) ("[x" + n + "," + "y" + n + "," + "z" + n + "] = 0"), - function(n) ({ id: arrPatt([ident("x" + n), ident("y" + n), ident("z" + n)]), + function(n) ({ id: arrPatt([assignElem("x" + n), assignElem("y" + n), assignElem("z" + n)]), init: lit(0) })); testVarPatternCombinations(function(n) ("[a" + n + ", ..." + "b" + n + "] = 0"), - function(n) ({ id: arrPatt([ident("a" + n), spread(ident("b" + n))]), + function(n) ({ id: arrPatt([assignElem("a" + n), spread(ident("b" + n))]), init: lit(0) })); +testVarPatternCombinations(function(n) ("[a" + n + ", " + "b" + n + " = 10] = 0"), + function(n) ({ id: arrPatt([assignElem("a" + n), assignElem("b" + n, lit(10))]), + init: lit(0) })); // destructuring assignment function testAssignmentCombinations(makePattSrc, makePattPatt) { @@ -746,18 +767,18 @@ function testAssignmentCombinations(makePattSrc, makePattPatt) { testAssignmentCombinations(function (n) ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "} = 0"), function (n) (aExpr("=", - objPatt([{ key: ident("a" + n), value: ident("x" + n) }, - { key: ident("b" + n), value: ident("y" + n) }, - { key: ident("c" + n), value: ident("z" + n) }]), + objPatt([assignProp("a" + n, ident("x" + n)), + assignProp("b" + n, ident("y" + n)), + assignProp("c" + n, ident("z" + n))]), lit(0)))); // destructuring in for-in and for-each-in loop heads -var axbycz = objPatt([{ key: ident("a"), value: ident("x") }, - { key: ident("b"), value: ident("y") }, - { key: ident("c"), value: ident("z") }]); -var xyz = arrPatt([ident("x"), ident("y"), ident("z")]); +var axbycz = objPatt([assignProp("a", ident("x")), + assignProp("b", ident("y")), + assignProp("c", ident("z"))]); +var xyz = arrPatt([assignElem("x"), assignElem("y"), assignElem("z")]); assertStmt("for (var {a:x,b:y,c:z} in foo);", forInStmt(varDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); assertStmt("for (let {a:x,b:y,c:z} in foo);", forInStmt(letDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); diff --git a/js/src/vm/NativeObject-inl.h b/js/src/vm/NativeObject-inl.h index 96a99a9be795..3a0d8f8d9bd3 100644 --- a/js/src/vm/NativeObject-inl.h +++ b/js/src/vm/NativeObject-inl.h @@ -400,38 +400,30 @@ NewNativeObjectWithClassProto(ExclusiveContext *cx, const js::Class *clasp, JSOb /* * Call obj's resolve hook. * - * cx, id, and flags are the parameters initially passed to the ongoing lookup; - * objp and propp are its out parameters. obj is an object along the prototype - * chain from where the lookup started. + * cx and id are the parameters initially passed to the ongoing lookup; + * propp and recursedp are its out parameters. * * There are four possible outcomes: * * - On failure, report an error or exception and return false. * - * - If we are already resolving a property of *curobjp, set *recursedp = true, + * - If we are already resolving a property of obj, set *recursedp = true, * and return true. * - * - If the resolve hook finds or defines the sought property, set *objp and - * *propp appropriately, set *recursedp = false, and return true. + * - If the resolve hook finds or defines the sought property, set propp + * appropriately, set *recursedp = false, and return true. * - * - Otherwise no property was resolved. Set *propp = nullptr and + * - Otherwise no property was resolved. Set propp to nullptr and * *recursedp = false and return true. */ static MOZ_ALWAYS_INLINE bool -CallResolveOp(JSContext *cx, HandleNativeObject obj, HandleId id, MutableHandleObject objp, - MutableHandleShape propp, bool *recursedp) +CallResolveOp(JSContext *cx, HandleNativeObject obj, HandleId id, MutableHandleShape propp, + bool *recursedp) { - /* - * Avoid recursion on (obj, id) already being resolved on cx. - * - * Once we have successfully added an entry for (obj, key) to - * cx->resolvingTable, control must go through cleanup: before - * returning. But note that JS_DHASH_ADD may find an existing - * entry, in which case we bail to suppress runaway recursion. - */ + // Avoid recursion on (obj, id) already being resolved on cx. AutoResolving resolving(cx, obj, id); if (resolving.alreadyStarted()) { - /* Already resolving id in obj -- suppress recursion. */ + // Already resolving id in obj, suppress recursion. *recursedp = true; return true; } @@ -444,18 +436,14 @@ CallResolveOp(JSContext *cx, HandleNativeObject obj, HandleId id, MutableHandleO if (!resolved) return true; - objp.set(obj); - if (JSID_IS_INT(id) && obj->containsDenseElement(JSID_TO_INT(id))) { MarkDenseOrTypedArrayElementFound(propp); return true; } - if (Shape *shape = obj->lookup(cx, id)) - propp.set(shape); - else - objp.set(nullptr); + MOZ_ASSERT(!IsAnyTypedArray(obj)); + propp.set(obj->lookup(cx, id)); return true; } @@ -464,13 +452,11 @@ static MOZ_ALWAYS_INLINE bool LookupOwnPropertyInline(ExclusiveContext *cx, typename MaybeRooted::HandleType obj, typename MaybeRooted::HandleType id, - typename MaybeRooted::MutableHandleType objp, typename MaybeRooted::MutableHandleType propp, bool *donep) { // Check for a native dense element. if (JSID_IS_INT(id) && obj->containsDenseElement(JSID_TO_INT(id))) { - objp.set(obj); MarkDenseOrTypedArrayElementFound(propp); *donep = true; return true; @@ -483,10 +469,8 @@ LookupOwnPropertyInline(ExclusiveContext *cx, uint64_t index; if (IsTypedArrayIndex(id, &index)) { if (index < AnyTypedArrayLength(obj)) { - objp.set(obj); MarkDenseOrTypedArrayElementFound(propp); } else { - objp.set(nullptr); propp.set(nullptr); } *donep = true; @@ -496,7 +480,6 @@ LookupOwnPropertyInline(ExclusiveContext *cx, // Check for a native property. if (Shape *shape = obj->lookup(cx, id)) { - objp.set(obj); propp.set(shape); *donep = true; return true; @@ -512,7 +495,6 @@ LookupOwnPropertyInline(ExclusiveContext *cx, if (!CallResolveOp(cx->asJSContext(), MaybeRooted::toHandle(obj), MaybeRooted::toHandle(id), - MaybeRooted::toMutableHandle(objp), MaybeRooted::toMutableHandle(propp), &recursed)) { @@ -520,7 +502,6 @@ LookupOwnPropertyInline(ExclusiveContext *cx, } if (recursed) { - objp.set(nullptr); propp.set(nullptr); *donep = true; return true; @@ -532,6 +513,7 @@ LookupOwnPropertyInline(ExclusiveContext *cx, } } + propp.set(nullptr); *donep = false; return true; } @@ -584,10 +566,15 @@ LookupPropertyInline(ExclusiveContext *cx, while (true) { bool done; - if (!LookupOwnPropertyInline(cx, current, id, objp, propp, &done)) + if (!LookupOwnPropertyInline(cx, current, id, propp, &done)) return false; - if (done) + if (done) { + if (propp) + objp.set(current); + else + objp.set(nullptr); return true; + } typename MaybeRooted::RootType proto(cx, current->getProto()); diff --git a/js/src/vm/NativeObject.cpp b/js/src/vm/NativeObject.cpp index b56df98e56ac..0277e9aa4dbd 100644 --- a/js/src/vm/NativeObject.cpp +++ b/js/src/vm/NativeObject.cpp @@ -1458,14 +1458,8 @@ static bool NativeLookupOwnProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id, MutableHandle shapep) { - RootedObject pobj(cx); bool done; - - if (!LookupOwnPropertyInline(cx, obj, id, &pobj, shapep, &done)) - return false; - if (!done || pobj != obj) - shapep.set(nullptr); - return true; + return LookupOwnPropertyInline(cx, obj, id, shapep, &done); } template @@ -2072,13 +2066,9 @@ js::NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiv for (;;) { // Steps 2-3. ('done' is a SpiderMonkey-specific thing, used below.) bool done; - RootedObject ancestor(cx); - if (!LookupOwnPropertyInline(cx, pobj, id, &ancestor, &shape, &done)) + if (!LookupOwnPropertyInline(cx, pobj, id, &shape, &done)) return false; - if (!done || ancestor != pobj) - shape = nullptr; - if (shape) { // Steps 5-6. return SetExistingProperty(cx, obj, receiver, id, pobj, shape, vp, strict); diff --git a/js/src/vm/Shape-inl.h b/js/src/vm/Shape-inl.h index a17755fed1ce..0b5c3ebeb807 100644 --- a/js/src/vm/Shape-inl.h +++ b/js/src/vm/Shape-inl.h @@ -224,14 +224,12 @@ GetShapeAttributes(JSObject *obj, Shape *shape) return shape->attributes(); } -#ifdef JSGC_COMPACTING inline void BaseShape::fixupAfterMovingGC() { if (hasTable()) table().fixupAfterMovingGC(); } -#endif } /* namespace js */ diff --git a/js/src/vm/Shape.cpp b/js/src/vm/Shape.cpp index 70b86fbb4505..5caf797d9287 100644 --- a/js/src/vm/Shape.cpp +++ b/js/src/vm/Shape.cpp @@ -256,7 +256,6 @@ ShapeTable::search(jsid id, bool adding) MOZ_CRASH("Shape::search failed to find an expected entry."); } -#ifdef JSGC_COMPACTING void ShapeTable::fixupAfterMovingGC() { @@ -268,7 +267,6 @@ ShapeTable::fixupAfterMovingGC() entry.setPreservingCollision(Forwarded(shape)); } } -#endif bool ShapeTable::change(int log2Delta, ExclusiveContext *cx) @@ -1693,7 +1691,6 @@ JSCompartment::sweepInitialShapeTable() } } -#ifdef JSGC_COMPACTING void JSCompartment::fixupInitialShapeTable() { @@ -1732,7 +1729,6 @@ JSCompartment::fixupInitialShapeTable() } } } -#endif // JSGC_COMPACTING void AutoRooterGetterSetter::Inner::trace(JSTracer *trc) diff --git a/js/src/vm/Shape.h b/js/src/vm/Shape.h index 37cf4e15fa74..a7416b02673d 100644 --- a/js/src/vm/Shape.h +++ b/js/src/vm/Shape.h @@ -227,10 +227,8 @@ class ShapeTable { bool change(int log2Delta, ExclusiveContext *cx); Entry &search(jsid id, bool adding); -#ifdef JSGC_COMPACTING /* Update entries whose shapes have been moved */ void fixupAfterMovingGC(); -#endif private: Entry &getEntry(uint32_t i) const { @@ -530,9 +528,7 @@ class BaseShape : public gc::TenuredCell gc::MarkObject(trc, &metadata, "metadata"); } -#ifdef JSGC_COMPACTING void fixupAfterMovingGC(); -#endif private: static void staticAsserts() { @@ -1061,9 +1057,7 @@ class Shape : public gc::TenuredCell inline Shape *search(ExclusiveContext *cx, jsid id); inline Shape *searchLinear(jsid id); -#ifdef JSGC_COMPACTING void fixupAfterMovingGC(); -#endif /* For JIT usage */ static inline size_t offsetOfBase() { return offsetof(Shape, base_); } @@ -1071,10 +1065,8 @@ class Shape : public gc::TenuredCell static inline uint32_t fixedSlotsMask() { return FIXED_SLOTS_MASK; } private: -#ifdef JSGC_COMPACTING void fixupDictionaryShapeAfterMovingGC(); void fixupShapeTreeAfterMovingGC(); -#endif static void staticAsserts() { JS_STATIC_ASSERT(offsetof(Shape, base_) == offsetof(js::shadow::Shape, base)); diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp index 1ce3b9cc67f6..e3adc3246dca 100644 --- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -65,7 +65,7 @@ using JS::CanonicalizeNaN; // a stable ID, it need not be at the end of the list and should not be used for // sizing data structures. -enum StructuredDataType MOZ_ENUM_TYPE(uint32_t) { +enum StructuredDataType : uint32_t { /* Structured data types provided by the engine */ SCTAG_FLOAT_MAX = 0xFFF00000, SCTAG_NULL = 0xFFFF0000, diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index da7304faaaab..80cfb1454872 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -1065,9 +1065,12 @@ public: static void TraceWrappedNativesInAllScopes(JSTracer* trc, XPCJSRuntime* rt); - void TraceInside(JSTracer *trc) { + void TraceSelf(JSTracer *trc) { MOZ_ASSERT(mGlobalJSObject); mGlobalJSObject.trace(trc, "XPCWrappedNativeScope::mGlobalJSObject"); + } + + void TraceInside(JSTracer *trc) { if (mContentXBLScope) mContentXBLScope.trace(trc, "XPCWrappedNativeScope::mXBLScope"); for (size_t i = 0; i < mAddonScopes.Length(); i++) @@ -1847,7 +1850,7 @@ public: mScriptableInfo->Mark(); } - GetScope()->TraceInside(trc); + GetScope()->TraceSelf(trc); } void TraceJS(JSTracer *trc) { @@ -2162,7 +2165,7 @@ public: if (HasProto()) GetProto()->TraceSelf(trc); else - GetScope()->TraceInside(trc); + GetScope()->TraceSelf(trc); if (mFlatJSObject && JS_IsGlobalObject(mFlatJSObject)) { xpc::TraceXPCGlobal(trc, mFlatJSObject); diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index eccbbd03387b..b1ed38498adf 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -2343,11 +2343,14 @@ ContainerState::PopPaintedLayerData() EventRegions regions; regions.mHitRegion = ScaleRegionToOutsidePixels(data->mHitRegion); // Points whose hit-region status we're not sure about need to be dispatched - // to the content thread. + // to the content thread. If a point is in both maybeHitRegion and hitRegion + // then it's not a "maybe" any more, and doesn't go into the dispatch-to- + // content region. nsIntRegion maybeHitRegion = ScaleRegionToOutsidePixels(data->mMaybeHitRegion); regions.mDispatchToContentHitRegion.Sub(maybeHitRegion, regions.mHitRegion); - regions.mDispatchToContentHitRegion.Or(regions.mDispatchToContentHitRegion, - ScaleRegionToOutsidePixels(data->mDispatchToContentHitRegion)); + regions.mDispatchToContentHitRegion.OrWith( + ScaleRegionToOutsidePixels(data->mDispatchToContentHitRegion)); + regions.mHitRegion.OrWith(maybeHitRegion); nsIntPoint translation = -GetTranslationForPaintedLayer(data->mLayer); regions.mHitRegion.MoveBy(translation); diff --git a/layout/forms/moz.build b/layout/forms/moz.build index bd961dad0d16..a77aa5f31db3 100644 --- a/layout/forms/moz.build +++ b/layout/forms/moz.build @@ -56,8 +56,4 @@ LOCAL_INCLUDES += [ if CONFIG['ENABLE_INTL_API']: # nsNumberControlFrame.cpp requires ICUUtils.h which in turn requires # i18n/unum.h - LOCAL_INCLUDES += [ - '../../intl/icu/source/common', - '../../intl/icu/source/i18n', - ] - + CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS'] diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index 175013a135b9..b59dcd8116f8 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -1469,7 +1469,7 @@ void nsDisplayComboboxFocus::Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) { static_cast(mFrame) - ->PaintFocus(*aCtx, ToReferenceFrame()); + ->PaintFocus(*aCtx->GetDrawTarget(), ToReferenceFrame()); } void @@ -1511,7 +1511,7 @@ nsComboboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, DisplaySelectionOverlay(aBuilder, aLists.Content()); } -void nsComboboxControlFrame::PaintFocus(nsRenderingContext& aRenderingContext, +void nsComboboxControlFrame::PaintFocus(DrawTarget& aDrawTarget, nsPoint aPt) { /* Do we need to do anything? */ @@ -1519,13 +1519,12 @@ void nsComboboxControlFrame::PaintFocus(nsRenderingContext& aRenderingContext, if (eventStates.HasState(NS_EVENT_STATE_DISABLED) || sFocused != this) return; - gfxContext* gfx = aRenderingContext.ThebesContext(); + int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel(); - gfx->Save(); nsRect clipRect = mDisplayFrame->GetRect() + aPt; - gfx->Clip(NSRectToSnappedRect(clipRect, - PresContext()->AppUnitsPerDevPixel(), - *aRenderingContext.GetDrawTarget())); + aDrawTarget.PushClipRect(NSRectToSnappedRect(clipRect, + appUnitsPerDevPixel, + aDrawTarget)); // REVIEW: Why does the old code paint mDisplayFrame again? We've // already painted it in the children above. So clipping it here won't do @@ -1540,12 +1539,10 @@ void nsComboboxControlFrame::PaintFocus(nsRenderingContext& aRenderingContext, nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1); clipRect.width -= onePixel; clipRect.height -= onePixel; - Rect r = - ToRect(nsLayoutUtils::RectToGfxRect(clipRect, PresContext()->AppUnitsPerDevPixel())); - StrokeSnappedEdgesOfRect(r, *aRenderingContext.GetDrawTarget(), - color, strokeOptions); + Rect r = ToRect(nsLayoutUtils::RectToGfxRect(clipRect, appUnitsPerDevPixel)); + StrokeSnappedEdgesOfRect(r, aDrawTarget, color, strokeOptions); - gfx->Restore(); + aDrawTarget.PopClip(); } //--------------------------------------------------------- diff --git a/layout/forms/nsComboboxControlFrame.h b/layout/forms/nsComboboxControlFrame.h index cfa29eb2265a..39fa6ce82d4b 100644 --- a/layout/forms/nsComboboxControlFrame.h +++ b/layout/forms/nsComboboxControlFrame.h @@ -37,6 +37,12 @@ class nsComboboxDisplayFrame; class nsIDOMEventListener; class nsIScrollableFrame; +namespace mozilla { +namespace gfx { +class DrawTarget; +} +} + class nsComboboxControlFrame MOZ_FINAL : public nsBlockFrame, public nsIFormControlFrame, public nsIComboboxControlFrame, @@ -45,6 +51,8 @@ class nsComboboxControlFrame MOZ_FINAL : public nsBlockFrame, public nsIRollupListener, public nsIStatefulFrame { + typedef mozilla::gfx::DrawTarget DrawTarget; + public: friend nsContainerFrame* NS_NewComboboxControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, @@ -84,7 +92,7 @@ public: const nsRect& aDirtyRect, const nsDisplayListSet& aLists) MOZ_OVERRIDE; - void PaintFocus(nsRenderingContext& aRenderingContext, nsPoint aPt); + void PaintFocus(DrawTarget& aDrawTarget, nsPoint aPt); // XXXbz this is only needed to prevent the quirk percent height stuff from // leaking out of the combobox. We may be able to get rid of this as more diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp index cbd60543e193..927bfe5636e9 100644 --- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -2916,8 +2916,9 @@ void SVGTextDrawPathCallbacks::HandleTextGeometry() { if (IsClipPathChild()) { - gfx->SetColor(gfxRGBA(1.0f, 1.0f, 1.0f, 1.0f)); - gfx->Fill(); + RefPtr path = gfx->GetPath(); + ColorPattern white(Color(1.f, 1.f, 1.f, 1.f)); // for masking, so no ToDeviceColor + gfx->GetDrawTarget()->Fill(path, white); } else { // Normal painting. gfxContextMatrixAutoSaveRestore saveMatrix(gfx); @@ -2984,11 +2985,15 @@ SVGTextDrawPathCallbacks::FillGeometry() GeneralPattern fillPattern; MakeFillPattern(&fillPattern); if (fillPattern.GetPattern()) { - gfx->SetFillRule( - nsSVGUtils::ToFillRule( - IsClipPathChild() ? - mFrame->StyleSVG()->mClipRule : mFrame->StyleSVG()->mFillRule)); - gfx->Fill(fillPattern); + RefPtr path = gfx->GetPath(); + FillRule fillRule = nsSVGUtils::ToFillRule(IsClipPathChild() ? + mFrame->StyleSVG()->mClipRule : + mFrame->StyleSVG()->mFillRule); + if (fillRule != path->GetFillRule()) { + RefPtr builder = path->CopyToBuilder(fillRule); + path = builder->Finish(); + } + gfx->GetDrawTarget()->Fill(path, fillPattern); } } diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp index b8112fe2f65d..34b1c46136d8 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp @@ -468,20 +468,32 @@ PeerConnectionImpl::ConvertRTCConfiguration(const RTCConfiguration& aSrc, IceConfiguration *aDst) { #ifdef MOZILLA_INTERNAL_API - if (!aSrc.mIceServers.WasPassed()) { - return NS_OK; + if (aSrc.mIceServers.WasPassed()) { + for (size_t i = 0; i < aSrc.mIceServers.Value().Length(); i++) { + nsresult rv = AddIceServer(aSrc.mIceServers.Value()[i], aDst); + NS_ENSURE_SUCCESS(rv, rv); + } } - for (uint32_t i = 0; i < aSrc.mIceServers.Value().Length(); i++) { - const RTCIceServer& server = aSrc.mIceServers.Value()[i]; - NS_ENSURE_TRUE(server.mUrl.WasPassed(), NS_ERROR_UNEXPECTED); +#endif + return NS_OK; +} +nsresult +PeerConnectionImpl::AddIceServer(const RTCIceServer &aServer, + IceConfiguration *aDst) +{ +#ifdef MOZILLA_INTERNAL_API + NS_ENSURE_STATE(aServer.mUrls.WasPassed()); + NS_ENSURE_STATE(aServer.mUrls.Value().IsStringSequence()); + auto &urls = aServer.mUrls.Value().GetAsStringSequence(); + for (size_t i = 0; i < urls.Length(); i++) { // Without STUN/TURN handlers, NS_NewURI returns nsSimpleURI rather than // nsStandardURL. To parse STUN/TURN URI's to spec // http://tools.ietf.org/html/draft-nandakumar-rtcweb-stun-uri-02#section-3 // http://tools.ietf.org/html/draft-petithuguenin-behave-turn-uri-03#section-3 // we parse out the query-string, and use ParseAuthority() on the rest nsRefPtr url; - nsresult rv = NS_NewURI(getter_AddRefs(url), server.mUrl.Value()); + nsresult rv = NS_NewURI(getter_AddRefs(url), urls[i]); NS_ENSURE_SUCCESS(rv, rv); bool isStun = false, isStuns = false, isTurn = false, isTurns = false; url->SchemeIs("stun", &isStun); @@ -542,8 +554,8 @@ PeerConnectionImpl::ConvertRTCConfiguration(const RTCConfiguration& aSrc, port = (isStuns || isTurns)? 5349 : 3478; if (isTurn || isTurns) { - NS_ConvertUTF16toUTF8 credential(server.mCredential); - NS_ConvertUTF16toUTF8 username(server.mUsername); + NS_ConvertUTF16toUTF8 credential(aServer.mCredential); + NS_ConvertUTF16toUTF8 username(aServer.mUsername); // Bug 1039655 - TURN TCP is not e10s ready if ((transport == kNrIceTransportTcp) && diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h index c95f36e0c31e..5ddad70707ee 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h @@ -78,6 +78,7 @@ class DOMMediaStream; namespace dom { struct RTCConfiguration; +struct RTCIceServer; struct RTCOfferOptions; #ifdef USE_FAKE_MEDIA_STREAMS typedef Fake_MediaStreamTrack MediaStreamTrack; @@ -118,6 +119,7 @@ namespace mozilla { using mozilla::dom::PeerConnectionObserver; using mozilla::dom::RTCConfiguration; +using mozilla::dom::RTCIceServer; using mozilla::dom::RTCOfferOptions; using mozilla::DOMMediaStream; using mozilla::NrIceCtx; @@ -259,6 +261,8 @@ public: static PeerConnectionImpl* CreatePeerConnection(); static nsresult ConvertRTCConfiguration(const RTCConfiguration& aSrc, IceConfiguration *aDst); + static nsresult AddIceServer(const RTCIceServer& aServer, + IceConfiguration* aDst); already_AddRefed MakeMediaStream(uint32_t aHint); nsresult CreateRemoteSourceStreamInfo(nsRefPtr* aInfo, diff --git a/mfbt/TypedEnum.h b/mfbt/TypedEnum.h index 31215151931d..9c8d9b49e46b 100644 --- a/mfbt/TypedEnum.h +++ b/mfbt/TypedEnum.h @@ -14,31 +14,6 @@ #if defined(__cplusplus) -/** - * MOZ_ENUM_TYPE specifies the underlying numeric type for an enum. It's - * specified by placing MOZ_ENUM_TYPE(type) immediately after the enum name in - * its declaration, and before the opening curly brace, like - * - * enum MyEnum MOZ_ENUM_TYPE(uint16_t) - * { - * A, - * B = 7, - * C - * }; - * - * In supporting compilers, the macro will expand to ": uint16_t". The - * compiler will allocate exactly two bytes for MyEnum and will require all - * enumerators to have values between 0 and 65535. (Thus specifying "B = - * 100000" instead of "B = 7" would fail to compile.) In old compilers the - * macro expands to the empty string, and the underlying type is generally - * undefined. - */ -#ifdef MOZ_HAVE_CXX11_ENUM_TYPE -# define MOZ_ENUM_TYPE(type) : type -#else -# define MOZ_ENUM_TYPE(type) /* no support */ -#endif - /** * MOZ_BEGIN_ENUM_CLASS and MOZ_END_ENUM_CLASS provide access to the * strongly-typed enumeration feature of C++11 ("enum class"). If supported @@ -155,7 +130,7 @@ class Name \ { \ public: \ - enum Enum MOZ_ENUM_TYPE(type) \ + enum Enum : type \ { # define MOZ_END_NESTED_ENUM_CLASS(Name) \ }; \ diff --git a/mfbt/TypedEnumInternal.h b/mfbt/TypedEnumInternal.h index 5af19e20202e..a2c1c998c80e 100644 --- a/mfbt/TypedEnumInternal.h +++ b/mfbt/TypedEnumInternal.h @@ -26,18 +26,15 @@ # define __has_extension __has_feature /* compatibility, for older versions of clang */ # endif # if __has_extension(cxx_strong_enums) -# define MOZ_HAVE_CXX11_ENUM_TYPE # define MOZ_HAVE_CXX11_STRONG_ENUMS # endif #elif defined(__GNUC__) # if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L # if MOZ_GCC_VERSION_AT_LEAST(4, 6, 3) -# define MOZ_HAVE_CXX11_ENUM_TYPE # define MOZ_HAVE_CXX11_STRONG_ENUMS # endif # endif #elif defined(_MSC_VER) -# define MOZ_HAVE_CXX11_ENUM_TYPE # define MOZ_HAVE_CXX11_STRONG_ENUMS #endif diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index 7212cbd6ff8e..d17d219b7898 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -563,7 +563,7 @@ pref("media.fragmented-mp4.android-media-codec.enabled", true); pref("media.fragmented-mp4.android-media-codec.preferred", true); // optimize images memory usage -pref("image.mem.decodeondraw", false); +pref("image.mem.decodeondraw", true); #ifdef NIGHTLY_BUILD // Shumway component (SWF player) is disabled by default. Also see bug 904346. diff --git a/mobile/android/modules/TabMirror.jsm b/mobile/android/modules/TabMirror.jsm index f7a38851d5ce..2d5f53c32320 100644 --- a/mobile/android/modules/TabMirror.jsm +++ b/mobile/android/modules/TabMirror.jsm @@ -7,7 +7,7 @@ const { classes: Cc, interfaces: Ci, utils: Cu } = Components; Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Messaging.jsm"); -const CONFIG = { iceServers: [{ "url": "stun:stun.services.mozilla.com" }] }; +const CONFIG = { iceServers: [{ "urls": ["stun:stun.services.mozilla.com"] }] }; let log = Cu.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog.d.bind(null, "TabMirror"); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index afb30fea4a66..af6281a27e13 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -360,7 +360,7 @@ pref("media.peerconnection.video.start_bitrate", 300); pref("media.peerconnection.video.max_bitrate", 2000); #endif pref("media.navigator.permission.disabled", false); -pref("media.peerconnection.default_iceservers", "[{\"url\": \"stun:stun.services.mozilla.com\"}]"); +pref("media.peerconnection.default_iceservers", "[{\"urls\": [\"stun:stun.services.mozilla.com\"]}]"); pref("media.peerconnection.ice.loopback", false); // Set only for testing in offline environments. pref("media.peerconnection.use_document_iceservers", true); // Do not enable identity before ensuring that the UX cannot be spoofed @@ -3789,7 +3789,7 @@ pref("image.mem.discardable", true); // Prevents images from automatically being decoded on load, instead allowing // them to be decoded on demand when they are drawn. -pref("image.mem.decodeondraw", false); +pref("image.mem.decodeondraw", true); // Allows image locking of decoded image data in content processes. pref("image.mem.allow_locking_in_content_processes", true); diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index f32fb093e36a..9e4d3916a038 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -2183,8 +2183,10 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI, nsCOMPtr uri; mRedirects[i]->GetURI(getter_AddRefs(uri)); nsCString spec; - uri->GetSpec(spec); - LOG(("HttpBaseChannel::SetupReplacementChannel adding redirect %s " + if (uri) { + uri->GetSpec(spec); + } + LOG(("HttpBaseChannel::SetupReplacementChannel adding redirect \'%s\' " "[this=%p]", spec.get(), this)); #endif httpInternal->AddRedirect(mRedirects[i]); diff --git a/netwerk/test/mochitests/mochitest.ini b/netwerk/test/mochitests/mochitest.ini index ebd580569ce7..008c964287cc 100644 --- a/netwerk/test/mochitests/mochitest.ini +++ b/netwerk/test/mochitests/mochitest.ini @@ -1,5 +1,6 @@ [DEFAULT] -skip-if = buildapp == 'b2g' || e10s +skip-if = buildapp == 'b2g' || e10s || toolkit == 'android' # Android: Bug 1111137 & 1078267 + support-files = method.sjs partial_content.sjs @@ -10,7 +11,6 @@ support-files = [test_partially_cached_content.html] [test_uri_scheme.html] [test_user_agent_overrides.html] -skip-if = toolkit == 'android' # Bug 1111137 [test_user_agent_updates.html] [test_user_agent_updates_reset.html] [test_xhr_method_case.html] diff --git a/netwerk/test/unit/xpcshell.ini b/netwerk/test/unit/xpcshell.ini index ed8ad166cb94..1f2f29cb9ebe 100644 --- a/netwerk/test/unit/xpcshell.ini +++ b/netwerk/test/unit/xpcshell.ini @@ -263,8 +263,10 @@ fail-if = os == "android" # spdy and http2 unit tests require us to have node available to run the spdy and http2 server [test_spdy.js] run-if = hasNode +run-sequentially = node server exceptions dont replay well [test_http2.js] run-if = hasNode +run-sequentially = node server exceptions dont replay well [test_speculative_connect.js] [test_standardurl.js] [test_standardurl_port.js] diff --git a/testing/config/mozharness/android_arm_4_4_config.py b/testing/config/mozharness/android_arm_4_4_config.py new file mode 100644 index 000000000000..0d2f0b0588b8 --- /dev/null +++ b/testing/config/mozharness/android_arm_4_4_config.py @@ -0,0 +1,105 @@ +# 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/. + +config = { + "suite_definitions": { + "mochitest": { + "run_filename": "runtestsremote.py", + "testsdir": "mochitest", + "options": ["--autorun", "--close-when-done", "--dm_trans=adb", + "--console-level=INFO", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s", + "--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s", + "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s", + "--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s", + "--quiet", "--log-raw=%(raw_log_file)s", + "--total-chunks=16", + "--run-only-tests=android23.json", + ], + }, + "mochitest-gl": { + "run_filename": "runtestsremote.py", + "testsdir": "mochitest", + "options": ["--autorun", "--close-when-done", "--dm_trans=adb", + "--console-level=INFO", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s", + "--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s", + "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s", + "--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s", + "--quiet", "--log-raw=%(raw_log_file)s", + "--total-chunks=2", + "--test-manifest=gl.json", + ], + }, + "robocop": { + "run_filename": "runtestsremote.py", + "testsdir": "mochitest", + "options": ["--autorun", "--close-when-done", "--dm_trans=adb", + "--console-level=INFO", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s", + "--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s", + "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s", + "--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s", + "--quiet", "--log-raw=%(raw_log_file)s", + "--total-chunks=4", + "--robocop-path=../..", + "--robocop-ids=fennec_ids.txt", + "--robocop=robocop.ini", + ], + }, + "reftest": { + "run_filename": "remotereftest.py", + "testsdir": "reftest", + "options": [ "--app=%(app)s", "--ignore-window-size", + "--dm_trans=adb", + "--bootstrap", + "--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s", + "--utility-path=%(utility_path)s", "--http-port=%(http_port)s", + "--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s", + "--symbols-path=%(symbols_path)s", + "--total-chunks=16", + "tests/layout/reftests/reftest.list", + ], + }, + "crashtest": { + "run_filename": "remotereftest.py", + "testsdir": "reftest", + "options": [ "--app=%(app)s", "--ignore-window-size", + "--dm_trans=adb", + "--bootstrap", + "--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s", + "--utility-path=%(utility_path)s", "--http-port=%(http_port)s", + "--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s", + "--symbols-path=%(symbols_path)s", + "--total-chunks=2", + "tests/testing/crashtest/crashtests.list", + ], + }, + "jsreftest": { + "run_filename": "remotereftest.py", + "testsdir": "reftest", + "options": [ "--app=%(app)s", "--ignore-window-size", + "--dm_trans=adb", + "--bootstrap", + "--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s", + "--utility-path=%(utility_path)s", "--http-port=%(http_port)s", + "--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s", + "--symbols-path=%(symbols_path)s", + "../jsreftest/tests/jstests.list", + "--total-chunks=6", + "--extra-profile-file=jsreftest/tests/user.js", + ], + }, + "xpcshell": { + "run_filename": "remotexpcshelltests.py", + "testsdir": "xpcshell", + "options": [ + "--dm_trans=adb", + "--xre-path=%(xre_path)s", "--testing-modules-dir=%(modules_dir)s", + "--apk=%(installer_path)s", "--no-logfiles", + "--symbols-path=%(symbols_path)s", + "--manifest=tests/xpcshell.ini", + "--log-raw=%(raw_log_file)s", + "--total-chunks=3", + ], + }, + }, # end suite_definitions +} diff --git a/testing/talos/talos.json b/testing/talos/talos.json index a75772999df9..1fc45bac6a28 100644 --- a/testing/talos/talos.json +++ b/testing/talos/talos.json @@ -5,7 +5,7 @@ }, "global": { "talos_repo": "https://hg.mozilla.org/build/talos", - "talos_revision": "ebc4327b8cb8" + "talos_revision": "39c9c9b33cfc" }, "extra_options": { "android": [ "--apkPath=%(apk_path)s" ] @@ -39,7 +39,8 @@ "tests": ["tpaint"] }, "other-snow-e10s": { - "tests": ["tpaint"] + "tests": ["tpaint"], + "talos_options": ["--e10s"] }, "other_nol64": { "tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore"] @@ -80,7 +81,8 @@ "tests": ["glterrain"] }, "g1-snow-e10s": { - "tests": ["glterrain"] + "tests": ["glterrain"], + "talos_options": ["--e10s"] }, "svgr": { "tests": ["tsvgx", "tsvgr_opacity", "tart", "tscrollx", "cart"] @@ -93,7 +95,8 @@ "tests": ["tsvgx", "tscrollx"] }, "svgr-snow-e10s": { - "tests": ["tsvgx", "tscrollx"] + "tests": ["tsvgx", "tscrollx"], + "talos_options": ["--e10s"] }, "tp5o": { "tests": ["tp5o"], diff --git a/testing/web-platform/harness/wptrunner/browsers/firefox.py b/testing/web-platform/harness/wptrunner/browsers/firefox.py index 50c99f4d1d83..a1c3a620f6ff 100644 --- a/testing/web-platform/harness/wptrunner/browsers/firefox.py +++ b/testing/web-platform/harness/wptrunner/browsers/firefox.py @@ -186,8 +186,16 @@ class FirefoxBrowser(Browser): # TODO: Maybe only set this if certutil won't launch? env = os.environ.copy() certutil_dir = os.path.dirname(self.binary) - env["LD_LIBRARY_PATH"] = certutil_dir - env["PATH"] = os.path.pathsep.join([certutil_dir, env["PATH"]]) + if mozinfo.isMac: + env_var = "DYLD_LIBRARY_PATH" + elif mozinfo.isUnix: + env_var = "LD_LIBRARY_PATH" + else: + env_var = "PATH" + + + env[env_var] = (os.path.pathsep.join([certutil_dir, env[env_var]]) + if env_var in env else certutil_dir) def certutil(*args): cmd = [self.certutil_binary] + list(args) diff --git a/toolkit/content/tests/widgets/mochitest.ini b/toolkit/content/tests/widgets/mochitest.ini index 298424b523e1..eb8214b86e0d 100644 --- a/toolkit/content/tests/widgets/mochitest.ini +++ b/toolkit/content/tests/widgets/mochitest.ini @@ -28,5 +28,6 @@ skip-if = toolkit == 'android' #TIMED_OUT [test_videocontrols_audio.html] [test_videocontrols_audio_direction.html] [test_videocontrols_standalone.html] +skip-if = android_version == '10' # bug 1075573 [test_videocontrols_video_direction.html] [test_bug898940.html] diff --git a/uriloader/prefetch/nsOfflineCacheUpdate.h b/uriloader/prefetch/nsOfflineCacheUpdate.h index 89367c1650fc..3edfa2f6b0e3 100644 --- a/uriloader/prefetch/nsOfflineCacheUpdate.h +++ b/uriloader/prefetch/nsOfflineCacheUpdate.h @@ -76,7 +76,7 @@ public: nsresult GetStatus(uint16_t *aStatus); private: - enum LoadStatus MOZ_ENUM_TYPE(uint16_t) { + enum LoadStatus : uint16_t { UNINITIALIZED = 0U, REQUESTED = 1U, RECEIVING = 2U, diff --git a/widget/EventForwards.h b/widget/EventForwards.h index d1e4a7fa8be4..f9260f71e7ee 100644 --- a/widget/EventForwards.h +++ b/widget/EventForwards.h @@ -32,7 +32,7 @@ namespace mozilla { typedef uint8_t EventClassIDType; -enum EventClassID MOZ_ENUM_TYPE(EventClassIDType) +enum EventClassID : EventClassIDType { // The event class name will be: // eBasicEventClass for WidgetEvent @@ -77,7 +77,7 @@ enum CodeNameIndex #define NS_DEFINE_COMMAND(aName, aCommandStr) , Command##aName typedef int8_t CommandInt; -enum Command MOZ_ENUM_TYPE(CommandInt) +enum Command : CommandInt { CommandDoNothing diff --git a/widget/gonk/HwcComposer2D.cpp b/widget/gonk/HwcComposer2D.cpp index fec58ec3fb47..e57e897f690a 100644 --- a/widget/gonk/HwcComposer2D.cpp +++ b/widget/gonk/HwcComposer2D.cpp @@ -30,7 +30,8 @@ #include "mozilla/StaticPtr.h" #include "cutils/properties.h" #include "gfx2DGlue.h" -#include "nsWindow.h" +#include "gfxPlatform.h" +#include "VsyncSource.h" #if ANDROID_VERSION >= 17 #include "libdisplay/FramebufferSurface.h" @@ -227,7 +228,8 @@ HwcComposer2D::Vsync(int aDisplay, nsecs_t aVsyncTimestamp) LOGE("Non-uniform vsync interval: %lld\n", vsyncInterval); } mLastVsyncTime = aVsyncTimestamp; - nsWindow::NotifyVsync(vsyncTime); + + gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay().NotifyVsync(vsyncTime); } // Called on the "invalidator" thread (run from HAL). diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp index a394dbbf68e4..544805bd19fb 100644 --- a/widget/gonk/nsWindow.cpp +++ b/widget/gonk/nsWindow.cpp @@ -215,21 +215,6 @@ nsWindow::DoDraw(void) } } -/* static */ void -nsWindow::NotifyVsync(TimeStamp aVsyncTimestamp) -{ - if (!gFocusedWindow) { - return; - } - - CompositorVsyncDispatcher* vsyncDispatcher = gFocusedWindow->GetCompositorVsyncDispatcher(); - // During bootup, there is a delay between when the nsWindow is created - // and when the Compositor is created, but vsync is already turned on - if (vsyncDispatcher) { - vsyncDispatcher->NotifyVsync(aVsyncTimestamp); - } -} - /*static*/ nsEventStatus nsWindow::DispatchInputEvent(WidgetGUIEvent& aEvent) { diff --git a/widget/gonk/nsWindow.h b/widget/gonk/nsWindow.h index 67d7529a8438..cf816ab2dda3 100644 --- a/widget/gonk/nsWindow.h +++ b/widget/gonk/nsWindow.h @@ -50,7 +50,6 @@ public: nsWindow(); virtual ~nsWindow(); - static void NotifyVsync(mozilla::TimeStamp aVsyncTimestamp); static void DoDraw(void); static nsEventStatus DispatchInputEvent(mozilla::WidgetGUIEvent& aEvent); static void DispatchTouchInput(mozilla::MultiTouchInput& aInput); diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 460641c9aa4b..8e329e453eab 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -225,7 +225,7 @@ struct nsIMEUpdatePreference { typedef uint8_t Notifications; - enum MOZ_ENUM_TYPE(Notifications) + enum : Notifications { NOTIFY_NOTHING = 0, NOTIFY_SELECTION_CHANGE = 1 << 0, @@ -519,7 +519,7 @@ struct SizeConstraints { // Update values in GeckoEditable.java if you make changes here. // XXX Negative values are used in Android... typedef int8_t IMEMessageType; -enum IMEMessage MOZ_ENUM_TYPE(IMEMessageType) +enum IMEMessage : IMEMessageType { // An editable content is getting focus NOTIFY_IME_OF_FOCUS = 1, diff --git a/widget/windows/nsTextStore.h b/widget/windows/nsTextStore.h index 85169478ed4b..8b57847a91e1 100644 --- a/widget/windows/nsTextStore.h +++ b/widget/windows/nsTextStore.h @@ -480,7 +480,7 @@ protected: struct PendingAction MOZ_FINAL { - enum ActionType MOZ_ENUM_TYPE(uint8_t) + enum ActionType : uint8_t { COMPOSITION_START, COMPOSITION_UPDATE, @@ -635,7 +635,7 @@ protected: nsTextStore::Selection& mSelection; // The minimum offset of modified part of the text. - enum MOZ_ENUM_TYPE(uint32_t) + enum : uint32_t { NOT_MODIFIED = UINT32_MAX }; diff --git a/xpcom/base/nsError.h b/xpcom/base/nsError.h index ce6a45ef9b50..f6392f107acd 100644 --- a/xpcom/base/nsError.h +++ b/xpcom/base/nsError.h @@ -136,7 +136,7 @@ * #define's for compatibility with old code. */ #include "ErrorListCxxDefines.h" -#elif defined(MOZ_HAVE_CXX11_ENUM_TYPE) +#elif defined(__cplusplus) typedef enum tag_nsresult : uint32_t { #undef ERROR @@ -144,21 +144,6 @@ #include "ErrorList.h" #undef ERROR } nsresult; -#elif defined(__cplusplus) - /* - * We're C++ in an old compiler lacking enum classes *and* typed enums (likely - * gcc < 4.5.1 as clang/MSVC have long supported one or both), or compiler - * support is unknown. Yet nsresult must have unsigned 32-bit representation. - * So just make it a typedef, and implement the constants with global consts. - */ - typedef uint32_t nsresult; - - const nsresult - #undef ERROR - #define ERROR(key, val) key = val - #include "ErrorList.h" - #undef ERROR - ; #else /* * C doesn't have any way to fix the type underlying an enum, and enum diff --git a/xpcom/tests/TestPipes.cpp b/xpcom/tests/gtest/TestPipes.cpp similarity index 60% rename from xpcom/tests/TestPipes.cpp rename to xpcom/tests/gtest/TestPipes.cpp index c630e930efed..5ec57e041b62 100644 --- a/xpcom/tests/TestPipes.cpp +++ b/xpcom/tests/gtest/TestPipes.cpp @@ -3,8 +3,9 @@ * 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/. */ -#include "TestHarness.h" - +#include +#include "nsIAsyncInputStream.h" +#include "nsIAsyncOutputStream.h" #include "nsIThread.h" #include "nsIRunnable.h" #include "nsThreadUtils.h" @@ -13,76 +14,11 @@ #include "nsCRT.h" #include "nsIPipe.h" // new implementation -#include "mozilla/Monitor.h" +#include "mozilla/ReentrantMonitor.h" + +#include "gtest/gtest.h" using namespace mozilla; -/** NS_NewPipe2 reimplemented, because it's not exported by XPCOM */ -nsresult TP_NewPipe2(nsIAsyncInputStream** input, - nsIAsyncOutputStream** output, - bool nonBlockingInput, - bool nonBlockingOutput, - uint32_t segmentSize, - uint32_t segmentCount, - nsIMemory* segmentAlloc) -{ - nsCOMPtr pipe = do_CreateInstance("@mozilla.org/pipe;1"); - if (!pipe) - return NS_ERROR_OUT_OF_MEMORY; - - nsresult rv = pipe->Init(nonBlockingInput, - nonBlockingOutput, - segmentSize, - segmentCount, - segmentAlloc); - - if (NS_FAILED(rv)) - return rv; - - pipe->GetInputStream(input); - pipe->GetOutputStream(output); - return NS_OK; -} - -/** NS_NewPipe reimplemented, because it's not exported by XPCOM */ -#define TP_DEFAULT_SEGMENT_SIZE 4096 -nsresult TP_NewPipe(nsIInputStream **pipeIn, - nsIOutputStream **pipeOut, - uint32_t segmentSize = 0, - uint32_t maxSize = 0, - bool nonBlockingInput = false, - bool nonBlockingOutput = false, - nsIMemory *segmentAlloc = nullptr); -nsresult TP_NewPipe(nsIInputStream **pipeIn, - nsIOutputStream **pipeOut, - uint32_t segmentSize, - uint32_t maxSize, - bool nonBlockingInput, - bool nonBlockingOutput, - nsIMemory *segmentAlloc) -{ - if (segmentSize == 0) - segmentSize = TP_DEFAULT_SEGMENT_SIZE; - - // Handle maxSize of UINT32_MAX as a special case - uint32_t segmentCount; - if (maxSize == UINT32_MAX) - segmentCount = UINT32_MAX; - else - segmentCount = maxSize / segmentSize; - - nsIAsyncInputStream *in; - nsIAsyncOutputStream *out; - nsresult rv = TP_NewPipe2(&in, &out, nonBlockingInput, nonBlockingOutput, - segmentSize, segmentCount, segmentAlloc); - if (NS_FAILED(rv)) return rv; - - *pipeIn = in; - *pipeOut = out; - return NS_OK; -} - - -#define KEY 0xa7 #define ITERATIONS 33333 char kTestPattern[] = "My hovercraft is full of eels.\n"; @@ -104,11 +40,11 @@ WriteAll(nsIOutputStream *os, const char *buf, uint32_t bufLen, uint32_t *lenWri return NS_OK; } -class nsReceiver : public nsIRunnable { +class nsReceiver MOZ_FINAL : public nsIRunnable { public: NS_DECL_THREADSAFE_ISUPPORTS - NS_IMETHOD Run() { + NS_IMETHOD Run() MOZ_OVERRIDE { nsresult rv; char buf[101]; uint32_t count; @@ -136,11 +72,14 @@ public: return rv; } - nsReceiver(nsIInputStream* in) : mIn(in), mCount(0) { + explicit nsReceiver(nsIInputStream* in) : mIn(in), mCount(0) { } uint32_t GetBytesRead() { return mCount; } +private: + ~nsReceiver() {} + protected: nsCOMPtr mIn; uint32_t mCount; @@ -151,7 +90,7 @@ NS_IMPL_ISUPPORTS(nsReceiver, nsIRunnable) nsresult TestPipe(nsIInputStream* in, nsIOutputStream* out) { - nsCOMPtr receiver = new nsReceiver(in); + nsRefPtr receiver = new nsReceiver(in); if (!receiver) return NS_ERROR_OUT_OF_MEMORY; @@ -188,18 +127,18 @@ TestPipe(nsIInputStream* in, nsIOutputStream* out) printf("wrote %d bytes, time = %dms\n", total, PR_IntervalToMilliseconds(end - start)); - NS_ASSERTION(receiver->GetBytesRead() == total, "didn't read everything"); + EXPECT_EQ(receiver->GetBytesRead(), total); return NS_OK; } //////////////////////////////////////////////////////////////////////////////// -class nsShortReader : public nsIRunnable { +class nsShortReader MOZ_FINAL : public nsIRunnable { public: NS_DECL_THREADSAFE_ISUPPORTS - NS_IMETHOD Run() { + NS_IMETHOD Run() MOZ_OVERRIDE { nsresult rv; char buf[101]; uint32_t count; @@ -230,24 +169,24 @@ public: return rv; } - nsShortReader(nsIInputStream* in) : mIn(in), mReceived(0) { - mMon = new Monitor("nsShortReader"); + explicit nsShortReader(nsIInputStream* in) : mIn(in), mReceived(0) { + mMon = new ReentrantMonitor("nsShortReader"); } void Received(uint32_t count) { - MonitorAutoEnter mon(*mMon); + ReentrantMonitorAutoEnter mon(*mMon); mReceived += count; mon.Notify(); } uint32_t WaitForReceipt(const uint32_t aWriteCount) { - MonitorAutoEnter mon(*mMon); + ReentrantMonitorAutoEnter mon(*mMon); uint32_t result = mReceived; while (result < aWriteCount) { mon.Wait(); - NS_ASSERTION(mReceived > result, "failed to receive"); + EXPECT_TRUE(mReceived > result); result = mReceived; } @@ -255,10 +194,13 @@ public: return result; } +private: + ~nsShortReader() {} + protected: nsCOMPtr mIn; uint32_t mReceived; - Monitor* mMon; + ReentrantMonitor* mMon; }; NS_IMPL_ISUPPORTS(nsShortReader, nsIRunnable) @@ -266,7 +208,7 @@ NS_IMPL_ISUPPORTS(nsShortReader, nsIRunnable) nsresult TestShortWrites(nsIInputStream* in, nsIOutputStream* out) { - nsCOMPtr receiver = new nsShortReader(in); + nsRefPtr receiver = new nsShortReader(in); if (!receiver) return NS_ERROR_OUT_OF_MEMORY; @@ -282,10 +224,10 @@ TestShortWrites(nsIInputStream* in, nsIOutputStream* out) char* buf = PR_smprintf("%d %s", i, kTestPattern); uint32_t len = strlen(buf); len = len * rand() / RAND_MAX; - len = XPCOM_MAX(1, len); + len = std::min(1u, len); rv = WriteAll(out, buf, len, &writeCount); if (NS_FAILED(rv)) return rv; - NS_ASSERTION(writeCount == len, "didn't write enough"); + EXPECT_EQ(writeCount, len); total += writeCount; if (gTrace) @@ -297,9 +239,9 @@ TestShortWrites(nsIInputStream* in, nsIOutputStream* out) #ifdef DEBUG const uint32_t received = -#endif receiver->WaitForReceipt(writeCount); - NS_ASSERTION(received == writeCount, "received wrong amount"); + EXPECT_EQ(received, writeCount); +#endif } rv = out->Close(); if (NS_FAILED(rv)) return rv; @@ -313,12 +255,12 @@ TestShortWrites(nsIInputStream* in, nsIOutputStream* out) //////////////////////////////////////////////////////////////////////////////// -class nsPump : public nsIRunnable +class nsPump MOZ_FINAL : public nsIRunnable { public: NS_DECL_THREADSAFE_ISUPPORTS - NS_IMETHOD Run() { + NS_IMETHOD Run() MOZ_OVERRIDE { nsresult rv; uint32_t count; while (true) { @@ -346,6 +288,9 @@ public: : mIn(in), mOut(out), mCount(0) { } +private: + ~nsPump() {} + protected: nsCOMPtr mIn; nsCOMPtr mOut; @@ -354,35 +299,36 @@ protected: NS_IMPL_ISUPPORTS(nsPump, nsIRunnable) -nsresult -TestChainedPipes() +TEST(Pipes, ChainedPipes) { nsresult rv; - printf("TestChainedPipes\n"); + if (gTrace) { + printf("TestChainedPipes\n"); + } nsCOMPtr in1; nsCOMPtr out1; - rv = TP_NewPipe(getter_AddRefs(in1), getter_AddRefs(out1), 20, 1999); - if (NS_FAILED(rv)) return rv; + rv = NS_NewPipe(getter_AddRefs(in1), getter_AddRefs(out1), 20, 1999); + if (NS_FAILED(rv)) return; nsCOMPtr in2; nsCOMPtr out2; - rv = TP_NewPipe(getter_AddRefs(in2), getter_AddRefs(out2), 200, 401); - if (NS_FAILED(rv)) return rv; + rv = NS_NewPipe(getter_AddRefs(in2), getter_AddRefs(out2), 200, 401); + if (NS_FAILED(rv)) return; - nsCOMPtr pump = new nsPump(in1, out2); - if (pump == nullptr) return NS_ERROR_OUT_OF_MEMORY; + nsRefPtr pump = new nsPump(in1, out2); + if (pump == nullptr) return; nsCOMPtr thread; rv = NS_NewThread(getter_AddRefs(thread), pump); - if (NS_FAILED(rv)) return rv; + if (NS_FAILED(rv)) return; - nsCOMPtr receiver = new nsReceiver(in2); - if (receiver == nullptr) return NS_ERROR_OUT_OF_MEMORY; + nsRefPtr receiver = new nsReceiver(in2); + if (receiver == nullptr) return; nsCOMPtr receiverThread; rv = NS_NewThread(getter_AddRefs(receiverThread), receiver); - if (NS_FAILED(rv)) return rv; + if (NS_FAILED(rv)) return; uint32_t total = 0; for (uint32_t i = 0; i < ITERATIONS; i++) { @@ -390,10 +336,10 @@ TestChainedPipes() char* buf = PR_smprintf("%d %s", i, kTestPattern); uint32_t len = strlen(buf); len = len * rand() / RAND_MAX; - len = XPCOM_MAX(1, len); + len = std::max(1u, len); rv = WriteAll(out1, buf, len, &writeCount); - if (NS_FAILED(rv)) return rv; - NS_ASSERTION(writeCount == len, "didn't write enough"); + if (NS_FAILED(rv)) return; + EXPECT_EQ(writeCount, len); total += writeCount; if (gTrace) @@ -401,14 +347,14 @@ TestChainedPipes() PR_smprintf_free(buf); } - printf("wrote total of %d bytes\n", total); + if (gTrace) { + printf("wrote total of %d bytes\n", total); + } rv = out1->Close(); - if (NS_FAILED(rv)) return rv; + if (NS_FAILED(rv)) return; thread->Shutdown(); receiverThread->Shutdown(); - - return NS_OK; } //////////////////////////////////////////////////////////////////////////////// @@ -420,50 +366,26 @@ RunTests(uint32_t segSize, uint32_t segCount) nsCOMPtr in; nsCOMPtr out; uint32_t bufSize = segSize * segCount; - printf("Testing New Pipes: segment size %d buffer size %d\n", segSize, bufSize); - - printf("Testing long writes...\n"); - rv = TP_NewPipe(getter_AddRefs(in), getter_AddRefs(out), segSize, bufSize); - NS_ASSERTION(NS_SUCCEEDED(rv), "TP_NewPipe failed"); + if (gTrace) { + printf("Testing New Pipes: segment size %d buffer size %d\n", segSize, bufSize); + printf("Testing long writes...\n"); + } + rv = NS_NewPipe(getter_AddRefs(in), getter_AddRefs(out), segSize, bufSize); + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = TestPipe(in, out); - NS_ASSERTION(NS_SUCCEEDED(rv), "TestPipe failed"); + EXPECT_TRUE(NS_SUCCEEDED(rv)); - printf("Testing short writes...\n"); - rv = TP_NewPipe(getter_AddRefs(in), getter_AddRefs(out), segSize, bufSize); - NS_ASSERTION(NS_SUCCEEDED(rv), "TP_NewPipe failed"); + if (gTrace) { + printf("Testing short writes...\n"); + } + rv = NS_NewPipe(getter_AddRefs(in), getter_AddRefs(out), segSize, bufSize); + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = TestShortWrites(in, out); - NS_ASSERTION(NS_SUCCEEDED(rv), "TestPipe failed"); + EXPECT_TRUE(NS_SUCCEEDED(rv)); } -//////////////////////////////////////////////////////////////////////////////// - -#if 0 -extern void -TestSegmentedBuffer(); -#endif - -int -main(int argc, char* argv[]) +TEST(Pipes, Main) { - nsresult rv; - - nsCOMPtr servMgr; - rv = NS_InitXPCOM2(getter_AddRefs(servMgr), nullptr, nullptr); - if (NS_FAILED(rv)) return rv; - - if (argc > 1 && nsCRT::strcmp(argv[1], "-trace") == 0) - gTrace = true; - - rv = TestChainedPipes(); - NS_ASSERTION(NS_SUCCEEDED(rv), "TestChainedPipes failed"); RunTests(16, 1); RunTests(4096, 16); - - servMgr = 0; - rv = NS_ShutdownXPCOM(nullptr); - NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); - - return 0; } - -//////////////////////////////////////////////////////////////////////////////// diff --git a/xpcom/tests/TestPriorityQueue.cpp b/xpcom/tests/gtest/TestPriorityQueue.cpp similarity index 60% rename from xpcom/tests/TestPriorityQueue.cpp rename to xpcom/tests/gtest/TestPriorityQueue.cpp index 74e86f79effa..7aec8ca009a7 100644 --- a/xpcom/tests/TestPriorityQueue.cpp +++ b/xpcom/tests/gtest/TestPriorityQueue.cpp @@ -7,6 +7,7 @@ #include "nsTPriorityQueue.h" #include #include +#include "gtest/gtest.h" template void @@ -16,32 +17,13 @@ CheckPopSequence(const nsTPriorityQueue& aQueue, nsTPriorityQueue copy(aQueue); for (uint32_t i = 0; i < aSequenceLength; i++) { - if (copy.IsEmpty()) { - printf("Number of elements in the queue is too short by %d.\n", - aSequenceLength - i); - exit(-1); - } + EXPECT_FALSE(copy.IsEmpty()); T pop = copy.Pop(); - if (pop != aExpectedSequence[i]) { - printf("Unexpected value in pop sequence at position %d\n", i); - printf(" Sequence:"); - for (size_t j = 0; j < aSequenceLength; j++) { - printf(" %d", aExpectedSequence[j]); - if (j == i) { - printf("**"); - } - } - printf("\n ** Got %d instead\n", pop); - exit(-1); - } + EXPECT_EQ(pop, aExpectedSequence[i]); } - if (!copy.IsEmpty()) { - printf("Number of elements in the queue is too long by %d.\n", - copy.Length()); - exit(-1); - } + EXPECT_TRUE(copy.IsEmpty()); } template @@ -52,11 +34,11 @@ public: } }; -int main() +TEST(PriorityQueue, Main) { nsTPriorityQueue queue; - NS_ABORT_IF_FALSE(queue.IsEmpty(), "Queue not initially empty"); + EXPECT_TRUE(queue.IsEmpty()); queue.Push(8); queue.Push(6); @@ -64,9 +46,9 @@ int main() queue.Push(2); queue.Push(10); queue.Push(6); - NS_ABORT_IF_FALSE(queue.Top() == 2, "Unexpected queue top"); - NS_ABORT_IF_FALSE(queue.Length() == 6, "Unexpected queue length"); - NS_ABORT_IF_FALSE(!queue.IsEmpty(), "Queue empty when populated"); + EXPECT_EQ(queue.Top(), 2); + EXPECT_EQ(queue.Length(), 6u); + EXPECT_FALSE(queue.IsEmpty()); int expected[] = { 2, 4, 6, 6, 8, 10 }; CheckPopSequence(queue, expected, sizeof(expected) / sizeof(expected[0])); @@ -77,7 +59,7 @@ int main() CheckPopSequence(queue2, expected, sizeof(expected) / sizeof(expected[0])); queue.Clear(); - NS_ABORT_IF_FALSE(queue.IsEmpty(), "Queue not emptied by Clear"); + EXPECT_TRUE(queue.IsEmpty()); // try same sequence with a max heap nsTPriorityQueue > max_queue; @@ -87,10 +69,8 @@ int main() max_queue.Push(2); max_queue.Push(10); max_queue.Push(6); - NS_ABORT_IF_FALSE(max_queue.Top() == 10, "Unexpected queue top for max heap"); + EXPECT_EQ(max_queue.Top(), 10); int expected_max[] = { 10, 8, 6, 6, 4, 2 }; CheckPopSequence(max_queue, expected_max, sizeof(expected_max) / sizeof(expected_max[0])); - - return 0; } diff --git a/xpcom/tests/TestStorageStream.cpp b/xpcom/tests/gtest/TestStorageStream.cpp similarity index 71% rename from xpcom/tests/TestStorageStream.cpp rename to xpcom/tests/gtest/TestStorageStream.cpp index 7b1dad018d1d..f8a92fd69638 100644 --- a/xpcom/tests/TestStorageStream.cpp +++ b/xpcom/tests/gtest/TestStorageStream.cpp @@ -7,8 +7,9 @@ #include "nsIInputStream.h" #include "nsIOutputStream.h" #include "nsCOMPtr.h" +#include "gtest/gtest.h" -int main() +TEST(TestStorageStreams, Main) { char kData[4096]; memset(kData, 0, sizeof(kData)); @@ -17,94 +18,75 @@ int main() nsCOMPtr stor; rv = NS_NewStorageStream(4096, UINT32_MAX, getter_AddRefs(stor)); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); nsCOMPtr out; rv = stor->GetOutputStream(0, getter_AddRefs(out)); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); uint32_t n; rv = out->Write(kData, sizeof(kData), &n); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = out->Write(kData, sizeof(kData), &n); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = out->Close(); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); out = nullptr; - + nsCOMPtr in; rv = stor->NewInputStream(0, getter_AddRefs(in)); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); char buf[4096]; // consume contents of input stream do { rv = in->Read(buf, sizeof(buf), &n); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); } while (n != 0); rv = in->Close(); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); in = nullptr; // now, write 3 more full 4k segments + 11 bytes, starting at 8192 // total written equals 20491 bytes rv = stor->GetOutputStream(8192, getter_AddRefs(out)); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = out->Write(kData, sizeof(kData), &n); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = out->Write(kData, sizeof(kData), &n); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = out->Write(kData, sizeof(kData), &n); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = out->Write(kData, 11, &n); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = out->Close(); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); out = nullptr; // now, read all rv = stor->NewInputStream(0, getter_AddRefs(in)); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); // consume contents of input stream do { rv = in->Read(buf, sizeof(buf), &n); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); } while (n != 0); rv = in->Close(); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); in = nullptr; - - return 0; } diff --git a/xpcom/tests/gtest/moz.build b/xpcom/tests/gtest/moz.build index 50fffc042896..e0e23b953d20 100644 --- a/xpcom/tests/gtest/moz.build +++ b/xpcom/tests/gtest/moz.build @@ -8,7 +8,10 @@ UNIFIED_SOURCES += [ 'TestCRT.cpp', 'TestEncoding.cpp', 'TestExpirationTracker.cpp', + 'TestPipes.cpp', + 'TestPriorityQueue.cpp', 'TestSnappyStreams.cpp', + 'TestStorageStream.cpp', 'TestStrings.cpp', ] diff --git a/xpcom/tests/moz.build b/xpcom/tests/moz.build index 131cacdf5452..ad73e74f82e2 100644 --- a/xpcom/tests/moz.build +++ b/xpcom/tests/moz.build @@ -80,9 +80,6 @@ if CONFIG['MOZ_MEMORY']: # XXX Make these tests work in libxul builds. #CPP_UNIT_TESTS += [ -# 'TestPipes', -# 'TestPriorityQueue', -# 'TestStorageStream', # 'TestSynchronization', # 'TestTArray', # 'TestThreadPool',