author | Ryan VanderMeulen <ryanvm@gmail.com> |
Mon, 04 Nov 2013 16:33:35 -0500 | |
changeset 153429 | 94a672274c2b319732713e02527a542e6b63ae1b |
parent 153428 | 311650f884516d100d36e4d61fedbffe2ca18704 (current diff) |
parent 153398 | 7d298c4380ad7e0f65c421a7ae6345bfb7a3f3f5 (diff) |
child 153430 | a8131d677d9b5d640e18cb3cab06f669a2175050 |
push id | 25587 |
push user | kwierso@gmail.com |
push date | Tue, 05 Nov 2013 05:07:06 +0000 |
treeherder | mozilla-central@b0bce439c6e2 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 28.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "17d3c31fb43696cda00ae13b79b8f2053fa12e11", + "revision": "00ceae21c52602059b7614b661bc39a3c73c84de", "repo_path": "/integration/gaia-central" }
--- a/browser/components/migration/src/SafariProfileMigrator.js +++ b/browser/components/migration/src/SafariProfileMigrator.js @@ -337,39 +337,16 @@ Preferences.prototype = { // Firefox has an elaborate set of Image preferences. The correlation is: // Mode: Safari Firefox // Blocked FALSE 2 // Allowed TRUE 1 // Allowed, originating site only -- 3 this._set("WebKitDisplayImagesKey", "permissions.default.image", function(webkitVal) webkitVal ? 1 : 2); - // Default charset migration - this._set("WebKitDefaultTextEncodingName", "intl.charset.default", - function(webkitCharset) { - // We don't support x-mac-korean (see bug 713516), but it mostly matches - // EUC-KR. - if (webkitCharset == "x-mac-korean") - return "EUC-KR"; - - // getCharsetAlias throws if an invalid value is passed in. - try { - return Cc["@mozilla.org/charset-converter-manager;1"]. - getService(Ci.nsICharsetConverterManager). - getCharsetAlias(webkitCharset); - } - catch(ex) { - Cu.reportError("Could not convert webkit charset '" + webkitCharset + - "' to a supported charset"); - } - // Don't set the preference if we could not get the corresponding - // charset. - return undefined; - }); - #ifdef XP_WIN // Cookie-accept policy. // For the OS X version, see WebFoundationCookieBehavior. // Setting Safari Firefox // Always Accept 0 0 // Accept from Originating 2 1 // Never Accept 1 2 this._set("WebKitCookieStorageAcceptPolicy",
--- a/browser/components/preferences/fonts.js +++ b/browser/components/preferences/fonts.js @@ -93,28 +93,16 @@ var gFontsDialog = { if (fontItems.length) break; } if (fontItems.length) return fontItems[0].getAttribute("value"); return defaultValue; }, - _charsetMenuInitialized: false, - readDefaultCharset: function () - { - if (!this._charsetMenuInitialized) { - var os = Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService); - os.notifyObservers(null, "charsetmenu-selected", "other"); - this._charsetMenuInitialized = true; - } - return undefined; - }, - readUseDocumentFonts: function () { var preference = document.getElementById("browser.display.use_document_fonts"); return preference.value == 1; }, writeUseDocumentFonts: function () {
--- a/browser/components/preferences/fonts.xul +++ b/browser/components/preferences/fonts.xul @@ -32,17 +32,17 @@ <prefpane id="FontsDialogPane" helpTopic="prefs-fonts-and-colors"> <preferences id="fontPreferences"> <preference id="font.language.group" name="font.language.group" type="wstring"/> <preference id="browser.display.use_document_fonts" name="browser.display.use_document_fonts" type="int"/> - <preference id="intl.charset.default" name="intl.charset.default" type="wstring"/> + <preference id="intl.charset.fallback.override" name="intl.charset.fallback.override" type="string"/> </preferences> <stringbundle id="bundlePreferences" src="chrome://browser/locale/preferences/preferences.properties"/> <script type="application/javascript" src="chrome://mozapps/content/preferences/fontbuilder.js"/> <script type="application/javascript" src="chrome://browser/content/preferences/fonts.js"/> <!-- Fonts for: [ Language ] --> <groupbox> @@ -257,21 +257,32 @@ <!-- Character Encoding --> <groupbox> <caption label="&languages.customize.Fallback.grouplabel;"/> <description>&languages.customize.Fallback.desc;</description> <hbox align="center"> <label value="&languages.customize.Fallback.label;" accesskey="&languages.customize.Fallback.accesskey;" control="DefaultCharsetList"/> - <menulist id="DefaultCharsetList" ref="NC:DecodersRoot" datasources="rdf:charset-menu" - preference="intl.charset.default" - onsyncfrompreference="return gFontsDialog.readDefaultCharset();"> - <template> - <menupopup> - <menuitem label="rdf:http://home.netscape.com/NC-rdf#Name" value="..." uri="..."/> - </menupopup> - </template> + <menulist id="DefaultCharsetList" preference="intl.charset.fallback.override"> + <menupopup> + <menuitem label="&languages.customize.Fallback.auto;" value=""/> + <menuitem label="&languages.customize.Fallback.arabic;" value="windows-1256"/> + <menuitem label="&languages.customize.Fallback.baltic;" value="windows-1257"/> + <menuitem label="&languages.customize.Fallback.ceiso;" value="ISO-8859-2"/> + <menuitem label="&languages.customize.Fallback.cewindows;" value="windows-1250"/> + <menuitem label="&languages.customize.Fallback.simplified;" value="gbk"/> + <menuitem label="&languages.customize.Fallback.traditional;" value="Big5"/> + <menuitem label="&languages.customize.Fallback.cyrillic;" value="windows-1251"/> + <menuitem label="&languages.customize.Fallback.greek;" value="ISO-8859-7"/> + <menuitem label="&languages.customize.Fallback.hebrew;" value="windows-1255"/> + <menuitem label="&languages.customize.Fallback.japanese;" value="Shift_JIS"/> + <menuitem label="&languages.customize.Fallback.korean;" value="EUC-KR"/> + <menuitem label="&languages.customize.Fallback.thai;" value="windows-874"/> + <menuitem label="&languages.customize.Fallback.turkish;" value="windows-1254"/> + <menuitem label="&languages.customize.Fallback.vietnamese;" value="windows-1258"/> + <menuitem label="&languages.customize.Fallback.other;" value="windows-1252"/> + </menupopup> </menulist> </hbox> </groupbox> </prefpane> </prefwindow>
--- a/browser/locales/en-US/chrome/browser/preferences/fonts.dtd +++ b/browser/locales/en-US/chrome/browser/preferences/fonts.dtd @@ -67,8 +67,45 @@ <!ENTITY allowPagesToUse.label "Allow pages to choose their own fonts, instead of my selections above"> <!ENTITY allowPagesToUse.accesskey "A"> <!ENTITY languages.customize.Fallback.grouplabel "Character Encoding for Legacy Content"> <!ENTITY languages.customize.Fallback.label "Fallback Character Encoding:"> <!ENTITY languages.customize.Fallback.accesskey "C"> <!ENTITY languages.customize.Fallback.desc "This character encoding is used for legacy content that fails to declare its encoding."> + +<!ENTITY languages.customize.Fallback.auto "Default for Current Locale"> +<!-- LOCALIZATION NOTE (languages.customize.Fallback.arabic): + Translate "Arabic" as an adjective for an encoding, not as the name of the language. --> +<!ENTITY languages.customize.Fallback.arabic "Arabic"> +<!ENTITY languages.customize.Fallback.baltic "Baltic"> +<!ENTITY languages.customize.Fallback.ceiso "Central European, ISO"> +<!ENTITY languages.customize.Fallback.cewindows "Central European, Microsoft"> +<!-- LOCALIZATION NOTE (languages.customize.Fallback.simplified): + Translate "Chinese" as an adjective for an encoding, not as the name of the language. --> +<!ENTITY languages.customize.Fallback.simplified "Chinese, Simplified"> +<!-- LOCALIZATION NOTE (languages.customize.Fallback.traditional): + Translate "Chinese" as an adjective for an encoding, not as the name of the language. --> +<!ENTITY languages.customize.Fallback.traditional "Chinese, Traditional"> +<!ENTITY languages.customize.Fallback.cyrillic "Cyrillic"> +<!-- LOCALIZATION NOTE (languages.customize.Fallback.greek): + Translate "Greek" as an adjective for an encoding, not as the name of the language. --> +<!ENTITY languages.customize.Fallback.greek "Greek"> +<!-- LOCALIZATION NOTE (languages.customize.Fallback.hebrew): + Translate "Hebrew" as an adjective for an encoding, not as the name of the language. --> +<!ENTITY languages.customize.Fallback.hebrew "Hebrew"> +<!-- LOCALIZATION NOTE (languages.customize.Fallback.japanese): + Translate "Japanese" as an adjective for an encoding, not as the name of the language. --> +<!ENTITY languages.customize.Fallback.japanese "Japanese"> +<!-- LOCALIZATION NOTE (languages.customize.Fallback.korean): + Translate "Korean" as an adjective for an encoding, not as the name of the language. --> +<!ENTITY languages.customize.Fallback.korean "Korean"> +<!-- LOCALIZATION NOTE (languages.customize.Fallback.thai): + Translate "Thai" as an adjective for an encoding, not as the name of the language. --> +<!ENTITY languages.customize.Fallback.thai "Thai"> +<!-- LOCALIZATION NOTE (languages.customize.Fallback.turkish): + Translate "Turkish" as an adjective for an encoding, not as the name of the language. --> +<!ENTITY languages.customize.Fallback.turkish "Turkish"> +<!-- LOCALIZATION NOTE (languages.customize.Fallback.vietnamese): + Translate "Vietnamese" as an adjective for an encoding, not as the name of the language. --> +<!ENTITY languages.customize.Fallback.vietnamese "Vietnamese"> +<!ENTITY languages.customize.Fallback.other "Other (incl. Western European)">
--- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -78,16 +78,17 @@ #include "nsArrayUtils.h" #include "nsIEffectiveTLDService.h" #include "nsIPrompt.h" //AHMED 12-2 #include "nsBidiUtils.h" #include "mozilla/dom/EncodingUtils.h" +#include "mozilla/dom/FallbackEncoding.h" #include "nsIEditingSession.h" #include "nsIEditor.h" #include "nsNodeInfoManager.h" #include "nsIPlaintextEditor.h" #include "nsIHTMLEditor.h" #include "nsIEditorStyleSheets.h" #include "nsIInlineSpellChecker.h" #include "nsRange.h" @@ -440,36 +441,23 @@ nsHTMLDocument::TryParentCharset(nsIDocS } aCharset.Assign(parentCharset); aCharsetSource = kCharsetFromParentFrame; } } void -nsHTMLDocument::TryWeakDocTypeDefault(int32_t& aCharsetSource, - nsACString& aCharset) +nsHTMLDocument::TryFallback(int32_t& aCharsetSource, nsACString& aCharset) { - if (kCharsetFromWeakDocTypeDefault <= aCharsetSource) + if (kCharsetFromFallback <= aCharsetSource) return; - const nsAdoptingCString& defCharset = - Preferences::GetLocalizedCString("intl.charset.default"); - - // Don't let the user break things by setting intl.charset.default to - // not a rough ASCII superset - nsAutoCString canonical; - if (EncodingUtils::FindEncodingForLabel(defCharset, canonical) && - EncodingUtils::IsAsciiCompatible(canonical)) { - aCharset = canonical; - } else { - aCharset.AssignLiteral("windows-1252"); - } - aCharsetSource = kCharsetFromWeakDocTypeDefault; - return; + aCharsetSource = kCharsetFromFallback; + FallbackEncoding::FromLocale(aCharset); } void nsHTMLDocument::SetDocumentCharacterSet(const nsACString& aCharSetID) { nsDocument::SetDocumentCharacterSet(aCharSetID); // Make sure to stash this charset on our channel as needed if it's a wyciwyg // channel. @@ -637,17 +625,17 @@ nsHTMLDocument::StartDocumentLoad(const // For error reporting nsHtml5TreeOpExecutor* executor = nullptr; if (loadAsHtml5) { executor = static_cast<nsHtml5TreeOpExecutor*> (mParser->GetContentSink()); } if (!IsHTML() || !docShell) { // no docshell for text/html XHR - charsetSource = IsHTML() ? kCharsetFromWeakDocTypeDefault + charsetSource = IsHTML() ? kCharsetFromFallback : kCharsetFromDocTypeDefault; charset.AssignLiteral("UTF-8"); TryChannelCharset(aChannel, charsetSource, charset, executor); parserCharsetSource = charsetSource; parserCharset = charset; } else { NS_ASSERTION(docShell, "Unexpected null value"); @@ -678,17 +666,17 @@ nsHTMLDocument::StartDocumentLoad(const TryHintCharset(muCV, charsetSource, charset); // XXX mailnews-only TryParentCharset(docShell, charsetSource, charset); if (cachingChan && !urlSpec.IsEmpty()) { TryCacheCharset(cachingChan, charsetSource, charset); } - TryWeakDocTypeDefault(charsetSource, charset); + TryFallback(charsetSource, charset); if (wyciwygChannel) { // We know for sure that the parser needs to be using UTF16. parserCharset = "UTF-16"; parserCharsetSource = charsetSource < kCharsetFromChannel ? kCharsetFromChannel : charsetSource; nsAutoCString cachedCharset;
--- a/content/html/document/src/nsHTMLDocument.h +++ b/content/html/document/src/nsHTMLDocument.h @@ -308,18 +308,17 @@ protected: nsIDocShell* aDocShell, int32_t& aCharsetSource, nsACString& aCharset); static void TryCacheCharset(nsICachingChannel* aCachingChannel, int32_t& aCharsetSource, nsACString& aCharset); void TryParentCharset(nsIDocShell* aDocShell, int32_t& charsetSource, nsACString& aCharset); - static void TryWeakDocTypeDefault(int32_t& aCharsetSource, - nsACString& aCharset); + static void TryFallback(int32_t& aCharsetSource, nsACString& aCharset); // Override so we can munge the charset on our wyciwyg channel as needed. virtual void SetDocumentCharacterSet(const nsACString& aCharSetID) MOZ_OVERRIDE; // Tracks if we are currently processing any document.write calls (either // implicit or explicit). Note that if a write call writes out something which // would block the parser, then mWriteLevel will be incorrect until the parser // finishes processing that script.
--- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -1891,17 +1891,17 @@ nsDocShell::GatherCharsetMenuTelemetry() bool isFileURL = false; nsIURI* url = doc->GetOriginalURI(); if (url) { url->SchemeIs("file", &isFileURL); } int32_t charsetSource = doc->GetDocumentCharacterSetSource(); switch (charsetSource) { - case kCharsetFromWeakDocTypeDefault: + case kCharsetFromFallback: case kCharsetFromDocTypeDefault: case kCharsetFromCache: case kCharsetFromParentFrame: case kCharsetFromHintPrevDoc: // Changing charset on an unlabeled doc. if (isFileURL) { Telemetry::Accumulate(Telemetry::CHARSET_OVERRIDE_SITUATION, 0); } else {
--- a/dom/bluetooth/BluetoothServiceBluedroid.cpp +++ b/dom/bluetooth/BluetoothServiceBluedroid.cpp @@ -56,30 +56,107 @@ public: private: BluetoothSignal mSignal; }; /** * Static variables */ - static bluetooth_device_t* sBtDevice; static const bt_interface_t* sBtInterface; static bool sIsBtEnabled = false; static bool sAdapterDiscoverable = false; static nsString sAdapterBdAddress; static nsString sAdapterBdName; static uint32_t sAdapterDiscoverableTimeout; +static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sChangeDiscoveryRunnableArray; static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sSetPropertyRunnableArray; /** * Static callback functions */ static void +ClassToIcon(uint32_t aClass, nsAString& aRetIcon) +{ + switch ((aClass & 0x1f00) >> 8) { + case 0x01: + aRetIcon.AssignLiteral("computer"); + break; + case 0x02: + switch ((aClass & 0xfc) >> 2) { + case 0x01: + case 0x02: + case 0x03: + case 0x05: + aRetIcon.AssignLiteral("phone"); + break; + case 0x04: + aRetIcon.AssignLiteral("modem"); + break; + } + break; + case 0x03: + aRetIcon.AssignLiteral("network-wireless"); + break; + case 0x04: + switch ((aClass & 0xfc) >> 2) { + case 0x01: + case 0x02: + case 0x06: + aRetIcon.AssignLiteral("audio-card"); + break; + case 0x0b: + case 0x0c: + case 0x0d: + aRetIcon.AssignLiteral("camera-video"); + break; + default: + aRetIcon.AssignLiteral("audio-card"); + break; + } + break; + case 0x05: + switch ((aClass & 0xc0) >> 6) { + case 0x00: + switch ((aClass && 0x1e) >> 2) { + case 0x01: + case 0x02: + aRetIcon.AssignLiteral("input-gaming"); + break; + } + break; + case 0x01: + aRetIcon.AssignLiteral("input-keyboard"); + break; + case 0x02: + switch ((aClass && 0x1e) >> 2) { + case 0x05: + aRetIcon.AssignLiteral("input-tablet"); + break; + default: + aRetIcon.AssignLiteral("input-mouse"); + break; + } + } + break; + case 0x06: + if (aClass & 0x80) { + aRetIcon.AssignLiteral("printer"); + break; + } + if (aClass & 0x20) { + aRetIcon.AssignLiteral("camera-photo"); + break; + } + break; + } +} + +static void AdapterStateChangeCallback(bt_state_t aStatus) { MOZ_ASSERT(!NS_IsMainThread()); BT_LOGD("%s, BT_STATE:%d", __FUNCTION__, aStatus); nsAutoString signalName; if (aStatus == BT_STATE_ON) { sIsBtEnabled = true; @@ -105,16 +182,26 @@ BdAddressTypeToString(bt_bdaddr_t* aBdAd sprintf((char*)bdstr, "%02x:%02x:%02x:%02x:%02x:%02x", (int)addr[0],(int)addr[1],(int)addr[2], (int)addr[3],(int)addr[4],(int)addr[5]); aRetBdAddress = NS_ConvertUTF8toUTF16((char*)bdstr); } +static bool +IsReady() +{ + if (!sBtInterface || !sIsBtEnabled) { + BT_LOGR("Warning! Bluetooth Service is not ready"); + return false; + } + return true; +} + static void AdapterPropertiesChangeCallback(bt_status_t aStatus, int aNumProperties, bt_property_t *aProperties) { MOZ_ASSERT(!NS_IsMainThread()); BluetoothValue propertyValue; InfallibleTArray<BluetoothNamedValue> propertiesArray; @@ -167,20 +254,120 @@ AdapterPropertiesChangeCallback(bt_statu if (!sSetPropertyRunnableArray.IsEmpty()) { DispatchBluetoothReply(sSetPropertyRunnableArray[0], BluetoothValue(true), EmptyString()); sSetPropertyRunnableArray.RemoveElementAt(0); } } } -bt_callbacks_t sBluetoothCallbacks = { +static void +RemoteDevicePropertiesChangeCallback(bt_status_t aStatus, + bt_bdaddr_t *aBdAddress, + int aNumProperties, + bt_property_t *aProperties) +{ + MOZ_ASSERT(!NS_IsMainThread()); + + // First, get remote device bd_address since it will be the key of + // return name value pair. + nsString remoteDeviceBdAddress; + BdAddressTypeToString(aBdAddress, remoteDeviceBdAddress); + + InfallibleTArray<BluetoothNamedValue> deviceProperties; + + for (int i = 0; i < aNumProperties; ++i) { + bt_property_t p = aProperties[i]; + + if (p.type == BT_PROPERTY_BDNAME) { + BluetoothValue propertyValue = NS_ConvertUTF8toUTF16((char*)p.val); + deviceProperties.AppendElement( + BluetoothNamedValue(NS_LITERAL_STRING("Name"), propertyValue)); + } else if (p.type == BT_PROPERTY_CLASS_OF_DEVICE) { + uint32_t cod = *(uint32_t*)p.val; + deviceProperties.AppendElement( + BluetoothNamedValue(NS_LITERAL_STRING("Class"), BluetoothValue(cod))); + nsString icon; + ClassToIcon(cod, icon); + deviceProperties.AppendElement( + BluetoothNamedValue(NS_LITERAL_STRING("Icon"), BluetoothValue(icon))); + } else { + BT_LOGR("Other non-handled device properties. Type: %d", p.type); + } + } +} + +static void +DeviceFoundCallback(int aNumProperties, bt_property_t *aProperties) +{ + MOZ_ASSERT(!NS_IsMainThread()); + + BluetoothValue propertyValue; + InfallibleTArray<BluetoothNamedValue> propertiesArray; + + for (int i = 0; i < aNumProperties; i++) { + bt_property_t p = aProperties[i]; + + if (p.type == BT_PROPERTY_BDADDR) { + nsString remoteDeviceBdAddress; + BdAddressTypeToString((bt_bdaddr_t*)p.val, remoteDeviceBdAddress); + propertyValue = remoteDeviceBdAddress; + propertiesArray.AppendElement( + BluetoothNamedValue(NS_LITERAL_STRING("Address"), propertyValue)); + } else if (p.type == BT_PROPERTY_BDNAME) { + propertyValue = NS_ConvertUTF8toUTF16((char*)p.val); + propertiesArray.AppendElement( + BluetoothNamedValue(NS_LITERAL_STRING("Name"), propertyValue)); + } else if (p.type == BT_PROPERTY_CLASS_OF_DEVICE) { + uint32_t cod = *(uint32_t*)p.val; + propertyValue = cod; + propertiesArray.AppendElement( + BluetoothNamedValue(NS_LITERAL_STRING("Class"), propertyValue)); + nsString icon; + ClassToIcon(cod, icon); + propertyValue = icon; + propertiesArray.AppendElement( + BluetoothNamedValue(NS_LITERAL_STRING("Icon"), propertyValue)); + } else { + BT_LOGD("Not handled remote device property: %d", p.type); + } + } + + BluetoothValue value = propertiesArray; + BluetoothSignal signal(NS_LITERAL_STRING("DeviceFound"), + NS_LITERAL_STRING(KEY_ADAPTER), value); + nsRefPtr<DistributeBluetoothSignalTask> + t = new DistributeBluetoothSignalTask(signal); + if (NS_FAILED(NS_DispatchToMainThread(t))) { + NS_WARNING("Failed to dispatch to main thread!"); + } +} + +static void +DiscoveryStateChangedCallback(bt_discovery_state_t aState) +{ + MOZ_ASSERT(!NS_IsMainThread()); + + if (!sChangeDiscoveryRunnableArray.IsEmpty()) { + BluetoothValue values(true); + DispatchBluetoothReply(sChangeDiscoveryRunnableArray[0], + values, EmptyString()); + + sChangeDiscoveryRunnableArray.RemoveElementAt(0); + } +} + +bt_callbacks_t sBluetoothCallbacks = +{ sizeof(sBluetoothCallbacks), AdapterStateChangeCallback, - AdapterPropertiesChangeCallback + AdapterPropertiesChangeCallback, + RemoteDevicePropertiesChangeCallback, + DeviceFoundCallback, + DiscoveryStateChangedCallback }; /** * Static functions */ static bool EnsureBluetoothHalLoad() { @@ -330,23 +517,53 @@ BluetoothServiceBluedroid::GetPairedDevi { return NS_OK; } nsresult BluetoothServiceBluedroid::StartDiscoveryInternal( BluetoothReplyRunnable* aRunnable) { + MOZ_ASSERT(NS_IsMainThread()); + + if (!IsReady()) { + NS_NAMED_LITERAL_STRING(errorStr, "Bluetooth service is not ready yet!"); + DispatchBluetoothReply(aRunnable, BluetoothValue(), errorStr); + + return NS_OK; + } + int ret = sBtInterface->start_discovery(); + if (ret != BT_STATUS_SUCCESS) { + ReplyStatusError(aRunnable, ret, NS_LITERAL_STRING("StartDiscovery")); + + return NS_OK; + } + + sChangeDiscoveryRunnableArray.AppendElement(aRunnable); return NS_OK; } nsresult BluetoothServiceBluedroid::StopDiscoveryInternal( BluetoothReplyRunnable* aRunnable) { + MOZ_ASSERT(NS_IsMainThread()); + + if (!IsReady()) { + NS_NAMED_LITERAL_STRING(errorStr, "Bluetooth service is not ready yet!"); + DispatchBluetoothReply(aRunnable, BluetoothValue(), errorStr); + return NS_OK; + } + int ret = sBtInterface->cancel_discovery(); + if (ret != BT_STATUS_SUCCESS) { + ReplyStatusError(aRunnable, ret, NS_LITERAL_STRING("StopDiscovery")); + return NS_OK; + } + + sChangeDiscoveryRunnableArray.AppendElement(aRunnable); return NS_OK; } nsresult BluetoothServiceBluedroid::GetDevicePropertiesInternal( const BluetoothSignal& aSignal) { return NS_OK; @@ -354,16 +571,23 @@ BluetoothServiceBluedroid::GetDeviceProp nsresult BluetoothServiceBluedroid::SetProperty(BluetoothObjectType aType, const BluetoothNamedValue& aValue, BluetoothReplyRunnable* aRunnable) { MOZ_ASSERT(NS_IsMainThread()); + if (!IsReady()) { + NS_NAMED_LITERAL_STRING(errorStr, "Bluetooth service is not ready yet!"); + DispatchBluetoothReply(aRunnable, BluetoothValue(), errorStr); + + return NS_OK; + } + const nsString propName = aValue.name(); bt_property_t prop; nsString str; // For Bluedroid, it's necessary to check property name for SetProperty if (propName.EqualsLiteral("Name")) { prop.type = BT_PROPERTY_BDNAME; } else if (propName.EqualsLiteral("Discoverable")) {
new file mode 100644 --- /dev/null +++ b/dom/encoding/FallbackEncoding.cpp @@ -0,0 +1,137 @@ +/* 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/. */ + +#include "mozilla/dom/FallbackEncoding.h" + +#include "mozilla/dom/EncodingUtils.h" +#include "nsUConvPropertySearch.h" +#include "nsIChromeRegistry.h" +#include "mozilla/Preferences.h" +#include "mozilla/Services.h" + +namespace mozilla { +namespace dom { + +static const char* localesFallbacks[][3] = { +#include "localesfallbacks.properties.h" +}; + +FallbackEncoding* FallbackEncoding::sInstance = nullptr; + +FallbackEncoding::FallbackEncoding() +{ + MOZ_COUNT_CTOR(FallbackEncoding); + MOZ_ASSERT(!FallbackEncoding::sInstance, + "Singleton already exists."); +} + +FallbackEncoding::~FallbackEncoding() +{ + MOZ_COUNT_DTOR(FallbackEncoding); +} + +void +FallbackEncoding::Get(nsACString& aFallback) +{ + if (!mFallback.IsEmpty()) { + aFallback = mFallback; + return; + } + + const nsAdoptingCString& override = + Preferences::GetCString("intl.charset.fallback.override"); + // Don't let the user break things by setting the override to unreasonable + // values via about:config + if (!EncodingUtils::FindEncodingForLabel(override, mFallback) || + !EncodingUtils::IsAsciiCompatible(mFallback) || + mFallback.EqualsLiteral("UTF-8")) { + mFallback.Truncate(); + } + + if (!mFallback.IsEmpty()) { + aFallback = mFallback; + return; + } + + nsAutoCString locale; + nsCOMPtr<nsIXULChromeRegistry> registry = + mozilla::services::GetXULChromeRegistryService(); + if (registry) { + registry->GetSelectedLocale(NS_LITERAL_CSTRING("global"), locale); + } + + // Let's lower case the string just in case unofficial language packs + // don't stick to conventions. + ToLowerCase(locale); // ASCII lowercasing with CString input! + + // Special case Traditional Chinese before throwing away stuff after the + // language itself. Today we only ship zh-TW, but be defensive about + // possible future values. + if (locale.EqualsLiteral("zh-tw") || + locale.EqualsLiteral("zh-hk") || + locale.EqualsLiteral("zh-mo") || + locale.EqualsLiteral("zh-hant")) { + mFallback.AssignLiteral("Big5"); + aFallback = mFallback; + return; + } + + // Throw away regions and other variants to accommodate weird stuff seen + // in telemetry--apparently unofficial language packs. + int32_t index = locale.FindChar('-'); + if (index >= 0) { + locale.Truncate(index); + } + + if (NS_FAILED(nsUConvPropertySearch::SearchPropertyValue( + localesFallbacks, ArrayLength(localesFallbacks), locale, mFallback))) { + mFallback.AssignLiteral("windows-1252"); + } + + aFallback = mFallback; +} + +void +FallbackEncoding::FromLocale(nsACString& aFallback) +{ + MOZ_ASSERT(FallbackEncoding::sInstance, + "Using uninitialized fallback cache."); + FallbackEncoding::sInstance->Get(aFallback); +} + +// PrefChangedFunc +int +FallbackEncoding::PrefChanged(const char*, void*) +{ + MOZ_ASSERT(FallbackEncoding::sInstance, + "Pref callback called with null fallback cache."); + FallbackEncoding::sInstance->Invalidate(); + return 0; +} + +void +FallbackEncoding::Initialize() +{ + MOZ_ASSERT(!FallbackEncoding::sInstance, + "Initializing pre-existing fallback cache."); + FallbackEncoding::sInstance = new FallbackEncoding; + Preferences::RegisterCallback(FallbackEncoding::PrefChanged, + "intl.charset.fallback.override", + nullptr); + Preferences::RegisterCallback(FallbackEncoding::PrefChanged, + "general.useragent.locale", + nullptr); +} + +void +FallbackEncoding::Shutdown() +{ + MOZ_ASSERT(FallbackEncoding::sInstance, + "Releasing non-existent fallback cache."); + delete FallbackEncoding::sInstance; + FallbackEncoding::sInstance = nullptr; +} + +} // namespace dom +} // namespace mozilla
new file mode 100644 --- /dev/null +++ b/dom/encoding/FallbackEncoding.h @@ -0,0 +1,72 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_FallbackEncoding_h_ +#define mozilla_dom_FallbackEncoding_h_ + +#include "nsString.h" + +namespace mozilla { +namespace dom { + +class FallbackEncoding +{ +public: + + /** + * Gets the locale-dependent fallback encoding for legacy HTML and plain + * text content. + * + * @param aFallback the outparam for the fallback encoding + */ + static void FromLocale(nsACString& aFallback); + + // public API ends here! + + /** + * Allocate sInstance used by FromLocale(). + * To be called from nsLayoutStatics only. + */ + static void Initialize(); + + /** + * Delete sInstance used by FromLocale(). + * To be called from nsLayoutStatics only. + */ + static void Shutdown(); + +private: + + /** + * The fallback cache. + */ + static FallbackEncoding* sInstance; + + FallbackEncoding(); + ~FallbackEncoding(); + + /** + * Invalidates the cache. + */ + void Invalidate() + { + mFallback.Truncate(); + } + + static int PrefChanged(const char*, void*); + + /** + * Gets the fallback encoding label. + * @param aFallback the fallback encoding + */ + void Get(nsACString& aFallback); + + nsCString mFallback; +}; + +} // dom +} // mozilla + +#endif // mozilla_dom_FallbackEncoding_h_ +
--- a/dom/encoding/Makefile.in +++ b/dom/encoding/Makefile.in @@ -4,16 +4,20 @@ LOCAL_INCLUDES = \ -I$(topsrcdir)/intl/locale/src \ $(NULL) include $(topsrcdir)/config/rules.mk EncodingUtils.$(OBJ_SUFFIX): labelsencodings.properties.h +FallbackEncoding.$(OBJ_SUFFIX): localesfallbacks.properties.h PROPS2ARRAYS = $(topsrcdir)/intl/locale/src/props2arrays.py labelsencodings.properties.h: $(PROPS2ARRAYS) labelsencodings.properties $(PYTHON) $^ $@ +localesfallbacks.properties.h: $(PROPS2ARRAYS) localesfallbacks.properties + $(PYTHON) $^ $@ GARBAGE += \ - charsetalias.properties.h \ + labelsencodings.properties.h \ + localesfallbacks.properties.h \ $(NULL)
new file mode 100644 --- /dev/null +++ b/dom/encoding/localesfallbacks.properties @@ -0,0 +1,72 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# This file contains mappings from languages to legacy encodings for languages +# that are associated with legacy encoding other than windows-1252 (except +# Traditional Chinese, which is handled as a special case elsewhere). +# +# The keys are language codes without regions. The values are Gecko-canonical +# encoding labels (not necessarily lower case!). +# +# Rules: +# +# * Avoid editing this file! +# +# * If you do edit this file, be sure to file a spec bug against WHATWG HTML +# to keep this file in sync with +# http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#determining-the-character-encoding +# +# * As an exception to the previous rule, gbk is used instead of GB18030 +# until/unless work on http://encoding.spec.whatwg.org/ shows that the former +# can be treated as an alias of the latter and our decoder implementation +# has been audited to match the spec. +# +# * Use only the language code without a hyphen or anything that would come +# after the hyphen. +# +# * Don't put windows-1252-affiliated languages here. +# +# * Don't put Traditional Chinese here. + +ar=windows-1256 +# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23089 +ba=windows-1251 +# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23089 +be=windows-1251 +bg=windows-1251 +cs=windows-1250 +# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23090 +el=ISO-8859-7 +et=windows-1257 +fa=windows-1256 +he=windows-1255 +hr=windows-1250 +hu=ISO-8859-2 +ja=Shift_JIS +# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23089 +kk=windows-1251 +ko=EUC-KR +ku=windows-1254 +# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23089 +ky=windows-1251 +lt=windows-1257 +lv=windows-1257 +# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23089 +mk=windows-1251 +pl=ISO-8859-2 +ru=windows-1251 +# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23089 +sah=windows-1251 +sk=windows-1250 +sl=ISO-8859-2 +sr=windows-1251 +# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23089 +tg=windows-1251 +th=windows-874 +tr=windows-1254 +# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23089 +tt=windows-1251 +uk=windows-1251 +vi=windows-1258 +zh=gbk
--- a/dom/encoding/moz.build +++ b/dom/encoding/moz.build @@ -5,22 +5,24 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. TEST_DIRS += ['test'] MODULE = 'dom' EXPORTS.mozilla.dom += [ 'EncodingUtils.h', + 'FallbackEncoding.h', 'TextDecoder.h', 'TextEncoder.h', ] SOURCES += [ 'EncodingUtils.cpp', + 'FallbackEncoding.cpp', 'TextDecoder.cpp', 'TextEncoder.cpp', ] FAIL_ON_WARNINGS = True LIBXUL_LIBRARY = True
--- a/dom/indexedDB/IDBDatabase.h +++ b/dom/indexedDB/IDBDatabase.h @@ -157,16 +157,22 @@ public: return mContentParent; } already_AddRefed<IDBObjectStore> CreateObjectStoreInternal(IDBTransaction* aTransaction, const ObjectStoreInfoGuts& aInfo, ErrorResult& aRv); + IDBFactory* + Factory() const + { + return mFactory; + } + // nsWrapperCache virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE; // WebIDL nsPIDOMWindow* GetParentObject() const { @@ -217,16 +223,17 @@ public: return PersistenceTypeToStorage(mPersistenceType); } already_AddRefed<IDBRequest> MozCreateFileHandle(const nsAString& aName, const Optional<nsAString>& aType, ErrorResult& aRv); virtual void LastRelease() MOZ_OVERRIDE; + private: IDBDatabase(); ~IDBDatabase(); void OnUnlink(); // The factory must be kept alive when IndexedDB is used in multiple // processes. If it dies then the entire actor tree will be destroyed with it
--- a/dom/indexedDB/IDBFactory.h +++ b/dom/indexedDB/IDBFactory.h @@ -142,16 +142,22 @@ public: } const nsCString& GetASCIIOrigin() const { return mASCIIOrigin; } + bool + FromIPC() + { + return !!mContentParent; + } + // nsWrapperCache virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE; // WebIDL nsPIDOMWindow* GetParentObject() const {
--- a/dom/indexedDB/IDBRequest.cpp +++ b/dom/indexedDB/IDBRequest.cpp @@ -61,69 +61,60 @@ IDBRequest::IDBRequest() IDBRequest::~IDBRequest() { mResultVal = JSVAL_VOID; NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); } // static already_AddRefed<IDBRequest> -IDBRequest::Create(IDBWrapperCache* aOwnerCache, +IDBRequest::Create(IDBDatabase* aDatabase, IDBTransaction* aTransaction) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); nsRefPtr<IDBRequest> request(new IDBRequest()); request->mTransaction = aTransaction; - request->BindToOwner(aOwnerCache); - request->SetScriptOwner(aOwnerCache->GetScriptOwner()); - request->CaptureCaller(); + request->BindToOwner(aDatabase); + request->SetScriptOwner(aDatabase->GetScriptOwner()); + + if (!aDatabase->Factory()->FromIPC()) { + request->CaptureCaller(); + } + return request.forget(); } // static already_AddRefed<IDBRequest> IDBRequest::Create(IDBObjectStore* aSourceAsObjectStore, - IDBWrapperCache* aOwnerCache, + IDBDatabase* aDatabase, IDBTransaction* aTransaction) { - nsRefPtr<IDBRequest> request = Create(aOwnerCache, aTransaction); + nsRefPtr<IDBRequest> request = Create(aDatabase, aTransaction); request->mSourceAsObjectStore = aSourceAsObjectStore; return request.forget(); } // static already_AddRefed<IDBRequest> IDBRequest::Create(IDBIndex* aSourceAsIndex, - IDBWrapperCache* aOwnerCache, + IDBDatabase* aDatabase, IDBTransaction* aTransaction) { - nsRefPtr<IDBRequest> request = Create(aOwnerCache, aTransaction); + nsRefPtr<IDBRequest> request = Create(aDatabase, aTransaction); request->mSourceAsIndex = aSourceAsIndex; return request.forget(); } -// static -already_AddRefed<IDBRequest> -IDBRequest::Create(IDBCursor* aSourceAsCursor, - IDBWrapperCache* aOwnerCache, - IDBTransaction* aTransaction) -{ - nsRefPtr<IDBRequest> request = Create(aOwnerCache, aTransaction); - - request->mSourceAsCursor = aSourceAsCursor; - - return request.forget(); -} - #ifdef DEBUG void IDBRequest::AssertSourceIsCorrect() const { // At most one of mSourceAs* is allowed to be non-null. Check that by // summing the double negation of each one and asserting the sum is at most // 1. @@ -282,21 +273,17 @@ IDBRequest::GetJSContext() void IDBRequest::CaptureCaller() { AutoJSContext cx; const char* filename = nullptr; uint32_t lineNo = 0; if (!nsJSUtils::GetCallingLocation(cx, &filename, &lineNo)) { - // If our caller is in another process, we won't have a JSContext on the - // stack, and AutoJSContext will push the SafeJSContext. But that won't have - // any script on it (certainly not after the push), so GetCallingLocation - // will fail when it calls JS_DescribeScriptedCaller. That's fine. - NS_WARNING("Failed to get caller."); + MOZ_CRASH("Failed to get caller."); return; } mFilename.Assign(NS_ConvertUTF8toUTF16(filename)); mLineNo = lineNo; } void @@ -413,19 +400,22 @@ IDBOpenDBRequest::Create(IDBFactory* aFa { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(aFactory, "Null pointer!"); nsRefPtr<IDBOpenDBRequest> request = new IDBOpenDBRequest(); request->BindToOwner(aOwner); request->SetScriptOwner(aScriptOwner); - request->CaptureCaller(); request->mFactory = aFactory; + if (!aFactory->FromIPC()) { + request->CaptureCaller(); + } + return request.forget(); } void IDBOpenDBRequest::SetTransaction(IDBTransaction* aTransaction) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
--- a/dom/indexedDB/IDBRequest.h +++ b/dom/indexedDB/IDBRequest.h @@ -41,31 +41,27 @@ class IndexedDBRequestParentBase; class IDBRequest : public IDBWrapperCache { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(IDBRequest, IDBWrapperCache) static - already_AddRefed<IDBRequest> Create(IDBWrapperCache* aOwnerCache, + already_AddRefed<IDBRequest> Create(IDBDatabase* aDatabase, IDBTransaction* aTransaction); static already_AddRefed<IDBRequest> Create(IDBObjectStore* aSource, - IDBWrapperCache* aOwnerCache, + IDBDatabase* aDatabase, IDBTransaction* aTransaction); static already_AddRefed<IDBRequest> Create(IDBIndex* aSource, - IDBWrapperCache* aOwnerCache, - IDBTransaction* aTransaction); - static - already_AddRefed<IDBRequest> Create(IDBCursor* aSource, - IDBWrapperCache* aOwnerCache, + IDBDatabase* aDatabase, IDBTransaction* aTransaction); // nsIDOMEventTarget virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE; void GetSource(Nullable<OwningIDBObjectStoreOrIDBIndexOrIDBCursor>& aSource) const; void Reset();
--- a/dom/mobilemessage/interfaces/nsIDOMMobileMessageManager.idl +++ b/dom/mobilemessage/interfaces/nsIDOMMobileMessageManager.idl @@ -6,17 +6,17 @@ interface nsIDOMEventListener; interface nsIDOMMozSmsFilter; interface nsIDOMMozSmsSegmentInfo; interface nsIDOMDOMCursor; interface nsIDOMDOMRequest; interface nsIDOMBlob; -[scriptable, builtinclass, uuid(d1e35354-3d21-11e3-86da-77253f4c5683)] +[scriptable, builtinclass, uuid(0e4ff35e-ab84-434a-96b4-46807798cc7e)] interface nsIDOMMozMobileMessageManager : nsIDOMEventTarget { nsIDOMDOMRequest getSegmentInfoForText(in DOMString text); /** * Function to send SMS. * @@ -52,17 +52,18 @@ interface nsIDOMMozMobileMessageManager nsIDOMDOMRequest getMessage(in long id); // The parameter can be either a message id or a nsIDOMMoz{Mms,Sms}Message. nsIDOMDOMRequest delete(in jsval param); // Iterates through nsIDOMMoz{Mms,Sms}Message. nsIDOMDOMCursor getMessages(in nsIDOMMozSmsFilter filter, in boolean reverse); - nsIDOMDOMRequest markMessageRead(in long id, in boolean value); + nsIDOMDOMRequest markMessageRead(in long id, in boolean value, + [optional] in boolean aSendReadReport); // Iterates through nsIDOMMozMobileMessageThread. nsIDOMDOMCursor getThreads(); nsIDOMDOMRequest retrieveMMS(in long id); [implicit_jscontext] attribute jsval onreceived; [implicit_jscontext] attribute jsval onretrieving;
--- a/dom/mobilemessage/interfaces/nsIDOMMozMmsMessage.idl +++ b/dom/mobilemessage/interfaces/nsIDOMMozMmsMessage.idl @@ -16,17 +16,17 @@ dictionary MmsAttachment }; dictionary MmsDeliveryInfo { DOMString? receiver; DOMString? deliveryStatus; }; -[scriptable, builtinclass, uuid(35d88c5e-2746-11e3-9d7b-83ca2203a291)] +[scriptable, builtinclass, uuid(85bfc639-0d8f-43fa-8c12-6bd2958bf219)] interface nsIDOMMozMmsMessage : nsISupports { /** * |type| is always "mms". */ readonly attribute DOMString type; readonly attribute long id; @@ -62,9 +62,12 @@ interface nsIDOMMozMmsMessage : nsISuppo [implicit_jscontext] readonly attribute jsval attachments; // MmsAttachment[] [implicit_jscontext] readonly attribute jsval expiryDate; // Date object // Expiry date for an MMS to be // manually downloaded. + + // Request read report from sender or not. + readonly attribute boolean isReadReportRequested; };
--- a/dom/mobilemessage/interfaces/nsIMmsService.idl +++ b/dom/mobilemessage/interfaces/nsIMmsService.idl @@ -7,20 +7,24 @@ interface nsIMobileMessageCallback; interface nsIDOMBlob; %{C++ #define MMS_SERVICE_CID { 0x06d9124b, 0x80e0, 0x40ed, \ { 0x98, 0x71, 0x4d, 0x23, 0x4a, 0x0f, 0xd4, 0x31 } } #define MMS_SERVICE_CONTRACTID "@mozilla.org/mms/mmsservice;1" %} -[scriptable, uuid(544bfa56-3d60-11e3-8b69-2383ccac8c81)] +[scriptable, uuid(543278b3-d926-4c65-84b8-b49ad7a17d21)] interface nsIMmsService : nsISupports { readonly attribute unsigned long mmsDefaultServiceId; void send(in unsigned long serviceId, in jsval parameters /* MmsParameters */, in nsIMobileMessageCallback request); void retrieve(in long id, in nsIMobileMessageCallback request); + + void sendReadReport(in DOMString messageID, + in DOMString toAddress, + in DOMString iccId); };
--- a/dom/mobilemessage/interfaces/nsIMobileMessageDatabaseService.idl +++ b/dom/mobilemessage/interfaces/nsIMobileMessageDatabaseService.idl @@ -11,29 +11,30 @@ #define MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID "@mozilla.org/mobilemessage/mobilemessagedatabaseservice;1" %} interface nsICursorContinueCallback; interface nsIDOMMozSmsFilter; interface nsIMobileMessageCallback; interface nsIMobileMessageCursorCallback; -[scriptable, uuid(ea6f49ae-3a4c-47eb-a489-15578e634100)] +[scriptable, uuid(8439916f-abc1-4c67-aa45-8a276a0a7855)] interface nsIMobileMessageDatabaseService : nsISupports { [binaryname(GetMessageMoz)] void getMessage(in long messageId, in nsIMobileMessageCallback request); void deleteMessage([array, size_is(count)] in long messageIds, in uint32_t count, in nsIMobileMessageCallback request); nsICursorContinueCallback createMessageCursor(in nsIDOMMozSmsFilter filter, in boolean reverse, in nsIMobileMessageCursorCallback callback); void markMessageRead(in long messageId, in boolean value, + in boolean sendReadReport, in nsIMobileMessageCallback request); nsICursorContinueCallback createThreadCursor(in nsIMobileMessageCursorCallback callback); };
--- a/dom/mobilemessage/interfaces/nsIMobileMessageService.idl +++ b/dom/mobilemessage/interfaces/nsIMobileMessageService.idl @@ -9,17 +9,17 @@ interface nsIDOMMozMmsMessage; interface nsIDOMMozMobileMessageThread; interface nsIDOMMozSmsSegmentInfo; %{C++ #define MOBILE_MESSAGE_SERVICE_CID { 0x829c1dd6, 0x0466, 0x4591, { 0x83, 0x6f, 0xb8, 0xf6, 0xfd, 0x1f, 0x7b, 0xa5 } } #define MOBILE_MESSAGE_SERVICE_CONTRACTID "@mozilla.org/mobilemessage/mobilemessageservice;1" %} -[scriptable, builtinclass, uuid(729b616e-2766-11e3-9c6a-47e6110e44c6)] +[scriptable, builtinclass, uuid(7a39eeb4-827e-4c70-9804-288f94174ebe)] interface nsIMobileMessageService : nsISupports { [implicit_jscontext] nsIDOMMozSmsMessage createSmsMessage(in long id, in unsigned long long threadId, in DOMString iccId, in DOMString delivery, in DOMString deliveryStatus, @@ -39,17 +39,18 @@ interface nsIMobileMessageService : nsIS in jsval deliveryInfo, in DOMString sender, in jsval receivers, in jsval timestamp, in boolean read, in DOMString subject, in DOMString smil, in jsval attachments, - in jsval expiryDate); + in jsval expiryDate, + in boolean isReadReportRequested); nsIDOMMozSmsSegmentInfo createSmsSegmentInfo(in long segments, in long charsPerSegment, in long charsAvailableInLastSegment); [implicit_jscontext] nsIDOMMozMobileMessageThread createThread(in unsigned long long id, in jsval participants,
--- a/dom/mobilemessage/src/MmsMessage.cpp +++ b/dom/mobilemessage/src/MmsMessage.cpp @@ -40,45 +40,48 @@ MmsMessage::MmsMessage(int32_t const nsTArray<MmsDeliveryInfo>& aDeliveryInfo, const nsAString& aSender, const nsTArray<nsString>& aReceivers, uint64_t aTimestamp, bool aRead, const nsAString& aSubject, const nsAString& aSmil, const nsTArray<MmsAttachment>& aAttachments, - uint64_t aExpiryDate) + uint64_t aExpiryDate, + bool aIsReadReportRequested) : mId(aId), mThreadId(aThreadId), mIccId(aIccId), mDelivery(aDelivery), mDeliveryInfo(aDeliveryInfo), mSender(aSender), mReceivers(aReceivers), mTimestamp(aTimestamp), mRead(aRead), mSubject(aSubject), mSmil(aSmil), mAttachments(aAttachments), - mExpiryDate(aExpiryDate) + mExpiryDate(aExpiryDate), + mIsReadReportRequested(aIsReadReportRequested) { } MmsMessage::MmsMessage(const mobilemessage::MmsMessageData& aData) : mId(aData.id()) , mThreadId(aData.threadId()) , mIccId(aData.iccId()) , mDelivery(aData.delivery()) , mSender(aData.sender()) , mReceivers(aData.receivers()) , mTimestamp(aData.timestamp()) , mRead(aData.read()) , mSubject(aData.subject()) , mSmil(aData.smil()) , mExpiryDate(aData.expiryDate()) + , mIsReadReportRequested(aData.isReadReportRequested()) { uint32_t len = aData.attachments().Length(); mAttachments.SetCapacity(len); for (uint32_t i = 0; i < len; i++) { MmsAttachment att; const MmsAttachmentData &element = aData.attachments()[i]; att.id = element.id(); att.location = element.location(); @@ -170,16 +173,17 @@ MmsMessage::Create(int32_t const nsAString& aSender, const JS::Value& aReceivers, const JS::Value& aTimestamp, bool aRead, const nsAString& aSubject, const nsAString& aSmil, const JS::Value& aAttachments, const JS::Value& aExpiryDate, + bool aIsReadReportRequested, JSContext* aCx, nsIDOMMozMmsMessage** aMessage) { *aMessage = nullptr; // Set |delivery|. DeliveryState delivery; if (aDelivery.Equals(DELIVERY_SENT)) { @@ -289,17 +293,18 @@ MmsMessage::Create(int32_t deliveryInfo, aSender, receivers, timestamp, aRead, aSubject, aSmil, attachments, - expiryDate); + expiryDate, + aIsReadReportRequested); message.forget(aMessage); return NS_OK; } bool MmsMessage::GetData(ContentParent* aParent, mobilemessage::MmsMessageData& aData) { @@ -311,16 +316,17 @@ MmsMessage::GetData(ContentParent* aPare aData.delivery() = mDelivery; aData.sender().Assign(mSender); aData.receivers() = mReceivers; aData.timestamp() = mTimestamp; aData.read() = mRead; aData.subject() = mSubject; aData.smil() = mSmil; aData.expiryDate() = mExpiryDate; + aData.isReadReportRequested() = mIsReadReportRequested; aData.deliveryInfo().SetCapacity(mDeliveryInfo.Length()); for (uint32_t i = 0; i < mDeliveryInfo.Length(); i++) { MmsDeliveryInfoData infoData; const MmsDeliveryInfo &info = mDeliveryInfo[i]; infoData.receiver().Assign(info.receiver); DeliveryStatus status; @@ -609,10 +615,18 @@ MmsMessage::GetExpiryDate(JSContext* cx, { JSObject *obj = JS_NewDateObjectMsec(cx, mExpiryDate); NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE); *aDate = OBJECT_TO_JSVAL(obj); return NS_OK; } +NS_IMETHODIMP +MmsMessage::GetIsReadReportRequested(bool* aIsReadReportRequested) +{ + *aIsReadReportRequested = mIsReadReportRequested; + return NS_OK; +} + + } // namespace dom } // namespace mozilla
--- a/dom/mobilemessage/src/MmsMessage.h +++ b/dom/mobilemessage/src/MmsMessage.h @@ -34,33 +34,35 @@ public: const nsTArray<idl::MmsDeliveryInfo>& aDeliveryInfo, const nsAString& aSender, const nsTArray<nsString>& aReceivers, uint64_t aTimestamp, bool aRead, const nsAString& aSubject, const nsAString& aSmil, const nsTArray<idl::MmsAttachment>& aAttachments, - uint64_t aExpiryDate); + uint64_t aExpiryDate, + bool aIsReadReportRequested); MmsMessage(const mobilemessage::MmsMessageData& aData); static nsresult Create(int32_t aId, uint64_t aThreadId, const nsAString& aIccId, const nsAString& aDelivery, const JS::Value& aDeliveryInfo, const nsAString& aSender, const JS::Value& aReceivers, const JS::Value& aTimestamp, bool aRead, const nsAString& aSubject, const nsAString& aSmil, const JS::Value& aAttachments, const JS::Value& aExpiryDate, + bool aIsReadReportRequested, JSContext* aCx, nsIDOMMozMmsMessage** aMessage); bool GetData(ContentParent* aParent, mobilemessage::MmsMessageData& aData); private: @@ -72,14 +74,15 @@ private: nsString mSender; nsTArray<nsString> mReceivers; uint64_t mTimestamp; bool mRead; nsString mSubject; nsString mSmil; nsTArray<idl::MmsAttachment> mAttachments; uint64_t mExpiryDate; + bool mIsReadReportRequested; }; } // namespace dom } // namespace mozilla #endif // mozilla_dom_mobilemessage_MmsMessage_h
--- a/dom/mobilemessage/src/MobileMessageManager.cpp +++ b/dom/mobilemessage/src/MobileMessageManager.cpp @@ -392,25 +392,28 @@ MobileMessageManager::GetMessages(nsIDOM cursorCallback->mDOMCursor = new DOMCursor(GetOwner(), continueCallback); NS_ADDREF(*aCursor = cursorCallback->mDOMCursor); return NS_OK; } NS_IMETHODIMP MobileMessageManager::MarkMessageRead(int32_t aId, bool aValue, + bool aSendReadReport, nsIDOMDOMRequest** aRequest) { nsCOMPtr<nsIMobileMessageDatabaseService> mobileMessageDBService = do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID); NS_ENSURE_TRUE(mobileMessageDBService, NS_ERROR_FAILURE); nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner()); nsCOMPtr<nsIMobileMessageCallback> msgCallback = new MobileMessageCallback(request); - nsresult rv = mobileMessageDBService->MarkMessageRead(aId, aValue, msgCallback); + nsresult rv = mobileMessageDBService->MarkMessageRead(aId, aValue, + aSendReadReport, + msgCallback); NS_ENSURE_SUCCESS(rv, rv); request.forget(aRequest); return NS_OK; } NS_IMETHODIMP MobileMessageManager::GetThreads(nsIDOMDOMCursor** aCursor)
--- a/dom/mobilemessage/src/MobileMessageService.cpp +++ b/dom/mobilemessage/src/MobileMessageService.cpp @@ -69,32 +69,34 @@ MobileMessageService::CreateMmsMessage(i const nsAString& aSender, const JS::Value& aReceivers, const JS::Value& aTimestamp, bool aRead, const nsAString& aSubject, const nsAString& aSmil, const JS::Value& aAttachments, const JS::Value& aExpiryDate, + bool aIsReadReportRequested, JSContext* aCx, nsIDOMMozMmsMessage** aMessage) { return MmsMessage::Create(aId, aThreadId, aIccId, aDelivery, aDeliveryInfo, aSender, aReceivers, aTimestamp, aRead, aSubject, aSmil, aAttachments, aExpiryDate, + aIsReadReportRequested, aCx, aMessage); } NS_IMETHODIMP MobileMessageService::CreateSmsSegmentInfo(int32_t aSegments, int32_t aCharsPerSegment, int32_t aCharsAvailableInLastSegment,
--- a/dom/mobilemessage/src/android/MmsService.cpp +++ b/dom/mobilemessage/src/android/MmsService.cpp @@ -32,11 +32,20 @@ MmsService::Send(uint32_t aServiceid, NS_IMETHODIMP MmsService::Retrieve(int32_t aId, nsIMobileMessageCallback *aRequest) { // TODO: Bug 860174, implement this function. NS_NOTYETIMPLEMENTED("Implement me!"); return NS_ERROR_NOT_IMPLEMENTED; } +NS_IMETHODIMP +MmsService::SendReadReport(const nsAString & messageID, + const nsAString & toAddress, + const nsAString & iccId) +{ + NS_NOTYETIMPLEMENTED("Implement me!"); + return NS_ERROR_NOT_IMPLEMENTED; +} + } // namespace mobilemessage } // namespace dom } // namespace mozilla
--- a/dom/mobilemessage/src/android/MobileMessageDatabaseService.cpp +++ b/dom/mobilemessage/src/android/MobileMessageDatabaseService.cpp @@ -53,16 +53,17 @@ MobileMessageDatabaseService::CreateMess nsICursorContinueCallback** aResult) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP MobileMessageDatabaseService::MarkMessageRead(int32_t aMessageId, bool aValue, + bool aSendReadReport, nsIMobileMessageCallback* aRequest) { // TODO: This would need to be implemented as part of Bug 748391 return NS_OK; } NS_IMETHODIMP MobileMessageDatabaseService::CreateThreadCursor(nsIMobileMessageCursorCallback* aCallback,
--- a/dom/mobilemessage/src/fallback/MmsService.cpp +++ b/dom/mobilemessage/src/fallback/MmsService.cpp @@ -30,11 +30,20 @@ MmsService::Send(uint32_t aServiceId, NS_IMETHODIMP MmsService::Retrieve(int32_t aId, nsIMobileMessageCallback *aRequest) { NS_NOTYETIMPLEMENTED("Implement me!"); return NS_ERROR_NOT_IMPLEMENTED; } +NS_IMETHODIMP +MmsService::SendReadReport(const nsAString & messageID, + const nsAString & toAddress, + const nsAString & iccId) +{ + NS_NOTYETIMPLEMENTED("Implement me!"); + return NS_ERROR_NOT_IMPLEMENTED; +} + } // namespace mobilemessage } // namespace dom } // namespace mozilla
--- a/dom/mobilemessage/src/fallback/MobileMessageDatabaseService.cpp +++ b/dom/mobilemessage/src/fallback/MobileMessageDatabaseService.cpp @@ -36,16 +36,17 @@ MobileMessageDatabaseService::CreateMess { NS_ERROR("We should not be here!"); return NS_OK; } NS_IMETHODIMP MobileMessageDatabaseService::MarkMessageRead(int32_t aMessageId, bool aValue, + bool aSendReadReport, nsIMobileMessageCallback* aRequest) { NS_ERROR("We should not be here!"); return NS_OK; } NS_IMETHODIMP MobileMessageDatabaseService::CreateThreadCursor(nsIMobileMessageCursorCallback* aCallback,
--- a/dom/mobilemessage/src/gonk/MmsPduHelper.jsm +++ b/dom/mobilemessage/src/gonk/MmsPduHelper.jsm @@ -1621,16 +1621,22 @@ const MMS_PDU_TYPES = (function () { "x-mms-mms-version", "message-id", "to", "date", "x-mms-status"]); add(MMS_PDU_TYPE_ACKNOWLEDGE_IND, false, ["x-mms-message-type", "x-mms-transaction-id", "x-mms-mms-version"]); + add(MMS_PDU_TYPE_READ_REC_IND, false, ["x-mms-message-type", + "message-id", + "x-mms-mms-version", + "to", + "from", + "x-mms-read-status"]); return pdus; })(); /** * Header field names and assigned numbers. * * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.4 @@ -1667,17 +1673,17 @@ const MMS_HEADER_FIELDS = (function () { add("x-mms-response-text", 0x13, ResponseText); add("x-mms-sender-visibility", 0x14, BooleanValue); add("x-mms-status", 0x15, StatusValue); add("subject", 0x16, EncodedStringValue); add("to", 0x17, Address); add("x-mms-transaction-id", 0x18, WSP.TextString); add("x-mms-retrieve-status", 0x19, RetrieveStatusValue); add("x-mms-retrieve-text", 0x1A, EncodedStringValue); - //add("x-mms-read-status", 0x1B); + add("x-mms-read-status", 0x1B, BooleanValue); add("x-mms-reply-charging", 0x1C, ReplyChargingValue); add("x-mms-reply-charging-deadline", 0x1D, ExpiryValue); add("x-mms-reply-charging-id", 0x1E, WSP.TextString); add("x-mms-reply-charging-size", 0x1F, WSP.LongInteger); add("x-mms-previously-sent-by", 0x20, PreviouslySentByValue); add("x-mms-previously-sent-date", 0x21, PreviouslySentDateValue); add("x-mms-store", 0x22, BooleanValue); add("x-mms-mm-state", 0x23, MmStateValue);
--- a/dom/mobilemessage/src/gonk/MmsService.js +++ b/dom/mobilemessage/src/gonk/MmsService.js @@ -133,27 +133,29 @@ XPCOMUtils.defineLazyServiceGetter(this, XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService", "@mozilla.org/mobilemessage/mobilemessageservice;1", "nsIMobileMessageService"); XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger", "@mozilla.org/system-message-internal;1", "nsISystemMessagesInternal"); +XPCOMUtils.defineLazyServiceGetter(this, "gRil", + "@mozilla.org/ril;1", + "nsIRadioInterfaceLayer"); + XPCOMUtils.defineLazyGetter(this, "MMS", function () { let MMS = {}; Cu.import("resource://gre/modules/MmsPduHelper.jsm", MMS); return MMS; }); function MmsConnection(aServiceId) { this.serviceId = aServiceId; - let ril = Cc["@mozilla.org/ril;1"] - .getService(Ci["nsIRadioInterfaceLayer"]); - this.radioInterface = ril.getRadioInterface(aServiceId); + this.radioInterface = gRil.getRadioInterface(aServiceId); }; MmsConnection.prototype = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]), /** MMS proxy settings. */ mmsc: "", mmsProxy: "", @@ -1309,16 +1311,57 @@ function getDefaultServiceId() { if (id >= numRil || id < 0) { id = 0; } return id; } /** + * Return M-Read-Rec.ind back to MMSC + * + * @param messageID + * Message-ID of the message. + * @param toAddress + * The address of the recipient of the Read Report, i.e. the originator + * of the original multimedia message. + * + * @see OMA-TS-MMS_ENC-V1_3-20110913-A section 6.7.2 + */ +function ReadRecTransaction(mmsConnection, messageID, toAddress) { + this.mmsConnection = mmsConnection; + let headers = {}; + + // Mandatory fields + headers["x-mms-message-type"] = MMS.MMS_PDU_TYPE_READ_REC_IND; + headers["x-mms-mms-version"] = MMS.MMS_VERSION; + headers["message-id"] = messageID; + let type = MMS.Address.resolveType(toAddress); + let to = {address: toAddress, + type: type} + headers["to"] = to; + headers["from"] = null; + headers["x-mms-read-status"] = true; + + this.istream = MMS.PduHelper.compose(null, {headers: headers}); + if (!this.istream) { + throw Cr.NS_ERROR_FAILURE; + } +} +ReadRecTransaction.prototype = { + run: function() { + gMmsTransactionHelper.sendRequest(this.mmsConnection, + "POST", + null, + this.istream, + null); + } +}; + +/** * MmsService */ function MmsService() { if (DEBUG) { let macro = (MMS.MMS_VERSION >> 4) & 0x0f; let minor = MMS.MMS_VERSION & 0x0f; debug("Running protocol version: " + macro + "." + minor); } @@ -2130,21 +2173,19 @@ MmsService.prototype = { if (DEBUG) debug("The message to be retrieved is expired."); aRequest.notifyGetMessageFailed(Ci.nsIMobileMessageCallback.NOT_FOUND_ERROR); return; } } // Get the RIL service ID based on the saved MMS message record's ICC ID, // which could fail when the corresponding SIM card isn't installed. - let ril = Cc["@mozilla.org/ril;1"] - .getService(Ci["nsIRadioInterfaceLayer"]); let serviceId; try { - serviceId = ril.getClientIdByIccId(aMessageRecord.iccId); + serviceId = gRil.getClientIdByIccId(aMessageRecord.iccId); } catch (e) { if (DEBUG) debug("RIL service is not available for ICC ID."); aRequest.notifyGetMessageFailed(Ci.nsIMobileMessageCallback.NO_SIM_CARD_ERROR); return; } let mmsConnection = gMmsConnections.getConnByServiceId(serviceId); @@ -2253,16 +2294,42 @@ MmsService.prototype = { this.retrieveMessage(mmsConnection, url, responseNotify.bind(this), aDomMessage); }).bind(this)); }).bind(this)); }, + sendReadReport: function sendReadReport(messageID, toAddress, iccId) { + if (DEBUG) { + debug("messageID: " + messageID + " toAddress: " + + JSON.stringify(toAddress)); + } + + // Get the RIL service ID based on the saved MMS message record's ICC ID, + // which could fail when the corresponding SIM card isn't installed. + let serviceId; + try { + serviceId = gRil.getClientIdByIccId(iccId); + } catch (e) { + if (DEBUG) debug("RIL service is not available for ICC ID."); + return; + } + + let mmsConnection = gMmsConnections.getConnByServiceId(serviceId); + try { + let transaction = + new ReadRecTransaction(mmsConnection, messageID, toAddress); + transaction.run(); + } catch (e) { + if (DEBUG) debug("sendReadReport fail. e = " + e); + } + }, + // nsIWapPushApplication receiveWapPush: function receiveWapPush(array, length, offset, options) { let data = {array: array, offset: offset}; let msg = MMS.PduHelper.parse(data, null); if (!msg) { return false; }
--- a/dom/mobilemessage/src/gonk/MobileMessageDatabaseService.js +++ b/dom/mobilemessage/src/gonk/MobileMessageDatabaseService.js @@ -19,17 +19,17 @@ const RIL_GETMESSAGESCURSOR_CID = const RIL_GETTHREADSCURSOR_CID = Components.ID("{95ee7c3e-d6f2-4ec4-ade5-0c453c036d35}"); const DEBUG = false; const DISABLE_MMS_GROUPING_FOR_RECEIVING = true; const DB_NAME = "sms"; -const DB_VERSION = 16; +const DB_VERSION = 17; const MESSAGE_STORE_NAME = "sms"; const THREAD_STORE_NAME = "thread"; const PARTICIPANT_STORE_NAME = "participant"; const MOST_RECENT_STORE_NAME = "most-recent"; const DELIVERY_SENDING = "sending"; const DELIVERY_SENT = "sent"; const DELIVERY_RECEIVED = "received"; @@ -60,16 +60,19 @@ const NEXT = "next"; const COLLECT_ID_END = 0; const COLLECT_ID_ERROR = -1; const COLLECT_TIMESTAMP_UNUSED = 0; XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService", "@mozilla.org/mobilemessage/mobilemessageservice;1", "nsIMobileMessageService"); +XPCOMUtils.defineLazyServiceGetter(this, "gMMSService", + "@mozilla.org/mms/rilmmsservice;1", + "nsIMmsService"); /** * MobileMessageDatabaseService */ function MobileMessageDatabaseService() { // Prime the directory service's cache to ensure that the ProfD entry exists // by the time IndexedDB queries for it off the main thread. (See bug 743635.) Services.dirsvc.get("ProfD", Ci.nsIFile); @@ -225,20 +228,24 @@ MobileMessageDatabaseService.prototype = if (DEBUG) debug("Upgrade to version 14. Fix the wrong participants."); self.upgradeSchema13(event.target.transaction, next); break; case 14: if (DEBUG) debug("Upgrade to version 15. Add deliveryTimestamp."); self.upgradeSchema14(event.target.transaction, next); break; case 15: - if (DEBUG) debug("Upgrade to version 15. Add ICC ID for each message."); + if (DEBUG) debug("Upgrade to version 16. Add ICC ID for each message."); self.upgradeSchema15(event.target.transaction, next); break; case 16: + if (DEBUG) debug("Upgrade to version 17. Add isReadReportSent for incoming MMS."); + self.upgradeSchema16(event.target.transaction, next); + break; + case 17: // This will need to be moved for each new version if (DEBUG) debug("Upgrade finished."); break; default: event.target.transaction.abort(); callback("Old database version: " + event.oldVersion, null); break; } @@ -1067,16 +1074,39 @@ MobileMessageDatabaseService.prototype = let messageRecord = cursor.value; messageRecord.iccId = null; cursor.update(messageRecord); cursor.continue(); }; }, + /** + * Add isReadReportSent for incoming MMS. + */ + upgradeSchema16: function upgradeSchema16(transaction, next) { + let messageStore = transaction.objectStore(MESSAGE_STORE_NAME); + + // Update type attributes. + messageStore.openCursor().onsuccess = function(event) { + let cursor = event.target.result; + if (!cursor) { + next(); + return; + } + + let messageRecord = cursor.value; + if (messageRecord.type == "mms") { + messageRecord.isReadReportSent = false; + cursor.update(messageRecord); + } + cursor.continue(); + }; + }, + matchParsedPhoneNumbers: function matchParsedPhoneNumbers(addr1, parsedAddr1, addr2, parsedAddr2) { if ((parsedAddr1.internationalNumber && parsedAddr1.internationalNumber === parsedAddr2.internationalNumber) || (parsedAddr1.nationalNumber && parsedAddr1.nationalNumber === parsedAddr2.nationalNumber)) { return true; } @@ -1176,29 +1206,31 @@ MobileMessageDatabaseService.prototype = "content": partContent }); } } let expiryDate = 0; if (headers["x-mms-expiry"] != undefined) { expiryDate = aMessageRecord.timestamp + headers["x-mms-expiry"] * 1000; } + let isReadReportRequested = headers["x-mms-read-report"] || false; return gMobileMessageService.createMmsMessage(aMessageRecord.id, aMessageRecord.threadId, aMessageRecord.iccId, aMessageRecord.delivery, aMessageRecord.deliveryInfo, aMessageRecord.sender, aMessageRecord.receivers, aMessageRecord.timestamp, aMessageRecord.read, subject, smil, attachments, - expiryDate); + expiryDate, + isReadReportRequested); } }, findParticipantRecordByAddress: function findParticipantRecordByAddress( aParticipantStore, aAddress, aCreate, aCallback) { if (DEBUG) { debug("findParticipantRecordByAddress(" + JSON.stringify(aAddress) + ", " + aCreate + ")"); @@ -1727,16 +1759,17 @@ MobileMessageDatabaseService.prototype = // Adding needed indexes and extra attributes for internal use. // threadIdIndex & participantIdsIndex are filled in saveRecord(). aMessage.readIndex = [FILTER_READ_UNREAD, timestamp]; aMessage.read = FILTER_READ_UNREAD; if (aMessage.type == "mms") { aMessage.transactionIdIndex = aMessage.transactionId; + aMessage.isReadReportSent = false; } if (aMessage.type == "sms") { aMessage.delivery = DELIVERY_RECEIVED; aMessage.deliveryStatus = DELIVERY_STATUS_SUCCESS; // If |deliveryTimestamp| is not specified, use 0 as default. if (aMessage.deliveryTimestamp == undefined) { @@ -2054,54 +2087,72 @@ MobileMessageDatabaseService.prototype = let collector = cursor.collector; let collect = collector.collect.bind(collector); FilterSearcherHelper.transact(self, txn, error, filter, reverse, collect); }, [MESSAGE_STORE_NAME, PARTICIPANT_STORE_NAME]); return cursor; }, - markMessageRead: function markMessageRead(messageId, value, aRequest) { + markMessageRead: function markMessageRead(messageId, value, aSendReadReport, aRequest) { if (DEBUG) debug("Setting message " + messageId + " read to " + value); this.newTxn(READ_WRITE, function (error, txn, stores) { if (error) { if (DEBUG) debug(error); aRequest.notifyMarkMessageReadFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR); return; } + txn.onerror = function onerror(event) { if (DEBUG) debug("Caught error on transaction ", event.target.errorCode); aRequest.notifyMarkMessageReadFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR); }; + let messageStore = stores[0]; let threadStore = stores[1]; messageStore.get(messageId).onsuccess = function onsuccess(event) { let messageRecord = event.target.result; if (!messageRecord) { if (DEBUG) debug("Message ID " + messageId + " not found"); aRequest.notifyMarkMessageReadFailed(Ci.nsIMobileMessageCallback.NOT_FOUND_ERROR); return; } + if (messageRecord.id != messageId) { if (DEBUG) { debug("Retrieve message ID (" + messageId + ") is " + "different from the one we got"); } aRequest.notifyMarkMessageReadFailed(Ci.nsIMobileMessageCallback.UNKNOWN_ERROR); return; } + // If the value to be set is the same as the current message `read` // value, we just notify successfully. if (messageRecord.read == value) { if (DEBUG) debug("The value of messageRecord.read is already " + value); aRequest.notifyMessageMarkedRead(messageRecord.read); return; } + messageRecord.read = value ? FILTER_READ_READ : FILTER_READ_UNREAD; messageRecord.readIndex = [messageRecord.read, messageRecord.timestamp]; + let readReportMessageId, readReportTo; + if (aSendReadReport && + messageRecord.type == "mms" && + messageRecord.delivery == DELIVERY_RECEIVED && + messageRecord.read == FILTER_READ_READ && + !messageRecord.isReadReportSent) { + messageRecord.isReadReportSent = true; + + let from = messageRecord.headers["from"]; + readReportTo = from && from.address; + readReportMessageId = messageRecord.headers["message-id"]; + } + if (DEBUG) debug("Message.read set to: " + value); messageStore.put(messageRecord).onsuccess = function onsuccess(event) { if (DEBUG) { debug("Update successfully completed. Message: " + JSON.stringify(event.target.result)); } // Now update the unread count. @@ -2113,16 +2164,21 @@ MobileMessageDatabaseService.prototype = if (DEBUG) { debug("Updating unreadCount for thread id " + threadId + ": " + (value ? threadRecord.unreadCount + 1 : threadRecord.unreadCount - 1) + " -> " + threadRecord.unreadCount); } threadStore.put(threadRecord).onsuccess = function(event) { + if(readReportMessageId && readReportTo) { + gMMSService.sendReadReport(readReportMessageId, + readReportTo, + messageRecord.iccId); + } aRequest.notifyMessageMarkedRead(messageRecord.read); }; }; }; }; }, [MESSAGE_STORE_NAME, THREAD_STORE_NAME]); },
--- a/dom/mobilemessage/src/ipc/PSms.ipdl +++ b/dom/mobilemessage/src/ipc/PSms.ipdl @@ -57,16 +57,17 @@ struct CreateMessageCursorRequest SmsFilterData filter; bool reverse; }; struct MarkMessageReadRequest { int32_t messageId; bool value; + bool sendReadReport; }; struct GetSegmentInfoForTextRequest { nsString text; }; struct CreateThreadCursorRequest
--- a/dom/mobilemessage/src/ipc/SmsIPCService.cpp +++ b/dom/mobilemessage/src/ipc/SmsIPCService.cpp @@ -238,19 +238,20 @@ SmsIPCService::CreateMessageCursor(nsIDO return SendCursorRequest(CreateMessageCursorRequest(data, aReverse), aCursorCallback, aResult); } NS_IMETHODIMP SmsIPCService::MarkMessageRead(int32_t aMessageId, bool aValue, + bool aSendReadReport, nsIMobileMessageCallback* aRequest) { - return SendRequest(MarkMessageReadRequest(aMessageId, aValue), aRequest); + return SendRequest(MarkMessageReadRequest(aMessageId, aValue, aSendReadReport), aRequest); } NS_IMETHODIMP SmsIPCService::CreateThreadCursor(nsIMobileMessageCursorCallback* aCursorCallback, nsICursorContinueCallback** aResult) { return SendCursorRequest(CreateThreadCursorRequest(), aCursorCallback, aResult); @@ -328,8 +329,17 @@ SmsIPCService::Send(uint32_t aServiceId, return SendRequest(SendMessageRequest(req), aRequest); } NS_IMETHODIMP SmsIPCService::Retrieve(int32_t aId, nsIMobileMessageCallback *aRequest) { return SendRequest(RetrieveMessageRequest(aId), aRequest); } + +NS_IMETHODIMP +SmsIPCService::SendReadReport(const nsAString & messageID, + const nsAString & toAddress, + const nsAString & iccId) +{ + NS_ERROR("We should not be here!"); + return NS_OK; +}
--- a/dom/mobilemessage/src/ipc/SmsParent.cpp +++ b/dom/mobilemessage/src/ipc/SmsParent.cpp @@ -537,17 +537,17 @@ bool SmsRequestParent::DoRequest(const MarkMessageReadRequest& aRequest) { nsresult rv = NS_ERROR_FAILURE; nsCOMPtr<nsIMobileMessageDatabaseService> dbService = do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID); if (dbService) { rv = dbService->MarkMessageRead(aRequest.messageId(), aRequest.value(), - this); + aRequest.sendReadReport(), this); } if (NS_FAILED(rv)) { return NS_SUCCEEDED(NotifyMarkMessageReadFailed(nsIMobileMessageCallback::INTERNAL_ERROR)); } return true; }
--- a/dom/mobilemessage/src/ipc/SmsTypes.ipdlh +++ b/dom/mobilemessage/src/ipc/SmsTypes.ipdlh @@ -62,16 +62,17 @@ struct MmsMessageData nsString sender; nsString[] receivers; uint64_t timestamp; bool read; nsString subject; nsString smil; MmsAttachmentData[] attachments; uint64_t expiryDate; + bool isReadReportRequested; }; union MobileMessageData { MmsMessageData; SmsMessageData; };
--- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -519,17 +519,17 @@ nsJSObjWrapper::NP_Deallocate(NPObject * // static void nsJSObjWrapper::NP_Invalidate(NPObject *npobj) { nsJSObjWrapper *jsnpobj = (nsJSObjWrapper *)npobj; if (jsnpobj && jsnpobj->mJSObj) { // Unroot the object's JSObject - js_RemoveRoot(sJSRuntime, &jsnpobj->mJSObj); + JS_RemoveObjectRootRT(sJSRuntime, &jsnpobj->mJSObj); if (sJSObjWrappers.ops) { // Remove the wrapper from the hash nsJSObjWrapperKey key(jsnpobj->mJSObj, jsnpobj->mNpp); PL_DHashTableOperate(&sJSObjWrappers, &key, PL_DHASH_REMOVE); }
--- a/extensions/universalchardet/tests/CharsetDetectionTests.js +++ b/extensions/universalchardet/tests/CharsetDetectionTests.js @@ -40,27 +40,19 @@ function InitDetectorTests() } catch (e) { gOldPref = ""; } SetDetectorPref(gDetectorList[0]); gTestIndex = 0; $("testframe").onload = DoDetectionTest; if (gExpectedCharset == "default") { - try { - gExpectedCharset = prefService - .getComplexValue("intl.charset.default", - Ci.nsIPrefLocalizedString) - .data; - if (gExpectedCharset == "ISO-8859-1") { - gExpectedCharset = "windows-1252"; - } - } catch (e) { - gExpectedCharset = "windows-1252"; - } + // No point trying to be generic here, because we have plenty of other + // unit tests that fail if run using a non-windows-1252 locale. + gExpectedCharset = "windows-1252"; } // Get the local directory. This needs to be a file: URI because chrome: // URIs are always UTF-8 (bug 617339) and we are testing decoding from other // charsets. var jar = getJar(getRootDirectory(window.location.href)); var dir = jar ? extractJarToTmp(jar) :
--- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -380,20 +380,20 @@ frontend::CompileScript(ExclusiveContext * header) override any source map urls passed as comment pragmas. */ if (options.sourceMapURL) { if (!ss->setSourceMapURL(cx, options.sourceMapURL)) return nullptr; } /* - * Nowadays the threaded interpreter needs a stop instruction, so we + * Nowadays the threaded interpreter needs a last return instruction, so we * do have to emit that here. */ - if (Emit1(cx, &bce, JSOP_STOP) < 0) + if (Emit1(cx, &bce, JSOP_RETRVAL) < 0) return nullptr; if (!JSScript::fullyInitFromEmitter(cx, script, &bce)) return nullptr; bce.tellDebuggerAboutCompiledScript(cx); if (sct && !extraSct && !sct->complete())
--- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -1135,27 +1135,16 @@ TryConvertFreeName(BytecodeEmitter *bce, } /* * When parsing inner functions lazily, parse nodes for outer functions no * longer exist and only the function's scope chain is available for * resolving upvar accesses within the inner function. */ if (bce->emitterMode == BytecodeEmitter::LazyFunction) { - // The only statements within a lazy function which can push lexical - // scopes are try/catch blocks. Use generic ops in this case. - for (StmtInfoBCE *stmt = bce->topStmt; stmt; stmt = stmt->down) { - switch (stmt->type) { - case STMT_TRY: - case STMT_FINALLY: - return true; - default:; - } - } - size_t hops = 0; FunctionBox *funbox = bce->sc->asFunctionBox(); if (funbox->hasExtensibleScope()) return false; if (funbox->function()->isNamedLambda() && funbox->function()->atom() == pn->pn_atom) return false; if (funbox->isHeavyweight()) { hops++; @@ -2695,20 +2684,20 @@ frontend::EmitFunctionScript(ExclusiveCo return false; // No need to check for finally blocks, etc as in EmitReturn. if (Emit1(cx, bce, JSOP_RETURN) < 0) return false; } /* - * Always end the script with a JSOP_STOP. Some other parts of the codebase + * Always end the script with a JSOP_RETRVAL. Some other parts of the codebase * depend on this opcode, e.g. js_InternalInterpret. */ - if (Emit1(cx, bce, JSOP_STOP) < 0) + if (Emit1(cx, bce, JSOP_RETRVAL) < 0) return false; if (!JSScript::fullyInitFromEmitter(cx, bce->script, bce)) return false; /* * If this function is only expected to run once, mark the script so that * initializers created within it may be given more precise types. @@ -3157,17 +3146,17 @@ enum GroupOption { GroupIsDecl, GroupIsN * we set *pop to JSOP_NOP so callers can veto emitting pn followed by a pop. */ static bool MaybeEmitGroupAssignment(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *pn, GroupOption groupOption, JSOp *pop) { JS_ASSERT(pn->isKind(PNK_ASSIGN)); JS_ASSERT(pn->isOp(JSOP_NOP)); - JS_ASSERT(*pop == JSOP_POP || *pop == JSOP_POPV); + JS_ASSERT(*pop == JSOP_POP || *pop == JSOP_SETRVAL); ParseNode *lhs = pn->pn_left; ParseNode *rhs = pn->pn_right; if (lhs->isKind(PNK_ARRAY) && rhs->isKind(PNK_ARRAY) && !(rhs->pn_xflags & PNX_SPECIALARRAYINIT) && lhs->pn_count <= rhs->pn_count) { if (groupOption == GroupIsDecl && !EmitDestructuringDecls(cx, bce, prologOp, lhs)) @@ -3189,17 +3178,17 @@ MaybeEmitGroupAssignment(ExclusiveContex * decompile so we restrict the ourselves to cases where the lhs and rhs are in * 1:1 correspondence and lhs elements are simple names. */ static bool MaybeEmitLetGroupDecl(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, JSOp *pop) { JS_ASSERT(pn->isKind(PNK_ASSIGN)); JS_ASSERT(pn->isOp(JSOP_NOP)); - JS_ASSERT(*pop == JSOP_POP || *pop == JSOP_POPV); + JS_ASSERT(*pop == JSOP_POP || *pop == JSOP_SETRVAL); ParseNode *lhs = pn->pn_left; ParseNode *rhs = pn->pn_right; if (lhs->isKind(PNK_ARRAY) && rhs->isKind(PNK_ARRAY) && !(rhs->pn_xflags & PNX_SPECIALARRAYINIT) && !(lhs->pn_xflags & PNX_SPECIALARRAYINIT) && lhs->pn_count == rhs->pn_count) { @@ -5304,17 +5293,17 @@ EmitStatement(ExclusiveContext *cx, Byte /* * Top-level or called-from-a-native JS_Execute/EvaluateScript, * debugger, and eval frames may need the value of the ultimate * expression statement as the script's result, despite the fact * that it appears useless to the compiler. * * API users may also set the JSOPTION_NO_SCRIPT_RVAL option when - * calling JS_Compile* to suppress JSOP_POPV. + * calling JS_Compile* to suppress JSOP_SETRVAL. */ bool wantval = false; bool useful = false; if (bce->sc->isFunctionBox()) { JS_ASSERT(!bce->script->noScriptRval); } else { useful = wantval = !bce->script->noScriptRval; } @@ -5334,17 +5323,17 @@ EmitStatement(ExclusiveContext *cx, Byte bce->topStmt->type == STMT_LABEL && bce->topStmt->update >= bce->offset()) { useful = true; } } if (useful) { - JSOp op = wantval ? JSOP_POPV : JSOP_POP; + JSOp op = wantval ? JSOP_SETRVAL : JSOP_POP; JS_ASSERT_IF(pn2->isKind(PNK_ASSIGN), pn2->isOp(JSOP_NOP)); #if JS_HAS_DESTRUCTURING if (!wantval && pn2->isKind(PNK_ASSIGN) && !MaybeEmitGroupAssignment(cx, bce, op, pn2, GroupIsNotDecl, &op)) { return false; }
--- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -265,57 +265,37 @@ HashTableWriteBarrierPost(JSRuntime *rt, #ifdef JSGC_GENERATIONAL if (key && IsInsideNursery(rt, key)) { JS::shadow::Runtime *shadowRuntime = JS::shadow::Runtime::asShadowRuntime(rt); shadowRuntime->gcStoreBufferPtr()->putGeneric(gc::HashKeyRef<Map, Key>(map, key)); } #endif } +/* + * Base class for barriered pointer types. + */ template<class T, typename Unioned = uintptr_t> -class EncapsulatedPtr +class BarrieredPtr { protected: union { T *value; Unioned other; }; + BarrieredPtr(T *v) : value(v) {} + ~BarrieredPtr() { pre(); } + public: - EncapsulatedPtr() : value(nullptr) {} - EncapsulatedPtr(T *v) : value(v) {} - explicit EncapsulatedPtr(const EncapsulatedPtr<T> &v) : value(v.value) {} - - ~EncapsulatedPtr() { pre(); } - void init(T *v) { JS_ASSERT(!IsPoisonedPtr<T>(v)); this->value = v; } - /* Use to set the pointer to nullptr. */ - void clear() { - pre(); - value = nullptr; - } - - EncapsulatedPtr<T, Unioned> &operator=(T *v) { - pre(); - JS_ASSERT(!IsPoisonedPtr<T>(v)); - value = v; - return *this; - } - - EncapsulatedPtr<T, Unioned> &operator=(const EncapsulatedPtr<T> &v) { - pre(); - JS_ASSERT(!IsPoisonedPtr<T>(v.value)); - value = v.value; - return *this; - } - /* Use this if the automatic coercion to T* isn't working. */ T *get() const { return value; } /* * Use these if you want to change the value without invoking the barrier. * Obviously this is dangerous unless you know the barrier is not needed. */ T **unsafeGet() { return &value; } @@ -327,29 +307,58 @@ class EncapsulatedPtr T *operator->() const { return value; } operator T*() const { return value; } protected: void pre() { T::writeBarrierPre(value); } }; +template<class T, typename Unioned = uintptr_t> +class EncapsulatedPtr : public BarrieredPtr<T, Unioned> +{ + public: + EncapsulatedPtr() : BarrieredPtr<T, Unioned>(nullptr) {} + EncapsulatedPtr(T *v) : BarrieredPtr<T, Unioned>(v) {} + explicit EncapsulatedPtr(const EncapsulatedPtr<T, Unioned> &v) + : BarrieredPtr<T, Unioned>(v.value) {} + + /* Use to set the pointer to nullptr. */ + void clear() { + this->pre(); + this->value = nullptr; + } + + EncapsulatedPtr<T, Unioned> &operator=(T *v) { + this->pre(); + JS_ASSERT(!IsPoisonedPtr<T>(v)); + this->value = v; + return *this; + } + + EncapsulatedPtr<T, Unioned> &operator=(const EncapsulatedPtr<T> &v) { + this->pre(); + JS_ASSERT(!IsPoisonedPtr<T>(v.value)); + this->value = v.value; + return *this; + } +}; + /* * A pre- and post-barriered heap pointer, for use inside the JS engine. * * Not to be confused with JS::Heap<T>. */ template <class T, class Unioned = uintptr_t> -class HeapPtr : public EncapsulatedPtr<T, Unioned> +class HeapPtr : public BarrieredPtr<T, Unioned> { public: - HeapPtr() : EncapsulatedPtr<T>(nullptr) {} - explicit HeapPtr(T *v) : EncapsulatedPtr<T>(v) { post(); } - explicit HeapPtr(const HeapPtr<T> &v) - : EncapsulatedPtr<T>(v) { post(); } + HeapPtr() : BarrieredPtr<T, Unioned>(nullptr) {} + explicit HeapPtr(T *v) : BarrieredPtr<T, Unioned>(v) { post(); } + explicit HeapPtr(const HeapPtr<T> &v) : BarrieredPtr<T, Unioned>(v) { post(); } void init(T *v) { JS_ASSERT(!IsPoisonedPtr<T>(v)); this->value = v; post(); } HeapPtr<T, Unioned> &operator=(T *v) { @@ -405,25 +414,25 @@ class FixedHeapPtr } void init(T *ptr) { value = ptr; } }; template <class T> -class RelocatablePtr : public EncapsulatedPtr<T> +class RelocatablePtr : public BarrieredPtr<T> { public: - RelocatablePtr() : EncapsulatedPtr<T>(nullptr) {} - explicit RelocatablePtr(T *v) : EncapsulatedPtr<T>(v) { + RelocatablePtr() : BarrieredPtr<T>(nullptr) {} + explicit RelocatablePtr(T *v) : BarrieredPtr<T>(v) { if (v) post(); } - RelocatablePtr(const RelocatablePtr<T> &v) : EncapsulatedPtr<T>(v) { + RelocatablePtr(const RelocatablePtr<T> &v) : BarrieredPtr<T>(v) { if (this->value) post(); } ~RelocatablePtr() { if (this->value) relocate(this->value->runtimeFromAnyThread()); } @@ -490,16 +499,19 @@ BarrieredSetPair(Zone *zone, v1.post(); v2.post(); } class Shape; class BaseShape; namespace types { struct TypeObject; } +typedef BarrieredPtr<JSObject> BarrieredPtrObject; +typedef BarrieredPtr<JSScript> BarrieredPtrScript; + typedef EncapsulatedPtr<JSObject> EncapsulatedPtrObject; typedef EncapsulatedPtr<JSScript> EncapsulatedPtrScript; typedef RelocatablePtr<JSObject> RelocatablePtrObject; typedef RelocatablePtr<JSScript> RelocatablePtrScript; typedef HeapPtr<JSObject> HeapPtrObject; typedef HeapPtr<JSFunction> HeapPtrFunction; @@ -535,64 +547,50 @@ struct EncapsulatedPtrHasher static HashNumber hash(Lookup obj) { return DefaultHasher<T *>::hash(obj); } static bool match(const Key &k, Lookup l) { return k.get() == l; } static void rekey(Key &k, const Key& newKey) { k.unsafeSet(newKey); } }; template <class T> struct DefaultHasher< EncapsulatedPtr<T> > : EncapsulatedPtrHasher<T> { }; -class EncapsulatedValue : public ValueOperations<EncapsulatedValue> +/* + * Base class for barriered value types. + */ +class BarrieredValue : public ValueOperations<BarrieredValue> { protected: Value value; /* * Ensure that EncapsulatedValue is not constructable, except by our * implementations. */ - EncapsulatedValue() MOZ_DELETE; + BarrieredValue() MOZ_DELETE; - public: - EncapsulatedValue(const Value &v) : value(v) { - JS_ASSERT(!IsPoisonedValue(v)); - } - EncapsulatedValue(const EncapsulatedValue &v) : value(v) { + BarrieredValue(const Value &v) : value(v) { JS_ASSERT(!IsPoisonedValue(v)); } - ~EncapsulatedValue() { + ~BarrieredValue() { pre(); } + public: void init(const Value &v) { JS_ASSERT(!IsPoisonedValue(v)); value = v; } void init(JSRuntime *rt, const Value &v) { JS_ASSERT(!IsPoisonedValue(v)); value = v; } - EncapsulatedValue &operator=(const Value &v) { - pre(); - JS_ASSERT(!IsPoisonedValue(v)); - value = v; - return *this; - } - - EncapsulatedValue &operator=(const EncapsulatedValue &v) { - pre(); - JS_ASSERT(!IsPoisonedValue(v)); - value = v.get(); - return *this; - } - - bool operator==(const EncapsulatedValue &v) const { return value == v.value; } - bool operator!=(const EncapsulatedValue &v) const { return value != v.value; } + bool operator==(const BarrieredValue &v) const { return value == v.value; } + bool operator!=(const BarrieredValue &v) const { return value != v.value; } const Value &get() const { return value; } Value *unsafeGet() { return &value; } operator const Value &() const { return value; } JSGCTraceKind gcKind() const { return value.gcKind(); } uint64_t asRawBits() const { return value.asRawBits(); } @@ -631,43 +629,64 @@ class EncapsulatedValue : public ValueOp static JS::shadow::Runtime *shadowRuntimeFromMainThread(const Value &v) { return reinterpret_cast<JS::shadow::Runtime*>(runtimeFromMainThread(v)); } static JS::shadow::Runtime *shadowRuntimeFromAnyThread(const Value &v) { return reinterpret_cast<JS::shadow::Runtime*>(runtimeFromAnyThread(v)); } private: - friend class ValueOperations<EncapsulatedValue>; + friend class ValueOperations<BarrieredValue>; const Value * extract() const { return &value; } }; +class EncapsulatedValue : public BarrieredValue +{ + public: + EncapsulatedValue(const Value &v) : BarrieredValue(v) {} + EncapsulatedValue(const EncapsulatedValue &v) : BarrieredValue(v) {} + + EncapsulatedValue &operator=(const Value &v) { + pre(); + JS_ASSERT(!IsPoisonedValue(v)); + value = v; + return *this; + } + + EncapsulatedValue &operator=(const EncapsulatedValue &v) { + pre(); + JS_ASSERT(!IsPoisonedValue(v)); + value = v.get(); + return *this; + } +}; + /* * A pre- and post-barriered heap JS::Value, for use inside the JS engine. * * Not to be confused with JS::Heap<JS::Value>. */ -class HeapValue : public EncapsulatedValue +class HeapValue : public BarrieredValue { public: explicit HeapValue() - : EncapsulatedValue(UndefinedValue()) + : BarrieredValue(UndefinedValue()) { post(); } explicit HeapValue(const Value &v) - : EncapsulatedValue(v) + : BarrieredValue(v) { JS_ASSERT(!IsPoisonedValue(v)); post(); } explicit HeapValue(const HeapValue &v) - : EncapsulatedValue(v.value) + : BarrieredValue(v.value) { JS_ASSERT(!IsPoisonedValue(v.value)); post(); } ~HeapValue() { pre(); } @@ -740,33 +759,30 @@ class HeapValue : public EncapsulatedVal writeBarrierPost(value, &value); } void post(JSRuntime *rt) { writeBarrierPost(rt, value, &value); } }; -class RelocatableValue : public EncapsulatedValue +class RelocatableValue : public BarrieredValue { public: - explicit RelocatableValue() - : EncapsulatedValue(UndefinedValue()) - {} + explicit RelocatableValue() : BarrieredValue(UndefinedValue()) {} explicit RelocatableValue(const Value &v) - : EncapsulatedValue(v) + : BarrieredValue(v) { - JS_ASSERT(!IsPoisonedValue(v)); if (v.isMarkable()) post(); } RelocatableValue(const RelocatableValue &v) - : EncapsulatedValue(v.value) + : BarrieredValue(v.value) { JS_ASSERT(!IsPoisonedValue(v.value)); if (v.value.isMarkable()) post(); } ~RelocatableValue() { @@ -817,43 +833,35 @@ class RelocatableValue : public Encapsul void relocate(JSRuntime *rt) { #ifdef JSGC_GENERATIONAL JS::shadow::Runtime *shadowRuntime = JS::shadow::Runtime::asShadowRuntime(rt); shadowRuntime->gcStoreBufferPtr()->removeRelocatableValue(&value); #endif } }; -class HeapSlot : public EncapsulatedValue +class HeapSlot : public BarrieredValue { - /* - * Operator= is not valid for HeapSlot because is must take the object and - * slot offset to provide to the post/generational barrier. - */ - inline HeapSlot &operator=(const Value &v) MOZ_DELETE; - inline HeapSlot &operator=(const HeapValue &v) MOZ_DELETE; - inline HeapSlot &operator=(const HeapSlot &v) MOZ_DELETE; - public: enum Kind { Slot, Element }; explicit HeapSlot() MOZ_DELETE; explicit HeapSlot(JSObject *obj, Kind kind, uint32_t slot, const Value &v) - : EncapsulatedValue(v) + : BarrieredValue(v) { JS_ASSERT(!IsPoisonedValue(v)); post(obj, kind, slot, v); } explicit HeapSlot(JSObject *obj, Kind kind, uint32_t slot, const HeapSlot &s) - : EncapsulatedValue(s.value) + : BarrieredValue(s.value) { JS_ASSERT(!IsPoisonedValue(s.value)); post(obj, kind, slot, s); } ~HeapSlot() { pre(); } @@ -920,17 +928,17 @@ class HeapSlot : public EncapsulatedValu } void post(JSRuntime *rt, JSObject *owner, Kind kind, uint32_t slot, Value target) { HeapSlot::writeBarrierPost(rt, owner, kind, slot, target); } }; static inline const Value * -Valueify(const EncapsulatedValue *array) +Valueify(const BarrieredValue *array) { JS_STATIC_ASSERT(sizeof(HeapValue) == sizeof(Value)); JS_STATIC_ASSERT(sizeof(HeapSlot) == sizeof(Value)); return (const Value *)array; } static inline HeapValue * HeapValueify(Value *v) @@ -949,37 +957,32 @@ class HeapSlotArray operator const Value *() const { return Valueify(array); } operator HeapSlot *() const { return array; } HeapSlotArray operator +(int offset) const { return HeapSlotArray(array + offset); } HeapSlotArray operator +(uint32_t offset) const { return HeapSlotArray(array + offset); } }; -class EncapsulatedId +/* + * Base class for barriered jsid types. + */ +class BarrieredId { protected: jsid value; private: - EncapsulatedId(const EncapsulatedId &v) MOZ_DELETE; + BarrieredId(const BarrieredId &v) MOZ_DELETE; + + protected: + explicit BarrieredId(jsid id) : value(id) {} + ~BarrieredId() { pre(); } public: - explicit EncapsulatedId() : value(JSID_VOID) {} - explicit EncapsulatedId(jsid id) : value(id) {} - ~EncapsulatedId() { pre(); } - - EncapsulatedId &operator=(const EncapsulatedId &v) { - if (v.value != value) - pre(); - JS_ASSERT(!IsPoisonedId(v.value)); - value = v.value; - return *this; - } - bool operator==(jsid id) const { return value == id; } bool operator!=(jsid id) const { return value != id; } jsid get() const { return value; } jsid *unsafeGet() { return &value; } void unsafeSet(jsid newId) { value = newId; } operator jsid() const { return value; } @@ -1000,23 +1003,46 @@ class EncapsulatedId js::gc::MarkStringUnbarriered(shadowZone->barrierTracer(), &str, "write barrier"); JS_ASSERT(str == JSID_TO_STRING(value)); } } #endif } }; -class RelocatableId : public EncapsulatedId +class EncapsulatedId : public BarrieredId { public: - explicit RelocatableId() : EncapsulatedId() {} - explicit inline RelocatableId(jsid id) : EncapsulatedId(id) {} + explicit EncapsulatedId(jsid id) : BarrieredId(id) {} + explicit EncapsulatedId() : BarrieredId(JSID_VOID) {} + + EncapsulatedId &operator=(const EncapsulatedId &v) { + if (v.value != value) + pre(); + JS_ASSERT(!IsPoisonedId(v.value)); + value = v.value; + return *this; + } +}; + +class RelocatableId : public BarrieredId +{ + public: + explicit RelocatableId() : BarrieredId(JSID_VOID) {} + explicit inline RelocatableId(jsid id) : BarrieredId(id) {} ~RelocatableId() { pre(); } + bool operator==(jsid id) const { return value == id; } + bool operator!=(jsid id) const { return value != id; } + + jsid get() const { return value; } + operator jsid() const { return value; } + + jsid *unsafeGet() { return &value; } + RelocatableId &operator=(jsid id) { if (id != value) pre(); JS_ASSERT(!IsPoisonedId(id)); value = id; return *this; } @@ -1029,23 +1055,23 @@ class RelocatableId : public Encapsulate } }; /* * A pre- and post-barriered heap jsid, for use inside the JS engine. * * Not to be confused with JS::Heap<jsid>. */ -class HeapId : public EncapsulatedId +class HeapId : public BarrieredId { public: - explicit HeapId() : EncapsulatedId() {} + explicit HeapId() : BarrieredId(JSID_VOID) {} explicit HeapId(jsid id) - : EncapsulatedId(id) + : BarrieredId(id) { JS_ASSERT(!IsPoisonedId(id)); post(); } ~HeapId() { pre(); } void init(jsid id) {
--- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -214,17 +214,17 @@ void MarkUnbarriered(JSTracer *trc, T **thingp, const char *name) { JS_SET_TRACING_NAME(trc, name); MarkInternal(trc, thingp); } template <typename T> static void -Mark(JSTracer *trc, EncapsulatedPtr<T> *thing, const char *name) +Mark(JSTracer *trc, BarrieredPtr<T> *thing, const char *name) { JS_SET_TRACING_NAME(trc, name); MarkInternal(trc, thing->unsafeGet()); } } /* namespace gc */ } /* namespace js */ @@ -306,17 +306,17 @@ IsAboutToBeFinalized(T **thingp) */ JS_ASSERT(!(*thingp)->arenaHeader()->allocatedDuringIncremental); return !(*thingp)->isMarked(); } #define DeclMarkerImpl(base, type) \ void \ -Mark##base(JSTracer *trc, EncapsulatedPtr<type> *thing, const char *name) \ +Mark##base(JSTracer *trc, BarrieredPtr<type> *thing, const char *name) \ { \ Mark<type>(trc, thing, name); \ } \ \ void \ Mark##base##Root(JSTracer *trc, type **thingp, const char *name) \ { \ MarkRoot<type>(trc, thingp, name); \ @@ -347,29 +347,29 @@ Mark##base##RootRange(JSTracer *trc, siz \ bool \ Is##base##Marked(type **thingp) \ { \ return IsMarked<type>(thingp); \ } \ \ bool \ -Is##base##Marked(EncapsulatedPtr<type> *thingp) \ +Is##base##Marked(BarrieredPtr<type> *thingp) \ { \ return IsMarked<type>(thingp->unsafeGet()); \ } \ \ bool \ Is##base##AboutToBeFinalized(type **thingp) \ { \ return IsAboutToBeFinalized<type>(thingp); \ } \ \ bool \ -Is##base##AboutToBeFinalized(EncapsulatedPtr<type> *thingp) \ +Is##base##AboutToBeFinalized(BarrieredPtr<type> *thingp) \ { \ return IsAboutToBeFinalized<type>(thingp->unsafeGet()); \ } DeclMarkerImpl(BaseShape, BaseShape) DeclMarkerImpl(BaseShape, UnownedBaseShape) DeclMarkerImpl(IonCode, jit::IonCode) DeclMarkerImpl(Object, ArgumentsObject) @@ -471,17 +471,17 @@ MarkIdInternal(JSTracer *trc, jsid *id) *id = OBJECT_TO_JSID(obj); } else { /* Unset realLocation manually if we do not call MarkInternal. */ JS_UNSET_TRACING_LOCATION(trc); } } void -gc::MarkId(JSTracer *trc, EncapsulatedId *id, const char *name) +gc::MarkId(JSTracer *trc, BarrieredId *id, const char *name) { JS_SET_TRACING_NAME(trc, name); MarkIdInternal(trc, id->unsafeGet()); } void gc::MarkIdRoot(JSTracer *trc, jsid *id, const char *name) { @@ -532,17 +532,17 @@ MarkValueInternal(JSTracer *trc, Value * v->setObjectOrNull((JSObject *)thing); } else { /* Unset realLocation manually if we do not call MarkInternal. */ JS_UNSET_TRACING_LOCATION(trc); } } void -gc::MarkValue(JSTracer *trc, EncapsulatedValue *v, const char *name) +gc::MarkValue(JSTracer *trc, BarrieredValue *v, const char *name) { JS_SET_TRACING_NAME(trc, name); MarkValueInternal(trc, v->unsafeGet()); } void gc::MarkValueRoot(JSTracer *trc, Value *v, const char *name) { @@ -563,17 +563,17 @@ gc::MarkTypeRoot(JSTracer *trc, types::T } else if (v->isTypeObject()) { types::TypeObject *typeObj = v->typeObject(); MarkInternal(trc, &typeObj); *v = types::Type::ObjectType(typeObj); } } void -gc::MarkValueRange(JSTracer *trc, size_t len, EncapsulatedValue *vec, const char *name) +gc::MarkValueRange(JSTracer *trc, size_t len, BarrieredValue *vec, const char *name) { for (size_t i = 0; i < len; ++i) { JS_SET_TRACING_INDEX(trc, name, i); MarkValueInternal(trc, vec[i].unsafeGet()); } } void @@ -872,17 +872,17 @@ PushMarkStack(GCMarker *gcmarker, BaseSh } static void ScanShape(GCMarker *gcmarker, Shape *shape) { restart: PushMarkStack(gcmarker, shape->base()); - const EncapsulatedId &id = shape->propidRef(); + const BarrieredId &id = shape->propidRef(); if (JSID_IS_STRING(id)) PushMarkStack(gcmarker, JSID_TO_STRING(id)); else if (JS_UNLIKELY(JSID_IS_OBJECT(id))) PushMarkStack(gcmarker, JSID_TO_OBJECT(id)); shape = shape->previous(); if (shape && shape->markIfUnmarked(gcmarker->getMarkColor())) goto restart;
--- a/js/src/gc/Marking.h +++ b/js/src/gc/Marking.h @@ -76,25 +76,25 @@ namespace gc { * object not in the group of compartments currently being swept, as even if * it is unmarked it may still become marked before it is swept. * * IsObjectMarked(JSObject **thing); * This function is indended to be used in rare cases in code used to mark * GC things. It indicates whether the object is currently marked. */ #define DeclMarker(base, type) \ -void Mark##base(JSTracer *trc, EncapsulatedPtr<type> *thing, const char *name); \ +void Mark##base(JSTracer *trc, BarrieredPtr<type> *thing, const char *name); \ void Mark##base##Root(JSTracer *trc, type **thingp, const char *name); \ void Mark##base##Unbarriered(JSTracer *trc, type **thingp, const char *name); \ void Mark##base##Range(JSTracer *trc, size_t len, HeapPtr<type> *thing, const char *name); \ void Mark##base##RootRange(JSTracer *trc, size_t len, type **thing, const char *name); \ bool Is##base##Marked(type **thingp); \ -bool Is##base##Marked(EncapsulatedPtr<type> *thingp); \ +bool Is##base##Marked(BarrieredPtr<type> *thingp); \ bool Is##base##AboutToBeFinalized(type **thingp); \ -bool Is##base##AboutToBeFinalized(EncapsulatedPtr<type> *thingp); +bool Is##base##AboutToBeFinalized(BarrieredPtr<type> *thingp); \ DeclMarker(BaseShape, BaseShape) DeclMarker(BaseShape, UnownedBaseShape) DeclMarker(IonCode, jit::IonCode) DeclMarker(Object, ArgumentsObject) DeclMarker(Object, ArrayBufferObject) DeclMarker(Object, ArrayBufferViewObject) DeclMarker(Object, DebugScopeObject) @@ -137,37 +137,37 @@ void MarkGCThingRoot(JSTracer *trc, void **thingp, const char *name); void MarkGCThingUnbarriered(JSTracer *trc, void **thingp, const char *name); /*** ID Marking ***/ void -MarkId(JSTracer *trc, EncapsulatedId *id, const char *name); +MarkId(JSTracer *trc, BarrieredId *id, const char *name); void MarkIdRoot(JSTracer *trc, jsid *id, const char *name); void MarkIdUnbarriered(JSTracer *trc, jsid *id, const char *name); void MarkIdRange(JSTracer *trc, size_t len, HeapId *vec, const char *name); void MarkIdRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name); /*** Value Marking ***/ void -MarkValue(JSTracer *trc, EncapsulatedValue *v, const char *name); +MarkValue(JSTracer *trc, BarrieredValue *v, const char *name); void -MarkValueRange(JSTracer *trc, size_t len, EncapsulatedValue *vec, const char *name); +MarkValueRange(JSTracer *trc, size_t len, BarrieredValue *vec, const char *name); inline void MarkValueRange(JSTracer *trc, HeapValue *begin, HeapValue *end, const char *name) { return MarkValueRange(trc, end - begin, begin, name); } void @@ -254,29 +254,29 @@ PushArena(GCMarker *gcmarker, ArenaHeade /*** Generic ***/ /* * The Mark() functions interface should only be used by code that must be * templated. Other uses should use the more specific, type-named functions. */ inline void -Mark(JSTracer *trc, EncapsulatedValue *v, const char *name) +Mark(JSTracer *trc, BarrieredValue *v, const char *name) { MarkValue(trc, v, name); } inline void -Mark(JSTracer *trc, EncapsulatedPtrObject *o, const char *name) +Mark(JSTracer *trc, BarrieredPtrObject *o, const char *name) { MarkObject(trc, o, name); } inline void -Mark(JSTracer *trc, EncapsulatedPtrScript *o, const char *name) +Mark(JSTracer *trc, BarrieredPtrScript *o, const char *name) { MarkScript(trc, o, name); } inline void Mark(JSTracer *trc, HeapPtr<jit::IonCode> *code, const char *name) { MarkIonCode(trc, code, name); @@ -298,51 +298,51 @@ Mark(JSTracer *trc, ScopeObject **obj, c bool IsCellMarked(Cell **thingp); bool IsCellAboutToBeFinalized(Cell **thing); inline bool -IsMarked(EncapsulatedValue *v) +IsMarked(BarrieredValue *v) { if (!v->isMarkable()) return true; return IsValueMarked(v->unsafeGet()); } inline bool -IsMarked(EncapsulatedPtrObject *objp) +IsMarked(BarrieredPtrObject *objp) { return IsObjectMarked(objp); } inline bool -IsMarked(EncapsulatedPtrScript *scriptp) +IsMarked(BarrieredPtrScript *scriptp) { return IsScriptMarked(scriptp); } inline bool -IsAboutToBeFinalized(EncapsulatedValue *v) +IsAboutToBeFinalized(BarrieredValue *v) { if (!v->isMarkable()) return false; return IsValueAboutToBeFinalized(v->unsafeGet()); } inline bool -IsAboutToBeFinalized(EncapsulatedPtrObject *objp) +IsAboutToBeFinalized(BarrieredPtrObject *objp) { return IsObjectAboutToBeFinalized(objp); } inline bool -IsAboutToBeFinalized(EncapsulatedPtrScript *scriptp) +IsAboutToBeFinalized(BarrieredPtrScript *scriptp) { return IsScriptAboutToBeFinalized(scriptp); } #ifdef JS_ION /* Nonsense to get WeakCache to work with new Marking semantics. */ inline bool
--- a/js/src/jit-test/jit_test.py +++ b/js/src/jit-test/jit_test.py @@ -191,17 +191,16 @@ def main(argv): job_list.append(new_test) prefix = [os.path.abspath(args[0])] + shlex.split(options.shell_args) prolog = os.path.join(jittests.LIB_DIR, 'prolog.js') if options.remote: prolog = posixpath.join(options.remote_test_root, 'jit-tests', 'jit-tests', 'lib', 'prolog.js') prefix += ['-f', prolog] - prefix += ['--js-cache', jittests.JS_CACHE_DIR] # Avoid racing on the cache by having the js shell create a new cache # subdir for each process. The js shell takes care of deleting these # subdirs when the process exits. if options.max_jobs > 1 and jittests.HAVE_MULTIPROCESSING: prefix += ['--js-cache-per-process'] # Clean up any remnants from previous crashes etc
--- a/js/src/jit/BacktrackingAllocator.cpp +++ b/js/src/jit/BacktrackingAllocator.cpp @@ -363,24 +363,27 @@ BacktrackingAllocator::groupAndQueueRegi BacktrackingVirtualRegister ® = vregs[i]; JS_ASSERT(reg.numIntervals() <= 2); JS_ASSERT(!reg.canonicalSpill()); if (!reg.numIntervals()) continue; + // Disable this for now; see bugs 906858, 931487, and 932465. +#if 0 // Eagerly set the canonical spill slot for registers which are preset // for that slot, and reuse it for other registers in the group. LDefinition *def = reg.def(); if (def->policy() == LDefinition::PRESET && !def->output()->isRegister()) { reg.setCanonicalSpill(*def->output()); if (reg.group() && reg.group()->spill.isUse()) reg.group()->spill = *def->output(); } +#endif // Place all intervals for this register on the allocation queue. // During initial queueing use single queue items for groups of // registers, so that they will be allocated together and reduce the // risk of unnecessary conflicts. This is in keeping with the idea that // register groups are effectively single registers whose value changes // during execution. If any intervals in the group are evicted later // then they will be reallocated individually.
--- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -723,30 +723,34 @@ BaselineCompiler::emitSPSPop() MethodStatus BaselineCompiler::emitBody() { JS_ASSERT(pc == script->code); bool lastOpUnreachable = false; uint32_t emittedOps = 0; + mozilla::DebugOnly<jsbytecode *> prevpc = pc; while (true) { JSOp op = JSOp(*pc); IonSpew(IonSpew_BaselineOp, "Compiling op @ %d: %s", int(pc - script->code), js_CodeName[op]); BytecodeInfo *info = analysis_.maybeInfo(pc); // Skip unreachable ops. if (!info) { - if (op == JSOP_STOP) + // Test if last instructions and stop emitting in that case. + pc += GetBytecodeLength(pc); + if (pc >= script->code + script->length) break; - pc += GetBytecodeLength(pc); + lastOpUnreachable = true; + prevpc = pc; continue; } // Fully sync the stack if there are incoming jumps. if (info->jumpTarget) { frame.syncStack(0); frame.setStackDepth(info->stackDepth); } @@ -786,25 +790,29 @@ BaselineCompiler::emitBody() case OP: \ if (!this->emit_##OP()) \ return Method_Error; \ break; OPCODE_LIST(EMIT_OP) #undef EMIT_OP } - if (op == JSOP_STOP) + // Test if last instructions and stop emitting in that case. + pc += GetBytecodeLength(pc); + if (pc >= script->code + script->length) break; - pc += GetBytecodeLength(pc); emittedOps++; lastOpUnreachable = false; +#ifdef DEBUG + prevpc = pc; +#endif } - JS_ASSERT(JSOp(*pc) == JSOP_STOP); + JS_ASSERT(JSOp(*prevpc) == JSOP_RETRVAL); return Method_Compiled; } bool BaselineCompiler::emit_JSOP_NOP() { return true; } @@ -2687,36 +2695,36 @@ BaselineCompiler::emitReturn() pushArg(Imm32(1)); pushArg(R0.scratchReg()); if (!callVM(DebugEpilogueInfo)) return false; masm.loadValue(frame.addressOfReturnValue(), JSReturnOperand); } - if (JSOp(*pc) != JSOP_STOP) { - // JSOP_STOP is immediately followed by the return label, so we don't - // need a jump. + // Only emit the jump if this JSOP_RETRVAL is not the last instruction. + // Not needed for last instruction, because last instruction flows + // into return label. + if (pc + GetBytecodeLength(pc) < script->code + script->length) masm.jump(&return_); - } return true; } bool BaselineCompiler::emit_JSOP_RETURN() { JS_ASSERT(frame.stackDepth() == 1); frame.popValue(JSReturnOperand); return emitReturn(); } bool -BaselineCompiler::emit_JSOP_STOP() +BaselineCompiler::emit_JSOP_RETRVAL() { JS_ASSERT(frame.stackDepth() == 0); masm.moveValue(UndefinedValue(), JSReturnOperand); if (!script->noScriptRval) { // Return the value in the return value slot, if any. Label done; @@ -2724,22 +2732,16 @@ BaselineCompiler::emit_JSOP_STOP() masm.branchTest32(Assembler::Zero, flags, Imm32(BaselineFrame::HAS_RVAL), &done); masm.loadValue(frame.addressOfReturnValue(), JSReturnOperand); masm.bind(&done); } return emitReturn(); } -bool -BaselineCompiler::emit_JSOP_RETRVAL() -{ - return emit_JSOP_STOP(); -} - typedef bool (*ToIdFn)(JSContext *, HandleScript, jsbytecode *, HandleValue, HandleValue, MutableHandleValue); static const VMFunction ToIdInfo = FunctionInfo<ToIdFn>(js::ToIdOperation); bool BaselineCompiler::emit_JSOP_TOID() { // Load index in R0, but keep values on the stack for the decompiler. @@ -2844,22 +2846,16 @@ BaselineCompiler::emit_JSOP_CALLEE() JS_ASSERT(function()); frame.syncStack(0); masm.loadPtr(frame.addressOfCallee(), R0.scratchReg()); masm.tagValue(JSVAL_TYPE_OBJECT, R0.scratchReg(), R0); frame.push(R0); return true; } -bool -BaselineCompiler::emit_JSOP_POPV() -{ - return emit_JSOP_SETRVAL(); -} - typedef bool (*NewArgumentsObjectFn)(JSContext *, BaselineFrame *, MutableHandleValue); static const VMFunction NewArgumentsObjectInfo = FunctionInfo<NewArgumentsObjectFn>(jit::NewArgumentsObject); bool BaselineCompiler::emit_JSOP_ARGUMENTS() { frame.syncStack(0);
--- a/js/src/jit/BaselineCompiler.h +++ b/js/src/jit/BaselineCompiler.h @@ -159,21 +159,19 @@ namespace jit { _(JSOP_REST) \ _(JSOP_TOID) \ _(JSOP_TABLESWITCH) \ _(JSOP_ITER) \ _(JSOP_MOREITER) \ _(JSOP_ITERNEXT) \ _(JSOP_ENDITER) \ _(JSOP_CALLEE) \ - _(JSOP_POPV) \ _(JSOP_SETRVAL) \ - _(JSOP_RETURN) \ - _(JSOP_STOP) \ - _(JSOP_RETRVAL) + _(JSOP_RETRVAL) \ + _(JSOP_RETURN) class BaselineCompiler : public BaselineCompilerSpecific { FixedList<Label> labels_; NonAssertingLabel return_; #ifdef JSGC_GENERATIONAL NonAssertingLabel postBarrierSlot_; #endif
--- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -1217,17 +1217,16 @@ IonBuilder::traverseBytecode() case JSOP_POPN: case JSOP_DUP: case JSOP_DUP2: case JSOP_PICK: case JSOP_SWAP: case JSOP_SETARG: case JSOP_SETLOCAL: case JSOP_SETRVAL: - case JSOP_POPV: case JSOP_VOID: // Don't require SSA uses for values popped by these ops. break; case JSOP_POS: case JSOP_TOID: // These ops may leave their input on the stack without setting // the Folded flag. If this value will be popped immediately, @@ -1266,17 +1265,16 @@ IonBuilder::snoopControlFlow(JSOp op) switch (op) { case JSOP_NOP: return maybeLoop(op, info().getNote(gsn, pc)); case JSOP_POP: return maybeLoop(op, info().getNote(gsn, pc)); case JSOP_RETURN: - case JSOP_STOP: case JSOP_RETRVAL: return processReturn(op); case JSOP_THROW: return processThrow(); case JSOP_GOTO: { @@ -1673,17 +1671,16 @@ IonBuilder::inspectOpcode(JSOp op) case JSOP_ENDITER: return jsop_iterend(); case JSOP_IN: return jsop_in(); case JSOP_SETRVAL: - case JSOP_POPV: JS_ASSERT(!script()->noScriptRval); current->setSlot(info().returnValueSlot(), current->pop()); return true; case JSOP_INSTANCEOF: return jsop_instanceof(); default: @@ -3473,28 +3470,25 @@ IonBuilder::processReturn(JSOp op) { MDefinition *def; switch (op) { case JSOP_RETURN: // Return the last instruction. def = current->pop(); break; - case JSOP_STOP: + case JSOP_RETRVAL: // Return undefined eagerly if script doesn't use return value. if (script()->noScriptRval) { MInstruction *ins = MConstant::New(UndefinedValue()); current->add(ins); def = ins; break; } - // Fall through - case JSOP_RETRVAL: - // Return the value in the return value slot. def = current->getSlot(info().returnValueSlot()); break; default: def = nullptr; MOZ_ASSUME_UNREACHABLE("unknown return op"); }
--- a/js/src/jsanalyze.cpp +++ b/js/src/jsanalyze.cpp @@ -222,17 +222,17 @@ ScriptAnalysis::analyzeBytecode(JSContex JS_ASSERT(stackDepth >= nuses); stackDepth -= nuses; stackDepth += ndefs; switch (op) { case JSOP_RETURN: - case JSOP_STOP: + case JSOP_RETRVAL: numReturnSites_++; break; case JSOP_NAME: case JSOP_CALLNAME: case JSOP_BINDNAME: case JSOP_SETNAME: case JSOP_DELNAME: @@ -1216,17 +1216,16 @@ ScriptAnalysis::analyzeSSA(JSContext *cx } } } break; } case JSOP_THROW: case JSOP_RETURN: - case JSOP_STOP: case JSOP_RETRVAL: mergeAllExceptionTargets(cx, values, exceptionTargets); break; default:; } if (IsJumpOpcode(op)) {
--- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -1649,62 +1649,62 @@ JS_AddNamedScriptRoot(JSContext *cx, JSS } /* We allow unrooting from finalizers within the GC */ JS_PUBLIC_API(void) JS_RemoveValueRoot(JSContext *cx, jsval *vp) { CHECK_REQUEST(cx); - js_RemoveRoot(cx->runtime(), (void *)vp); + RemoveRoot(cx->runtime(), (void *)vp); } JS_PUBLIC_API(void) JS_RemoveStringRoot(JSContext *cx, JSString **rp) { CHECK_REQUEST(cx); - js_RemoveRoot(cx->runtime(), (void *)rp); + RemoveRoot(cx->runtime(), (void *)rp); } JS_PUBLIC_API(void) JS_RemoveObjectRoot(JSContext *cx, JSObject **rp) { CHECK_REQUEST(cx); - js_RemoveRoot(cx->runtime(), (void *)rp); + RemoveRoot(cx->runtime(), (void *)rp); } JS_PUBLIC_API(void) JS_RemoveScriptRoot(JSContext *cx, JSScript **rp) { CHECK_REQUEST(cx); - js_RemoveRoot(cx->runtime(), (void *)rp); + RemoveRoot(cx->runtime(), (void *)rp); } JS_PUBLIC_API(void) JS_RemoveValueRootRT(JSRuntime *rt, jsval *vp) { - js_RemoveRoot(rt, (void *)vp); + RemoveRoot(rt, (void *)vp); } JS_PUBLIC_API(void) JS_RemoveStringRootRT(JSRuntime *rt, JSString **rp) { - js_RemoveRoot(rt, (void *)rp); + RemoveRoot(rt, (void *)rp); } JS_PUBLIC_API(void) JS_RemoveObjectRootRT(JSRuntime *rt, JSObject **rp) { - js_RemoveRoot(rt, (void *)rp); + RemoveRoot(rt, (void *)rp); } JS_PUBLIC_API(void) JS_RemoveScriptRootRT(JSRuntime *rt, JSScript **rp) { - js_RemoveRoot(rt, (void *)rp); + RemoveRoot(rt, (void *)rp); } JS_NEVER_INLINE JS_PUBLIC_API(void) JS_AnchorPtr(void *p) { } JS_PUBLIC_API(bool)
--- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -1975,21 +1975,16 @@ extern JS_PUBLIC_API(void) JS_RemoveStringRootRT(JSRuntime *rt, JSString **rp); extern JS_PUBLIC_API(void) JS_RemoveObjectRootRT(JSRuntime *rt, JSObject **rp); extern JS_PUBLIC_API(void) JS_RemoveScriptRootRT(JSRuntime *rt, JSScript **rp); -/* TODO: remove these APIs */ - -extern JS_FRIEND_API(void) -js_RemoveRoot(JSRuntime *rt, void *rp); - /* * C-compatible version of the Anchor class. It should be called after the last * use of the variable it protects. */ extern JS_NEVER_INLINE JS_PUBLIC_API(void) JS_AnchorPtr(void *p); /*
--- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -1195,17 +1195,17 @@ array_join(JSContext *cx, unsigned argc, } static inline bool InitArrayTypes(JSContext *cx, TypeObject *type, const Value *vector, unsigned count) { if (cx->typeInferenceEnabled() && !type->unknownProperties()) { AutoEnterAnalysis enter(cx); - TypeSet *types = type->getProperty(cx, JSID_VOID); + HeapTypeSet *types = type->getProperty(cx, JSID_VOID); if (!types) return false; for (unsigned i = 0; i < count; i++) { if (vector[i].isMagic(JS_ELEMENTS_HOLE)) continue; Type valtype = GetValueType(vector[i]); types->addType(cx, valtype);
--- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -1099,21 +1099,21 @@ extern JS_FRIEND_API(bool) js_AddObjectRoot(JSRuntime *rt, JSObject **objp) { return AddRoot(rt, objp, nullptr, JS_GC_ROOT_OBJECT_PTR); } extern JS_FRIEND_API(void) js_RemoveObjectRoot(JSRuntime *rt, JSObject **objp) { - js_RemoveRoot(rt, objp); -} - -JS_FRIEND_API(void) -js_RemoveRoot(JSRuntime *rt, void *rp) + RemoveRoot(rt, objp); +} + +void +js::RemoveRoot(JSRuntime *rt, void *rp) { rt->gcRootsHash.remove(rp); rt->gcPoke = true; } typedef RootedValueMap::Range RootRange; typedef RootedValueMap::Entry RootEntry; typedef RootedValueMap::Enum RootEnum;
--- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -663,16 +663,19 @@ extern bool AddObjectRoot(JSContext *cx, JSObject **rp, const char *name); extern bool AddObjectRoot(JSRuntime *rt, JSObject **rp, const char *name); extern bool AddScriptRoot(JSContext *cx, JSScript **rp, const char *name); +extern void +RemoveRoot(JSRuntime *rt, void *rp); + } /* namespace js */ extern bool js_InitGC(JSRuntime *rt, uint32_t maxbytes); extern void js_FinishGC(JSRuntime *rt);
--- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -392,20 +392,18 @@ TypeSet::addTypesToConstraint(JSContext if (!enumerateTypes(&types)) cx->compartment()->types.setPendingNukeTypes(cx); for (unsigned i = 0; i < types.length(); i++) constraint->newType(cx, this, types[i]); } void -TypeSet::add(JSContext *cx, TypeConstraint *constraint, bool callExisting) +ConstraintTypeSet::add(JSContext *cx, TypeConstraint *constraint, bool callExisting) { - JS_ASSERT(isStackSet() || isHeapSet()); - if (!constraint) { /* OOM failure while constructing the constraint. */ cx->compartment()->types.setPendingNukeTypes(cx); return; } JS_ASSERT(cx->compartment()->activeAnalysis); @@ -480,19 +478,17 @@ TypeSet::clone(LifoAlloc *alloc, Tempora TypeObjectKey **newSet; if (capacity) { newSet = alloc->newArray<TypeObjectKey*>(capacity); if (!newSet) return false; PodCopy(newSet, objectSet, capacity); } - uint32_t newFlags = flags & ~(TYPE_FLAG_STACK_SET | TYPE_FLAG_HEAP_SET); - - new(result) TemporaryTypeSet(newFlags, capacity ? newSet : objectSet); + new(result) TemporaryTypeSet(flags, capacity ? newSet : objectSet); return true; } TemporaryTypeSet * TypeSet::clone(LifoAlloc *alloc) const { TemporaryTypeSet *res = alloc->new_<TemporaryTypeSet>(); if (!res || !clone(alloc, res)) @@ -1347,17 +1343,17 @@ TypeObjectKey::watchStateChangeForTypedA static void ObjectStateChange(ExclusiveContext *cxArg, TypeObject *object, bool markingUnknown) { if (object->unknownProperties()) return; /* All constraints listening to state changes are on the empty id. */ - TypeSet *types = object->maybeGetProperty(JSID_EMPTY); + HeapTypeSet *types = object->maybeGetProperty(JSID_EMPTY); /* Mark as unknown after getting the types, to avoid assertion. */ if (markingUnknown) object->flags |= OBJECT_FLAG_DYNAMIC_MASK | OBJECT_FLAG_UNKNOWN_PROPERTIES; if (types) { if (JSContext *cx = cxArg->maybeJSContext()) { TypeConstraint *constraint = types->constraintList; @@ -2167,17 +2163,17 @@ TypeCompartment::markSetsUnknown(JSConte * a generic object type. It is not sufficient to mark just the persistent * sets, as analysis of individual opcodes can pull type objects from * static information (like initializer objects at various offsets). * * We make a list of properties to update and fix them afterwards, as adding * types can't be done while iterating over cells as it can potentially make * new type objects as well or trigger GC. */ - Vector<TypeSet *> pending(cx); + Vector<ConstraintTypeSet *> pending(cx); for (gc::CellIter i(cx->zone(), gc::FINALIZE_TYPE_OBJECT); !i.done(); i.next()) { TypeObject *object = i.get<TypeObject>(); unsigned count = object->getPropertyCount(); for (unsigned i = 0; i < count; i++) { Property *prop = object->getProperty(i); if (prop && prop->types.hasType(Type::ObjectType(target))) { if (!pending.append(&prop->types)) cx->compartment()->types.setPendingNukeTypes(cx); @@ -2187,17 +2183,17 @@ TypeCompartment::markSetsUnknown(JSConte for (unsigned i = 0; i < pending.length(); i++) pending[i]->addType(cx, Type::AnyObjectType()); for (gc::CellIter i(cx->zone(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) { RootedScript script(cx, i.get<JSScript>()); if (script->types) { unsigned count = TypeScript::NumTypeSets(script); - TypeSet *typeArray = script->types->typeArray(); + StackTypeSet *typeArray = script->types->typeArray(); for (unsigned i = 0; i < count; i++) { if (typeArray[i].hasType(Type::ObjectType(target))) typeArray[i].addType(cx, Type::AnyObjectType()); } } } } @@ -2756,17 +2752,17 @@ TypeObject::matchDefiniteProperties(Hand static inline void InlineAddTypeProperty(ExclusiveContext *cx, TypeObject *obj, jsid id, Type type) { JS_ASSERT(id == IdToTypeId(id)); AutoEnterAnalysis enter(cx); - TypeSet *types = obj->getProperty(cx, id); + HeapTypeSet *types = obj->getProperty(cx, id); if (!types || types->hasType(type)) return; InferSpew(ISpewOps, "externalType: property %s %s: %s", TypeObjectString(obj), TypeIdString(id), TypeString(type)); types->addType(cx, type); } @@ -2806,17 +2802,17 @@ TypeObject::addPropertyType(ExclusiveCon void TypeObject::markPropertyConfigured(ExclusiveContext *cx, jsid id) { AutoEnterAnalysis enter(cx); id = IdToTypeId(id); - TypeSet *types = getProperty(cx, id); + HeapTypeSet *types = getProperty(cx, id); if (types) types->setConfiguredProperty(cx); } bool TypeObject::isPropertyConfigured(jsid id) { TypeSet *types = maybeGetProperty(id); @@ -2827,17 +2823,17 @@ TypeObject::isPropertyConfigured(jsid id void TypeObject::markStateChange(ExclusiveContext *cxArg) { if (unknownProperties()) return; AutoEnterAnalysis enter(cxArg); - TypeSet *types = maybeGetProperty(JSID_EMPTY); + HeapTypeSet *types = maybeGetProperty(JSID_EMPTY); if (types) { if (JSContext *cx = cxArg->maybeJSContext()) { TypeConstraint *constraint = types->constraintList; while (constraint) { constraint->newObjectState(cx, this); constraint = constraint->next; } } else { @@ -3181,20 +3177,20 @@ types::AddClearDefiniteFunctionUsesInScr // |script|, and add constraints to ensure that if the type sets' contents // change then the definite properties are cleared from the type. // This ensures that the inlining performed when the definite properties // analysis was done is stable. TypeObjectKey *calleeKey = Type::ObjectType(calleeScript->function()).objectKey(); unsigned count = TypeScript::NumTypeSets(script); - TypeSet *typeArray = script->types->typeArray(); + StackTypeSet *typeArray = script->types->typeArray(); for (unsigned i = 0; i < count; i++) { - TypeSet *types = &typeArray[i]; + StackTypeSet *types = &typeArray[i]; if (!types->unknownObject() && types->getObjectCount() == 1) { if (calleeKey != types->getObject(0)) { // Also check if the object is the Function.call or // Function.apply native. IonBuilder uses the presence of these // functions during inlining. JSObject *singleton = types->getSingleObject(0); if (!singleton || !singleton->is<JSFunction>()) continue; @@ -3360,17 +3356,17 @@ types::TypeMonitorResult(JSContext *cx, return; if (!script->hasBaselineScript()) return; AutoEnterAnalysis enter(cx); Type type = GetValueType(rval); - TypeSet *types = TypeScript::BytecodeTypes(script, pc); + StackTypeSet *types = TypeScript::BytecodeTypes(script, pc); if (types->hasType(type)) return; InferSpew(ISpewOps, "bytecodeType: #%u:%05u: %s", script->id(), pc - script->code, TypeString(type)); types->addType(cx, type); } @@ -3446,17 +3442,17 @@ JSScript::makeTypes(JSContext *cx) new(types) TypeScript(); return analyzedArgsUsage() || ensureRanAnalysis(cx); } AutoEnterAnalysis enter(cx); unsigned count = TypeScript::NumTypeSets(this); - types = (TypeScript *) cx->calloc_(sizeof(TypeScript) + (sizeof(TypeSet) * count)); + types = (TypeScript *) cx->calloc_(sizeof(TypeScript) + (sizeof(StackTypeSet) * count)); if (!types) { cx->compartment()->types.setPendingNukeTypes(cx); return false; } new(types) TypeScript(); TypeSet *typeArray = types->typeArray(); @@ -3881,17 +3877,17 @@ ExclusiveContext::getLazyType(const Clas return type; } ///////////////////////////////////////////////////////////////////// // Tracing ///////////////////////////////////////////////////////////////////// void -TypeSet::sweep(Zone *zone) +ConstraintTypeSet::sweep(Zone *zone) { /* * Purge references to type objects that are no longer live. Type sets hold * only weak references. For type sets containing more than one object, * live entries in the object hash need to be copied to the zone's * new arena. */ unsigned objectCount = baseObjectCount(); @@ -4177,17 +4173,17 @@ TypeCompartment::~TypeCompartment() /* static */ void TypeScript::Sweep(FreeOp *fop, JSScript *script) { JSCompartment *compartment = script->compartment(); JS_ASSERT(compartment->zone()->isGCSweeping()); JS_ASSERT(compartment->zone()->types.inferenceEnabled); unsigned num = NumTypeSets(script); - TypeSet *typeArray = script->types->typeArray(); + StackTypeSet *typeArray = script->types->typeArray(); /* Remove constraints and references to dead objects from the persistent type sets. */ for (unsigned i = 0; i < num; i++) typeArray[i].sweep(compartment->zone()); /* * Freeze constraints on stack type sets need to be regenerated the next * time the script is analyzed.
--- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -342,44 +342,27 @@ enum { TYPE_FLAG_LAZYARGS = 0x40, TYPE_FLAG_ANYOBJECT = 0x80, /* Mask containing all primitives */ TYPE_FLAG_PRIMITIVE = TYPE_FLAG_UNDEFINED | TYPE_FLAG_NULL | TYPE_FLAG_BOOLEAN | TYPE_FLAG_INT32 | TYPE_FLAG_DOUBLE | TYPE_FLAG_STRING, /* Mask/shift for the number of objects in objectSet */ - TYPE_FLAG_OBJECT_COUNT_LIMIT = 7, + TYPE_FLAG_OBJECT_COUNT_MASK = 0x1f00, TYPE_FLAG_OBJECT_COUNT_SHIFT = 8, - TYPE_FLAG_OBJECT_COUNT_MASK = /* = 0x700 */ - TYPE_FLAG_OBJECT_COUNT_LIMIT << TYPE_FLAG_OBJECT_COUNT_SHIFT, + TYPE_FLAG_OBJECT_COUNT_LIMIT = + TYPE_FLAG_OBJECT_COUNT_MASK >> TYPE_FLAG_OBJECT_COUNT_SHIFT, /* Whether the contents of this type set are totally unknown. */ TYPE_FLAG_UNKNOWN = 0x00002000, /* Mask of normal type flags on a type set. */ TYPE_FLAG_BASE_MASK = 0x000020ff, - /* - * Flags describing the kind of type set this is. - * - * - StackTypeSet are associated with TypeScripts, for arguments and values - * observed at property reads. These are implicitly frozen on compilation - * and do not have constraints attached to them. - * - * - HeapTypeSet are associated with the properties of TypeObjects. These - * may have constraints added to them to trigger invalidation of compiled - * code. - * - * - TemporaryTypeSet are created during compilation and do not outlive - * that compilation. - */ - TYPE_FLAG_STACK_SET = 0x00004000, - TYPE_FLAG_HEAP_SET = 0x00008000, - /* Additional flags for HeapTypeSet sets. */ /* * Whether the property has ever been deleted or reconfigured to behave * differently from a normal native property (e.g. made non-writable or * given a scripted getter or setter). */ TYPE_FLAG_CONFIGURED_PROPERTY = 0x00010000, @@ -480,39 +463,48 @@ enum { | OBJECT_FLAG_SETS_MARKED_UNKNOWN }; typedef uint32_t TypeObjectFlags; class StackTypeSet; class HeapTypeSet; class TemporaryTypeSet; -/* Information about the set of types associated with an lvalue. */ +/* + * Information about the set of types associated with an lvalue. There are + * three kinds of type sets: + * + * - StackTypeSet are associated with TypeScripts, for arguments and values + * observed at property reads. These are implicitly frozen on compilation + * and do not have constraints attached to them. + * + * - HeapTypeSet are associated with the properties of TypeObjects. These + * may have constraints added to them to trigger invalidation of compiled + * code. + * + * - TemporaryTypeSet are created during compilation and do not outlive + * that compilation. + */ class TypeSet { protected: /* Flags for this type set. */ TypeFlags flags; /* Possible objects this type set can represent. */ TypeObjectKey **objectSet; public: - /* Chain of constraints which propagate changes out from this type set. */ - TypeConstraint *constraintList; - TypeSet() - : flags(0), objectSet(nullptr), constraintList(nullptr) + : flags(0), objectSet(nullptr) {} void print(); - inline void sweep(JS::Zone *zone); - /* Whether this set contains a specific type. */ inline bool hasType(Type type) const; TypeFlags baseFlags() const { return flags & TYPE_FLAG_BASE_MASK; } bool unknown() const { return !!(flags & TYPE_FLAG_UNKNOWN); } bool unknownObject() const { return !!(flags & (TYPE_FLAG_UNKNOWN | TYPE_FLAG_ANYOBJECT)); } bool empty() const { return !baseFlags() && !baseObjectCount(); } @@ -531,25 +523,16 @@ class TypeSet } /* Join two type sets into a new set. The result should not be modified further. */ static TemporaryTypeSet *unionSets(TypeSet *a, TypeSet *b, LifoAlloc *alloc); /* Add a type to this set using the specified allocator. */ inline bool addType(Type type, LifoAlloc *alloc, bool *padded = nullptr); - /* - * Add a type to this set, calling any constraint handlers if this is a new - * possible type. - */ - inline void addType(ExclusiveContext *cx, Type type); - - /* Mark this type set as representing a configured property. */ - inline void setConfiguredProperty(ExclusiveContext *cx); - /* Get a list of all types in this set. */ typedef Vector<Type, 1, SystemAllocPolicy> TypeList; bool enumerateTypes(TypeList *list); /* * Iterate through the objects in this set. getObjectCount overapproximates * in the hash case (see SET_ARRAY_SIZE in jsinferinlines.h), and getObject * may return nullptr. @@ -569,81 +552,88 @@ class TypeSet bool canSetDefinite(unsigned slot) { return (slot + 1) <= (TYPE_FLAG_DEFINITE_MASK >> TYPE_FLAG_DEFINITE_SHIFT); } void setDefinite(unsigned slot) { JS_ASSERT(canSetDefinite(slot)); flags |= ((slot + 1) << TYPE_FLAG_DEFINITE_SHIFT); } - bool isStackSet() { - return flags & TYPE_FLAG_STACK_SET; - } - bool isHeapSet() { - return flags & TYPE_FLAG_HEAP_SET; - } - /* Whether any values in this set might have the specified type. */ bool mightBeType(JSValueType type); /* * Get whether this type set is known to be a subset of other. * This variant doesn't freeze constraints. That variant is called knownSubset */ bool isSubset(TypeSet *other); /* Forward all types in this set to the specified constraint. */ void addTypesToConstraint(JSContext *cx, TypeConstraint *constraint); - /* Add a new constraint to this set. */ - void add(JSContext *cx, TypeConstraint *constraint, bool callExisting = true); - - inline StackTypeSet *toStackSet(); - inline HeapTypeSet *toHeapSet(); - // Clone a type set into an arbitrary allocator. TemporaryTypeSet *clone(LifoAlloc *alloc) const; bool clone(LifoAlloc *alloc, TemporaryTypeSet *result) const; protected: uint32_t baseObjectCount() const { return (flags & TYPE_FLAG_OBJECT_COUNT_MASK) >> TYPE_FLAG_OBJECT_COUNT_SHIFT; } inline void setBaseObjectCount(uint32_t count); inline void clearObjects(); }; -class StackTypeSet : public TypeSet +/* Superclass common to stack and heap type sets. */ +class ConstraintTypeSet : public TypeSet { public: - StackTypeSet() { flags |= TYPE_FLAG_STACK_SET; } + /* Chain of constraints which propagate changes out from this type set. */ + TypeConstraint *constraintList; + + ConstraintTypeSet() : constraintList(nullptr) {} + + /* + * Add a type to this set, calling any constraint handlers if this is a new + * possible type. + */ + inline void addType(ExclusiveContext *cx, Type type); + + /* Add a new constraint to this set. */ + void add(JSContext *cx, TypeConstraint *constraint, bool callExisting = true); + + inline void sweep(JS::Zone *zone); }; -class HeapTypeSet : public TypeSet +class StackTypeSet : public ConstraintTypeSet { public: - HeapTypeSet() { flags |= TYPE_FLAG_HEAP_SET; } +}; + +class HeapTypeSet : public ConstraintTypeSet +{ + public: + /* Mark this type set as representing a configured property. */ + inline void setConfiguredProperty(ExclusiveContext *cx); }; class CompilerConstraintList; CompilerConstraintList * NewCompilerConstraintList(); class TemporaryTypeSet : public TypeSet { public: TemporaryTypeSet() {} TemporaryTypeSet(Type type); TemporaryTypeSet(uint32_t flags, TypeObjectKey **objectSet) { this->flags = flags; this->objectSet = objectSet; - JS_ASSERT(!isStackSet() && !isHeapSet()); } /* * Constraints for JIT compilation. * * Methods for JIT compilation. These must be used when a script is * currently being compiled (see AutoEnterCompilation) and will add * constraints ensuring that if the return value change in the future due @@ -720,30 +710,16 @@ class TemporaryTypeSet : public TypeSet /* * Whether known double optimizations are possible for element accesses on * objects in this type set. */ DoubleConversion convertDoubleElements(CompilerConstraintList *constraints); }; -inline StackTypeSet * -TypeSet::toStackSet() -{ - JS_ASSERT(isStackSet()); - return (StackTypeSet *) this; -} - -inline HeapTypeSet * -TypeSet::toHeapSet() -{ - JS_ASSERT(isHeapSet()); - return (HeapTypeSet *) this; -} - bool AddClearDefiniteGetterSetterForPrototypeChain(JSContext *cx, TypeObject *type, jsid id); void AddClearDefiniteFunctionUsesInScript(JSContext *cx, TypeObject *type, JSScript *script, JSScript *calleeScript); /* Is this a reasonable PC to be doing inlining on? */ @@ -1393,17 +1369,17 @@ struct TypeCompartment /* * Worklist of types which need to be propagated to constraints. We use a * worklist to avoid blowing the native stack. */ struct PendingWork { TypeConstraint *constraint; - TypeSet *source; + ConstraintTypeSet *source; Type type; }; PendingWork *pendingArray; unsigned pendingCount; unsigned pendingCapacity; /* Whether we are currently resolving the pending worklist. */ bool resolving; @@ -1436,17 +1412,18 @@ struct TypeCompartment JSObject *newTypedObject(JSContext *cx, IdValuePair *properties, size_t nproperties); TypeCompartment(); ~TypeCompartment(); inline JSCompartment *compartment(); /* Add a type to register with a list of constraints. */ - inline void addPending(JSContext *cx, TypeConstraint *constraint, TypeSet *source, Type type); + inline void addPending(JSContext *cx, TypeConstraint *constraint, + ConstraintTypeSet *source, Type type); bool growPendingArray(JSContext *cx); /* Resolve pending type registrations, excluding delayed ones. */ inline void resolvePending(JSContext *cx); /* Prints results of this compartment if spew is enabled or force is set. */ void print(JSContext *cx, bool force);
--- a/js/src/jsinferinlines.h +++ b/js/src/jsinferinlines.h @@ -848,17 +848,18 @@ TypeScript::SetArgument(JSContext *cx, J inline JSCompartment * TypeCompartment::compartment() { return (JSCompartment *)((char *)this - offsetof(JSCompartment, types)); } inline void -TypeCompartment::addPending(JSContext *cx, TypeConstraint *constraint, TypeSet *source, Type type) +TypeCompartment::addPending(JSContext *cx, TypeConstraint *constraint, + ConstraintTypeSet *source, Type type) { JS_ASSERT(this == &cx->compartment()->types); JS_ASSERT(!cx->runtime()->isHeapBusy()); InferSpew(ISpewOps, "pending: %sC%p%s %s", InferSpewColor(constraint), constraint, InferSpewColorReset(), TypeString(type)); @@ -1193,25 +1194,22 @@ TypeSet::addType(Type type, LifoAlloc *a } if (padded) *padded = true; return true; } inline void -TypeSet::addType(ExclusiveContext *cxArg, Type type) +ConstraintTypeSet::addType(ExclusiveContext *cxArg, Type type) { JS_ASSERT(cxArg->compartment()->activeAnalysis); - // Temporary type sets use a separate LifoAlloc for storage. - JS_ASSERT(isStackSet() || isHeapSet()); - bool added = false; - if (!addType(type, &cxArg->typeLifoAlloc(), &added)) { + if (!TypeSet::addType(type, &cxArg->typeLifoAlloc(), &added)) { cxArg->compartment()->types.setPendingNukeTypes(cxArg); return; } if (!added) return; InferSpew(ISpewOps, "addType: %sT%p%s %s", InferSpewColor(this), this, InferSpewColorReset(), @@ -1226,17 +1224,17 @@ TypeSet::addType(ExclusiveContext *cxArg } cx->compartment()->types.resolvePending(cx); } else { JS_ASSERT(!constraintList); } } inline void -TypeSet::setConfiguredProperty(ExclusiveContext *cxArg) +HeapTypeSet::setConfiguredProperty(ExclusiveContext *cxArg) { if (flags & TYPE_FLAG_CONFIGURED_PROPERTY) return; flags |= TYPE_FLAG_CONFIGURED_PROPERTY; /* Propagate the change to all constraints. */ if (JSContext *cx = cxArg->maybeJSContext()) {
--- a/js/src/jsopcode.h +++ b/js/src/jsopcode.h @@ -252,17 +252,16 @@ IsJumpOpcode(JSOp op) static inline bool BytecodeFallsThrough(JSOp op) { switch (op) { case JSOP_GOTO: case JSOP_DEFAULT: case JSOP_RETURN: - case JSOP_STOP: case JSOP_RETRVAL: case JSOP_THROW: case JSOP_TABLESWITCH: return false; case JSOP_GOSUB: /* These fall through indirectly, after executing a 'finally'. */ return true; default: @@ -552,17 +551,17 @@ BytecodeFlowsToBitop(jsbytecode *pc) extern bool IsValidBytecodeOffset(JSContext *cx, JSScript *script, size_t offset); inline bool FlowsIntoNext(JSOp op) { /* JSOP_YIELD is considered to flow into the next instruction, like JSOP_CALL. */ - return op != JSOP_STOP && op != JSOP_RETURN && op != JSOP_RETRVAL && op != JSOP_THROW && + return op != JSOP_RETRVAL && op != JSOP_RETURN && op != JSOP_THROW && op != JSOP_GOTO && op != JSOP_RETSUB; } inline bool IsArgOp(JSOp op) { return JOF_OPTYPE(op) == JOF_QARG; }
--- a/js/src/jsopcode.tbl +++ b/js/src/jsopcode.tbl @@ -40,17 +40,17 @@ 1234567890123456789012345678901234567890 /* * Generic nop for the decompiler. */ OPDEF(JSOP_NOP, 0, "nop", NULL, 1, 0, 0, JOF_BYTE) /* Long-standing JavaScript bytecodes. */ OPDEF(JSOP_UNDEFINED, 1, js_undefined_str, "", 1, 0, 1, JOF_BYTE) -OPDEF(JSOP_POPV, 2, "popv", NULL, 1, 1, 0, JOF_BYTE) +OPDEF(JSOP_UNUSED2, 2, "unused2", NULL, 1, 1, 0, JOF_BYTE) OPDEF(JSOP_ENTERWITH, 3, "enterwith", NULL, 1, 1, 1, JOF_BYTE) OPDEF(JSOP_LEAVEWITH, 4, "leavewith", NULL, 1, 1, 0, JOF_BYTE) OPDEF(JSOP_RETURN, 5, "return", NULL, 1, 1, 0, JOF_BYTE) OPDEF(JSOP_GOTO, 6, "goto", NULL, 5, 0, 0, JOF_JUMP) OPDEF(JSOP_IFEQ, 7, "ifeq", NULL, 5, 1, 0, JOF_JUMP|JOF_DETECTING) OPDEF(JSOP_IFNE, 8, "ifne", NULL, 5, 1, 0, JOF_JUMP) /* Get the arguments object for the current, lightweight function activation. */ @@ -348,19 +348,24 @@ OPDEF(JSOP_UNUSED148, 148,"unused148 /* Placeholders for a real jump opcode set during backpatch chain fixup. */ OPDEF(JSOP_BACKPATCH, 149,"backpatch", NULL, 5, 0, 0, JOF_JUMP) OPDEF(JSOP_UNUSED150, 150,"unused150", NULL, 1, 0, 0, JOF_BYTE) /* Set pending exception from the stack, to trigger rethrow. */ OPDEF(JSOP_THROWING, 151,"throwing", NULL, 1, 1, 0, JOF_BYTE) -/* Set and get return value pseudo-register in stack frame. */ -OPDEF(JSOP_SETRVAL, 152,"setrval", NULL, 1, 1, 0, JOF_BYTE) -OPDEF(JSOP_RETRVAL, 153,"retrval", NULL, 1, 0, 0, JOF_BYTE) +/* Set the return value pseudo-register in stack frame. */ +OPDEF(JSOP_SETRVAL, 152,"setrval", NULL, 1, 1, 0, JOF_BYTE) +/* + * Stop interpretation and return value set by JSOP_SETRVAL. When not set, + * returns UndefinedValue. Also emitted at end of script so interpreter + * don't need to check if opcode is still in script range. + */ +OPDEF(JSOP_RETRVAL, 153,"retrval", NULL, 1, 0, 0, JOF_BYTE) /* Free variable references that must either be found on the global or a ReferenceError */ OPDEF(JSOP_GETGNAME, 154,"getgname", NULL, 5, 0, 1, JOF_ATOM|JOF_NAME|JOF_TYPESET|JOF_GNAME) OPDEF(JSOP_SETGNAME, 155,"setgname", NULL, 5, 2, 1, JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING|JOF_GNAME) OPDEF(JSOP_UNUSED156, 156, "unused156", NULL, 1, 0, 0, JOF_BYTE) OPDEF(JSOP_UNUSED157, 157, "unused157", NULL, 1, 0, 0, JOF_BYTE) OPDEF(JSOP_UNUSED158, 158, "unused158", NULL, 1, 0, 0, JOF_BYTE) @@ -410,21 +415,17 @@ OPDEF(JSOP_UINT24, 188,"uint24", OPDEF(JSOP_UNUSED189, 189,"unused189", NULL, 1, 0, 0, JOF_BYTE) OPDEF(JSOP_UNUSED190, 190,"unused190", NULL, 1, 0, 0, JOF_BYTE) OPDEF(JSOP_UNUSED191, 191,"unused191", NULL, 1, 0, 0, JOF_BYTE) OPDEF(JSOP_UNUSED192, 192,"unused192", NULL, 1, 0, 0, JOF_BYTE) OPDEF(JSOP_CALLELEM, 193, "callelem", NULL, 1, 2, 1, JOF_BYTE |JOF_ELEM|JOF_TYPESET|JOF_LEFTASSOC) -/* - * Stop interpretation, emitted at end of script to save the threaded bytecode - * interpreter an extra branch test on every DO_NEXT_OP (see jsinterp.c). - */ -OPDEF(JSOP_STOP, 194,"stop", NULL, 1, 0, 0, JOF_BYTE) +OPDEF(JSOP_UNUSED194, 194,"unused194", NULL, 1, 0, 0, JOF_BYTE) /* * Get an extant property value, throwing ReferenceError if the identified * property does not exist. */ OPDEF(JSOP_GETXPROP, 195,"getxprop", NULL, 5, 1, 1, JOF_ATOM|JOF_PROP|JOF_TYPESET) OPDEF(JSOP_UNUSED196, 196,"unused196", NULL, 1, 0, 0, JOF_BYTE)
--- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1801,17 +1801,17 @@ JSScript::fullyInitTrivial(ExclusiveCont { if (!partiallyInit(cx, script, 0, 0, 0, 0, 0)) return false; SharedScriptData *ssd = SharedScriptData::new_(cx, 1, 1, 0); if (!ssd) return false; - ssd->data[0] = JSOP_STOP; + ssd->data[0] = JSOP_RETRVAL; ssd->data[1] = SRC_NULL; script->length = 1; return SaveSharedScriptData(cx, script, ssd, 1); } /* static */ bool JSScript::fullyInitFromEmitter(ExclusiveContext *cx, HandleScript script, BytecodeEmitter *bce) {
--- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -1001,17 +1001,17 @@ class JSScript : public js::gc::Barriere */ bool isEmpty() const { if (length > 3) return false; jsbytecode *pc = code; if (noScriptRval && JSOp(*pc) == JSOP_FALSE) ++pc; - return JSOp(*pc) == JSOP_STOP; + return JSOp(*pc) == JSOP_RETRVAL; } bool varIsAliased(unsigned varSlot); bool formalIsAliased(unsigned argSlot); bool formalLivesInArgumentsObject(unsigned argSlot); private: /*
--- a/js/src/tests/lib/jittests.py +++ b/js/src/tests/lib/jittests.py @@ -96,16 +96,17 @@ class Test: t.allow_oom = self.allow_oom t.valgrind = self.valgrind t.tz_pacific = self.tz_pacific t.expect_error = self.expect_error t.expect_status = self.expect_status return t COOKIE = '|jit-test|' + CacheDir = JS_CACHE_DIR @classmethod def from_file(cls, path, options): test = cls(path) line = open(path).readline() i = line.find(cls.COOKIE) if i != -1: @@ -174,17 +175,18 @@ class Test: # the remote device. fmt = 'const platform=%r; const libdir=%r; const scriptdir=%r' if remote_prefix: fmt = 'const platform="%s"; const libdir="%s"; const scriptdir="%s"' expr = fmt % (sys.platform, libdir, scriptdir_var) # We may have specified '-a' or '-d' twice: once via --jitflags, once # via the "|jit-test|" line. Remove dups because they are toggles. - cmd = prefix + list(set(self.jitflags)) + ['-e', expr, '-f', path] + cmd = prefix + ['--js-cache', Test.CacheDir] + cmd += list(set(self.jitflags)) + ['-e', expr, '-f', path] if self.valgrind: cmd = self.VALGRIND_CMD + cmd return cmd def find_tests(substring=None): ans = [] for dirpath, dirnames, filenames in os.walk(TEST_DIR): dirnames.sort() @@ -651,16 +653,19 @@ def run_tests_remote(tests, prefix, opti # Push js shell and libraries. if dm.dirExists(jit_tests_dir): dm.removeDir(jit_tests_dir) dm.mkDirs(options.remote_test_root) push_libs(options, dm) push_progs(options, dm, [prefix[0]]) dm.chmodDir(options.remote_test_root) + Test.CacheDir = posixpath.join(options.remote_test_root, '.js-cache') + dm.mkDirs(Test.CacheDir) + dm.pushDir(ECMA6_DIR, posixpath.join(jit_tests_dir, 'tests', 'ecma_6'), timeout=600) dm.pushDir(os.path.dirname(TEST_DIR), options.remote_test_root, timeout=600) prefix[0] = os.path.join(options.remote_test_root, 'js') # Run all tests. gen = get_remote_results(tests, dm, prefix, options) ok = process_test_results(gen, len(tests), options) return ok
--- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -460,17 +460,17 @@ js::Invoke(JSContext *cx, CallArgs args, JSFunction *fun = &callee.as<JSFunction>(); JS_ASSERT_IF(construct, !fun->isNativeConstructor()); if (fun->isNative()) return CallJSNative(cx, fun->native(), args); if (!fun->getOrCreateScript(cx)) return false; - /* Run function until JSOP_STOP, JSOP_RETURN or error. */ + /* Run function until JSOP_RETRVAL, JSOP_RETURN or error. */ InvokeState state(cx, args, initial); // Check to see if useNewType flag should be set for this frame. if (construct && cx->typeInferenceEnabled()) { ScriptFrameIter iter(cx); if (!iter.done()) { JSScript *script = iter.script(); jsbytecode *pc = iter.pc(); @@ -1363,17 +1363,17 @@ Interpret(JSContext *cx, RunState &state bool interpReturnOK; if (!activation.entryFrame()->isGeneratorFrame()) { if (!activation.entryFrame()->prologue(cx)) goto error; } else { probes::EnterScript(cx, script, script->function(), activation.entryFrame()); } - if (cx->compartment()->debugMode()) { + if (JS_UNLIKELY(cx->compartment()->debugMode())) { JSTrapStatus status = ScriptDebugPrologue(cx, activation.entryFrame()); switch (status) { case JSTRAP_CONTINUE: break; case JSTRAP_RETURN: interpReturnOK = true; goto forced_return; case JSTRAP_THROW: @@ -1464,16 +1464,17 @@ CASE(EnableInterruptsPseudoOpcode) /* Commence executing the actual opcode. */ SANITY_CHECKS(); DISPATCH_TO(op); } /* Various 1-byte no-ops. */ CASE(JSOP_NOP) +CASE(JSOP_UNUSED2) CASE(JSOP_UNUSED44) CASE(JSOP_UNUSED45) CASE(JSOP_UNUSED46) CASE(JSOP_UNUSED47) CASE(JSOP_UNUSED48) CASE(JSOP_UNUSED49) CASE(JSOP_UNUSED50) CASE(JSOP_UNUSED51) @@ -1520,16 +1521,17 @@ CASE(JSOP_UNUSED179) CASE(JSOP_UNUSED180) CASE(JSOP_UNUSED181) CASE(JSOP_UNUSED182) CASE(JSOP_UNUSED183) CASE(JSOP_UNUSED189) CASE(JSOP_UNUSED190) CASE(JSOP_UNUSED191) CASE(JSOP_UNUSED192) +CASE(JSOP_UNUSED194) CASE(JSOP_UNUSED196) CASE(JSOP_UNUSED200) CASE(JSOP_UNUSED201) CASE(JSOP_GETFUNNS) CASE(JSOP_UNUSED208) CASE(JSOP_UNUSED209) CASE(JSOP_UNUSED210) CASE(JSOP_UNUSED219) @@ -1595,19 +1597,18 @@ CASE(JSOP_POPN) REGS.sp -= GET_UINT16(REGS.pc); #ifdef DEBUG if (StaticBlockObject *block = REGS.fp()->maybeBlockChain()) JS_ASSERT(REGS.stackDepth() >= block->stackDepth() + block->slotCount()); #endif END_CASE(JSOP_POPN) CASE(JSOP_SETRVAL) -CASE(JSOP_POPV) POP_RETURN_VALUE(); -END_CASE(JSOP_POPV) +END_CASE(JSOP_SETRVAL) CASE(JSOP_ENTERWITH) { RootedValue &val = rootValue0; val = REGS.sp[-1]; if (!EnterWith(cx, REGS.fp(), val, REGS.stackDepth() - 1)) goto error; @@ -1630,34 +1631,33 @@ CASE(JSOP_LEAVEWITH) REGS.fp()->popWith(cx); REGS.sp--; END_CASE(JSOP_LEAVEWITH) CASE(JSOP_RETURN) POP_RETURN_VALUE(); /* FALL THROUGH */ -CASE(JSOP_RETRVAL) /* fp return value already set */ -CASE(JSOP_STOP) +CASE(JSOP_RETRVAL) { /* * When the inlined frame exits with an exception or an error, ok will be * false after the inline_return label. */ CHECK_BRANCH(); interpReturnOK = true; if (activation.entryFrame() != REGS.fp()) inline_return: { #if JS_TRACE_LOGGING TraceLogging::defaultLogger()->log(TraceLogging::SCRIPT_STOP); #endif - if (cx->compartment()->debugMode()) + if (JS_UNLIKELY(cx->compartment()->debugMode())) interpReturnOK = ScriptDebugEpilogue(cx, REGS.fp(), interpReturnOK); if (!REGS.fp()->isYielding()) REGS.fp()->epilogue(cx); else probes::ExitScript(cx, script, script->function(), REGS.fp()); #if defined(JS_ION) @@ -2556,32 +2556,32 @@ CASE(JSOP_FUNCALL) #if JS_TRACE_LOGGING TraceLogging::defaultLogger()->log(TraceLogging::SCRIPT_START, script); TraceLogging::defaultLogger()->log(TraceLogging::INFO_ENGINE_INTERPRETER); #endif if (!REGS.fp()->prologue(cx)) goto error; - if (cx->compartment()->debugMode()) { + if (JS_UNLIKELY(cx->compartment()->debugMode())) { switch (ScriptDebugPrologue(cx, REGS.fp())) { case JSTRAP_CONTINUE: break; case JSTRAP_RETURN: interpReturnOK = true; goto forced_return; case JSTRAP_THROW: case JSTRAP_ERROR: goto error; default: MOZ_ASSUME_UNREACHABLE("bad ScriptDebugPrologue status"); } } - /* Load first op and dispatch it (safe since JSOP_STOP). */ + /* Load first op and dispatch it (safe since JSOP_RETRVAL). */ ADVANCE_AND_DISPATCH(0); } CASE(JSOP_SETCALL) { JS_ALWAYS_FALSE(SetCallOperation(cx)); goto error; } @@ -3319,17 +3319,17 @@ DEFAULT() MOZ_ASSUME_UNREACHABLE("Interpreter loop exited via fallthrough"); error: JS_ASSERT(uint32_t(REGS.pc - script->code) < script->length); if (cx->isExceptionPending()) { /* Call debugger throw hooks. */ - if (cx->compartment()->debugMode()) { + if (JS_UNLIKELY(cx->compartment()->debugMode())) { JSTrapStatus status = DebugExceptionUnwind(cx, REGS.fp(), REGS.pc); switch (status) { case JSTRAP_ERROR: goto error; case JSTRAP_CONTINUE: case JSTRAP_THROW: break; @@ -3425,17 +3425,17 @@ DEFAULT() forced_return: UnwindScope(cx, REGS.fp(), 0); REGS.setToEndOfScript(); if (activation.entryFrame() != REGS.fp()) goto inline_return; exit: - if (cx->compartment()->debugMode()) + if (JS_UNLIKELY(cx->compartment()->debugMode())) interpReturnOK = ScriptDebugEpilogue(cx, REGS.fp(), interpReturnOK); if (!REGS.fp()->isYielding()) REGS.fp()->epilogue(cx); else probes::ExitScript(cx, script, script->function(), REGS.fp()); gc::MaybeVerifyBarriers(cx, true);
--- a/js/src/vm/OldDebugAPI.cpp +++ b/js/src/vm/OldDebugAPI.cpp @@ -749,20 +749,20 @@ bad: JS_PUBLIC_API(void) JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda) { JSPropertyDesc *pd; uint32_t i; pd = pda->array; for (i = 0; i < pda->length; i++) { - js_RemoveRoot(cx->runtime(), &pd[i].id); - js_RemoveRoot(cx->runtime(), &pd[i].value); + RemoveRoot(cx->runtime(), &pd[i].id); + RemoveRoot(cx->runtime(), &pd[i].value); if (pd[i].flags & JSPD_ALIAS) - js_RemoveRoot(cx->runtime(), &pd[i].alias); + RemoveRoot(cx->runtime(), &pd[i].alias); } js_free(pd); pda->array = nullptr; pda->length = 0; } /************************************************************************/
--- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -118,17 +118,17 @@ StackFrame::copyFrameAndValues(JSContext srcend = othersp; dst = slots(); for (const Value *src = otherfp->slots(); src < srcend; src++, dst++) { *dst = *src; if (doPostBarrier) HeapValue::writeBarrierPost(*dst, dst); } - if (cx->compartment()->debugMode()) + if (JS_UNLIKELY(cx->compartment()->debugMode())) DebugScopes::onGeneratorFrameChange(otherfp, this, cx); } /* Note: explicit instantiation for js_NewGenerator located in jsiter.cpp. */ template void StackFrame::copyFrameAndValues<StackFrame::NoPostBarrier>( JSContext *, Value *, StackFrame *, const Value *, Value *); template @@ -299,17 +299,17 @@ StackFrame::epilogue(JSContext *cx) JS_ASSERT(!hasBlockChain()); RootedScript script(cx, this->script()); probes::ExitScript(cx, script, script->function(), this); if (isEvalFrame()) { if (isStrictEvalFrame()) { JS_ASSERT_IF(hasCallObj(), scopeChain()->as<CallObject>().isForEval()); - if (cx->compartment()->debugMode()) + if (JS_UNLIKELY(cx->compartment()->debugMode())) DebugScopes::onPopStrictEvalScope(this); } else if (isDirectEvalFrame()) { if (isDebuggerFrame()) JS_ASSERT(!scopeChain()->is<ScopeObject>()); } else { /* * Debugger.Object.prototype.evalInGlobal creates indirect eval * frames scoped to the given global; @@ -335,17 +335,17 @@ StackFrame::epilogue(JSContext *cx) JS_ASSERT(isNonEvalFunctionFrame()); if (fun()->isHeavyweight()) JS_ASSERT_IF(hasCallObj(), scopeChain()->as<CallObject>().callee().nonLazyScript() == script); else AssertDynamicScopeMatchesStaticScope(cx, script, scopeChain()); - if (cx->compartment()->debugMode()) + if (JS_UNLIKELY(cx->compartment()->debugMode())) DebugScopes::onPopCall(this, cx); if (isConstructing() && thisValue().isObject() && returnValue().isPrimitive()) setReturnValue(ObjectValue(constructorThis())); } bool StackFrame::pushBlock(JSContext *cx, StaticBlockObject &block) @@ -369,31 +369,31 @@ StackFrame::pushBlock(JSContext *cx, Sta return true; } void StackFrame::popBlock(JSContext *cx) { JS_ASSERT(hasBlockChain()); - if (cx->compartment()->debugMode()) + if (JS_UNLIKELY(cx->compartment()->debugMode())) DebugScopes::onPopBlock(cx, this); if (blockChain_->needsClone()) { JS_ASSERT(scopeChain_->as<ClonedBlockObject>().staticBlock() == *blockChain_); popOffScopeChain(); } blockChain_ = blockChain_->enclosingBlock(); } void StackFrame::popWith(JSContext *cx) { - if (cx->compartment()->debugMode()) + if (JS_UNLIKELY(cx->compartment()->debugMode())) DebugScopes::onPopWith(this); JS_ASSERT(scopeChain()->is<WithObject>()); popOffScopeChain(); } void StackFrame::mark(JSTracer *trc) @@ -459,18 +459,18 @@ js::MarkInterpreterActivations(JSRuntime // Unlike the other methods of this calss, this method is defined here so that // we don't have to #include jsautooplen.h in vm/Stack.h. void FrameRegs::setToEndOfScript() { JSScript *script = fp()->script(); sp = fp()->base(); - pc = script->code + script->length - JSOP_STOP_LENGTH; - JS_ASSERT(*pc == JSOP_STOP); + pc = script->code + script->length - JSOP_RETRVAL_LENGTH; + JS_ASSERT(*pc == JSOP_RETRVAL); } /*****************************************************************************/ StackFrame * InterpreterStack::pushInvokeFrame(JSContext *cx, const CallArgs &args, InitialFrameFlags initial) { LifoAlloc::Mark mark = allocator_.mark();
--- a/js/src/vm/ThreadPool.cpp +++ b/js/src/vm/ThreadPool.cpp @@ -181,20 +181,17 @@ ThreadPoolWorker::terminate() ///////////////////////////////////////////////////////////////////////////// // ThreadPool // // The |ThreadPool| starts up workers, submits work to them, and shuts // them down when requested. ThreadPool::ThreadPool(JSRuntime *rt) - : -#if defined(JS_THREADSAFE) || defined(DEBUG) - runtime_(rt) -#endif + : runtime_(rt) { } ThreadPool::~ThreadPool() { terminateWorkers(); }
--- a/js/src/vm/ThreadPool.h +++ b/js/src/vm/ThreadPool.h @@ -56,19 +56,17 @@ class TaskExecutor // have some worker threads pick up (and even finish) their piece of // the job before others have even started. class ThreadPool { private: friend class ThreadPoolWorker; // Initialized at startup only: -#if defined(JS_THREADSAFE) || defined(DEBUG) JSRuntime *const runtime_; -#endif js::Vector<ThreadPoolWorker*, 8, SystemAllocPolicy> workers_; bool lazyStartWorkers(JSContext *cx); void terminateWorkers(); void terminateWorkersAndReportOOM(JSContext *cx); public: ThreadPool(JSRuntime *rt);
--- a/js/xpconnect/public/nsAutoJSValHolder.h +++ b/js/xpconnect/public/nsAutoJSValHolder.h @@ -59,17 +59,17 @@ public: /** * Hold by rooting on the runtime. * Note that mVal may be JSVAL_NULL, which is not a problem. */ bool Hold(JSRuntime* aRt) { // Do we really care about different runtimes? if (mRt && aRt != mRt) { - js_RemoveRoot(mRt, &mVal); + JS_RemoveValueRootRT(mRt, &mVal); mRt = nullptr; } if (!mRt && JS_AddNamedValueRootRT(aRt, &mVal, "nsAutoJSValHolder")) { mRt = aRt; } return !!mRt;
--- a/layout/build/nsLayoutStatics.cpp +++ b/layout/build/nsLayoutStatics.cpp @@ -45,16 +45,17 @@ #include "nsCellMap.h" #include "nsTextFrame.h" #include "nsCCUncollectableMarker.h" #include "nsTextFragment.h" #include "nsCSSRuleProcessor.h" #include "nsCrossSiteListenerProxy.h" #include "nsHTMLDNSPrefetch.h" #include "nsHtml5Module.h" +#include "mozilla/dom/FallbackEncoding.h" #include "nsFocusManager.h" #include "nsListControlFrame.h" #include "mozilla/dom/HTMLInputElement.h" #include "SVGElementFactory.h" #include "nsSVGUtils.h" #include "nsMathMLAtoms.h" #include "nsMathMLOperators.h" #include "Navigator.h" @@ -253,16 +254,17 @@ nsLayoutStatics::Initialize() return rv; } AsyncLatencyLogger::InitializeStatics(); AudioStream::InitLibrary(); nsContentSink::InitializeStatics(); nsHtml5Module::InitializeStatics(); + mozilla::dom::FallbackEncoding::Initialize(); nsLayoutUtils::Initialize(); nsIPresShell::InitializeStatics(); nsRefreshDriver::InitializeStatics(); nsCORSListenerProxy::Startup(); NS_SealStaticAtomTable(); @@ -379,16 +381,18 @@ nsLayoutStatics::Shutdown() nsCORSListenerProxy::Shutdown(); nsIPresShell::ReleaseStatics(); nsTreeSanitizer::ReleaseStatics(); nsHtml5Module::ReleaseStatics(); + mozilla::dom::FallbackEncoding::Shutdown(); + nsRegion::ShutdownStatic(); NS_ShutdownEventTargetChainRecycler(); HTMLInputElement::DestroyUploadLastDir(); nsLayoutUtils::Shutdown();
--- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1515,17 +1515,17 @@ pref("intl.charsetmenu.browser.more3", pref("intl.charsetmenu.browser.more4", "armscii-8, TIS-620, ISO-8859-11, windows-874, IBM857, ISO-8859-9, x-mac-turkish, windows-1254, x-viet-tcvn5712, VISCII, x-viet-vps, windows-1258, x-mac-devanagari, x-mac-gujarati, x-mac-gurmukhi"); pref("intl.charsetmenu.browser.more5", "ISO-8859-6, windows-1256, ISO-8859-8-I, windows-1255, ISO-8859-8, IBM862"); pref("intl.charsetmenu.mailedit", "chrome://global/locale/intl.properties"); pref("intl.charsetmenu.browser.cache", ""); pref("intl.charsetmenu.mailview.cache", ""); pref("intl.charsetmenu.composer.cache", ""); pref("intl.charsetmenu.browser.cache.size", 5); pref("intl.charset.detector", "chrome://global/locale/intl.properties"); -pref("intl.charset.default", "chrome://global-platform/locale/intl.properties"); +pref("intl.charset.fallback.override", ""); pref("intl.ellipsis", "chrome://global-platform/locale/intl.properties"); pref("intl.locale.matchOS", false); // fallback charset list for Unicode conversion (converting from Unicode) // currently used for mail send only to handle symbol characters (e.g Euro, trademark, smartquotes) // for ISO-8859-1 pref("intl.fallbackCharsetList.ISO-8859-1", "windows-1252"); pref("font.language.group", "chrome://global/locale/intl.properties"); @@ -2747,22 +2747,22 @@ pref("font.name-list.fantasy.he", "Times pref("font.name.serif.ja", "Hiragino Mincho ProN"); pref("font.name.sans-serif.ja", "Hiragino Kaku Gothic ProN"); pref("font.name.monospace.ja", "Osaka-Mono"); pref("font.name-list.serif.ja", "Hiragino Mincho ProN,Hiragino Mincho Pro"); pref("font.name-list.sans-serif.ja", "Hiragino Kaku Gothic ProN,Hiragino Kaku Gothic Pro"); pref("font.name-list.monospace.ja", "Osaka-Mono"); -pref("font.name.serif.ko", "AppleMyungjo"); -pref("font.name.sans-serif.ko", "AppleGothic"); -pref("font.name.monospace.ko", "AppleGothic"); -pref("font.name-list.serif.ko", "AppleMyungjo"); -pref("font.name-list.sans-serif.ko", "AppleGothic"); -pref("font.name-list.monospace.ko", "AppleGothic"); +pref("font.name.serif.ko", "AppleMyungjo"); +pref("font.name.sans-serif.ko", "Apple SD Gothic Neo"); +pref("font.name.monospace.ko", "Apple SD Gothic Neo"); +pref("font.name-list.serif.ko", "AppleMyungjo"); +pref("font.name-list.sans-serif.ko", "Apple SD Gothic Neo,AppleGothic"); +pref("font.name-list.monospace.ko", "Apple SD Gothic Neo,AppleGothic"); pref("font.name.serif.th", "Thonburi"); pref("font.name.sans-serif.th", "Thonburi"); pref("font.name.monospace.th", "Ayuthaya"); pref("font.name-list.serif.th", "Thonburi"); pref("font.name-list.sans-serif.th", "Thonburi"); pref("font.name-list.monospace.th", "Ayuthaya");
--- a/netwerk/streamconv/converters/nsDirIndexParser.cpp +++ b/netwerk/streamconv/converters/nsDirIndexParser.cpp @@ -8,19 +8,17 @@ #include "mozilla/Util.h" #include "prprf.h" #include "nsDirIndexParser.h" #include "nsEscape.h" #include "nsIInputStream.h" #include "nsCRT.h" -#include "nsIPrefService.h" -#include "nsIPrefBranch.h" -#include "nsIPrefLocalizedString.h" +#include "mozilla/dom/FallbackEncoding.h" #include "nsITextToSubURI.h" #include "nsIDirIndex.h" #include "nsServiceManagerUtils.h" using namespace mozilla; NS_IMPL_ISUPPORTS3(nsDirIndexParser, nsIRequestObserver, @@ -30,34 +28,17 @@ NS_IMPL_ISUPPORTS3(nsDirIndexParser, nsDirIndexParser::nsDirIndexParser() { } nsresult nsDirIndexParser::Init() { mLineStart = 0; mHasDescription = false; mFormat = nullptr; - - // get default charset to be used for directory listings (fallback to - // ISO-8859-1 if pref is unavailable). - NS_NAMED_LITERAL_CSTRING(kFallbackEncoding, "ISO-8859-1"); - nsXPIDLString defCharset; - nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); - if (prefs) { - nsCOMPtr<nsIPrefLocalizedString> prefVal; - prefs->GetComplexValue("intl.charset.default", - NS_GET_IID(nsIPrefLocalizedString), - getter_AddRefs(prefVal)); - if (prefVal) - prefVal->ToString(getter_Copies(defCharset)); - } - if (!defCharset.IsEmpty()) - LossyCopyUTF16toASCII(defCharset, mEncoding); // charset labels are always ASCII - else - mEncoding.Assign(kFallbackEncoding); + mozilla::dom::FallbackEncoding::FromLocale(mEncoding); nsresult rv; // XXX not threadsafe if (gRefCntParser++ == 0) rv = CallGetService(NS_ITEXTTOSUBURI_CONTRACTID, &gTextToSubURI); else rv = NS_OK;
--- a/parser/html/nsHtml5StreamParser.cpp +++ b/parser/html/nsHtml5StreamParser.cpp @@ -297,17 +297,17 @@ nsHtml5StreamParser::SetupDecodingAndWri { NS_ASSERTION(IsParserThread(), "Wrong thread!"); nsresult rv = NS_OK; nsCOMPtr<nsICharsetConverterManager> convManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); rv = convManager->GetUnicodeDecoder(mCharset.get(), getter_AddRefs(mUnicodeDecoder)); if (rv == NS_ERROR_UCONV_NOCONV) { mCharset.AssignLiteral("windows-1252"); // lower case is the raw form - mCharsetSource = kCharsetFromWeakDocTypeDefault; + mCharsetSource = kCharsetFromFallback; rv = convManager->GetUnicodeDecoderRaw(mCharset.get(), getter_AddRefs(mUnicodeDecoder)); mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource); } NS_ENSURE_SUCCESS(rv, rv); return WriteSniffingBufferAndCurrentSegment(aFromSegment, aCount, aWriteCount); } nsresult @@ -607,20 +607,20 @@ nsHtml5StreamParser::FinalizeSniffing(co rv = mChardet->Done(); NS_ENSURE_SUCCESS(rv, rv); } // fall thru; callback may have changed charset } if (mCharsetSource == kCharsetUninitialized) { // Hopefully this case is never needed, but dealing with it anyway mCharset.AssignLiteral("windows-1252"); - mCharsetSource = kCharsetFromWeakDocTypeDefault; + mCharsetSource = kCharsetFromFallback; mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource); } else if (mMode == LOAD_AS_DATA && - mCharsetSource == kCharsetFromWeakDocTypeDefault) { + mCharsetSource == kCharsetFromFallback) { NS_ASSERTION(mReparseForbidden, "Reparse should be forbidden for XHR"); NS_ASSERTION(!mFeedChardet, "Should not feed chardet for XHR"); NS_ASSERTION(mCharset.EqualsLiteral("UTF-8"), "XHR should default to UTF-8"); // Now mark charset source as non-weak to signal that we have a decision mCharsetSource = kCharsetFromDocTypeDefault; mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource); } @@ -726,17 +726,17 @@ nsHtml5StreamParser::SniffStreamBytes(co mMetaScanner = nullptr; return WriteSniffingBufferAndCurrentSegment(aFromSegment, aCount, aWriteCount); } else { // nsHTMLDocument is supposed to make sure this does not happen. Let's // deal with this anyway, since who knows how kCharsetFromOtherComponent // is used. - mCharsetSource = kCharsetFromWeakDocTypeDefault; + mCharsetSource = kCharsetFromFallback; } } if (!mMetaScanner && (mMode == NORMAL || mMode == VIEW_SOURCE_HTML || mMode == LOAD_AS_DATA)) { mMetaScanner = new nsHtml5MetaScanner(); } @@ -976,17 +976,17 @@ nsHtml5StreamParser::OnStartRequest(nsIR // Instantiate the converter here to avoid BOM sniffing. nsCOMPtr<nsICharsetConverterManager> convManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); rv = convManager->GetUnicodeDecoder(mCharset.get(), getter_AddRefs(mUnicodeDecoder)); // if we failed to get a decoder, there will be fallback, so don't propagate // the error. if (NS_FAILED(rv)) { - mCharsetSource = kCharsetFromWeakDocTypeDefault; + mCharsetSource = kCharsetFromFallback; } return NS_OK; } NS_IMETHODIMP nsHtml5StreamParser::CheckListenerChain() { NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread!");
--- a/parser/nsCharsetSource.h +++ b/parser/nsCharsetSource.h @@ -2,17 +2,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef nsCharsetSource_h_ #define nsCharsetSource_h_ // note: the value order defines the priority; higher numbers take priority #define kCharsetUninitialized 0 -#define kCharsetFromWeakDocTypeDefault 1 +#define kCharsetFromFallback 1 #define kCharsetFromDocTypeDefault 2 // This and up confident for XHR #define kCharsetFromCache 3 #define kCharsetFromParentFrame 4 #define kCharsetFromAutoDetection 5 #define kCharsetFromHintPrevDoc 6 #define kCharsetFromMetaPrescan 7 // this one and smaller: HTML5 Tentative #define kCharsetFromMetaTag 8 // this one and greater: HTML5 Confident #define kCharsetFromIrreversibleAutoDetection 9
--- a/testing/mochitest/b2g-desktop.json +++ b/testing/mochitest/b2g-desktop.json @@ -422,11 +422,319 @@ "content/html/content/test/test_bug481335.xhtml":"timed out, bug 870262, :visited support", "layout/style/test/test_visited_image_loading.html":"bug 870262, :visited support", "layout/style/test/test_visited_image_loading_empty.html":"bug 870262, :visited support", "layout/style/test/test_visited_lying.html" : "bug 870262, :visited support", "layout/style/test/test_visited_pref.html" : "bug 870262, :visited support", "layout/style/test/test_visited_reftests.html":"bug 870262, :visited support", "Harness_sanity/test_sanityEventUtils.html": "bug 688052", - "Harness_sanity/test_sanitySimpletest.html": "bug 688052" + "Harness_sanity/test_sanitySimpletest.html": "bug 688052", + + "caps/tests/mochitest/test_bug292789.html": "Bug 931116, b2g desktop specific, initial triage", + "content/base/test/csp/test_policyuri_regression_from_multipolicy.html": "Bug 931116, b2g desktop specific, initial triage", + "content/base/test/test_bug326337.html": "Bug 931116, b2g desktop specific, initial triage", + "content/base/test/test_bug426646.html": "Bug 931116, b2g desktop specific, initial triage", + "content/base/test/test_bug557892.html": "Bug 931116, b2g desktop specific, initial triage", + "content/base/test/test_bug578096.html": "Bug 931116, b2g desktop specific, initial triage", + "content/base/test/test_copyimage.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug322588.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug493251.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug545268.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug650493.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug656379-1.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug656379-2.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug656954.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug659350.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug662678.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug667612.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug698929.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug741666.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug742376.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug812744.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug847597.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug855741.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_bug864040.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_clickevent_on_input.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_dblclick_explicit_original_target.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_dom_keyboard_event.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_dom_mouse_event.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_draggableprop.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_eventctors.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_focus_disabled.html": "Bug 931116, b2g desktop specific, initial triage", + "content/events/test/test_moz_mouse_pixel_scroll_event.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/forms/test_button_attributes_reflection.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/forms/test_change_event.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/forms/test_form_attribute-1.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/forms/test_input_event.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/forms/test_input_range_key_events.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/forms/test_input_range_rounding.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/test_bug633058.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/test_bug643051.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/test_bug651956.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/test_bug659743.xml": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/test_bug674558.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/test_iframe_sandbox_general.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/test_iframe_sandbox_modal.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/test_iframe_sandbox_popups.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/test_iframe_sandbox_popups_inheritance.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/test_mozaudiochannel.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/test_mozaudiochannel.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/test_mozaudiochannel.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/test_mozaudiochannel.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/content/test/test_mozaudiochannel.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/document/test/test_bug196523.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/document/test/test_bug199692.html": "Bug 931116, b2g desktop specific, initial triage", + "content/html/document/test/test_bug871161.html": "Bug 931116, b2g desktop specific, initial triage", + "content/xbl/test/test_bug310107.html": "Bug 931116, b2g desktop specific, initial triage", + "content/xml/document/test/test_bug691215.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/navigation/test_bug278916.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/navigation/test_bug279495.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/navigation/test_bug430723.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/navigation/test_opener.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/navigation/test_sessionhistory.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/navigation/test_sibling-off-domain.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/test_bfcache_plus_hash.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/test_bug369814.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/test_bug404548.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/test_bug509055.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/test_bug529119-1.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/test_bug529119-2.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/test_bug540462.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/test_bug598895.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/test_bug637644.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/test_bug640387_1.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/test_bug660404.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/test_bug669671.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/test_bug680257.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/test_bug728939.html": "Bug 931116, b2g desktop specific, initial triage", + "docshell/test/test_windowedhistoryframes.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/alarm/test/test_alarm_add_data.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/alarm/test/test_alarm_add_date.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/alarm/test/test_alarm_add_respectTimezone.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/alarm/test/test_alarm_remove.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/base/test/test_setting_opener.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/datastore/tests/test_oop.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/datastore/tests/test_readonly.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/datastore/tests/test_revision.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/datastore/tests/test_sync.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_add_put.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_add_twice_failure.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_advance.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_app_isolation_inproc.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_app_isolation_oop.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_autoIncrement.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_autoIncrement_indexes.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_bfcache.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_blob_archive.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_blob_simple.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_clear.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_complex_keyPaths.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_count.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_create_index.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_create_index_with_integer_keys.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_create_objectStore.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_cursor_mutation.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_cursor_update_updates_indexes.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_cursors.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_deleteDatabase.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_deleteDatabase_interactions.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_error_events_abort_transactions.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_event_propagation.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_event_source.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_exceptions_in_events.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_file_array.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_file_cross_database_copying.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_file_delete.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_file_os_delete.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_file_put_get_object.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_file_put_get_values.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_file_quota.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_file_replace.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_file_resurrection_delete.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_file_resurrection_transaction_abort.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_file_sharing.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_file_transaction_abort.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_filehandle_quota.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_filehandle_serialization.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_filehandle_store_snapshot.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_getAll.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_get_filehandle.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_globalObjects.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_global_data.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_index_empty_keyPath.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_index_getAll.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_index_getAllObjects.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_index_object_cursors.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_index_update_delete.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_indexes.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_indexes_bad_values.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_indexes_funny_things.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_key_requirements.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_keys.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_leaving_page.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_multientry.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_names_sorted.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_objectCursors.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_objectStore_getAllKeys.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_objectStore_inline_autoincrement_key_added_on_put.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_objectStore_openKeyCursor.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_objectStore_remove_values.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_object_identity.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_odd_result_order.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_open_empty_db.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_open_for_principal.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_open_objectStore.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_optionalArguments.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_overlapping_transactions.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_persistenceType.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_put_get_values.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_put_get_values_autoIncrement.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_readonly_transactions.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_remove_index.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_remove_objectStore.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_request_readyState.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_setVersion.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_setVersion_abort.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_setVersion_events.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_setVersion_exclusion.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_success_events_after_abort.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_third_party.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_traffic_jam.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_transaction_abort.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_transaction_abort_hang.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_transaction_lifetimes.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_transaction_lifetimes_nested.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_transaction_ordering.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_unique_index_update.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_webapp_clearBrowserData_inproc_inproc.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_webapp_clearBrowserData_inproc_oop.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/indexedDB/test/test_webapp_clearBrowserData_oop_inproc.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/permission/tests/test_embed-apps.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/permission/tests/test_wifi-manage.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_GCrace.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_NPNVdocumentOrigin.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_NPPVpluginWantsAllNetworkStreams.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_bug532208.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_bug539565-1.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_bug539565-2.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_bug771202.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_bug777098.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_bug784131.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_bug813906.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_bug854082.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_bug863792.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_cookies.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_copyText.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_crash_nested_loop.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_crashing.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_defaultValue.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_enumerate.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_fullpage.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_getauthenticationinfo.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_hanging.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_instance_re-parent.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_instance_unparent1.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_instance_unparent2.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_instance_unparent3.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_instantiation.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_multipleinstanceobjects.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_newstreamondestroy.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_npn_asynccall.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_npn_timers.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_npobject_getters.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_npruntime_construct.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_npruntime_identifiers.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_npruntime_npnevaluate.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_npruntime_npninvoke.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_npruntime_npninvokedefault.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_npruntime_npnsetexception.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_painting.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_pluginstream_asfile.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_pluginstream_asfileonly.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_pluginstream_err.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_pluginstream_geturl.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_pluginstream_geturlnotify.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_pluginstream_newstream.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_pluginstream_post.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_pluginstream_poststream.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_pluginstream_referer.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_pluginstream_seek.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_pluginstream_seek_close.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_pluginstream_src.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_pluginstream_src_dynamic.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_pluginstream_src_referer.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_propertyAndMethod.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_redirect_handling.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_secondPlugin.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_src_url_change.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_streamNotify.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_streamatclose.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_twostreams.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_visibility.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/plugins/test/mochitest/test_zero_opacity.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/bugs/test_bug346659.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/bugs/test_bug38959.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/bugs/test_bug458091.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/bugs/test_bug49312.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/bugs/test_bug562433.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/bugs/test_bug593174.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/bugs/test_bug622361.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/bugs/test_bug648465.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/dom-level0/test_innerWidthHeight_script.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_gamepad.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_gamepad.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_gamepad.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_gamepad.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_gamepad_connect_events.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_gamepad_connect_events.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_gamepad_connect_events.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_gamepad_connect_events.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_gamepad_frame_state_sync.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_gamepad_frame_state_sync.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_gamepad_frame_state_sync.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_gamepad_frame_state_sync.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_gamepad_hidden_frame.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_gamepad_hidden_frame.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_gamepad_hidden_frame.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_gamepad_hidden_frame.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_navigator_gamepads.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_navigator_gamepads.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_navigator_gamepads.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/gamepad/test_navigator_gamepads.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/general/test_497898.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/general/test__content.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/general/test_bug628069_1.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/general/test_bug631440.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/general/test_frameElementWrapping.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/general/test_framedhistoryframes.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/general/test_interfaces.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/general/test_offsets.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/general/test_outerHTML.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/general/test_outerHTML.xhtml": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/general/test_stylesheetPI.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/general/test_vibrator.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/general/test_windowProperties.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/general/test_windowedhistoryframes.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/sessionstorage/test_sessionStorageClone.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/sessionstorage/test_sessionStorageReplace.html": "Bug 931116, b2g desktop specific, initial triage", + "dom/tests/mochitest/whatwg/test_postMessage_closed.html": "Bug 931116, b2g desktop specific, initial triage", + "layout/base/tests/test_bug607529.html": "Bug 931116, b2g desktop specific, initial triage", + "layout/base/tests/test_bug749186.html": "Bug 931116, b2g desktop specific, initial triage", + "layout/base/tests/test_bug770106.html": "Bug 931116, b2g desktop specific, initial triage", + "layout/base/tests/test_bug842853.html": "Bug 931116, b2g desktop specific, initial triage", + "layout/base/tests/test_bug842853-2.html": "Bug 931116, b2g desktop specific, initial triage", + "layout/base/tests/test_bug858459.html": "Bug 931116, b2g desktop specific, initial triage", + "layout/base/tests/test_reftests_with_caret.html": "Bug 931116, b2g desktop specific, initial triage", + "layout/base/tests/test_remote_frame.html": "Bug 931116, b2g desktop specific, initial triage", + "layout/generic/test/test_bug735641.html": "Bug 931116, b2g desktop specific, initial triage", + "layout/generic/test/test_bug784410.html": "Bug 931116, b2g desktop specific, initial triage", + "layout/generic/test/test_plugin_clipping.xhtml": "Bug 931116, b2g desktop specific, initial triage", + "layout/generic/test/test_plugin_clipping2.xhtml": "Bug 931116, b2g desktop specific, initial triage", + "layout/generic/test/test_plugin_clipping_table.xhtml": "Bug 931116, b2g desktop specific, initial triage", + "layout/generic/test/test_plugin_clipping_transformed.xhtml": "Bug 931116, b2g desktop specific, initial triage", + "layout/style/test/test_property_syntax_errors.html": "Bug 931116, b2g desktop specific, initial triage", + "layout/style/test/test_redundant_font_download.html": "Bug 931116, b2g desktop specific, initial triage", + "layout/style/test/test_rem_unit.html": "Bug 931116, b2g desktop specific, initial triage", + "layout/style/test/test_rule_serialization.html": "Bug 931116, b2g desktop specific, initial triage", + "toolkit/devtools/apps/tests/test_webapps_actor.html": "Bug 931116, b2g desktop specific, initial triage" } }
--- a/testing/mochitest/mach_commands.py +++ b/testing/mochitest/mach_commands.py @@ -131,16 +131,18 @@ class MochitestRunner(MozbuildObject): options = parser.parse_args([])[0] if test_path: test_root_file = mozpack.path.join(self.mochitest_dir, 'tests', test_path) if not os.path.exists(test_root_file): print('Specified test path does not exist: %s' % test_root_file) return 1 options.testPath = test_path + elif conditions.is_b2g_desktop: + options.testManifest = 'b2g-desktop.json' else: options.testManifest = 'b2g.json' for k, v in kwargs.iteritems(): setattr(options, k, v) options.consoleLevel = 'INFO' if conditions.is_b2g_desktop(self):
--- a/toolkit/components/passwordmgr/test/chrome.ini +++ b/toolkit/components/passwordmgr/test/chrome.ini @@ -1,7 +1,9 @@ [DEFAULT] support-files = formsubmit.sjs notification_common.js pwmgr_common.js [test_privbrowsing_perwindowpb.html] +# Too many intermittent failures (bug 919016) +skip-if = os == "win"
--- a/toolkit/components/search/nsSearchService.js +++ b/toolkit/components/search/nsSearchService.js @@ -559,17 +559,18 @@ function queryCharsetFromCode(aCode) { codes[2561] = "Shift_JIS"; codes[2562] = "KOI8-R"; codes[2563] = "Big5"; codes[2565] = "HZ-GB-2312"; if (codes[aCode]) return codes[aCode]; - return getLocalizedPref("intl.charset.default", DEFAULT_QUERY_CHARSET); + // Don't bother being fancy about what to return in the failure case. + return "windows-1252"; } function fileCharsetFromCode(aCode) { const codes = [ "macintosh", // 0 "Shift_JIS", // 1 "Big5", // 2 "EUC-KR", // 3 "X-MAC-ARABIC", // 4
--- a/toolkit/locales/en-US/chrome/global-platform/mac/intl.properties +++ b/toolkit/locales/en-US/chrome/global-platform/mac/intl.properties @@ -1,9 +1,7 @@ # 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/. -# moved from navigator/locale/navigator.properties -intl.charset.default=ISO-8859-1 # LOCALIZATION NOTE (intl.ellipsis): Use the unicode ellipsis char, \u2026, # or use "..." if \u2026 doesn't suit traditions in your locale. intl.ellipsis=…
--- a/toolkit/locales/en-US/chrome/global-platform/unix/intl.properties +++ b/toolkit/locales/en-US/chrome/global-platform/unix/intl.properties @@ -1,9 +1,7 @@ # 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/. -# moved from navigator/locale/navigator.properties -intl.charset.default=ISO-8859-1 # LOCALIZATION NOTE (intl.ellipsis): Use the unicode ellipsis char, \u2026, # or use "..." if \u2026 doesn't suit traditions in your locale. intl.ellipsis=…
--- a/toolkit/locales/en-US/chrome/global-platform/win/intl.properties +++ b/toolkit/locales/en-US/chrome/global-platform/win/intl.properties @@ -1,9 +1,7 @@ # 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/. -# moved from navigator/locale/navigator.properties -intl.charset.default=ISO-8859-1 # LOCALIZATION NOTE (intl.ellipsis): Use the unicode ellipsis char, \u2026, # or use "..." if \u2026 doesn't suit traditions in your locale. intl.ellipsis=…
--- a/toolkit/locales/en-US/chrome/global/intl.properties +++ b/toolkit/locales/en-US/chrome/global/intl.properties @@ -35,28 +35,27 @@ intl.accept_languages=en-US, en # LOCALIZATION NOTE (font.language.group): # This preference controls the initial setting of the language drop-down menu # in the Content > Fonts & Colors > Advanced preference panel. # # Set it to the value of one of the menuitems in the "selectLangs" menulist in # http://mxr.mozilla.org/mozilla/source/browser/components/preferences/fonts.xul font.language.group=x-western -# LOCALIZATION NOTE (intl.charset.detector, intl.charset.default, intl.charsetmenu.browser.static, intl.charsetmenu.mailedit): +# LOCALIZATION NOTE (intl.charset.detector, intl.charsetmenu.browser.static, intl.charsetmenu.mailedit): # For the list of canonical charset values, refer to: # http://mxr.mozilla.org/mozilla-central/source/intl/locale/src/charsetalias.properties # # If you are modifying the charset preferences for your locale, be sure to use # the values from that list, not the keys. Note that these values are # case-sensitive and must be reproduced exactly as listed. # # Note also that the list of charsets in 'intl.charsetmenu.browser.static' # must always include "UTF-8". intl.charset.detector= -intl.charset.default=ISO-8859-1 intl.charsetmenu.browser.static=ISO-8859-1, UTF-8 intl.charsetmenu.mailedit=ISO-8859-1, ISO-8859-15, ISO-8859-6, armscii-8, ISO-8859-13, ISO-8859-14, ISO-8859-2, GB2312, GB18030, Big5, KOI8-R, windows-1251, KOI8-U, ISO-8859-7, ISO-8859-8-I, windows-1255, ISO-2022-JP, EUC-KR, ISO-8859-10, ISO-8859-3, TIS-620, ISO-8859-9, UTF-8, VISCII # LOCALIZATION NOTE (pluralRule): Pick the appropriate plural rule for your # language. This will determine how many plural forms of a word you will need # to provide and in what order. # See: http://developer.mozilla.org/en/docs/Localization_and_Plurals pluralRule=1
--- a/widget/android/AndroidBridge.cpp +++ b/widget/android/AndroidBridge.cpp @@ -188,24 +188,21 @@ AndroidBridge::Init(JNIEnv *jEnv) if (!GetStaticIntField("android/os/Build$VERSION", "SDK_INT", &mAPIVersion, jEnv)) { ALOG_BRIDGE("Failed to find API version"); } jSurfaceClass = getClassGlobalRef("android/view/Surface"); if (mAPIVersion <= 8 /* Froyo */) { jSurfacePointerField = getField("mSurface", "I"); - } else { + } else if (mAPIVersion > 8 && mAPIVersion < 19 /* KitKat */) { jSurfacePointerField = getField("mNativeSurface", "I"); - - // Apparently mNativeSurface doesn't exist in Key Lime Pie, so just clear the - // exception if we have one and move on. - if (jEnv->ExceptionCheck()) { - jEnv->ExceptionClear(); - } + } else { + // We don't know how to get this, just set it to 0 + jSurfacePointerField = 0; } jclass eglClass = getClassGlobalRef("com/google/android/gles_jni/EGLSurfaceImpl"); if (eglClass) { jEGLSurfacePointerField = getField("mEGLSurface", "I"); } else { jEGLSurfacePointerField = 0; }
--- a/xpcom/tests/TestPLDHash.cpp +++ b/xpcom/tests/TestPLDHash.cpp @@ -13,18 +13,17 @@ // which are unlikely to be hit during normal execution. namespace TestPLDHash { static bool test_pldhash_Init_capacity_ok() { // Try the largest allowed capacity. With PL_DHASH_MAX_SIZE==1<<26, this // will allocate 0.5GB of entry store on 32-bit platforms and 1GB on 64-bit - // platforms. Hopefully that's not too much for the test machines to handle - // reliably. + // platforms. PLDHashTable t; bool ok = PL_DHashTableInit(&t, PL_DHashGetStubOps(), nullptr, sizeof(PLDHashEntryStub), PL_DHASH_MAX_SIZE); if (ok) PL_DHashTableFinish(&t); return ok; } @@ -57,16 +56,18 @@ static bool test_pldhash_Init_overflow() // |nullptr| for |ops| is ok because it's unused due to the failure. PLDHashTable t; bool ok = PL_DHashTableInit(&t, /* ops = */nullptr, nullptr, sizeof(OneKBEntry), PL_DHASH_MAX_SIZE); return !ok; // expected to fail } +// See bug 931062, we skip this test on Android due to OOM. +#ifndef MOZ_WIDGET_ANDROID // We insert the integers 0.., so this is has function is (a) as simple as // possible, and (b) collision-free. Both of which are good, because we want // this test to be as fast as possible. static PLDHashNumber hash(PLDHashTable *table, const void *key) { return (PLDHashNumber)(size_t)key; } @@ -97,30 +98,34 @@ static bool test_pldhash_grow_to_max_cap } numInserted++; } // We stop when the element count is 96.875% of PL_DHASH_MAX_SIZE (see // MaxLoadOnGrowthFailure()). return numInserted == PL_DHASH_MAX_SIZE - (PL_DHASH_MAX_SIZE >> 5); } +#endif //---- typedef bool (*TestFunc)(); #define DECL_TEST(name) { #name, name } static const struct Test { const char* name; TestFunc func; } tests[] = { DECL_TEST(test_pldhash_Init_capacity_ok), DECL_TEST(test_pldhash_Init_capacity_too_large), DECL_TEST(test_pldhash_Init_overflow), +// See bug 931062, we skip this test on Android due to OOM. +#ifndef MOZ_WIDGET_ANDROID DECL_TEST(test_pldhash_grow_to_max_capacity), +#endif { nullptr, nullptr } }; } // namespace TestPLDHash using namespace TestPLDHash; int main(int argc, char *argv[])
--- a/xulrunner/config/mozconfigs/macosx-universal/xulrunner +++ b/xulrunner/config/mozconfigs/macosx-universal/xulrunner @@ -1,8 +1,9 @@ . $topsrcdir/build/macosx/universal/mozconfig export MOZILLA_OFFICIAL=1 ac_add_options --enable-application=xulrunner ac_add_options --disable-tests +ac_add_options --with-xulrunner-stub-name=xulrunner-stub . "$topsrcdir/xulrunner/config/mozconfigs/common.override"
--- a/xulrunner/stub/moz.build +++ b/xulrunner/stub/moz.build @@ -3,18 +3,18 @@ # 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/. MODULE = 'xulrunner' # The value of XULRUNNER_STUB_NAME is generated by configure to allow XULRunner # apps to override it using the --with-xulrunner-stub-name=<appname> argument. -# If this configure argument is not present then the default name is 'xulrunner' -# for Mac OS X and 'xulrunner-stub' for all other platforms. +# If this configure argument is not present then the default name is +# 'xulrunner-stub'. PROGRAM = CONFIG['XULRUNNER_STUB_NAME'] SOURCES += [ 'nsXULStub.cpp', ] if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': FINAL_TARGET = 'dist/XUL.framework/Versions/%(MOZILLA_VERSION)s' % CONFIG
--- a/xulrunner/stub/nsXULStub.cpp +++ b/xulrunner/stub/nsXULStub.cpp @@ -345,34 +345,34 @@ main(int argc, char **argv) rv = parser.Init(iniPath); if (NS_FAILED(rv)) { fprintf(stderr, "Could not read application.ini\n"); return 1; } if (!greFound) { #ifdef XP_MACOSX - // Check for <bundle>/Contents/Frameworks/XUL.framework/libxpcom.dylib + // Check for <bundle>/Contents/Frameworks/XUL.framework/Versions/Current/libmozglue.dylib CFURLRef fwurl = CFBundleCopyPrivateFrameworksURL(appBundle); CFURLRef absfwurl = nullptr; if (fwurl) { absfwurl = CFURLCopyAbsoluteURL(fwurl); CFRelease(fwurl); } if (absfwurl) { CFURLRef xulurl = CFURLCreateCopyAppendingPathComponent(nullptr, absfwurl, - CFSTR("XUL.framework"), + CFSTR("XUL.framework/Versions/Current"), true); if (xulurl) { CFURLRef xpcomurl = CFURLCreateCopyAppendingPathComponent(nullptr, xulurl, - CFSTR("libxpcom.dylib"), + CFSTR("libmozglue.dylib"), false); if (xpcomurl) { char tbuffer[MAXPATHLEN]; if (CFURLGetFileSystemRepresentation(xpcomurl, true, (UInt8*) tbuffer, sizeof(tbuffer)) &&