diff --git a/accessible/src/generic/Accessible.cpp b/accessible/src/generic/Accessible.cpp index 9407c893edd2..8e0cc73c96da 100644 --- a/accessible/src/generic/Accessible.cpp +++ b/accessible/src/generic/Accessible.cpp @@ -43,6 +43,7 @@ #include "nsIForm.h" #include "nsIFormControl.h" +#include "nsDeckFrame.h" #include "nsLayoutUtils.h" #include "nsIPresShell.h" #include "nsIStringBundle.h" @@ -606,26 +607,35 @@ Accessible::TranslateString(const nsString& aKey, nsAString& aStringOut) uint64_t Accessible::VisibilityState() { - uint64_t vstates = states::INVISIBLE | states::OFFSCREEN; - nsIFrame* frame = GetFrame(); if (!frame) - return vstates; + return states::INVISIBLE; - nsIPresShell* shell(mDoc->PresShell()); - if (!shell) - return vstates; + // Walk the parent frame chain to see if there's invisible parent or the frame + // is in background tab. + if (!frame->GetStyleVisibility()->IsVisible()) + return states::INVISIBLE; - // We need to know if at least a kMinPixels around the object is visible, - // otherwise it will be marked states::OFFSCREEN. - const uint16_t kMinPixels = 12; - const nsSize frameSize = frame->GetSize(); - const nsRectVisibility rectVisibility = - shell->GetRectVisibility(frame, nsRect(nsPoint(0,0), frameSize), - nsPresContext::CSSPixelsToAppUnits(kMinPixels)); + nsIFrame* curFrame = frame; + do { + nsIView* view = curFrame->GetView(); + if (view && view->GetVisibility() == nsViewVisibility_kHide) + return states::INVISIBLE; - if (rectVisibility == nsRectVisibility_kVisible) - vstates &= ~states::OFFSCREEN; + // Offscreen state for background tab content. + nsIFrame* parentFrame = curFrame->GetParent(); + nsDeckFrame* deckFrame = do_QueryFrame(parentFrame); + if (deckFrame && deckFrame->GetSelectedBox() != curFrame) + return states::OFFSCREEN; + + if (!parentFrame) { + parentFrame = nsLayoutUtils::GetCrossDocParentFrame(curFrame); + if (parentFrame && !parentFrame->GetStyleVisibility()->IsVisible()) + return states::INVISIBLE; + } + + curFrame = parentFrame; + } while (curFrame); // Zero area rects can occur in the first frame of a multi-frame text flow, // in which case the rendered text is not empty and the frame should not be @@ -638,16 +648,21 @@ Accessible::VisibilityState() nsAutoString renderedText; frame->GetRenderedText(&renderedText, nullptr, nullptr, 0, 1); if (renderedText.IsEmpty()) - return vstates; - + return states::INVISIBLE; } - // XXX Do we really need to cross from content to chrome ancestor? - if (!frame->IsVisibleConsideringAncestors(nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY)) - return vstates; + // We need to know if at least a kMinPixels around the object is visible, + // otherwise it will be marked states::OFFSCREEN. + const uint16_t kMinPixels = 12; + const nsSize frameSize = frame->GetSize(); + const nsRectVisibility rectVisibility = + mDoc->PresShell()->GetRectVisibility(frame, nsRect(nsPoint(0,0), frameSize), + nsPresContext::CSSPixelsToAppUnits(kMinPixels)); - // Assume we are visible enough. - return vstates &= ~states::INVISIBLE; + if (rectVisibility != nsRectVisibility_kVisible) + return states::OFFSCREEN; + + return 0; } uint64_t diff --git a/accessible/tests/mochitest/states/test_visibility.html b/accessible/tests/mochitest/states/test_visibility.html index 94553bcc3dee..41d4a7b1875f 100644 --- a/accessible/tests/mochitest/states/test_visibility.html +++ b/accessible/tests/mochitest/states/test_visibility.html @@ -16,27 +16,56 @@ src="../role.js"> + + diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index 1d775a33e08c..51b8cb6a3956 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -492,7 +492,7 @@ pref("dom.experimental_forms", true); // Turns on gralloc-based direct texturing for Gonk pref("gfx.gralloc.enabled", false); -// XXXX REMOVE FOR PRODUCTION. Turns on GC and CC logging +// XXXX REMOVE FOR PRODUCTION. Turns on GC and CC logging pref("javascript.options.mem.log", true); // Increase mark slice time from 10ms to 30ms @@ -513,9 +513,9 @@ pref("ui.showHideScrollbars", 1); // background. pref("dom.ipc.processPriorityManager.enabled", true); pref("dom.ipc.processPriorityManager.gracePeriodMS", 1000); -pref("hal.processPriorityManager.gonk.masterOomAdjust", 0); -pref("hal.processPriorityManager.gonk.foregroundOomAdjust", 1); -pref("hal.processPriorityManager.gonk.backgroundOomAdjust", 6); +pref("hal.processPriorityManager.gonk.masterOomScoreAdjust", 0); +pref("hal.processPriorityManager.gonk.foregroundOomScoreAdjust", 67); +pref("hal.processPriorityManager.gonk.backgroundOomScoreAdjust", 400); pref("hal.processPriorityManager.gonk.masterNice", -1); pref("hal.processPriorityManager.gonk.foregroundNice", 0); pref("hal.processPriorityManager.gonk.backgroundNice", 10); diff --git a/b2g/components/B2GComponents.manifest b/b2g/components/B2GComponents.manifest index 7a8fa4371918..493065339aa9 100644 --- a/b2g/components/B2GComponents.manifest +++ b/b2g/components/B2GComponents.manifest @@ -1,11 +1,6 @@ # Scrollbars category agent-style-sheets browser-content-stylesheet chrome://browser/content/content.css -# CameraContent.js -component {eff4231b-abce-4f7f-a40a-d646e8fde3ce} CameraContent.js -contract @mozilla.org/b2g-camera-content;1 {eff4231b-abce-4f7f-a40a-d646e8fde3ce} -category JavaScript-navigator-property mozCamera @mozilla.org/b2g-camera-content;1 - # AlertsService.js component {fe33c107-82a4-41d6-8c64-5353267e04c9} AlertsService.js contract @mozilla.org/system-alerts-service;1 {fe33c107-82a4-41d6-8c64-5353267e04c9} diff --git a/b2g/components/CameraContent.js b/b2g/components/CameraContent.js deleted file mode 100644 index 2a06d07f6b7c..000000000000 --- a/b2g/components/CameraContent.js +++ /dev/null @@ -1,83 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -const kProtocolName = "b2g-camera:"; - -let CameraContent = function() { - this.hasPrivileges = false; - this.mapping = []; -} - -CameraContent.prototype = { - getCameraURI: function(aOptions) { - if (!this.hasPrivileges) - return null; - - let options = aOptions || { }; - if (!options.camera) - options.camera = 0; - if (!options.width) - options.width = 320; - if (!options.height) - options.height = 240; - - let uuid = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString(); - uuid = uuid.substring(1, uuid.length - 2); // remove the brackets - this.mapping.push(uuid); - let uri = kProtocolName + "?camera=" + options.camera + - "&width=" + options.width + - "&height=" + options.height + - "&type=video/x-raw-yuv"; - // XXX that's no e10s ready, but the camera inputstream itself is not... - Services.prefs.setCharPref("b2g.camera." + kProtocolName + "?" + uuid, uri); - return kProtocolName + "?" + uuid; - }, - - observe: function(aSubject, aTopic, aData) { - if (aTopic == "inner-window-destroyed") { - let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data; - if (wId == this.innerWindowID) { - Services.obs.removeObserver(this, "inner-window-destroyed"); - for (let aId in this.mapping) - Services.prefs.clearUserPref("b2g.camera." + kProtocolName + "?" + aId); - this.mapping = null; - } - } - }, - - init: function(aWindow) { - let principal = aWindow.document.nodePrincipal; - let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager); - - let perm = Services.perms.testExactPermissionFromPrincipal(principal, "content-camera"); - - //only pages with perm set and chrome pages can use the camera in content - this.hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION; - - Services.obs.addObserver(this, "inner-window-destroyed", false); - let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); - this.innerWindowID = util.currentInnerWindowID; - }, - - classID: Components.ID("{eff4231b-abce-4f7f-a40a-d646e8fde3ce}"), - - QueryInterface: XPCOMUtils.generateQI([Ci.nsIB2GCameraContent, Ci.nsIDOMGlobalPropertyInitializer, Ci.nsIObserver]), - - classInfo: XPCOMUtils.generateCI({classID: Components.ID("{eff4231b-abce-4f7f-a40a-d646e8fde3ce}"), - contractID: "@mozilla.org/b2g-camera-content;1", - interfaces: [Ci.nsIB2GCameraContent], - flags: Ci.nsIClassInfo.DOM_OBJECT, - classDescription: "B2G Camera Content Helper"}) -} - -const NSGetFactory = XPCOMUtils.generateNSGetFactory([CameraContent]); diff --git a/b2g/components/Makefile.in b/b2g/components/Makefile.in index 5f28d6ab25e9..c4657b28a72c 100644 --- a/b2g/components/Makefile.in +++ b/b2g/components/Makefile.in @@ -20,7 +20,6 @@ EXTRA_PP_COMPONENTS = \ ActivitiesGlue.js \ AlertsService.js \ B2GComponents.manifest \ - CameraContent.js \ ContentHandler.js \ ContentPermissionPrompt.js \ DirectoryProvider.js \ diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index 22084f8bf8b9..a833ae9c6323 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -366,8 +366,6 @@ @BINPATH@/components/nsHelperAppDlg.js @BINPATH@/components/nsDownloadManagerUI.manifest @BINPATH@/components/nsDownloadManagerUI.js -@BINPATH@/components/nsProxyAutoConfig.manifest -@BINPATH@/components/nsProxyAutoConfig.js @BINPATH@/components/NetworkGeolocationProvider.manifest @BINPATH@/components/NetworkGeolocationProvider.js @BINPATH@/components/GPSDGeolocationProvider.manifest diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index fc254c24b0e7..65eb05bc6219 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -5818,10 +5818,6 @@ var OfflineApps = { } } - var storageManager = Cc["@mozilla.org/dom/storagemanager;1"]. - getService(Ci.nsIDOMStorageManager); - usage += storageManager.getUsage(host); - return usage; }, diff --git a/browser/components/preferences/advanced.js b/browser/components/preferences/advanced.js index fb291d2a738f..926c51d41dbd 100644 --- a/browser/components/preferences/advanced.js +++ b/browser/components/preferences/advanced.js @@ -316,10 +316,6 @@ var gAdvancedPane = { } } - var storageManager = Components.classes["@mozilla.org/dom/storagemanager;1"]. - getService(Components.interfaces.nsIDOMStorageManager); - usage += storageManager.getUsage(host); - return usage; }, @@ -407,12 +403,6 @@ var gAdvancedPane = { } } - // send out an offline-app-removed signal. The nsDOMStorage - // service will clear DOM storage for this host. - var obs = Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService); - obs.notifyObservers(null, "offline-app-removed", host); - // remove the permission var pm = Components.classes["@mozilla.org/permissionmanager;1"] .getService(Components.interfaces.nsIPermissionManager); diff --git a/browser/components/preferences/in-content/advanced.js b/browser/components/preferences/in-content/advanced.js index 1e21c5b5f518..32af1171054a 100644 --- a/browser/components/preferences/in-content/advanced.js +++ b/browser/components/preferences/in-content/advanced.js @@ -308,10 +308,6 @@ var gAdvancedPane = { } } - var storageManager = Components.classes["@mozilla.org/dom/storagemanager;1"]. - getService(Components.interfaces.nsIDOMStorageManager); - usage += storageManager.getUsage(host); - return usage; }, @@ -399,12 +395,6 @@ var gAdvancedPane = { } } - // send out an offline-app-removed signal. The nsDOMStorage - // service will clear DOM storage for this host. - var obs = Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService); - obs.notifyObservers(null, "offline-app-removed", host); - // remove the permission var pm = Components.classes["@mozilla.org/permissionmanager;1"] .getService(Components.interfaces.nsIPermissionManager); diff --git a/browser/components/sessionstore/test/browser_463205_sample.html b/browser/components/sessionstore/test/browser_463205_sample.html index 0e0982afe4d1..f55e5286b17f 100644 --- a/browser/components/sessionstore/test/browser_463205_sample.html +++ b/browser/components/sessionstore/test/browser_463205_sample.html @@ -3,15 +3,13 @@ Test for bug 463205 - + diff --git a/browser/devtools/debugger/debugger-view.js b/browser/devtools/debugger/debugger-view.js index 6cc95228e3d3..d082ef0162f6 100644 --- a/browser/devtools/debugger/debugger-view.js +++ b/browser/devtools/debugger/debugger-view.js @@ -471,7 +471,7 @@ GlobalSearchView.prototype = { for (let [url, text] of this._scriptSources) { // Check if the search token is not found anywhere in the script source. - if (text.toLowerCase().indexOf(lowerCaseToken) === -1) { + if (!text.toLowerCase().contains(lowerCaseToken)) { continue; } let lines = text.split("\n"); @@ -485,7 +485,7 @@ GlobalSearchView.prototype = { let lowerCaseLine = line.toLowerCase(); // Search is not case sensitive, and is tied to each line in the source. - if (lowerCaseLine.indexOf(lowerCaseToken) === -1) { + if (!lowerCaseLine.contains(lowerCaseToken)) { continue; } diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index e3d1851d0150..53d44666f3af 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -361,8 +361,6 @@ @BINPATH@/components/nsHelperAppDlg.js @BINPATH@/components/nsDownloadManagerUI.manifest @BINPATH@/components/nsDownloadManagerUI.js -@BINPATH@/components/nsProxyAutoConfig.manifest -@BINPATH@/components/nsProxyAutoConfig.js @BINPATH@/components/NetworkGeolocationProvider.manifest @BINPATH@/components/NetworkGeolocationProvider.js @BINPATH@/components/GPSDGeolocationProvider.manifest diff --git a/browser/installer/removed-files.in b/browser/installer/removed-files.in index 7d9e85af7b0a..49c6f86aac50 100644 --- a/browser/installer/removed-files.in +++ b/browser/installer/removed-files.in @@ -87,6 +87,8 @@ components/xpcom.xpt components/xpti.dat components/xptitemp.dat components/nsMicrosummaryService.js +components/nsProxyAutoConfig.manifest +components/nsProxyAutoConfig.js D3DCompiler_42.dll d3dx9_42.dll defaults/pref/all.js @@ -921,6 +923,7 @@ xpicleanup@BIN_SUFFIX@ components/nsPlacesExpiration.js components/nsPrivateBrowsingService.js components/nsPrompter.js + components/nsProxyAutoConfig.manifest components/nsProxyAutoConfig.js components/nsSafebrowsingApplication.js components/nsSearchService.js diff --git a/browser/modules/offlineAppCache.jsm b/browser/modules/offlineAppCache.jsm index 1bda4a42d25d..26c99b00b937 100644 --- a/browser/modules/offlineAppCache.jsm +++ b/browser/modules/offlineAppCache.jsm @@ -14,9 +14,5 @@ let OfflineAppCacheHelper = { try { cacheService.evictEntries(Ci.nsICache.STORE_OFFLINE); } catch(er) {} - - var storageManagerService = Cc["@mozilla.org/dom/storagemanager;1"]. - getService(Ci.nsIDOMStorageManager); - storageManagerService.clearOfflineApps(); } }; diff --git a/build/autoconf/libstdcxx.py b/build/autoconf/libstdcxx.py index 727131bea38b..f5d1f76052ef 100755 --- a/build/autoconf/libstdcxx.py +++ b/build/autoconf/libstdcxx.py @@ -16,7 +16,6 @@ import os import subprocess import re -import sys re_for_ld = re.compile('.*\((.*)\).*') @@ -72,19 +71,7 @@ def find_version(e): return encode_ver(last_version) if __name__ == '__main__': - if os.uname()[0] == 'Darwin': - sdk_dir = os.environ['MACOS_SDK_DIR'] - if 'MacOSX10.5.sdk' in sdk_dir: - target_ver = 0 - host_ver = 0 - else: - target_ver = encode_ver('3.4.9') - host_ver = encode_ver('3.4.9') - else: - cxx_env = os.environ['CXX'] - target_ver = find_version(cxx_env) - host_cxx_env = os.environ.get('HOST_CXX', cxx_env) - host_ver = find_version(host_cxx_env) - - print 'MOZ_LIBSTDCXX_TARGET_VERSION=%s' % target_ver - print 'MOZ_LIBSTDCXX_HOST_VERSION=%s' % host_ver + cxx_env = os.environ['CXX'] + print 'MOZ_LIBSTDCXX_TARGET_VERSION=%s' % find_version(cxx_env) + host_cxx_env = os.environ.get('HOST_CXX', cxx_env) + print 'MOZ_LIBSTDCXX_HOST_VERSION=%s' % find_version(host_cxx_env) diff --git a/build/macosx/mozconfig.common b/build/macosx/mozconfig.common index 0dafc503001d..e4e5e8865fa0 100644 --- a/build/macosx/mozconfig.common +++ b/build/macosx/mozconfig.common @@ -13,6 +13,4 @@ elif [ -d "$topsrcdir/../clang" ]; then export CC=$topsrcdir/../clang/bin/clang export CXX=$topsrcdir/../clang/bin/clang++ fi - -ac_add_options --enable-stdcxx-compat ac_add_options --with-ccache diff --git a/build/mobile/sutagent/android/ASMozStub.java b/build/mobile/sutagent/android/ASMozStub.java index c58473596ba3..586600cd976d 100755 --- a/build/mobile/sutagent/android/ASMozStub.java +++ b/build/mobile/sutagent/android/ASMozStub.java @@ -8,20 +8,29 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.ServerSocket; import java.util.Timer; +import java.io.IOException; +import java.net.InetAddress; +import com.mozilla.SUTAgentAndroid.SUTAgentAndroid; import com.mozilla.SUTAgentAndroid.R; import android.app.Notification; import android.app.NotificationManager; import android.content.Context; import android.content.Intent; +import android.net.wifi.WifiManager; import android.os.Handler; import android.os.IBinder; import android.util.Log; import android.view.Gravity; import android.widget.Toast; +import javax.jmdns.JmDNS; +import javax.jmdns.ServiceInfo; + public class ASMozStub extends android.app.Service { + private final static int COMMAND_PORT = 20701; + private final static int DATA_PORT = 20700; private ServerSocket cmdChnl = null; private ServerSocket dataChnl = null; @@ -79,19 +88,97 @@ public class ASMozStub extends android.app.Service { doToast("Listener Service created..."); } + WifiManager.MulticastLock multicastLock; + JmDNS jmdns; + + void startZeroConf() { + if (multicastLock == null) { + WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE); + multicastLock = wifi.createMulticastLock("SUTAgent"); + multicastLock.setReferenceCounted(true); + } + + multicastLock.acquire(); + + try { + InetAddress inetAddress = SUTAgentAndroid.getLocalInetAddress(); + + if (jmdns == null) { + jmdns = JmDNS.create(inetAddress, null); + } + + if (jmdns != null) { + String name = "SUTAgent"; + + String hwid = SUTAgentAndroid.getHWID(this); + if (hwid != null) { + name += " [hwid:" + hwid + "]"; + } + + // multicast reception is broken for some reason, so + // this service can't be resolved; it can only be + // broadcast. So, we cheat -- we put the IP address + // in the broadcast that we can pull out later. + // However, periods aren't legal, so replace them. + // The IP address will show up as [ip:127_0_0_1] + name += " [ip:" + inetAddress.getHostAddress().toString().replace('.', '_') + "]"; + + final ServiceInfo serviceInfo = ServiceInfo.create("_sutagent._tcp.local.", + name, + COMMAND_PORT, + "Android SUTAgent"); + final JmDNS dns = jmdns; + // we want to call registerService on a new thread, because it can block + // for a little while. + Thread registerThread = new Thread() { + public void run() { + try { + dns.registerService(serviceInfo); + } catch (IOException e) { + Log.e("SUTAgent", "Failed to register JmDNS service!", e); + } + } + }; + registerThread.setDaemon(true); + registerThread.start(); + } + } catch (IOException e) { + Log.e("SUTAgent", "Failed to register JmDNS service!", e); + } + } + + void stopZeroConf() { + if (jmdns != null) { + try { + jmdns.unregisterAllServices(); + jmdns.close(); + } catch (IOException e) { + Log.e("SUTAgent", "Failed to close JmDNS service!", e); + } + jmdns = null; + } + + if (multicastLock != null) { + multicastLock.release(); + multicastLock = null; + } + } + public void onStart(Intent intent, int startId) { super.onStart(intent, startId); try { - cmdChnl = new ServerSocket(20701); + cmdChnl = new ServerSocket(COMMAND_PORT); runCmdThrd = new RunCmdThread(cmdChnl, this, handler); runCmdThrd.start(); - doToast("Command channel port 20701 ..."); + doToast(String.format("Command channel port %d ...", COMMAND_PORT)); - dataChnl = new ServerSocket(20700); + dataChnl = new ServerSocket(DATA_PORT); runDataThrd = new RunDataThread(dataChnl, this); runDataThrd.start(); - doToast("Data channel port 20700 ..."); + doToast(String.format("Data channel port %d ...", DATA_PORT)); + + startZeroConf(); Notification notification = new Notification(); startForegroundCompat(R.string.foreground_service_started, notification); @@ -108,6 +195,8 @@ public class ASMozStub extends android.app.Service { { super.onDestroy(); + stopZeroConf(); + if (runCmdThrd.isAlive()) { runCmdThrd.StopListening(); diff --git a/build/mobile/sutagent/android/AndroidManifest.xml b/build/mobile/sutagent/android/AndroidManifest.xml index db0120863d66..8eca89ad345b 100644 --- a/build/mobile/sutagent/android/AndroidManifest.xml +++ b/build/mobile/sutagent/android/AndroidManifest.xml @@ -33,6 +33,7 @@ + diff --git a/build/mobile/sutagent/android/Makefile.in b/build/mobile/sutagent/android/Makefile.in index 64e40d5063f2..3f14e865dd90 100755 --- a/build/mobile/sutagent/android/Makefile.in +++ b/build/mobile/sutagent/android/Makefile.in @@ -47,7 +47,8 @@ GARBAGE += \ GARBAGE_DIRS += res classes network-libs -JAVA_CLASSPATH = $(ANDROID_SDK)/android.jar:$(srcdir)/network-libs/commons-net-2.0.jar +EXTRA_JARS = $(srcdir)/network-libs/commons-net-2.0.jar:$(srcdir)/network-libs/jmdns.jar +JAVA_CLASSPATH = $(ANDROID_SDK)/android.jar:$(EXTRA_JARS) include $(topsrcdir)/config/rules.mk @@ -59,10 +60,10 @@ tools:: sutAgentAndroid.apk classes.dex: $(JAVAFILES) $(NSINSTALL) -D classes $(JAVAC) $(JAVAC_FLAGS) -d classes $(addprefix $(srcdir)/,$(JAVAFILES)) - $(DX) --dex --output=$@ classes + $(DX) --dex --output=$@ classes $(subst :, ,$(EXTRA_JARS)) sutAgentAndroid.ap_: $(srcdir)/AndroidManifest.xml - $(AAPT) package -f -M $(srcdir)/AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -S res -F $@ + $(AAPT) package -f -M $(srcdir)/AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -S res -F $@ sutAgentAndroid-unsigned-unaligned.apk: sutAgentAndroid.ap_ classes.dex $(APKBUILDER) $@ -v $(APKBUILDER_FLAGS) -z sutAgentAndroid.ap_ -f classes.dex diff --git a/build/mobile/sutagent/android/SUTAgentAndroid.java b/build/mobile/sutagent/android/SUTAgentAndroid.java index 66aec4e183f9..6de45949a870 100755 --- a/build/mobile/sutagent/android/SUTAgentAndroid.java +++ b/build/mobile/sutagent/android/SUTAgentAndroid.java @@ -264,10 +264,13 @@ public class SUTAgentAndroid extends Activity } } + String hwid = getHWID(this); + sLocalIPAddr = getLocalIpAddress(); Toast.makeText(getApplication().getApplicationContext(), "SUTAgent [" + sLocalIPAddr + "] ...", Toast.LENGTH_LONG).show(); String sConfig = "Unique ID: " + sUniqueID + lineSep; + sConfig += "HWID: " + hwid + lineSep; sConfig += "OS Info" + lineSep; sConfig += "\t" + dc.GetOSInfo() + lineSep; sConfig += "Screen Info" + lineSep; @@ -738,23 +741,70 @@ public class SUTAgentAndroid extends Activity } }; - public String getLocalIpAddress() + static String sHWID = null; + public static String getHWID(Context cx) { + if (sHWID != null) + return sHWID; + + // If we're on SDK version >= 8, use Build.SERIAL + if (android.os.Build.VERSION.SDK_INT >= 8) { + sHWID = android.os.Build.SERIAL; + } + + if (sHWID != null) + return sHWID; + + // Otherwise, try from the telephony manager + TelephonyManager mTelephonyMgr = (TelephonyManager) cx.getSystemService(TELEPHONY_SERVICE); + if (mTelephonyMgr != null) { + sHWID = mTelephonyMgr.getDeviceId(); + } + + if (sHWID != null) + return sHWID; + + // Otherwise, try WIFI_SERVICE and use the wifi manager + WifiManager wifiMan = (WifiManager) cx.getSystemService(Context.WIFI_SERVICE); + if (wifiMan != null) { + WifiInfo wifi = wifiMan.getConnectionInfo(); + if (wifi != null) { + sHWID = "wifimac" + wifi.getMacAddress(); + } + } + + if (sHWID != null) + return sHWID; + + sHWID = "0011223344556677"; + + return sHWID; + } + + public static InetAddress getLocalInetAddress() throws SocketException { - try + for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { - for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) + NetworkInterface intf = en.nextElement(); + for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { - NetworkInterface intf = en.nextElement(); - for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) + InetAddress inetAddress = enumIpAddr.nextElement(); + if (!inetAddress.isLoopbackAddress() && InetAddressUtils.isIPv4Address(inetAddress.getHostAddress())) { - InetAddress inetAddress = enumIpAddr.nextElement(); - if (!inetAddress.isLoopbackAddress() && InetAddressUtils.isIPv4Address(inetAddress.getHostAddress())) - { - return inetAddress.getHostAddress().toString(); - } + return inetAddress; } } } + + return null; + } + + public String getLocalIpAddress() + { + try { + InetAddress inetAddress = getLocalInetAddress(); + if (inetAddress != null) + return inetAddress.getHostAddress().toString(); + } catch (SocketException ex) { Toast.makeText(getApplication().getApplicationContext(), ex.toString(), Toast.LENGTH_LONG).show(); diff --git a/build/mobile/sutagent/android/network-libs/jmdns.jar b/build/mobile/sutagent/android/network-libs/jmdns.jar new file mode 100644 index 000000000000..ec1c26354a40 Binary files /dev/null and b/build/mobile/sutagent/android/network-libs/jmdns.jar differ diff --git a/configure.in b/configure.in index c0313eed2af3..5d5295f99d2d 100644 --- a/configure.in +++ b/configure.in @@ -73,7 +73,7 @@ GCONF_VERSION=1.2.1 GIO_VERSION=2.18 STARTUP_NOTIFICATION_VERSION=0.8 DBUS_VERSION=0.60 -SQLITE_VERSION=3.7.13 +SQLITE_VERSION=3.7.14 MSMANIFEST_TOOL= @@ -4019,7 +4019,11 @@ if test "$MOZ_NATIVE_JPEG" = 1; then #include ], [ #if JPEG_LIB_VERSION < $MOZJPEG #error "Insufficient JPEG library version ($MOZJPEG required)." - #endif ], + #endif + #ifndef JCS_EXTENSIONS + #error "libjpeg-turbo JCS_EXTENSIONS required" + #endif + ], MOZ_NATIVE_JPEG=1, AC_MSG_ERROR([Insufficient JPEG library version for --with-system-jpeg])) fi @@ -7258,7 +7262,7 @@ MOZ_ARG_ENABLE_BOOL(stdcxx-compat, AC_SUBST(STDCXX_COMPAT) if test -n "$STDCXX_COMPAT"; then - eval $(CXX="$CXX" MACOS_SDK_DIR="$MACOS_SDK_DIR" $PYTHON $_topsrcdir/build/autoconf/libstdcxx.py) + eval $(CXX="$CXX" $PYTHON $_topsrcdir/build/autoconf/libstdcxx.py) AC_SUBST(MOZ_LIBSTDCXX_TARGET_VERSION) AC_SUBST(MOZ_LIBSTDCXX_HOST_VERSION) fi diff --git a/content/base/src/nsAttrName.h b/content/base/src/nsAttrName.h index bfbb3073e454..10ad5a95c28a 100644 --- a/content/base/src/nsAttrName.h +++ b/content/base/src/nsAttrName.h @@ -16,7 +16,7 @@ #include "nsIAtom.h" #include "nsDOMString.h" -typedef PRUptrdiff PtrBits; +typedef uintptr_t PtrBits; #define NS_ATTRNAME_NODEINFO_BIT 1 class nsAttrName diff --git a/content/base/src/nsAttrValue.h b/content/base/src/nsAttrValue.h index b992d32a024c..b4e0003171ec 100644 --- a/content/base/src/nsAttrValue.h +++ b/content/base/src/nsAttrValue.h @@ -20,7 +20,7 @@ #include "nsCOMPtr.h" #include "SVGAttrValueWrapper.h" -typedef PRUptrdiff PtrBits; +typedef uintptr_t PtrBits; class nsAString; class nsIAtom; class nsIDocument; diff --git a/content/base/src/nsGenericElement.h b/content/base/src/nsGenericElement.h index 8373f9e0ec2f..cb92da4a1eea 100644 --- a/content/base/src/nsGenericElement.h +++ b/content/base/src/nsGenericElement.h @@ -57,7 +57,7 @@ class nsDOMTokenList; class ContentUnbinder; struct nsRect; -typedef PRUptrdiff PtrBits; +typedef uintptr_t PtrBits; /** * A generic base class for DOM elements, implementing many nsIContent, diff --git a/content/base/src/nsPropertyTable.h b/content/base/src/nsPropertyTable.h index 013b35223ef8..29982d436762 100644 --- a/content/base/src/nsPropertyTable.h +++ b/content/base/src/nsPropertyTable.h @@ -27,7 +27,7 @@ #include "prtypes.h" class nsIAtom; -typedef PRUptrdiff PtrBits; +typedef uintptr_t PtrBits; typedef void (*NSPropertyFunc)(void *aObject, diff --git a/content/html/content/src/nsHTMLMediaElement.cpp b/content/html/content/src/nsHTMLMediaElement.cpp index 81b9b616118d..77eba5722aa9 100644 --- a/content/html/content/src/nsHTMLMediaElement.cpp +++ b/content/html/content/src/nsHTMLMediaElement.cpp @@ -1445,8 +1445,10 @@ nsHTMLMediaElement::BuildObjectFromTags(nsCStringHashKey::KeyType aKey, nsString wideValue = NS_ConvertUTF8toUTF16(aValue); JSString* string = JS_NewUCStringCopyZ(args->cx, wideValue.Data()); JS::Value value = STRING_TO_JSVAL(string); - if (!JS_SetProperty(args->cx, args->tags, aKey.Data(), &value)) { + if (!JS_DefineProperty(args->cx, args->tags, aKey.Data(), value, + NULL, NULL, JSPROP_ENUMERATE)) { NS_WARNING("Failed to set metadata property"); + return PL_DHASH_STOP; } return PL_DHASH_NEXT; @@ -1465,7 +1467,13 @@ nsHTMLMediaElement::MozGetMetadata(JSContext* cx, JS::Value* aValue) } if (mTags) { MetadataIterCx iter = {cx, tags}; - mTags->EnumerateRead(BuildObjectFromTags, static_cast(&iter)); + uint32_t ret = mTags->EnumerateRead(BuildObjectFromTags, + static_cast(&iter)); + LOG(PR_LOG_DEBUG, ("tag enumerator returned %d", ret)); + if (ret == PL_DHASH_STOP) { + NS_WARNING("couldn't create metadata object!"); + return NS_ERROR_FAILURE; + } } *aValue = OBJECT_TO_JSVAL(tags); diff --git a/content/xbl/src/nsXBLProtoImplMethod.h b/content/xbl/src/nsXBLProtoImplMethod.h index 6edfdead475b..40285b075322 100644 --- a/content/xbl/src/nsXBLProtoImplMethod.h +++ b/content/xbl/src/nsXBLProtoImplMethod.h @@ -107,11 +107,11 @@ public: } void SetUncompiledMethod(nsXBLUncompiledMethod* aUncompiledMethod) { - mUncompiledMethod = PRUptrdiff(aUncompiledMethod) | BIT_UNCOMPILED; + mUncompiledMethod = uintptr_t(aUncompiledMethod) | BIT_UNCOMPILED; } nsXBLUncompiledMethod* GetUncompiledMethod() const { - PRUptrdiff unmasked = mUncompiledMethod & ~BIT_UNCOMPILED; + uintptr_t unmasked = mUncompiledMethod & ~BIT_UNCOMPILED; return reinterpret_cast(unmasked); } @@ -119,7 +119,7 @@ protected: enum { BIT_UNCOMPILED = 1 << 0 }; union { - PRUptrdiff mUncompiledMethod; // An object that represents the method before being compiled. + uintptr_t mUncompiledMethod; // An object that represents the method before being compiled. JSObject* mJSMethodObject; // The JS object for the method (after compilation) }; diff --git a/db/sqlite3/README b/db/sqlite3/README index 326f3aa1ac25..0d65e518f9f8 100644 --- a/db/sqlite3/README +++ b/db/sqlite3/README @@ -15,23 +15,25 @@ For example: cd bld ;# Change to the build directory ../sqlite/configure ;# Run the configure script make ;# Run the makefile. + make install ;# (Optional) Install the build products -The configure script uses autoconf 2.50 and libtool. If the configure +The configure script uses autoconf 2.61 and libtool. If the configure script does not work out for you, there is a generic makefile named "Makefile.linux-gcc" in the top directory of the source tree that you -can copy and edit to suite your needs. Comments on the generic makefile +can copy and edit to suit your needs. Comments on the generic makefile show what changes are needed. The linux binaries on the website are created using the generic makefile, -not the configure script. The configure script is unmaintained. (You -can volunteer to take over maintenance of the configure script, if you want!) -The windows binaries on the website are created using MinGW32 configured -as a cross-compiler running under Linux. For details, see the ./publish.sh -script at the top-level of the source tree. +not the configure script. The windows binaries on the website are created +using MinGW32 configured as a cross-compiler running under Linux. For +details, see the ./publish.sh script at the top-level of the source tree. +The developers do not use teh configure script. + +SQLite does not require TCL to run, but a TCL installation is required +by the makefiles. SQLite contains a lot of generated code and TCL is +used to do much of that code generation. The makefile also requires +AWK. Contacts: http://www.sqlite.org/ - http://www.hwaci.com/sw/sqlite/ - http://groups.yahoo.com/group/sqlite/ - drh@hwaci.com diff --git a/db/sqlite3/README.MOZILLA b/db/sqlite3/README.MOZILLA index fa67f6d210b3..436bd5fed6c3 100644 --- a/db/sqlite3/README.MOZILLA +++ b/db/sqlite3/README.MOZILLA @@ -1,6 +1,6 @@ -This is sqlite 3.7.13 +This is sqlite 3.7.14 --- Ryan VanderMeulen , 06/2012 +-- Ryan VanderMeulen , 09/2012 See http://www.sqlite.org/ for more info. diff --git a/db/sqlite3/src/sqlite3.c b/db/sqlite3/src/sqlite3.c index f69816e2a65d..2d07999b3a50 100644 --- a/db/sqlite3/src/sqlite3.c +++ b/db/sqlite3/src/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.7.13. By combining all the individual C code files into this +** version 3.7.14. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -389,6 +389,7 @@ ** ** SQLITE_SYSTEM_MALLOC // Use normal system malloc() ** SQLITE_WIN32_MALLOC // Use Win32 native heap API +** SQLITE_ZERO_MALLOC // Use a stub allocator that always fails ** SQLITE_MEMDEBUG // Debugging version of system malloc() ** ** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the @@ -402,11 +403,19 @@ ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as ** the default. */ -#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)>1 -# error "At most one of the following compile-time configuration options\ - is allows: SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG" +#if defined(SQLITE_SYSTEM_MALLOC) \ + + defined(SQLITE_WIN32_MALLOC) \ + + defined(SQLITE_ZERO_MALLOC) \ + + defined(SQLITE_MEMDEBUG)>1 +# error "Two or more of the following compile-time configuration options\ + are defined but at most one is allowed:\ + SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG,\ + SQLITE_ZERO_MALLOC" #endif -#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)==0 +#if defined(SQLITE_SYSTEM_MALLOC) \ + + defined(SQLITE_WIN32_MALLOC) \ + + defined(SQLITE_ZERO_MALLOC) \ + + defined(SQLITE_MEMDEBUG)==0 # define SQLITE_SYSTEM_MALLOC 1 #endif @@ -664,9 +673,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.7.13" -#define SQLITE_VERSION_NUMBER 3007013 -#define SQLITE_SOURCE_ID "2012-06-11 02:05:22 f5b5a13f7394dc143aa136f1d4faba6839eaa6dc" +#define SQLITE_VERSION "3.7.14" +#define SQLITE_VERSION_NUMBER 3007014 +#define SQLITE_SOURCE_ID "2012-09-03 15:42:36 c0d89d4a9752922f9e367362366efde4f1b06f2a" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -776,7 +785,8 @@ SQLITE_API int sqlite3_threadsafe(void); ** the opaque structure named "sqlite3". It is useful to think of an sqlite3 ** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and ** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()] -** is its destructor. There are many other interfaces (such as +** and [sqlite3_close_v2()] are its destructors. There are many other +** interfaces (such as ** [sqlite3_prepare_v2()], [sqlite3_create_function()], and ** [sqlite3_busy_timeout()] to name but three) that are methods on an ** sqlite3 object. @@ -823,28 +833,46 @@ typedef sqlite_uint64 sqlite3_uint64; /* ** CAPI3REF: Closing A Database Connection ** -** ^The sqlite3_close() routine is the destructor for the [sqlite3] object. -** ^Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is -** successfully destroyed and all associated resources are deallocated. +** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors +** for the [sqlite3] object. +** ^Calls to sqlite3_close() and sqlite3_close_v2() return SQLITE_OK if +** the [sqlite3] object is successfully destroyed and all associated +** resources are deallocated. ** -** Applications must [sqlite3_finalize | finalize] all [prepared statements] -** and [sqlite3_blob_close | close] all [BLOB handles] associated with -** the [sqlite3] object prior to attempting to close the object. ^If +** ^If the database connection is associated with unfinalized prepared +** statements or unfinished sqlite3_backup objects then sqlite3_close() +** will leave the database connection open and return [SQLITE_BUSY]. +** ^If sqlite3_close_v2() is called with unfinalized prepared statements +** and unfinished sqlite3_backups, then the database connection becomes +** an unusable "zombie" which will automatically be deallocated when the +** last prepared statement is finalized or the last sqlite3_backup is +** finished. The sqlite3_close_v2() interface is intended for use with +** host languages that are garbage collected, and where the order in which +** destructors are called is arbitrary. +** +** Applications should [sqlite3_finalize | finalize] all [prepared statements], +** [sqlite3_blob_close | close] all [BLOB handles], and +** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated +** with the [sqlite3] object prior to attempting to close the object. ^If ** sqlite3_close() is called on a [database connection] that still has -** outstanding [prepared statements] or [BLOB handles], then it returns -** SQLITE_BUSY. +** outstanding [prepared statements], [BLOB handles], and/or +** [sqlite3_backup] objects then it returns SQLITE_OK but the deallocation +** of resources is deferred until all [prepared statements], [BLOB handles], +** and [sqlite3_backup] objects are also destroyed. ** -** ^If [sqlite3_close()] is invoked while a transaction is open, +** ^If an [sqlite3] object is destroyed while a transaction is open, ** the transaction is automatically rolled back. ** -** The C parameter to [sqlite3_close(C)] must be either a NULL +** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)] +** must be either a NULL ** pointer or an [sqlite3] object pointer obtained ** from [sqlite3_open()], [sqlite3_open16()], or ** [sqlite3_open_v2()], and not previously closed. -** ^Calling sqlite3_close() with a NULL pointer argument is a -** harmless no-op. +** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer +** argument is a harmless no-op. */ -SQLITE_API int sqlite3_close(sqlite3 *); +SQLITE_API int sqlite3_close(sqlite3*); +SQLITE_API int sqlite3_close_v2(sqlite3*); /* ** The type for a callback function. @@ -1055,7 +1083,7 @@ SQLITE_API int sqlite3_exec( ** CAPI3REF: Device Characteristics ** ** The xDeviceCharacteristics method of the [sqlite3_io_methods] -** object returns an integer which is a vector of the these +** object returns an integer which is a vector of these ** bit values expressing I/O characteristics of the mass storage ** device that holds the file that the [sqlite3_io_methods] ** refers to. @@ -3205,6 +3233,12 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** codepage is currently defined. Filenames containing international ** characters must be converted to UTF-8 prior to passing them into ** sqlite3_open() or sqlite3_open_v2(). +** +** Note to Windows Runtime users: The temporary directory must be set +** prior to calling sqlite3_open() or sqlite3_open_v2(). Otherwise, various +** features that require the use of temporary files may fail. +** +** See also: [sqlite3_temp_directory] */ SQLITE_API int sqlite3_open( const char *filename, /* Database filename (UTF-8) */ @@ -3697,8 +3731,11 @@ typedef struct sqlite3_context sqlite3_context; ** ^(In those routines that have a fourth argument, its value is the ** number of bytes in the parameter. To be clear: the value is the ** number of bytes in the value, not the number of characters.)^ -** ^If the fourth parameter is negative, the length of the string is +** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16() +** is negative, then the length of the string is ** the number of bytes up to the first zero terminator. +** If the fourth parameter to sqlite3_bind_blob() is negative, then +** the behavior is undefined. ** If a non-negative fourth parameter is provided to sqlite3_bind_text() ** or sqlite3_bind_text16() then that parameter must be the byte offset ** where the NUL terminator would occur assuming the string were NUL @@ -4695,11 +4732,11 @@ typedef void (*sqlite3_destructor_type)(void*); ** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() ** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. ** -** ^The sqlite3_result_toobig() interface causes SQLite to throw an error -** indicating that a string or BLOB is too long to represent. +** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an +** error indicating that a string or BLOB is too long to represent. ** -** ^The sqlite3_result_nomem() interface causes SQLite to throw an error -** indicating that a memory allocation failed. +** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an +** error indicating that a memory allocation failed. ** ** ^The sqlite3_result_int() interface sets the return value ** of the application-defined function to be the 32-bit signed integer @@ -5006,6 +5043,21 @@ SQLITE_API int sqlite3_sleep(int); ** Hence, if this variable is modified directly, either it should be ** made NULL or made to point to memory obtained from [sqlite3_malloc] ** or else the use of the [temp_store_directory pragma] should be avoided. +** +** Note to Windows Runtime users: The temporary directory must be set +** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various +** features that require the use of temporary files may fail. Here is an +** example of how to do this using C++ with the Windows Runtime: +** +**
+** LPCWSTR zPath = Windows::Storage::ApplicationData::Current->
+**       TemporaryFolder->Path->Data();
+** char zPathBuf[MAX_PATH + 1];
+** memset(zPathBuf, 0, sizeof(zPathBuf));
+** WideCharToMultiByte(CP_UTF8, 0, zPath, -1, zPathBuf, sizeof(zPathBuf),
+**       NULL, NULL);
+** sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf);
+** 
*/ SQLITE_API char *sqlite3_temp_directory; @@ -6051,7 +6103,6 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** implementations are available in the SQLite core: ** **
    -**
  • SQLITE_MUTEX_OS2 **
  • SQLITE_MUTEX_PTHREADS **
  • SQLITE_MUTEX_W32 **
  • SQLITE_MUTEX_NOOP @@ -6059,9 +6110,9 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** ** ^The SQLITE_MUTEX_NOOP implementation is a set of routines ** that does no real locking and is appropriate for use in -** a single-threaded application. ^The SQLITE_MUTEX_OS2, -** SQLITE_MUTEX_PTHREADS, and SQLITE_MUTEX_W32 implementations -** are appropriate for use on OS/2, Unix, and Windows. +** a single-threaded application. ^The SQLITE_MUTEX_PTHREADS and +** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix +** and Windows. ** ** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor ** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex @@ -8372,6 +8423,12 @@ SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); #define BTREE_USER_VERSION 6 #define BTREE_INCR_VACUUM 7 +/* +** Values that may be OR'd together to form the second argument of an +** sqlite3BtreeCursorHints() call. +*/ +#define BTREE_BULKLOAD 0x00000001 + SQLITE_PRIVATE int sqlite3BtreeCursor( Btree*, /* BTree containing table to open */ int iTable, /* Index of root page */ @@ -8415,8 +8472,8 @@ SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*); SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *); SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); - SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); +SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask); #ifndef NDEBUG SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); @@ -9290,7 +9347,7 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); /* ** Figure out if we are dealing with Unix, Windows, or some other ** operating system. After the following block of preprocess macros, -** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, and SQLITE_OS_OTHER +** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, and SQLITE_OS_OTHER ** will defined to either 1 or 0. One of the four will be 1. The other ** three will be 0. */ @@ -9300,8 +9357,6 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); # define SQLITE_OS_UNIX 0 # undef SQLITE_OS_WIN # define SQLITE_OS_WIN 0 -# undef SQLITE_OS_OS2 -# define SQLITE_OS_OS2 0 # else # undef SQLITE_OS_OTHER # endif @@ -9312,19 +9367,12 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); # if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) # define SQLITE_OS_WIN 1 # define SQLITE_OS_UNIX 0 -# define SQLITE_OS_OS2 0 -# elif defined(__EMX__) || defined(_OS2) || defined(OS2) || defined(_OS2_) || defined(__OS2__) -# define SQLITE_OS_WIN 0 -# define SQLITE_OS_UNIX 0 -# define SQLITE_OS_OS2 1 # else # define SQLITE_OS_WIN 0 # define SQLITE_OS_UNIX 1 -# define SQLITE_OS_OS2 0 # endif # else # define SQLITE_OS_UNIX 0 -# define SQLITE_OS_OS2 0 # endif #else # ifndef SQLITE_OS_WIN @@ -9336,21 +9384,6 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); # include #endif -#if SQLITE_OS_OS2 -# if (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 3) && defined(OS2_HIGH_MEMORY) -# include /* has to be included before os2.h for linking to work */ -# endif -# define INCL_DOSDATETIME -# define INCL_DOSFILEMGR -# define INCL_DOSERRORS -# define INCL_DOSMISC -# define INCL_DOSPROCESS -# define INCL_DOSMODULEMGR -# define INCL_DOSSEMAPHORES -# include -# include -#endif - /* ** Determine if we are dealing with Windows NT. ** @@ -9383,8 +9416,8 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); #endif /* -** Determine if we are dealing with WindowsRT (Metro) as this has a different and -** incompatible API from win32. +** Determine if we are dealing with WinRT, which provides only a subset of +** the full Win32 API. */ #if !defined(SQLITE_OS_WINRT) # define SQLITE_OS_WINRT 0 @@ -9620,8 +9653,6 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *); ** SQLITE_MUTEX_PTHREADS For multi-threaded applications on Unix. ** ** SQLITE_MUTEX_W32 For multi-threaded applications on Win32. -** -** SQLITE_MUTEX_OS2 For multi-threaded applications on OS/2. */ #if !SQLITE_THREADSAFE # define SQLITE_MUTEX_OMIT @@ -9631,8 +9662,6 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *); # define SQLITE_MUTEX_PTHREADS # elif SQLITE_OS_WIN # define SQLITE_MUTEX_W32 -# elif SQLITE_OS_OS2 -# define SQLITE_MUTEX_OS2 # else # define SQLITE_MUTEX_NOOP # endif @@ -9953,6 +9982,7 @@ struct sqlite3 { #define SQLITE_MAGIC_SICK 0x4b771290 /* Error and awaiting close */ #define SQLITE_MAGIC_BUSY 0xf03b7906 /* Database currently in use */ #define SQLITE_MAGIC_ERROR 0xb5357930 /* An SQLITE_MISUSE error occurred */ +#define SQLITE_MAGIC_ZOMBIE 0x64cffc7f /* Close with last statement close */ /* ** Each SQL function is defined by an instance of the following @@ -10659,8 +10689,9 @@ struct Expr { i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ u8 flags2; /* Second set of flags. EP2_... */ - u8 op2; /* If a TK_REGISTER, the original value of Expr.op */ - /* If TK_COLUMN, the value of p5 for OP_Column */ + u8 op2; /* TK_REGISTER: original value of Expr.op + ** TK_COLUMN: the value of p5 for OP_Column + ** TK_AGG_FUNCTION: nesting depth */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ Table *pTab; /* Table for TK_COLUMN expressions. */ #if SQLITE_MAX_EXPR_DEPTH>0 @@ -10885,7 +10916,7 @@ struct WherePlan { /* ** For each nested loop in a WHERE clause implementation, the WhereInfo ** structure contains a single instance of this structure. This structure -** is intended to be private the the where.c module and should not be +** is intended to be private to the where.c module and should not be ** access or modified by other modules. ** ** The pIdxInfo field is used to help pick the best index on a @@ -10915,6 +10946,7 @@ struct WhereLevel { int addrInTop; /* Top of the IN loop */ } *aInLoop; /* Information about each nested IN operator */ } in; /* Used when plan.wsFlags&WHERE_IN_ABLE */ + Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */ } u; /* The following field is really not part of the current level. But @@ -11087,10 +11119,10 @@ struct Select { typedef struct SelectDest SelectDest; struct SelectDest { u8 eDest; /* How to dispose of the results */ - u8 affinity; /* Affinity used when eDest==SRT_Set */ - int iParm; /* A parameter used by the eDest disposal method */ - int iMem; /* Base register where results are written */ - int nMem; /* Number of registers allocated */ + u8 affSdst; /* Affinity used when eDest==SRT_Set */ + int iSDParm; /* A parameter used by the eDest disposal method */ + int iSdst; /* Base register where results are written */ + int nSdst; /* Number of registers allocated */ }; /* @@ -11286,6 +11318,8 @@ struct AuthContext { #define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */ #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ +#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ +#define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */ /* * Each trigger present in the database schema is stored as an instance of @@ -11465,10 +11499,12 @@ struct Walker { int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */ int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */ Parse *pParse; /* Parser context. */ + int walkerDepth; /* Number of subqueries */ union { /* Extra data for callback */ NameContext *pNC; /* Naming context */ int i; /* Integer value */ SrcList *pSrcList; /* FROM clause */ + struct SrcCount *pSrcCount; /* Counting column references */ } u; }; @@ -11770,7 +11806,8 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, E #endif SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); -SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**,ExprList*,u16); +SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( + Parse*,SrcList*,Expr*,ExprList**,ExprList*,u16,int); SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); @@ -11802,6 +11839,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*); SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*); SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); +SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*); SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*); SQLITE_PRIVATE void sqlite3PrngSaveState(void); SQLITE_PRIVATE void sqlite3PrngRestoreState(void); @@ -11814,6 +11852,7 @@ SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*); SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*); SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*); SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *); +SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*); SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*); @@ -13355,11 +13394,11 @@ SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p); #else SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *); SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); -SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *, Mem *); -SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, VdbeCursor *, int *); -SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, VdbeCursor *, int *); -SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, VdbeCursor *, Mem *); -SQLITE_PRIVATE int sqlite3VdbeSorterCompare(VdbeCursor *, Mem *, int *); +SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *); +SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *); +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *); +SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *); +SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int *); #endif #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 @@ -15506,14 +15545,14 @@ static int sqlite3MemInit(void *NotUsed){ }else{ /* only 1 core, use our own zone to contention over global locks, ** e.g. we have our own dedicated locks */ - bool success; + bool success; malloc_zone_t* newzone = malloc_create_zone(4096, 0); malloc_set_zone_name(newzone, "Sqlite_Heap"); do{ success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, (void * volatile *)&_sqliteZone_); }while(!_sqliteZone_); - if( !success ){ + if( !success ){ /* somebody registered a zone first */ malloc_destroy_zone(newzone); } @@ -17719,282 +17758,6 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ #endif /* !defined(SQLITE_MUTEX_OMIT) */ /************** End of mutex_noop.c ******************************************/ -/************** Begin file mutex_os2.c ***************************************/ -/* -** 2007 August 28 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains the C functions that implement mutexes for OS/2 -*/ - -/* -** The code in this file is only used if SQLITE_MUTEX_OS2 is defined. -** See the mutex.h file for details. -*/ -#ifdef SQLITE_MUTEX_OS2 - -/********************** OS/2 Mutex Implementation ********************** -** -** This implementation of mutexes is built using the OS/2 API. -*/ - -/* -** The mutex object -** Each recursive mutex is an instance of the following structure. -*/ -struct sqlite3_mutex { - HMTX mutex; /* Mutex controlling the lock */ - int id; /* Mutex type */ -#ifdef SQLITE_DEBUG - int trace; /* True to trace changes */ -#endif -}; - -#ifdef SQLITE_DEBUG -#define SQLITE3_MUTEX_INITIALIZER { 0, 0, 0 } -#else -#define SQLITE3_MUTEX_INITIALIZER { 0, 0 } -#endif - -/* -** Initialize and deinitialize the mutex subsystem. -*/ -static int os2MutexInit(void){ return SQLITE_OK; } -static int os2MutexEnd(void){ return SQLITE_OK; } - -/* -** The sqlite3_mutex_alloc() routine allocates a new -** mutex and returns a pointer to it. If it returns NULL -** that means that a mutex could not be allocated. -** SQLite will unwind its stack and return an error. The argument -** to sqlite3_mutex_alloc() is one of these integer constants: -** -**
      -**
    • SQLITE_MUTEX_FAST -**
    • SQLITE_MUTEX_RECURSIVE -**
    • SQLITE_MUTEX_STATIC_MASTER -**
    • SQLITE_MUTEX_STATIC_MEM -**
    • SQLITE_MUTEX_STATIC_MEM2 -**
    • SQLITE_MUTEX_STATIC_PRNG -**
    • SQLITE_MUTEX_STATIC_LRU -**
    • SQLITE_MUTEX_STATIC_LRU2 -**
    -** -** The first two constants cause sqlite3_mutex_alloc() to create -** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE -** is used but not necessarily so when SQLITE_MUTEX_FAST is used. -** The mutex implementation does not need to make a distinction -** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does -** not want to. But SQLite will only request a recursive mutex in -** cases where it really needs one. If a faster non-recursive mutex -** implementation is available on the host platform, the mutex subsystem -** might return such a mutex in response to SQLITE_MUTEX_FAST. -** -** The other allowed parameters to sqlite3_mutex_alloc() each return -** a pointer to a static preexisting mutex. Six static mutexes are -** used by the current version of SQLite. Future versions of SQLite -** may add additional static mutexes. Static mutexes are for internal -** use by SQLite only. Applications that use SQLite mutexes should -** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or -** SQLITE_MUTEX_RECURSIVE. -** -** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST -** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() -** returns a different mutex on every call. But for the static -** mutex types, the same mutex is returned on every call that has -** the same type number. -*/ -static sqlite3_mutex *os2MutexAlloc(int iType){ - sqlite3_mutex *p = NULL; - switch( iType ){ - case SQLITE_MUTEX_FAST: - case SQLITE_MUTEX_RECURSIVE: { - p = sqlite3MallocZero( sizeof(*p) ); - if( p ){ - p->id = iType; - if( DosCreateMutexSem( 0, &p->mutex, 0, FALSE ) != NO_ERROR ){ - sqlite3_free( p ); - p = NULL; - } - } - break; - } - default: { - static volatile int isInit = 0; - static sqlite3_mutex staticMutexes[6] = { - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - }; - if ( !isInit ){ - APIRET rc; - PTIB ptib; - PPIB ppib; - HMTX mutex; - char name[32]; - DosGetInfoBlocks( &ptib, &ppib ); - sqlite3_snprintf( sizeof(name), name, "\\SEM32\\SQLITE%04x", - ppib->pib_ulpid ); - while( !isInit ){ - mutex = 0; - rc = DosCreateMutexSem( name, &mutex, 0, FALSE); - if( rc == NO_ERROR ){ - unsigned int i; - if( !isInit ){ - for( i = 0; i < sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++ ){ - DosCreateMutexSem( 0, &staticMutexes[i].mutex, 0, FALSE ); - } - isInit = 1; - } - DosCloseMutexSem( mutex ); - }else if( rc == ERROR_DUPLICATE_NAME ){ - DosSleep( 1 ); - }else{ - return p; - } - } - } - assert( iType-2 >= 0 ); - assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) ); - p = &staticMutexes[iType-2]; - p->id = iType; - break; - } - } - return p; -} - - -/* -** This routine deallocates a previously allocated mutex. -** SQLite is careful to deallocate every mutex that it allocates. -*/ -static void os2MutexFree(sqlite3_mutex *p){ -#ifdef SQLITE_DEBUG - TID tid; - PID pid; - ULONG ulCount; - DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); - assert( ulCount==0 ); - assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); -#endif - DosCloseMutexSem( p->mutex ); - sqlite3_free( p ); -} - -#ifdef SQLITE_DEBUG -/* -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are -** intended for use inside assert() statements. -*/ -static int os2MutexHeld(sqlite3_mutex *p){ - TID tid; - PID pid; - ULONG ulCount; - PTIB ptib; - DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); - if( ulCount==0 || ( ulCount>1 && p->id!=SQLITE_MUTEX_RECURSIVE ) ) - return 0; - DosGetInfoBlocks(&ptib, NULL); - return tid==ptib->tib_ptib2->tib2_ultid; -} -static int os2MutexNotheld(sqlite3_mutex *p){ - TID tid; - PID pid; - ULONG ulCount; - PTIB ptib; - DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); - if( ulCount==0 ) - return 1; - DosGetInfoBlocks(&ptib, NULL); - return tid!=ptib->tib_ptib2->tib2_ultid; -} -static void os2MutexTrace(sqlite3_mutex *p, char *pAction){ - TID tid; - PID pid; - ULONG ulCount; - DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); - printf("%s mutex %p (%d) with nRef=%ld\n", pAction, (void*)p, p->trace, ulCount); -} -#endif - -/* -** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt -** to enter a mutex. If another thread is already within the mutex, -** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return -** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK -** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can -** be entered multiple times by the same thread. In such cases the, -** mutex must be exited an equal number of times before another thread -** can enter. If the same thread tries to enter any other kind of mutex -** more than once, the behavior is undefined. -*/ -static void os2MutexEnter(sqlite3_mutex *p){ - assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) ); - DosRequestMutexSem(p->mutex, SEM_INDEFINITE_WAIT); -#ifdef SQLITE_DEBUG - if( p->trace ) os2MutexTrace(p, "enter"); -#endif -} -static int os2MutexTry(sqlite3_mutex *p){ - int rc = SQLITE_BUSY; - assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) ); - if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR ) { - rc = SQLITE_OK; -#ifdef SQLITE_DEBUG - if( p->trace ) os2MutexTrace(p, "try"); -#endif - } - return rc; -} - -/* -** The sqlite3_mutex_leave() routine exits a mutex that was -** previously entered by the same thread. The behavior -** is undefined if the mutex is not currently entered or -** is not currently allocated. SQLite will never do either. -*/ -static void os2MutexLeave(sqlite3_mutex *p){ - assert( os2MutexHeld(p) ); - DosReleaseMutexSem(p->mutex); -#ifdef SQLITE_DEBUG - if( p->trace ) os2MutexTrace(p, "leave"); -#endif -} - -SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ - static const sqlite3_mutex_methods sMutex = { - os2MutexInit, - os2MutexEnd, - os2MutexAlloc, - os2MutexFree, - os2MutexEnter, - os2MutexTry, - os2MutexLeave, -#ifdef SQLITE_DEBUG - os2MutexHeld, - os2MutexNotheld -#else - 0, - 0 -#endif - }; - - return &sMutex; -} -#endif /* SQLITE_MUTEX_OS2 */ - -/************** End of mutex_os2.c *******************************************/ /************** Begin file mutex_unix.c **************************************/ /* ** 2007 August 28 @@ -18459,7 +18222,7 @@ static int winMutex_isInit = 0; */ static long winMutex_lock = 0; -SQLITE_API extern void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ +SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ static int winMutexInit(void){ /* The first to increment to 1 does actual initialization */ @@ -19602,7 +19365,8 @@ static const et_info fmtinfo[] = { static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){ int digit; LONGDOUBLE_TYPE d; - if( (*cnt)++ >= 16 ) return '0'; + if( (*cnt)<=0 ) return '0'; + (*cnt)--; digit = (int)*val; d = digit; digit += '0'; @@ -19906,9 +19670,12 @@ SQLITE_PRIVATE void sqlite3VXPrintf( break; } if( realvalue>0.0 ){ - while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; } - while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; } - while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; } + LONGDOUBLE_TYPE scale = 1.0; + while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;} + while( realvalue>=1e64*scale && exp<=350 ){ scale *= 1e64; exp+=64; } + while( realvalue>=1e8*scale && exp<=350 ){ scale *= 1e8; exp+=8; } + while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; } + realvalue /= scale; while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; } while( realvalue<1.0 ){ realvalue *= 10.0; exp--; } if( exp>350 ){ @@ -19941,7 +19708,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf( xtype = etFLOAT; } }else{ - flag_rtz = 0; + flag_rtz = flag_altform2; } if( xtype==etEXP ){ e2 = 0; @@ -19956,7 +19723,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf( } } zOut = bufpt; - nsd = 0; + nsd = 16 + flag_altform2*10; flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2; /* The sign in front of the number */ if( prefix ){ @@ -21529,7 +21296,7 @@ do_atof_calc: /* if exponent, scale significand as appropriate ** and store in result. */ if( e ){ - double scale = 1.0; + LONGDOUBLE_TYPE scale = 1.0; /* attempt to handle extremely small/large numbers better */ if( e>307 && e<342 ){ while( e%308 ) { scale *= 1.0e+1; e -= 1; } @@ -22458,7 +22225,11 @@ static int rehash(Hash *pH, unsigned int new_size){ /* The inability to allocates space for a larger hash table is ** a performance hit but it is not a fatal error. So mark the - ** allocation as a benign. + ** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of + ** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero() + ** only zeroes the requested number of bytes whereas this module will + ** use the actual amount of space allocated for the hash table (which + ** may be larger than the requested amount). */ sqlite3BeginBenignMalloc(); new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) ); @@ -22784,2140 +22555,6 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ #endif /************** End of opcodes.c *********************************************/ -/************** Begin file os_os2.c ******************************************/ -/* -** 2006 Feb 14 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains code that is specific to OS/2. -*/ - - -#if SQLITE_OS_OS2 - -/* -** A Note About Memory Allocation: -** -** This driver uses malloc()/free() directly rather than going through -** the SQLite-wrappers sqlite3_malloc()/sqlite3_free(). Those wrappers -** are designed for use on embedded systems where memory is scarce and -** malloc failures happen frequently. OS/2 does not typically run on -** embedded systems, and when it does the developers normally have bigger -** problems to worry about than running out of memory. So there is not -** a compelling need to use the wrappers. -** -** But there is a good reason to not use the wrappers. If we use the -** wrappers then we will get simulated malloc() failures within this -** driver. And that causes all kinds of problems for our tests. We -** could enhance SQLite to deal with simulated malloc failures within -** the OS driver, but the code to deal with those failure would not -** be exercised on Linux (which does not need to malloc() in the driver) -** and so we would have difficulty writing coverage tests for that -** code. Better to leave the code out, we think. -** -** The point of this discussion is as follows: When creating a new -** OS layer for an embedded system, if you use this file as an example, -** avoid the use of malloc()/free(). Those routines work ok on OS/2 -** desktops but not so well in embedded systems. -*/ - -/* -** Macros used to determine whether or not to use threads. -*/ -#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE -# define SQLITE_OS2_THREADS 1 -#endif - -/* -** Include code that is common to all os_*.c files -*/ -/************** Include os_common.h in the middle of os_os2.c ****************/ -/************** Begin file os_common.h ***************************************/ -/* -** 2004 May 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains macros and a little bit of code that is common to -** all of the platform-specific files (os_*.c) and is #included into those -** files. -** -** This file should be #included by the os_*.c files only. It is not a -** general purpose header file. -*/ -#ifndef _OS_COMMON_H_ -#define _OS_COMMON_H_ - -/* -** At least two bugs have slipped in because we changed the MEMORY_DEBUG -** macro to SQLITE_DEBUG and some older makefiles have not yet made the -** switch. The following code should catch this problem at compile-time. -*/ -#ifdef MEMORY_DEBUG -# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." -#endif - -#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) -# ifndef SQLITE_DEBUG_OS_TRACE -# define SQLITE_DEBUG_OS_TRACE 0 -# endif - int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; -# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X -#else -# define OSTRACE(X) -#endif - -/* -** Macros for performance tracing. Normally turned off. Only works -** on i486 hardware. -*/ -#ifdef SQLITE_PERFORMANCE_TRACE - -/* -** hwtime.h contains inline assembler code for implementing -** high-performance timing routines. -*/ -/************** Include hwtime.h in the middle of os_common.h ****************/ -/************** Begin file hwtime.h ******************************************/ -/* -** 2008 May 27 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains inline asm code for retrieving "high-performance" -** counters for x86 class CPUs. -*/ -#ifndef _HWTIME_H_ -#define _HWTIME_H_ - -/* -** The following routine only works on pentium-class (or newer) processors. -** It uses the RDTSC opcode to read the cycle count value out of the -** processor and returns that value. This can be used for high-res -** profiling. -*/ -#if (defined(__GNUC__) || defined(_MSC_VER)) && \ - (defined(i386) || defined(__i386__) || defined(_M_IX86)) - - #if defined(__GNUC__) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned int lo, hi; - __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); - return (sqlite_uint64)hi << 32 | lo; - } - - #elif defined(_MSC_VER) - - __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ - __asm { - rdtsc - ret ; return value at EDX:EAX - } - } - - #endif - -#elif (defined(__GNUC__) && defined(__x86_64__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long val; - __asm__ __volatile__ ("rdtsc" : "=A" (val)); - return val; - } - -#elif (defined(__GNUC__) && defined(__ppc__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long long retval; - unsigned long junk; - __asm__ __volatile__ ("\n\ - 1: mftbu %1\n\ - mftb %L0\n\ - mftbu %0\n\ - cmpw %0,%1\n\ - bne 1b" - : "=r" (retval), "=r" (junk)); - return retval; - } - -#else - - #error Need implementation of sqlite3Hwtime() for your platform. - - /* - ** To compile without implementing sqlite3Hwtime() for your platform, - ** you can remove the above #error and use the following - ** stub function. You will lose timing support for many - ** of the debugging and testing utilities, but it should at - ** least compile and run. - */ -SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } - -#endif - -#endif /* !defined(_HWTIME_H_) */ - -/************** End of hwtime.h **********************************************/ -/************** Continuing where we left off in os_common.h ******************/ - -static sqlite_uint64 g_start; -static sqlite_uint64 g_elapsed; -#define TIMER_START g_start=sqlite3Hwtime() -#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start -#define TIMER_ELAPSED g_elapsed -#else -#define TIMER_START -#define TIMER_END -#define TIMER_ELAPSED ((sqlite_uint64)0) -#endif - -/* -** If we compile with the SQLITE_TEST macro set, then the following block -** of code will give us the ability to simulate a disk I/O error. This -** is used for testing the I/O recovery logic. -*/ -#ifdef SQLITE_TEST -SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */ -SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ -SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */ -SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */ -SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */ -SQLITE_API int sqlite3_diskfull_pending = 0; -SQLITE_API int sqlite3_diskfull = 0; -#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) -#define SimulateIOError(CODE) \ - if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ - || sqlite3_io_error_pending-- == 1 ) \ - { local_ioerr(); CODE; } -static void local_ioerr(){ - IOTRACE(("IOERR\n")); - sqlite3_io_error_hit++; - if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; -} -#define SimulateDiskfullError(CODE) \ - if( sqlite3_diskfull_pending ){ \ - if( sqlite3_diskfull_pending == 1 ){ \ - local_ioerr(); \ - sqlite3_diskfull = 1; \ - sqlite3_io_error_hit = 1; \ - CODE; \ - }else{ \ - sqlite3_diskfull_pending--; \ - } \ - } -#else -#define SimulateIOErrorBenign(X) -#define SimulateIOError(A) -#define SimulateDiskfullError(A) -#endif - -/* -** When testing, keep a count of the number of open files. -*/ -#ifdef SQLITE_TEST -SQLITE_API int sqlite3_open_file_count = 0; -#define OpenCounter(X) sqlite3_open_file_count+=(X) -#else -#define OpenCounter(X) -#endif - -#endif /* !defined(_OS_COMMON_H_) */ - -/************** End of os_common.h *******************************************/ -/************** Continuing where we left off in os_os2.c *********************/ - -/* Forward references */ -typedef struct os2File os2File; /* The file structure */ -typedef struct os2ShmNode os2ShmNode; /* A shared descritive memory node */ -typedef struct os2ShmLink os2ShmLink; /* A connection to shared-memory */ - -/* -** The os2File structure is subclass of sqlite3_file specific for the OS/2 -** protability layer. -*/ -struct os2File { - const sqlite3_io_methods *pMethod; /* Always the first entry */ - HFILE h; /* Handle for accessing the file */ - int flags; /* Flags provided to os2Open() */ - int locktype; /* Type of lock currently held on this file */ - int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */ - char *zFullPathCp; /* Full path name of this file */ - os2ShmLink *pShmLink; /* Instance of shared memory on this file */ -}; - -#define LOCK_TIMEOUT 10L /* the default locking timeout */ - -/* -** Missing from some versions of the OS/2 toolkit - -** used to allocate from high memory if possible -*/ -#ifndef OBJ_ANY -# define OBJ_ANY 0x00000400 -#endif - -/***************************************************************************** -** The next group of routines implement the I/O methods specified -** by the sqlite3_io_methods object. -******************************************************************************/ - -/* -** Close a file. -*/ -static int os2Close( sqlite3_file *id ){ - APIRET rc; - os2File *pFile = (os2File*)id; - - assert( id!=0 ); - OSTRACE(( "CLOSE %d (%s)\n", pFile->h, pFile->zFullPathCp )); - - rc = DosClose( pFile->h ); - - if( pFile->flags & SQLITE_OPEN_DELETEONCLOSE ) - DosForceDelete( (PSZ)pFile->zFullPathCp ); - - free( pFile->zFullPathCp ); - pFile->zFullPathCp = NULL; - pFile->locktype = NO_LOCK; - pFile->h = (HFILE)-1; - pFile->flags = 0; - - OpenCounter( -1 ); - return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; -} - -/* -** Read data from a file into a buffer. Return SQLITE_OK if all -** bytes were read successfully and SQLITE_IOERR if anything goes -** wrong. -*/ -static int os2Read( - sqlite3_file *id, /* File to read from */ - void *pBuf, /* Write content into this buffer */ - int amt, /* Number of bytes to read */ - sqlite3_int64 offset /* Begin reading at this offset */ -){ - ULONG fileLocation = 0L; - ULONG got; - os2File *pFile = (os2File*)id; - assert( id!=0 ); - SimulateIOError( return SQLITE_IOERR_READ ); - OSTRACE(( "READ %d lock=%d\n", pFile->h, pFile->locktype )); - if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){ - return SQLITE_IOERR; - } - if( DosRead( pFile->h, pBuf, amt, &got ) != NO_ERROR ){ - return SQLITE_IOERR_READ; - } - if( got == (ULONG)amt ) - return SQLITE_OK; - else { - /* Unread portions of the input buffer must be zero-filled */ - memset(&((char*)pBuf)[got], 0, amt-got); - return SQLITE_IOERR_SHORT_READ; - } -} - -/* -** Write data from a buffer into a file. Return SQLITE_OK on success -** or some other error code on failure. -*/ -static int os2Write( - sqlite3_file *id, /* File to write into */ - const void *pBuf, /* The bytes to be written */ - int amt, /* Number of bytes to write */ - sqlite3_int64 offset /* Offset into the file to begin writing at */ -){ - ULONG fileLocation = 0L; - APIRET rc = NO_ERROR; - ULONG wrote; - os2File *pFile = (os2File*)id; - assert( id!=0 ); - SimulateIOError( return SQLITE_IOERR_WRITE ); - SimulateDiskfullError( return SQLITE_FULL ); - OSTRACE(( "WRITE %d lock=%d\n", pFile->h, pFile->locktype )); - if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){ - return SQLITE_IOERR; - } - assert( amt>0 ); - while( amt > 0 && - ( rc = DosWrite( pFile->h, (PVOID)pBuf, amt, &wrote ) ) == NO_ERROR && - wrote > 0 - ){ - amt -= wrote; - pBuf = &((char*)pBuf)[wrote]; - } - - return ( rc != NO_ERROR || amt > (int)wrote ) ? SQLITE_FULL : SQLITE_OK; -} - -/* -** Truncate an open file to a specified size -*/ -static int os2Truncate( sqlite3_file *id, i64 nByte ){ - APIRET rc; - os2File *pFile = (os2File*)id; - assert( id!=0 ); - OSTRACE(( "TRUNCATE %d %lld\n", pFile->h, nByte )); - SimulateIOError( return SQLITE_IOERR_TRUNCATE ); - - /* If the user has configured a chunk-size for this file, truncate the - ** file so that it consists of an integer number of chunks (i.e. the - ** actual file size after the operation may be larger than the requested - ** size). - */ - if( pFile->szChunk ){ - nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; - } - - rc = DosSetFileSize( pFile->h, nByte ); - return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_TRUNCATE; -} - -#ifdef SQLITE_TEST -/* -** Count the number of fullsyncs and normal syncs. This is used to test -** that syncs and fullsyncs are occuring at the right times. -*/ -SQLITE_API int sqlite3_sync_count = 0; -SQLITE_API int sqlite3_fullsync_count = 0; -#endif - -/* -** Make sure all writes to a particular file are committed to disk. -*/ -static int os2Sync( sqlite3_file *id, int flags ){ - os2File *pFile = (os2File*)id; - OSTRACE(( "SYNC %d lock=%d\n", pFile->h, pFile->locktype )); -#ifdef SQLITE_TEST - if( flags & SQLITE_SYNC_FULL){ - sqlite3_fullsync_count++; - } - sqlite3_sync_count++; -#endif - /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a - ** no-op - */ -#ifdef SQLITE_NO_SYNC - UNUSED_PARAMETER(pFile); - return SQLITE_OK; -#else - return DosResetBuffer( pFile->h ) == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; -#endif -} - -/* -** Determine the current size of a file in bytes -*/ -static int os2FileSize( sqlite3_file *id, sqlite3_int64 *pSize ){ - APIRET rc = NO_ERROR; - FILESTATUS3 fsts3FileInfo; - memset(&fsts3FileInfo, 0, sizeof(fsts3FileInfo)); - assert( id!=0 ); - SimulateIOError( return SQLITE_IOERR_FSTAT ); - rc = DosQueryFileInfo( ((os2File*)id)->h, FIL_STANDARD, &fsts3FileInfo, sizeof(FILESTATUS3) ); - if( rc == NO_ERROR ){ - *pSize = fsts3FileInfo.cbFile; - return SQLITE_OK; - }else{ - return SQLITE_IOERR_FSTAT; - } -} - -/* -** Acquire a reader lock. -*/ -static int getReadLock( os2File *pFile ){ - FILELOCK LockArea, - UnlockArea; - APIRET res; - memset(&LockArea, 0, sizeof(LockArea)); - memset(&UnlockArea, 0, sizeof(UnlockArea)); - LockArea.lOffset = SHARED_FIRST; - LockArea.lRange = SHARED_SIZE; - UnlockArea.lOffset = 0L; - UnlockArea.lRange = 0L; - res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L ); - OSTRACE(( "GETREADLOCK %d res=%d\n", pFile->h, res )); - return res; -} - -/* -** Undo a readlock -*/ -static int unlockReadLock( os2File *id ){ - FILELOCK LockArea, - UnlockArea; - APIRET res; - memset(&LockArea, 0, sizeof(LockArea)); - memset(&UnlockArea, 0, sizeof(UnlockArea)); - LockArea.lOffset = 0L; - LockArea.lRange = 0L; - UnlockArea.lOffset = SHARED_FIRST; - UnlockArea.lRange = SHARED_SIZE; - res = DosSetFileLocks( id->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L ); - OSTRACE(( "UNLOCK-READLOCK file handle=%d res=%d?\n", id->h, res )); - return res; -} - -/* -** Lock the file with the lock specified by parameter locktype - one -** of the following: -** -** (1) SHARED_LOCK -** (2) RESERVED_LOCK -** (3) PENDING_LOCK -** (4) EXCLUSIVE_LOCK -** -** Sometimes when requesting one lock state, additional lock states -** are inserted in between. The locking might fail on one of the later -** transitions leaving the lock state different from what it started but -** still short of its goal. The following chart shows the allowed -** transitions and the inserted intermediate states: -** -** UNLOCKED -> SHARED -** SHARED -> RESERVED -** SHARED -> (PENDING) -> EXCLUSIVE -** RESERVED -> (PENDING) -> EXCLUSIVE -** PENDING -> EXCLUSIVE -** -** This routine will only increase a lock. The os2Unlock() routine -** erases all locks at once and returns us immediately to locking level 0. -** It is not possible to lower the locking level one step at a time. You -** must go straight to locking level 0. -*/ -static int os2Lock( sqlite3_file *id, int locktype ){ - int rc = SQLITE_OK; /* Return code from subroutines */ - APIRET res = NO_ERROR; /* Result of an OS/2 lock call */ - int newLocktype; /* Set pFile->locktype to this value before exiting */ - int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ - FILELOCK LockArea, - UnlockArea; - os2File *pFile = (os2File*)id; - memset(&LockArea, 0, sizeof(LockArea)); - memset(&UnlockArea, 0, sizeof(UnlockArea)); - assert( pFile!=0 ); - OSTRACE(( "LOCK %d %d was %d\n", pFile->h, locktype, pFile->locktype )); - - /* If there is already a lock of this type or more restrictive on the - ** os2File, do nothing. Don't use the end_lock: exit path, as - ** sqlite3_mutex_enter() hasn't been called yet. - */ - if( pFile->locktype>=locktype ){ - OSTRACE(( "LOCK %d %d ok (already held)\n", pFile->h, locktype )); - return SQLITE_OK; - } - - /* Make sure the locking sequence is correct - */ - assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); - assert( locktype!=PENDING_LOCK ); - assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); - - /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or - ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of - ** the PENDING_LOCK byte is temporary. - */ - newLocktype = pFile->locktype; - if( pFile->locktype==NO_LOCK - || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK) - ){ - LockArea.lOffset = PENDING_BYTE; - LockArea.lRange = 1L; - UnlockArea.lOffset = 0L; - UnlockArea.lRange = 0L; - - /* wait longer than LOCK_TIMEOUT here not to have to try multiple times */ - res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 100L, 0L ); - if( res == NO_ERROR ){ - gotPendingLock = 1; - OSTRACE(( "LOCK %d pending lock boolean set. res=%d\n", pFile->h, res )); - } - } - - /* Acquire a shared lock - */ - if( locktype==SHARED_LOCK && res == NO_ERROR ){ - assert( pFile->locktype==NO_LOCK ); - res = getReadLock(pFile); - if( res == NO_ERROR ){ - newLocktype = SHARED_LOCK; - } - OSTRACE(( "LOCK %d acquire shared lock. res=%d\n", pFile->h, res )); - } - - /* Acquire a RESERVED lock - */ - if( locktype==RESERVED_LOCK && res == NO_ERROR ){ - assert( pFile->locktype==SHARED_LOCK ); - LockArea.lOffset = RESERVED_BYTE; - LockArea.lRange = 1L; - UnlockArea.lOffset = 0L; - UnlockArea.lRange = 0L; - res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); - if( res == NO_ERROR ){ - newLocktype = RESERVED_LOCK; - } - OSTRACE(( "LOCK %d acquire reserved lock. res=%d\n", pFile->h, res )); - } - - /* Acquire a PENDING lock - */ - if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){ - newLocktype = PENDING_LOCK; - gotPendingLock = 0; - OSTRACE(( "LOCK %d acquire pending lock. pending lock boolean unset.\n", - pFile->h )); - } - - /* Acquire an EXCLUSIVE lock - */ - if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){ - assert( pFile->locktype>=SHARED_LOCK ); - res = unlockReadLock(pFile); - OSTRACE(( "unreadlock = %d\n", res )); - LockArea.lOffset = SHARED_FIRST; - LockArea.lRange = SHARED_SIZE; - UnlockArea.lOffset = 0L; - UnlockArea.lRange = 0L; - res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); - if( res == NO_ERROR ){ - newLocktype = EXCLUSIVE_LOCK; - }else{ - OSTRACE(( "OS/2 error-code = %d\n", res )); - getReadLock(pFile); - } - OSTRACE(( "LOCK %d acquire exclusive lock. res=%d\n", pFile->h, res )); - } - - /* If we are holding a PENDING lock that ought to be released, then - ** release it now. - */ - if( gotPendingLock && locktype==SHARED_LOCK ){ - int r; - LockArea.lOffset = 0L; - LockArea.lRange = 0L; - UnlockArea.lOffset = PENDING_BYTE; - UnlockArea.lRange = 1L; - r = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); - OSTRACE(( "LOCK %d unlocking pending/is shared. r=%d\n", pFile->h, r )); - } - - /* Update the state of the lock has held in the file descriptor then - ** return the appropriate result code. - */ - if( res == NO_ERROR ){ - rc = SQLITE_OK; - }else{ - OSTRACE(( "LOCK FAILED %d trying for %d but got %d\n", pFile->h, - locktype, newLocktype )); - rc = SQLITE_BUSY; - } - pFile->locktype = newLocktype; - OSTRACE(( "LOCK %d now %d\n", pFile->h, pFile->locktype )); - return rc; -} - -/* -** This routine checks if there is a RESERVED lock held on the specified -** file by this or any other process. If such a lock is held, return -** non-zero, otherwise zero. -*/ -static int os2CheckReservedLock( sqlite3_file *id, int *pOut ){ - int r = 0; - os2File *pFile = (os2File*)id; - assert( pFile!=0 ); - if( pFile->locktype>=RESERVED_LOCK ){ - r = 1; - OSTRACE(( "TEST WR-LOCK %d %d (local)\n", pFile->h, r )); - }else{ - FILELOCK LockArea, - UnlockArea; - APIRET rc = NO_ERROR; - memset(&LockArea, 0, sizeof(LockArea)); - memset(&UnlockArea, 0, sizeof(UnlockArea)); - LockArea.lOffset = RESERVED_BYTE; - LockArea.lRange = 1L; - UnlockArea.lOffset = 0L; - UnlockArea.lRange = 0L; - rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); - OSTRACE(( "TEST WR-LOCK %d lock reserved byte rc=%d\n", pFile->h, rc )); - if( rc == NO_ERROR ){ - APIRET rcu = NO_ERROR; /* return code for unlocking */ - LockArea.lOffset = 0L; - LockArea.lRange = 0L; - UnlockArea.lOffset = RESERVED_BYTE; - UnlockArea.lRange = 1L; - rcu = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); - OSTRACE(( "TEST WR-LOCK %d unlock reserved byte r=%d\n", pFile->h, rcu )); - } - r = !(rc == NO_ERROR); - OSTRACE(( "TEST WR-LOCK %d %d (remote)\n", pFile->h, r )); - } - *pOut = r; - return SQLITE_OK; -} - -/* -** Lower the locking level on file descriptor id to locktype. locktype -** must be either NO_LOCK or SHARED_LOCK. -** -** If the locking level of the file descriptor is already at or below -** the requested locking level, this routine is a no-op. -** -** It is not possible for this routine to fail if the second argument -** is NO_LOCK. If the second argument is SHARED_LOCK then this routine -** might return SQLITE_IOERR; -*/ -static int os2Unlock( sqlite3_file *id, int locktype ){ - int type; - os2File *pFile = (os2File*)id; - APIRET rc = SQLITE_OK; - APIRET res = NO_ERROR; - FILELOCK LockArea, - UnlockArea; - memset(&LockArea, 0, sizeof(LockArea)); - memset(&UnlockArea, 0, sizeof(UnlockArea)); - assert( pFile!=0 ); - assert( locktype<=SHARED_LOCK ); - OSTRACE(( "UNLOCK %d to %d was %d\n", pFile->h, locktype, pFile->locktype )); - type = pFile->locktype; - if( type>=EXCLUSIVE_LOCK ){ - LockArea.lOffset = 0L; - LockArea.lRange = 0L; - UnlockArea.lOffset = SHARED_FIRST; - UnlockArea.lRange = SHARED_SIZE; - res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); - OSTRACE(( "UNLOCK %d exclusive lock res=%d\n", pFile->h, res )); - if( locktype==SHARED_LOCK && getReadLock(pFile) != NO_ERROR ){ - /* This should never happen. We should always be able to - ** reacquire the read lock */ - OSTRACE(( "UNLOCK %d to %d getReadLock() failed\n", pFile->h, locktype )); - rc = SQLITE_IOERR_UNLOCK; - } - } - if( type>=RESERVED_LOCK ){ - LockArea.lOffset = 0L; - LockArea.lRange = 0L; - UnlockArea.lOffset = RESERVED_BYTE; - UnlockArea.lRange = 1L; - res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); - OSTRACE(( "UNLOCK %d reserved res=%d\n", pFile->h, res )); - } - if( locktype==NO_LOCK && type>=SHARED_LOCK ){ - res = unlockReadLock(pFile); - OSTRACE(( "UNLOCK %d is %d want %d res=%d\n", - pFile->h, type, locktype, res )); - } - if( type>=PENDING_LOCK ){ - LockArea.lOffset = 0L; - LockArea.lRange = 0L; - UnlockArea.lOffset = PENDING_BYTE; - UnlockArea.lRange = 1L; - res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); - OSTRACE(( "UNLOCK %d pending res=%d\n", pFile->h, res )); - } - pFile->locktype = locktype; - OSTRACE(( "UNLOCK %d now %d\n", pFile->h, pFile->locktype )); - return rc; -} - -/* -** Control and query of the open file handle. -*/ -static int os2FileControl(sqlite3_file *id, int op, void *pArg){ - switch( op ){ - case SQLITE_FCNTL_LOCKSTATE: { - *(int*)pArg = ((os2File*)id)->locktype; - OSTRACE(( "FCNTL_LOCKSTATE %d lock=%d\n", - ((os2File*)id)->h, ((os2File*)id)->locktype )); - return SQLITE_OK; - } - case SQLITE_FCNTL_CHUNK_SIZE: { - ((os2File*)id)->szChunk = *(int*)pArg; - return SQLITE_OK; - } - case SQLITE_FCNTL_SIZE_HINT: { - sqlite3_int64 sz = *(sqlite3_int64*)pArg; - SimulateIOErrorBenign(1); - os2Truncate(id, sz); - SimulateIOErrorBenign(0); - return SQLITE_OK; - } - case SQLITE_FCNTL_SYNC_OMITTED: { - return SQLITE_OK; - } - } - return SQLITE_NOTFOUND; -} - -/* -** Return the sector size in bytes of the underlying block device for -** the specified file. This is almost always 512 bytes, but may be -** larger for some devices. -** -** SQLite code assumes this function cannot fail. It also assumes that -** if two files are created in the same file-system directory (i.e. -** a database and its journal file) that the sector size will be the -** same for both. -*/ -static int os2SectorSize(sqlite3_file *id){ - UNUSED_PARAMETER(id); - return SQLITE_DEFAULT_SECTOR_SIZE; -} - -/* -** Return a vector of device characteristics. -*/ -static int os2DeviceCharacteristics(sqlite3_file *id){ - UNUSED_PARAMETER(id); - return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN; -} - - -/* -** Character set conversion objects used by conversion routines. -*/ -static UconvObject ucUtf8 = NULL; /* convert between UTF-8 and UCS-2 */ -static UconvObject uclCp = NULL; /* convert between local codepage and UCS-2 */ - -/* -** Helper function to initialize the conversion objects from and to UTF-8. -*/ -static void initUconvObjects( void ){ - if( UniCreateUconvObject( UTF_8, &ucUtf8 ) != ULS_SUCCESS ) - ucUtf8 = NULL; - if ( UniCreateUconvObject( (UniChar *)L"@path=yes", &uclCp ) != ULS_SUCCESS ) - uclCp = NULL; -} - -/* -** Helper function to free the conversion objects from and to UTF-8. -*/ -static void freeUconvObjects( void ){ - if ( ucUtf8 ) - UniFreeUconvObject( ucUtf8 ); - if ( uclCp ) - UniFreeUconvObject( uclCp ); - ucUtf8 = NULL; - uclCp = NULL; -} - -/* -** Helper function to convert UTF-8 filenames to local OS/2 codepage. -** The two-step process: first convert the incoming UTF-8 string -** into UCS-2 and then from UCS-2 to the current codepage. -** The returned char pointer has to be freed. -*/ -static char *convertUtf8PathToCp( const char *in ){ - UniChar tempPath[CCHMAXPATH]; - char *out = (char *)calloc( CCHMAXPATH, 1 ); - - if( !out ) - return NULL; - - if( !ucUtf8 || !uclCp ) - initUconvObjects(); - - /* determine string for the conversion of UTF-8 which is CP1208 */ - if( UniStrToUcs( ucUtf8, tempPath, (char *)in, CCHMAXPATH ) != ULS_SUCCESS ) - return out; /* if conversion fails, return the empty string */ - - /* conversion for current codepage which can be used for paths */ - UniStrFromUcs( uclCp, out, tempPath, CCHMAXPATH ); - - return out; -} - -/* -** Helper function to convert filenames from local codepage to UTF-8. -** The two-step process: first convert the incoming codepage-specific -** string into UCS-2 and then from UCS-2 to the codepage of UTF-8. -** The returned char pointer has to be freed. -** -** This function is non-static to be able to use this in shell.c and -** similar applications that take command line arguments. -*/ -char *convertCpPathToUtf8( const char *in ){ - UniChar tempPath[CCHMAXPATH]; - char *out = (char *)calloc( CCHMAXPATH, 1 ); - - if( !out ) - return NULL; - - if( !ucUtf8 || !uclCp ) - initUconvObjects(); - - /* conversion for current codepage which can be used for paths */ - if( UniStrToUcs( uclCp, tempPath, (char *)in, CCHMAXPATH ) != ULS_SUCCESS ) - return out; /* if conversion fails, return the empty string */ - - /* determine string for the conversion of UTF-8 which is CP1208 */ - UniStrFromUcs( ucUtf8, out, tempPath, CCHMAXPATH ); - - return out; -} - - -#ifndef SQLITE_OMIT_WAL - -/* -** Use main database file for interprocess locking. If un-defined -** a separate file is created for this purpose. The file will be -** used only to set file locks. There will be no data written to it. -*/ -#define SQLITE_OS2_NO_WAL_LOCK_FILE - -#if 0 -static void _ERR_TRACE( const char *fmt, ... ) { - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - fflush(stderr); -} -#define ERR_TRACE(rc, msg) \ - if( (rc) != SQLITE_OK ) _ERR_TRACE msg; -#else -#define ERR_TRACE(rc, msg) -#endif - -/* -** Helper functions to obtain and relinquish the global mutex. The -** global mutex is used to protect os2ShmNodeList. -** -** Function os2ShmMutexHeld() is used to assert() that the global mutex -** is held when required. This function is only used as part of assert() -** statements. e.g. -** -** os2ShmEnterMutex() -** assert( os2ShmMutexHeld() ); -** os2ShmLeaveMutex() -*/ -static void os2ShmEnterMutex(void){ - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); -} -static void os2ShmLeaveMutex(void){ - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); -} -#ifdef SQLITE_DEBUG -static int os2ShmMutexHeld(void) { - return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); -} -int GetCurrentProcessId(void) { - PPIB pib; - DosGetInfoBlocks(NULL, &pib); - return (int)pib->pib_ulpid; -} -#endif - -/* -** Object used to represent a the shared memory area for a single log file. -** When multiple threads all reference the same log-summary, each thread has -** its own os2File object, but they all point to a single instance of this -** object. In other words, each log-summary is opened only once per process. -** -** os2ShmMutexHeld() must be true when creating or destroying -** this object or while reading or writing the following fields: -** -** nRef -** pNext -** -** The following fields are read-only after the object is created: -** -** szRegion -** hLockFile -** shmBaseName -** -** Either os2ShmNode.mutex must be held or os2ShmNode.nRef==0 and -** os2ShmMutexHeld() is true when reading or writing any other field -** in this structure. -** -*/ -struct os2ShmNode { - sqlite3_mutex *mutex; /* Mutex to access this object */ - os2ShmNode *pNext; /* Next in list of all os2ShmNode objects */ - - int szRegion; /* Size of shared-memory regions */ - - int nRegion; /* Size of array apRegion */ - void **apRegion; /* Array of pointers to shared-memory regions */ - - int nRef; /* Number of os2ShmLink objects pointing to this */ - os2ShmLink *pFirst; /* First os2ShmLink object pointing to this */ - - HFILE hLockFile; /* File used for inter-process memory locking */ - char shmBaseName[1]; /* Name of the memory object !!! must last !!! */ -}; - - -/* -** Structure used internally by this VFS to record the state of an -** open shared memory connection. -** -** The following fields are initialized when this object is created and -** are read-only thereafter: -** -** os2Shm.pShmNode -** os2Shm.id -** -** All other fields are read/write. The os2Shm.pShmNode->mutex must be held -** while accessing any read/write fields. -*/ -struct os2ShmLink { - os2ShmNode *pShmNode; /* The underlying os2ShmNode object */ - os2ShmLink *pNext; /* Next os2Shm with the same os2ShmNode */ - u32 sharedMask; /* Mask of shared locks held */ - u32 exclMask; /* Mask of exclusive locks held */ -#ifdef SQLITE_DEBUG - u8 id; /* Id of this connection with its os2ShmNode */ -#endif -}; - - -/* -** A global list of all os2ShmNode objects. -** -** The os2ShmMutexHeld() must be true while reading or writing this list. -*/ -static os2ShmNode *os2ShmNodeList = NULL; - -/* -** Constants used for locking -*/ -#ifdef SQLITE_OS2_NO_WAL_LOCK_FILE -#define OS2_SHM_BASE (PENDING_BYTE + 0x10000) /* first lock byte */ -#else -#define OS2_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ -#endif - -#define OS2_SHM_DMS (OS2_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ - -/* -** Apply advisory locks for all n bytes beginning at ofst. -*/ -#define _SHM_UNLCK 1 /* no lock */ -#define _SHM_RDLCK 2 /* shared lock, no wait */ -#define _SHM_WRLCK 3 /* exlusive lock, no wait */ -#define _SHM_WRLCK_WAIT 4 /* exclusive lock, wait */ -static int os2ShmSystemLock( - os2ShmNode *pNode, /* Apply locks to this open shared-memory segment */ - int lockType, /* _SHM_UNLCK, _SHM_RDLCK, _SHM_WRLCK or _SHM_WRLCK_WAIT */ - int ofst, /* Offset to first byte to be locked/unlocked */ - int nByte /* Number of bytes to lock or unlock */ -){ - APIRET rc; - FILELOCK area; - ULONG mode, timeout; - - /* Access to the os2ShmNode object is serialized by the caller */ - assert( sqlite3_mutex_held(pNode->mutex) || pNode->nRef==0 ); - - mode = 1; /* shared lock */ - timeout = 0; /* no wait */ - area.lOffset = ofst; - area.lRange = nByte; - - switch( lockType ) { - case _SHM_WRLCK_WAIT: - timeout = (ULONG)-1; /* wait forever */ - case _SHM_WRLCK: - mode = 0; /* exclusive lock */ - case _SHM_RDLCK: - rc = DosSetFileLocks(pNode->hLockFile, - NULL, &area, timeout, mode); - break; - /* case _SHM_UNLCK: */ - default: - rc = DosSetFileLocks(pNode->hLockFile, - &area, NULL, 0, 0); - break; - } - - OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n", - pNode->hLockFile, - rc==SQLITE_OK ? "ok" : "failed", - lockType==_SHM_UNLCK ? "Unlock" : "Lock", - rc)); - - ERR_TRACE(rc, ("os2ShmSystemLock: %d %s\n", rc, pNode->shmBaseName)) - - return ( rc == 0 ) ? SQLITE_OK : SQLITE_BUSY; -} - -/* -** Find an os2ShmNode in global list or allocate a new one, if not found. -** -** This is not a VFS shared-memory method; it is a utility function called -** by VFS shared-memory methods. -*/ -static int os2OpenSharedMemory( os2File *fd, int szRegion ) { - os2ShmLink *pLink; - os2ShmNode *pNode; - int cbShmName, rc = SQLITE_OK; - char shmName[CCHMAXPATH + 30]; -#ifndef SQLITE_OS2_NO_WAL_LOCK_FILE - ULONG action; -#endif - - /* We need some additional space at the end to append the region number */ - cbShmName = sprintf(shmName, "\\SHAREMEM\\%s", fd->zFullPathCp ); - if( cbShmName >= CCHMAXPATH-8 ) - return SQLITE_IOERR_SHMOPEN; - - /* Replace colon in file name to form a valid shared memory name */ - shmName[10+1] = '!'; - - /* Allocate link object (we free it later in case of failure) */ - pLink = sqlite3_malloc( sizeof(*pLink) ); - if( !pLink ) - return SQLITE_NOMEM; - - /* Access node list */ - os2ShmEnterMutex(); - - /* Find node by it's shared memory base name */ - for( pNode = os2ShmNodeList; - pNode && stricmp(shmName, pNode->shmBaseName) != 0; - pNode = pNode->pNext ) ; - - /* Not found: allocate a new node */ - if( !pNode ) { - pNode = sqlite3_malloc( sizeof(*pNode) + cbShmName ); - if( pNode ) { - memset(pNode, 0, sizeof(*pNode) ); - pNode->szRegion = szRegion; - pNode->hLockFile = (HFILE)-1; - strcpy(pNode->shmBaseName, shmName); - -#ifdef SQLITE_OS2_NO_WAL_LOCK_FILE - if( DosDupHandle(fd->h, &pNode->hLockFile) != 0 ) { -#else - sprintf(shmName, "%s-lck", fd->zFullPathCp); - if( DosOpen((PSZ)shmName, &pNode->hLockFile, &action, 0, FILE_NORMAL, - OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW, - OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | - OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR, - NULL) != 0 ) { -#endif - sqlite3_free(pNode); - rc = SQLITE_IOERR; - } else { - pNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - if( !pNode->mutex ) { - sqlite3_free(pNode); - rc = SQLITE_NOMEM; - } - } - } else { - rc = SQLITE_NOMEM; - } - - if( rc == SQLITE_OK ) { - pNode->pNext = os2ShmNodeList; - os2ShmNodeList = pNode; - } else { - pNode = NULL; - } - } else if( pNode->szRegion != szRegion ) { - rc = SQLITE_IOERR_SHMSIZE; - pNode = NULL; - } - - if( pNode ) { - sqlite3_mutex_enter(pNode->mutex); - - memset(pLink, 0, sizeof(*pLink)); - - pLink->pShmNode = pNode; - pLink->pNext = pNode->pFirst; - pNode->pFirst = pLink; - pNode->nRef++; - - fd->pShmLink = pLink; - - sqlite3_mutex_leave(pNode->mutex); - - } else { - /* Error occured. Free our link object. */ - sqlite3_free(pLink); - } - - os2ShmLeaveMutex(); - - ERR_TRACE(rc, ("os2OpenSharedMemory: %d %s\n", rc, fd->zFullPathCp)) - - return rc; -} - -/* -** Purge the os2ShmNodeList list of all entries with nRef==0. -** -** This is not a VFS shared-memory method; it is a utility function called -** by VFS shared-memory methods. -*/ -static void os2PurgeShmNodes( int deleteFlag ) { - os2ShmNode *pNode; - os2ShmNode **ppNode; - - os2ShmEnterMutex(); - - ppNode = &os2ShmNodeList; - - while( *ppNode ) { - pNode = *ppNode; - - if( pNode->nRef == 0 ) { - *ppNode = pNode->pNext; - - if( pNode->apRegion ) { - /* Prevent other processes from resizing the shared memory */ - os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1); - - while( pNode->nRegion-- ) { -#ifdef SQLITE_DEBUG - int rc = -#endif - DosFreeMem(pNode->apRegion[pNode->nRegion]); - - OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n", - (int)GetCurrentProcessId(), pNode->nRegion, - rc == 0 ? "ok" : "failed")); - } - - /* Allow other processes to resize the shared memory */ - os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1); - - sqlite3_free(pNode->apRegion); - } - - DosClose(pNode->hLockFile); - -#ifndef SQLITE_OS2_NO_WAL_LOCK_FILE - if( deleteFlag ) { - char fileName[CCHMAXPATH]; - /* Skip "\\SHAREMEM\\" */ - sprintf(fileName, "%s-lck", pNode->shmBaseName + 10); - /* restore colon */ - fileName[1] = ':'; - - DosForceDelete(fileName); - } -#endif - - sqlite3_mutex_free(pNode->mutex); - - sqlite3_free(pNode); - - } else { - ppNode = &pNode->pNext; - } - } - - os2ShmLeaveMutex(); -} - -/* -** This function is called to obtain a pointer to region iRegion of the -** shared-memory associated with the database file id. Shared-memory regions -** are numbered starting from zero. Each shared-memory region is szRegion -** bytes in size. -** -** If an error occurs, an error code is returned and *pp is set to NULL. -** -** Otherwise, if the bExtend parameter is 0 and the requested shared-memory -** region has not been allocated (by any client, including one running in a -** separate process), then *pp is set to NULL and SQLITE_OK returned. If -** bExtend is non-zero and the requested shared-memory region has not yet -** been allocated, it is allocated by this function. -** -** If the shared-memory region has already been allocated or is allocated by -** this call as described above, then it is mapped into this processes -** address space (if it is not already), *pp is set to point to the mapped -** memory and SQLITE_OK returned. -*/ -static int os2ShmMap( - sqlite3_file *id, /* Handle open on database file */ - int iRegion, /* Region to retrieve */ - int szRegion, /* Size of regions */ - int bExtend, /* True to extend block if necessary */ - void volatile **pp /* OUT: Mapped memory */ -){ - PVOID pvTemp; - void **apRegion; - os2ShmNode *pNode; - int n, rc = SQLITE_OK; - char shmName[CCHMAXPATH]; - os2File *pFile = (os2File*)id; - - *pp = NULL; - - if( !pFile->pShmLink ) - rc = os2OpenSharedMemory( pFile, szRegion ); - - if( rc == SQLITE_OK ) { - pNode = pFile->pShmLink->pShmNode ; - - sqlite3_mutex_enter(pNode->mutex); - - assert( szRegion==pNode->szRegion ); - - /* Unmapped region ? */ - if( iRegion >= pNode->nRegion ) { - /* Prevent other processes from resizing the shared memory */ - os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1); - - apRegion = sqlite3_realloc( - pNode->apRegion, (iRegion + 1) * sizeof(apRegion[0])); - - if( apRegion ) { - pNode->apRegion = apRegion; - - while( pNode->nRegion <= iRegion ) { - sprintf(shmName, "%s-%u", - pNode->shmBaseName, pNode->nRegion); - - if( DosGetNamedSharedMem(&pvTemp, (PSZ)shmName, - PAG_READ | PAG_WRITE) != NO_ERROR ) { - if( !bExtend ) - break; - - if( DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion, - PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_ANY) != NO_ERROR && - DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion, - PAG_READ | PAG_WRITE | PAG_COMMIT) != NO_ERROR ) { - rc = SQLITE_NOMEM; - break; - } - } - - apRegion[pNode->nRegion++] = pvTemp; - } - - /* zero out remaining entries */ - for( n = pNode->nRegion; n <= iRegion; n++ ) - pNode->apRegion[n] = NULL; - - /* Return this region (maybe zero) */ - *pp = pNode->apRegion[iRegion]; - } else { - rc = SQLITE_NOMEM; - } - - /* Allow other processes to resize the shared memory */ - os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1); - - } else { - /* Region has been mapped previously */ - *pp = pNode->apRegion[iRegion]; - } - - sqlite3_mutex_leave(pNode->mutex); - } - - ERR_TRACE(rc, ("os2ShmMap: %s iRgn = %d, szRgn = %d, bExt = %d : %d\n", - pFile->zFullPathCp, iRegion, szRegion, bExtend, rc)) - - return rc; -} - -/* -** Close a connection to shared-memory. Delete the underlying -** storage if deleteFlag is true. -** -** If there is no shared memory associated with the connection then this -** routine is a harmless no-op. -*/ -static int os2ShmUnmap( - sqlite3_file *id, /* The underlying database file */ - int deleteFlag /* Delete shared-memory if true */ -){ - os2File *pFile = (os2File*)id; - os2ShmLink *pLink = pFile->pShmLink; - - if( pLink ) { - int nRef = -1; - os2ShmLink **ppLink; - os2ShmNode *pNode = pLink->pShmNode; - - sqlite3_mutex_enter(pNode->mutex); - - for( ppLink = &pNode->pFirst; - *ppLink && *ppLink != pLink; - ppLink = &(*ppLink)->pNext ) ; - - assert(*ppLink); - - if( *ppLink ) { - *ppLink = pLink->pNext; - nRef = --pNode->nRef; - } else { - ERR_TRACE(1, ("os2ShmUnmap: link not found ! %s\n", - pNode->shmBaseName)) - } - - pFile->pShmLink = NULL; - sqlite3_free(pLink); - - sqlite3_mutex_leave(pNode->mutex); - - if( nRef == 0 ) - os2PurgeShmNodes( deleteFlag ); - } - - return SQLITE_OK; -} - -/* -** Change the lock state for a shared-memory segment. -** -** Note that the relationship between SHAREd and EXCLUSIVE locks is a little -** different here than in posix. In xShmLock(), one can go from unlocked -** to shared and back or from unlocked to exclusive and back. But one may -** not go from shared to exclusive or from exclusive to shared. -*/ -static int os2ShmLock( - sqlite3_file *id, /* Database file holding the shared memory */ - int ofst, /* First lock to acquire or release */ - int n, /* Number of locks to acquire or release */ - int flags /* What to do with the lock */ -){ - u32 mask; /* Mask of locks to take or release */ - int rc = SQLITE_OK; /* Result code */ - os2File *pFile = (os2File*)id; - os2ShmLink *p = pFile->pShmLink; /* The shared memory being locked */ - os2ShmLink *pX; /* For looping over all siblings */ - os2ShmNode *pShmNode = p->pShmNode; /* Our node */ - - assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); - assert( n>=1 ); - assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) - || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) - || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) - || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); - assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); - - mask = (u32)((1U<<(ofst+n)) - (1U<1 || mask==(1<mutex); - - if( flags & SQLITE_SHM_UNLOCK ){ - u32 allMask = 0; /* Mask of locks held by siblings */ - - /* See if any siblings hold this same lock */ - for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ - if( pX==p ) continue; - assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); - allMask |= pX->sharedMask; - } - - /* Unlock the system-level locks */ - if( (mask & allMask)==0 ){ - rc = os2ShmSystemLock(pShmNode, _SHM_UNLCK, ofst+OS2_SHM_BASE, n); - }else{ - rc = SQLITE_OK; - } - - /* Undo the local locks */ - if( rc==SQLITE_OK ){ - p->exclMask &= ~mask; - p->sharedMask &= ~mask; - } - }else if( flags & SQLITE_SHM_SHARED ){ - u32 allShared = 0; /* Union of locks held by connections other than "p" */ - - /* Find out which shared locks are already held by sibling connections. - ** If any sibling already holds an exclusive lock, go ahead and return - ** SQLITE_BUSY. - */ - for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ - if( (pX->exclMask & mask)!=0 ){ - rc = SQLITE_BUSY; - break; - } - allShared |= pX->sharedMask; - } - - /* Get shared locks at the system level, if necessary */ - if( rc==SQLITE_OK ){ - if( (allShared & mask)==0 ){ - rc = os2ShmSystemLock(pShmNode, _SHM_RDLCK, ofst+OS2_SHM_BASE, n); - }else{ - rc = SQLITE_OK; - } - } - - /* Get the local shared locks */ - if( rc==SQLITE_OK ){ - p->sharedMask |= mask; - } - }else{ - /* Make sure no sibling connections hold locks that will block this - ** lock. If any do, return SQLITE_BUSY right away. - */ - for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ - if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ - rc = SQLITE_BUSY; - break; - } - } - - /* Get the exclusive locks at the system level. Then if successful - ** also mark the local connection as being locked. - */ - if( rc==SQLITE_OK ){ - rc = os2ShmSystemLock(pShmNode, _SHM_WRLCK, ofst+OS2_SHM_BASE, n); - if( rc==SQLITE_OK ){ - assert( (p->sharedMask & mask)==0 ); - p->exclMask |= mask; - } - } - } - - sqlite3_mutex_leave(pShmNode->mutex); - - OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n", - p->id, (int)GetCurrentProcessId(), p->sharedMask, p->exclMask, - rc ? "failed" : "ok")); - - ERR_TRACE(rc, ("os2ShmLock: ofst = %d, n = %d, flags = 0x%x -> %d \n", - ofst, n, flags, rc)) - - return rc; -} - -/* -** Implement a memory barrier or memory fence on shared memory. -** -** All loads and stores begun before the barrier must complete before -** any load or store begun after the barrier. -*/ -static void os2ShmBarrier( - sqlite3_file *id /* Database file holding the shared memory */ -){ - UNUSED_PARAMETER(id); - os2ShmEnterMutex(); - os2ShmLeaveMutex(); -} - -#else -# define os2ShmMap 0 -# define os2ShmLock 0 -# define os2ShmBarrier 0 -# define os2ShmUnmap 0 -#endif /* #ifndef SQLITE_OMIT_WAL */ - - -/* -** This vector defines all the methods that can operate on an -** sqlite3_file for os2. -*/ -static const sqlite3_io_methods os2IoMethod = { - 2, /* iVersion */ - os2Close, /* xClose */ - os2Read, /* xRead */ - os2Write, /* xWrite */ - os2Truncate, /* xTruncate */ - os2Sync, /* xSync */ - os2FileSize, /* xFileSize */ - os2Lock, /* xLock */ - os2Unlock, /* xUnlock */ - os2CheckReservedLock, /* xCheckReservedLock */ - os2FileControl, /* xFileControl */ - os2SectorSize, /* xSectorSize */ - os2DeviceCharacteristics, /* xDeviceCharacteristics */ - os2ShmMap, /* xShmMap */ - os2ShmLock, /* xShmLock */ - os2ShmBarrier, /* xShmBarrier */ - os2ShmUnmap /* xShmUnmap */ -}; - - -/*************************************************************************** -** Here ends the I/O methods that form the sqlite3_io_methods object. -** -** The next block of code implements the VFS methods. -****************************************************************************/ - -/* -** Create a temporary file name in zBuf. zBuf must be big enough to -** hold at pVfs->mxPathname characters. -*/ -static int getTempname(int nBuf, char *zBuf ){ - static const char zChars[] = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789"; - int i, j; - PSZ zTempPathCp; - char zTempPath[CCHMAXPATH]; - ULONG ulDriveNum, ulDriveMap; - - /* It's odd to simulate an io-error here, but really this is just - ** using the io-error infrastructure to test that SQLite handles this - ** function failing. - */ - SimulateIOError( return SQLITE_IOERR ); - - if( sqlite3_temp_directory ) { - sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", sqlite3_temp_directory); - } else if( DosScanEnv( (PSZ)"TEMP", &zTempPathCp ) == NO_ERROR || - DosScanEnv( (PSZ)"TMP", &zTempPathCp ) == NO_ERROR || - DosScanEnv( (PSZ)"TMPDIR", &zTempPathCp ) == NO_ERROR ) { - char *zTempPathUTF = convertCpPathToUtf8( (char *)zTempPathCp ); - sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", zTempPathUTF); - free( zTempPathUTF ); - } else if( DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ) == NO_ERROR ) { - zTempPath[0] = (char)('A' + ulDriveNum - 1); - zTempPath[1] = ':'; - zTempPath[2] = '\0'; - } else { - zTempPath[0] = '\0'; - } - - /* Strip off a trailing slashes or backslashes, otherwise we would get * - * multiple (back)slashes which causes DosOpen() to fail. * - * Trailing spaces are not allowed, either. */ - j = sqlite3Strlen30(zTempPath); - while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/' || - zTempPath[j-1] == ' ' ) ){ - j--; - } - zTempPath[j] = '\0'; - - /* We use 20 bytes to randomize the name */ - sqlite3_snprintf(nBuf-22, zBuf, - "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath); - j = sqlite3Strlen30(zBuf); - sqlite3_randomness( 20, &zBuf[j] ); - for( i = 0; i < 20; i++, j++ ){ - zBuf[j] = zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; - } - zBuf[j] = 0; - - OSTRACE(( "TEMP FILENAME: %s\n", zBuf )); - return SQLITE_OK; -} - - -/* -** Turn a relative pathname into a full pathname. Write the full -** pathname into zFull[]. zFull[] will be at least pVfs->mxPathname -** bytes in size. -*/ -static int os2FullPathname( - sqlite3_vfs *pVfs, /* Pointer to vfs object */ - const char *zRelative, /* Possibly relative input path */ - int nFull, /* Size of output buffer in bytes */ - char *zFull /* Output buffer */ -){ - char *zRelativeCp = convertUtf8PathToCp( zRelative ); - char zFullCp[CCHMAXPATH] = "\0"; - char *zFullUTF; - APIRET rc = DosQueryPathInfo( (PSZ)zRelativeCp, FIL_QUERYFULLNAME, - zFullCp, CCHMAXPATH ); - free( zRelativeCp ); - zFullUTF = convertCpPathToUtf8( zFullCp ); - sqlite3_snprintf( nFull, zFull, zFullUTF ); - free( zFullUTF ); - return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; -} - - -/* -** Open a file. -*/ -static int os2Open( - sqlite3_vfs *pVfs, /* Not used */ - const char *zName, /* Name of the file (UTF-8) */ - sqlite3_file *id, /* Write the SQLite file handle here */ - int flags, /* Open mode flags */ - int *pOutFlags /* Status return flags */ -){ - HFILE h; - ULONG ulOpenFlags = 0; - ULONG ulOpenMode = 0; - ULONG ulAction = 0; - ULONG rc; - os2File *pFile = (os2File*)id; - const char *zUtf8Name = zName; - char *zNameCp; - char zTmpname[CCHMAXPATH]; - - int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); - int isCreate = (flags & SQLITE_OPEN_CREATE); - int isReadWrite = (flags & SQLITE_OPEN_READWRITE); -#ifndef NDEBUG - int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); - int isReadonly = (flags & SQLITE_OPEN_READONLY); - int eType = (flags & 0xFFFFFF00); - int isOpenJournal = (isCreate && ( - eType==SQLITE_OPEN_MASTER_JOURNAL - || eType==SQLITE_OPEN_MAIN_JOURNAL - || eType==SQLITE_OPEN_WAL - )); -#endif - - UNUSED_PARAMETER(pVfs); - assert( id!=0 ); - - /* Check the following statements are true: - ** - ** (a) Exactly one of the READWRITE and READONLY flags must be set, and - ** (b) if CREATE is set, then READWRITE must also be set, and - ** (c) if EXCLUSIVE is set, then CREATE must also be set. - ** (d) if DELETEONCLOSE is set, then CREATE must also be set. - */ - assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); - assert(isCreate==0 || isReadWrite); - assert(isExclusive==0 || isCreate); - assert(isDelete==0 || isCreate); - - /* The main DB, main journal, WAL file and master journal are never - ** automatically deleted. Nor are they ever temporary files. */ - assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); - assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); - assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); - assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); - - /* Assert that the upper layer has set one of the "file-type" flags. */ - assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB - || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL - || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL - || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL - ); - - memset( pFile, 0, sizeof(*pFile) ); - pFile->h = (HFILE)-1; - - /* If the second argument to this function is NULL, generate a - ** temporary file name to use - */ - if( !zUtf8Name ){ - assert(isDelete && !isOpenJournal); - rc = getTempname(CCHMAXPATH, zTmpname); - if( rc!=SQLITE_OK ){ - return rc; - } - zUtf8Name = zTmpname; - } - - if( isReadWrite ){ - ulOpenMode |= OPEN_ACCESS_READWRITE; - }else{ - ulOpenMode |= OPEN_ACCESS_READONLY; - } - - /* Open in random access mode for possibly better speed. Allow full - ** sharing because file locks will provide exclusive access when needed. - ** The handle should not be inherited by child processes and we don't - ** want popups from the critical error handler. - */ - ulOpenMode |= OPEN_FLAGS_RANDOM | OPEN_SHARE_DENYNONE | - OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR; - - /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is - ** created. SQLite doesn't use it to indicate "exclusive access" - ** as it is usually understood. - */ - if( isExclusive ){ - /* Creates a new file, only if it does not already exist. */ - /* If the file exists, it fails. */ - ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS; - }else if( isCreate ){ - /* Open existing file, or create if it doesn't exist */ - ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; - }else{ - /* Opens a file, only if it exists. */ - ulOpenFlags |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; - } - - zNameCp = convertUtf8PathToCp( zUtf8Name ); - rc = DosOpen( (PSZ)zNameCp, - &h, - &ulAction, - 0L, - FILE_NORMAL, - ulOpenFlags, - ulOpenMode, - (PEAOP2)NULL ); - free( zNameCp ); - - if( rc != NO_ERROR ){ - OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulFlags=%#lx, ulMode=%#lx\n", - rc, zUtf8Name, ulAction, ulOpenFlags, ulOpenMode )); - - if( isReadWrite ){ - return os2Open( pVfs, zName, id, - ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), - pOutFlags ); - }else{ - return SQLITE_CANTOPEN; - } - } - - if( pOutFlags ){ - *pOutFlags = isReadWrite ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY; - } - - os2FullPathname( pVfs, zUtf8Name, sizeof( zTmpname ), zTmpname ); - pFile->zFullPathCp = convertUtf8PathToCp( zTmpname ); - pFile->pMethod = &os2IoMethod; - pFile->flags = flags; - pFile->h = h; - - OpenCounter(+1); - OSTRACE(( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags )); - return SQLITE_OK; -} - -/* -** Delete the named file. -*/ -static int os2Delete( - sqlite3_vfs *pVfs, /* Not used on os2 */ - const char *zFilename, /* Name of file to delete */ - int syncDir /* Not used on os2 */ -){ - APIRET rc; - char *zFilenameCp; - SimulateIOError( return SQLITE_IOERR_DELETE ); - zFilenameCp = convertUtf8PathToCp( zFilename ); - rc = DosDelete( (PSZ)zFilenameCp ); - free( zFilenameCp ); - OSTRACE(( "DELETE \"%s\"\n", zFilename )); - return (rc == NO_ERROR || - rc == ERROR_FILE_NOT_FOUND || - rc == ERROR_PATH_NOT_FOUND ) ? SQLITE_OK : SQLITE_IOERR_DELETE; -} - -/* -** Check the existance and status of a file. -*/ -static int os2Access( - sqlite3_vfs *pVfs, /* Not used on os2 */ - const char *zFilename, /* Name of file to check */ - int flags, /* Type of test to make on this file */ - int *pOut /* Write results here */ -){ - APIRET rc; - FILESTATUS3 fsts3ConfigInfo; - char *zFilenameCp; - - UNUSED_PARAMETER(pVfs); - SimulateIOError( return SQLITE_IOERR_ACCESS; ); - - zFilenameCp = convertUtf8PathToCp( zFilename ); - rc = DosQueryPathInfo( (PSZ)zFilenameCp, FIL_STANDARD, - &fsts3ConfigInfo, sizeof(FILESTATUS3) ); - free( zFilenameCp ); - OSTRACE(( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n", - fsts3ConfigInfo.attrFile, flags, rc )); - - switch( flags ){ - case SQLITE_ACCESS_EXISTS: - /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file - ** as if it does not exist. - */ - if( fsts3ConfigInfo.cbFile == 0 ) - rc = ERROR_FILE_NOT_FOUND; - break; - case SQLITE_ACCESS_READ: - break; - case SQLITE_ACCESS_READWRITE: - if( fsts3ConfigInfo.attrFile & FILE_READONLY ) - rc = ERROR_ACCESS_DENIED; - break; - default: - rc = ERROR_FILE_NOT_FOUND; - assert( !"Invalid flags argument" ); - } - - *pOut = (rc == NO_ERROR); - OSTRACE(( "ACCESS %s flags %d: rc=%d\n", zFilename, flags, *pOut )); - - return SQLITE_OK; -} - - -#ifndef SQLITE_OMIT_LOAD_EXTENSION -/* -** Interfaces for opening a shared library, finding entry points -** within the shared library, and closing the shared library. -*/ -/* -** Interfaces for opening a shared library, finding entry points -** within the shared library, and closing the shared library. -*/ -static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){ - HMODULE hmod; - APIRET rc; - char *zFilenameCp = convertUtf8PathToCp(zFilename); - rc = DosLoadModule(NULL, 0, (PSZ)zFilenameCp, &hmod); - free(zFilenameCp); - return rc != NO_ERROR ? 0 : (void*)hmod; -} -/* -** A no-op since the error code is returned on the DosLoadModule call. -** os2Dlopen returns zero if DosLoadModule is not successful. -*/ -static void os2DlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ -/* no-op */ -} -static void (*os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){ - PFN pfn; - APIRET rc; - rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)zSymbol, &pfn); - if( rc != NO_ERROR ){ - /* if the symbol itself was not found, search again for the same - * symbol with an extra underscore, that might be needed depending - * on the calling convention */ - char _zSymbol[256] = "_"; - strncat(_zSymbol, zSymbol, 254); - rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)_zSymbol, &pfn); - } - return rc != NO_ERROR ? 0 : (void(*)(void))pfn; -} -static void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){ - DosFreeModule((HMODULE)pHandle); -} -#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ - #define os2DlOpen 0 - #define os2DlError 0 - #define os2DlSym 0 - #define os2DlClose 0 -#endif - - -/* -** Write up to nBuf bytes of randomness into zBuf. -*/ -static int os2Randomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf ){ - int n = 0; -#if defined(SQLITE_TEST) - n = nBuf; - memset(zBuf, 0, nBuf); -#else - int i; - PPIB ppib; - PTIB ptib; - DATETIME dt; - static unsigned c = 0; - /* Ordered by variation probability */ - static ULONG svIdx[6] = { QSV_MS_COUNT, QSV_TIME_LOW, - QSV_MAXPRMEM, QSV_MAXSHMEM, - QSV_TOTAVAILMEM, QSV_TOTRESMEM }; - - /* 8 bytes; timezone and weekday don't increase the randomness much */ - if( (int)sizeof(dt)-3 <= nBuf - n ){ - c += 0x0100; - DosGetDateTime(&dt); - dt.year = (USHORT)((dt.year - 1900) | c); - memcpy(&zBuf[n], &dt, sizeof(dt)-3); - n += sizeof(dt)-3; - } - - /* 4 bytes; PIDs and TIDs are 16 bit internally, so combine them */ - if( (int)sizeof(ULONG) <= nBuf - n ){ - DosGetInfoBlocks(&ptib, &ppib); - *(PULONG)&zBuf[n] = MAKELONG(ppib->pib_ulpid, - ptib->tib_ptib2->tib2_ultid); - n += sizeof(ULONG); - } - - /* Up to 6 * 4 bytes; variables depend on the system state */ - for( i = 0; i < 6 && (int)sizeof(ULONG) <= nBuf - n; i++ ){ - DosQuerySysInfo(svIdx[i], svIdx[i], - (PULONG)&zBuf[n], sizeof(ULONG)); - n += sizeof(ULONG); - } -#endif - - return n; -} - -/* -** Sleep for a little while. Return the amount of time slept. -** The argument is the number of microseconds we want to sleep. -** The return value is the number of microseconds of sleep actually -** requested from the underlying operating system, a number which -** might be greater than or equal to the argument, but not less -** than the argument. -*/ -static int os2Sleep( sqlite3_vfs *pVfs, int microsec ){ - DosSleep( (microsec/1000) ); - return microsec; -} - -/* -** The following variable, if set to a non-zero value, becomes the result -** returned from sqlite3OsCurrentTime(). This is used for testing. -*/ -#ifdef SQLITE_TEST -SQLITE_API int sqlite3_current_time = 0; -#endif - -/* -** Find the current time (in Universal Coordinated Time). Write into *piNow -** the current time and date as a Julian Day number times 86_400_000. In -** other words, write into *piNow the number of milliseconds since the Julian -** epoch of noon in Greenwich on November 24, 4714 B.C according to the -** proleptic Gregorian calendar. -** -** On success, return 0. Return 1 if the time and date cannot be found. -*/ -static int os2CurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ -#ifdef SQLITE_TEST - static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; -#endif - int year, month, datepart, timepart; - - DATETIME dt; - DosGetDateTime( &dt ); - - year = dt.year; - month = dt.month; - - /* Calculations from http://www.astro.keele.ac.uk/~rno/Astronomy/hjd.html - ** http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c - ** Calculate the Julian days - */ - datepart = (int)dt.day - 32076 + - 1461*(year + 4800 + (month - 14)/12)/4 + - 367*(month - 2 - (month - 14)/12*12)/12 - - 3*((year + 4900 + (month - 14)/12)/100)/4; - - /* Time in milliseconds, hours to noon added */ - timepart = 12*3600*1000 + dt.hundredths*10 + dt.seconds*1000 + - ((int)dt.minutes + dt.timezone)*60*1000 + dt.hours*3600*1000; - - *piNow = (sqlite3_int64)datepart*86400*1000 + timepart; - -#ifdef SQLITE_TEST - if( sqlite3_current_time ){ - *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; - } -#endif - - UNUSED_PARAMETER(pVfs); - return 0; -} - -/* -** Find the current time (in Universal Coordinated Time). Write the -** current time and date as a Julian Day number into *prNow and -** return 0. Return 1 if the time and date cannot be found. -*/ -static int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){ - int rc; - sqlite3_int64 i; - rc = os2CurrentTimeInt64(pVfs, &i); - if( !rc ){ - *prNow = i/86400000.0; - } - return rc; -} - -/* -** The idea is that this function works like a combination of -** GetLastError() and FormatMessage() on windows (or errno and -** strerror_r() on unix). After an error is returned by an OS -** function, SQLite calls this function with zBuf pointing to -** a buffer of nBuf bytes. The OS layer should populate the -** buffer with a nul-terminated UTF-8 encoded error message -** describing the last IO error to have occurred within the calling -** thread. -** -** If the error message is too large for the supplied buffer, -** it should be truncated. The return value of xGetLastError -** is zero if the error message fits in the buffer, or non-zero -** otherwise (if the message was truncated). If non-zero is returned, -** then it is not necessary to include the nul-terminator character -** in the output buffer. -** -** Not supplying an error message will have no adverse effect -** on SQLite. It is fine to have an implementation that never -** returns an error message: -** -** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ -** assert(zBuf[0]=='\0'); -** return 0; -** } -** -** However if an error message is supplied, it will be incorporated -** by sqlite into the error message available to the user using -** sqlite3_errmsg(), possibly making IO errors easier to debug. -*/ -static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ - assert(zBuf[0]=='\0'); - return 0; -} - -/* -** Initialize and deinitialize the operating system interface. -*/ -SQLITE_API int sqlite3_os_init(void){ - static sqlite3_vfs os2Vfs = { - 3, /* iVersion */ - sizeof(os2File), /* szOsFile */ - CCHMAXPATH, /* mxPathname */ - 0, /* pNext */ - "os2", /* zName */ - 0, /* pAppData */ - - os2Open, /* xOpen */ - os2Delete, /* xDelete */ - os2Access, /* xAccess */ - os2FullPathname, /* xFullPathname */ - os2DlOpen, /* xDlOpen */ - os2DlError, /* xDlError */ - os2DlSym, /* xDlSym */ - os2DlClose, /* xDlClose */ - os2Randomness, /* xRandomness */ - os2Sleep, /* xSleep */ - os2CurrentTime, /* xCurrentTime */ - os2GetLastError, /* xGetLastError */ - os2CurrentTimeInt64, /* xCurrentTimeInt64 */ - 0, /* xSetSystemCall */ - 0, /* xGetSystemCall */ - 0 /* xNextSystemCall */ - }; - sqlite3_vfs_register(&os2Vfs, 1); - initUconvObjects(); -/* sqlite3OSTrace = 1; */ - return SQLITE_OK; -} -SQLITE_API int sqlite3_os_end(void){ - freeUconvObjects(); - return SQLITE_OK; -} - -#endif /* SQLITE_OS_OS2 */ - -/************** End of os_os2.c **********************************************/ /************** Begin file os_unix.c *****************************************/ /* ** 2004 May 22 @@ -25843,9 +23480,9 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) { case EACCES: /* EACCES is like EAGAIN during locking operations, but not any other time*/ if( (sqliteIOErr == SQLITE_IOERR_LOCK) || - (sqliteIOErr == SQLITE_IOERR_UNLOCK) || - (sqliteIOErr == SQLITE_IOERR_RDLOCK) || - (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){ + (sqliteIOErr == SQLITE_IOERR_UNLOCK) || + (sqliteIOErr == SQLITE_IOERR_RDLOCK) || + (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){ return SQLITE_BUSY; } /* else fall through */ @@ -26180,7 +23817,7 @@ static unixInodeInfo *inodeList = 0; ** The first argument passed to the macro should be the error code that ** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). ** The two subsequent arguments should be the name of the OS function that -** failed (e.g. "unlink", "open") and the the associated file-system path, +** failed (e.g. "unlink", "open") and the associated file-system path, ** if any. */ #define unixLogError(a,b,c) unixLogErrorAtLine(a,b,c,__LINE__) @@ -26203,7 +23840,7 @@ static int unixLogErrorAtLine( zErr = aErr; /* If STRERROR_R_CHAR_P (set by autoconf scripts) or __USE_GNU is defined, - ** assume that the system provides the the GNU version of strerror_r() that + ** assume that the system provides the GNU version of strerror_r() that ** returns a pointer to a buffer containing the error message. That pointer ** may point to aErr[], or it may point to some static storage somewhere. ** Otherwise, assume that the system provides the POSIX version of @@ -26892,7 +24529,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ pInode->eFileLock = NO_LOCK; }else{ rc = SQLITE_IOERR_UNLOCK; - pFile->lastErrno = errno; + pFile->lastErrno = errno; pInode->eFileLock = NO_LOCK; pFile->eFileLock = NO_LOCK; } @@ -26908,7 +24545,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ closePendingFds(pFile); } } - + end_unlock: unixLeaveMutex(); if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; @@ -27175,7 +24812,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) { assert( pFile ); OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock, - pFile->eFileLock, getpid())); + pFile->eFileLock, getpid())); assert( eFileLock<=SHARED_LOCK ); /* no-op if possible */ @@ -27562,7 +25199,7 @@ static int semUnlock(sqlite3_file *id, int eFileLock) { assert( pFile ); assert( pSem ); OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock, - pFile->eFileLock, getpid())); + pFile->eFileLock, getpid())); assert( eFileLock<=SHARED_LOCK ); /* no-op if possible */ @@ -28152,7 +25789,7 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ if( newOffset == -1 ){ ((unixFile*)id)->lastErrno = errno; }else{ - ((unixFile*)id)->lastErrno = 0; + ((unixFile*)id)->lastErrno = 0; } return -1; } @@ -28240,7 +25877,7 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){ if( newOffset == -1 ){ ((unixFile*)id)->lastErrno = errno; }else{ - ((unixFile*)id)->lastErrno = 0; + ((unixFile*)id)->lastErrno = 0; } return -1; } @@ -30754,7 +28391,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ ** address in the shared range is taken for a SHARED lock, the entire ** shared range is taken for an EXCLUSIVE lock): ** -** PENDING_BYTE 0x40000000 +** PENDING_BYTE 0x40000000 ** RESERVED_BYTE 0x40000001 ** SHARED_RANGE 0x40000002 -> 0x40000200 ** @@ -32274,9 +29911,11 @@ SQLITE_API int sqlite3_open_file_count = 0; # define FILE_ATTRIBUTE_MASK (0x0003FFF7) #endif +#ifndef SQLITE_OMIT_WAL /* Forward references */ typedef struct winShm winShm; /* A connection to shared-memory */ typedef struct winShmNode winShmNode; /* A region of shared-memory */ +#endif /* ** WinCE lacks native support for file locking so we have to fake it @@ -32304,7 +29943,9 @@ struct winFile { short sharedLockByte; /* Randomly chosen byte used as a shared lock */ u8 ctrlFlags; /* Flags. See WINFILE_* below */ DWORD lastErrno; /* The Windows errno from the last I/O error */ +#ifndef SQLITE_OMIT_WAL winShm *pShm; /* Instance of shared memory on this file */ +#endif const char *zPath; /* Full pathname of this file */ int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */ #if SQLITE_OS_WINCE @@ -32329,6 +29970,22 @@ struct winFile { # define SQLITE_WIN32_DBG_BUF_SIZE ((int)(4096-sizeof(DWORD))) #endif +/* + * The value used with sqlite3_win32_set_directory() to specify that + * the data directory should be changed. + */ +#ifndef SQLITE_WIN32_DATA_DIRECTORY_TYPE +# define SQLITE_WIN32_DATA_DIRECTORY_TYPE (1) +#endif + +/* + * The value used with sqlite3_win32_set_directory() to specify that + * the temporary directory should be changed. + */ +#ifndef SQLITE_WIN32_TEMP_DIRECTORY_TYPE +# define SQLITE_WIN32_TEMP_DIRECTORY_TYPE (2) +#endif + /* * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the * various Win32 API heap functions instead of our own. @@ -32516,7 +30173,8 @@ static struct win_syscall { #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) +#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ + !defined(SQLITE_OMIT_WAL)) { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, #else { "CreateFileMappingW", (SYSCALL)0, 0 }, @@ -32828,7 +30486,7 @@ static struct win_syscall { LPOVERLAPPED))aSyscall[45].pCurrent) #endif -#if !SQLITE_OS_WINRT +#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)) { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, #else { "MapViewOfFile", (SYSCALL)0, 0 }, @@ -32898,7 +30556,11 @@ static struct win_syscall { #define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ LPOVERLAPPED))aSyscall[55].pCurrent) +#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, +#else + { "UnmapViewOfFile", (SYSCALL)0, 0 }, +#endif #define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[56].pCurrent) @@ -32930,7 +30592,7 @@ static struct win_syscall { #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ DWORD))aSyscall[60].pCurrent) -#if !SQLITE_OS_WINCE +#if SQLITE_OS_WINRT { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, #else { "WaitForSingleObjectEx", (SYSCALL)0, 0 }, @@ -32939,7 +30601,7 @@ static struct win_syscall { #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ BOOL))aSyscall[61].pCurrent) -#if !SQLITE_OS_WINCE +#if SQLITE_OS_WINRT { "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 }, #else { "SetFilePointerEx", (SYSCALL)0, 0 }, @@ -32957,7 +30619,7 @@ static struct win_syscall { #define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \ FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[63].pCurrent) -#if SQLITE_OS_WINRT +#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL) { "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 }, #else { "MapViewOfFileFromApp", (SYSCALL)0, 0 }, @@ -33021,7 +30683,7 @@ static struct win_syscall { #define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[71].pCurrent) -#if SQLITE_OS_WINRT +#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL) { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 }, #else { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, @@ -33537,6 +31199,42 @@ SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ return zFilenameMbcs; } +/* +** This function sets the data directory or the temporary directory based on +** the provided arguments. The type argument must be 1 in order to set the +** data directory or 2 in order to set the temporary directory. The zValue +** argument is the name of the directory to use. The return value will be +** SQLITE_OK if successful. +*/ +SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){ + char **ppDirectory = 0; +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){ + ppDirectory = &sqlite3_data_directory; + }else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){ + ppDirectory = &sqlite3_temp_directory; + } + assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE + || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE + ); + assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) ); + if( ppDirectory ){ + char *zValueUtf8 = 0; + if( zValue && zValue[0] ){ + zValueUtf8 = unicodeToUtf8(zValue); + if ( zValueUtf8==0 ){ + return SQLITE_NOMEM; + } + } + sqlite3_free(*ppDirectory); + *ppDirectory = zValueUtf8; + return SQLITE_OK; + } + return SQLITE_ERROR; +} /* ** The return value of getLastErrorMsg @@ -33631,7 +31329,7 @@ static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ ** The first argument passed to the macro should be the error code that ** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). ** The two subsequent arguments should be the name of the OS function that -** failed and the the associated file-system path, if any. +** failed and the associated file-system path, if any. */ #define winLogError(a,b,c,d) winLogErrorAtLine(a,b,c,d,__LINE__) static int winLogErrorAtLine( @@ -34153,7 +31851,9 @@ static int winClose(sqlite3_file *id){ winFile *pFile = (winFile*)id; assert( id!=0 ); +#ifndef SQLITE_OMIT_WAL assert( pFile->pShm==0 ); +#endif OSTRACE(("CLOSE %d\n", pFile->h)); do{ rc = osCloseHandle(pFile->h); @@ -35755,6 +33455,13 @@ static int winOpen( assert( id!=0 ); UNUSED_PARAMETER(pVfs); +#if SQLITE_OS_WINRT + if( !sqlite3_temp_directory ){ + sqlite3_log(SQLITE_ERROR, + "sqlite3_temp_directory variable should be set for WinRT"); + } +#endif + pFile->h = INVALID_HANDLE_VALUE; /* If the second argument to this function is NULL, generate a @@ -35903,7 +33610,9 @@ static int winOpen( pFile->h = h; pFile->lastErrno = NO_ERROR; pFile->pVfs = pVfs; +#ifndef SQLITE_OMIT_WAL pFile->pShm = 0; +#endif pFile->zPath = zName; if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){ pFile->ctrlFlags |= WINFILE_PSOW; @@ -36066,7 +33775,7 @@ static int winAccess( } }else{ logIoerr(cnt); - if( lastErrno!=ERROR_FILE_NOT_FOUND ){ + if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename); sqlite3_free(zConverted); return SQLITE_IOERR_ACCESS; @@ -36879,10 +34588,9 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ /* Allocate the Bitvec to be tested and a linear array of ** bits to act as the reference */ pBitvec = sqlite3BitvecCreate( sz ); - pV = sqlite3_malloc( (sz+7)/8 + 1 ); + pV = sqlite3MallocZero( (sz+7)/8 + 1 ); pTmpSpace = sqlite3_malloc(BITVEC_SZ); if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; - memset(pV, 0, (sz+7)/8 + 1); /* NULL pBitvec tests */ sqlite3BitvecSet(0, 1); @@ -37966,11 +35674,10 @@ static int pcache1ResizeHash(PCache1 *p){ pcache1LeaveMutex(p->pGroup); if( p->nHash ){ sqlite3BeginBenignMalloc(); } - apNew = (PgHdr1 **)sqlite3_malloc(sizeof(PgHdr1 *)*nNew); + apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew); if( p->nHash ){ sqlite3EndBenignMalloc(); } pcache1EnterMutex(p->pGroup); if( apNew ){ - memset(apNew, 0, sizeof(PgHdr1 *)*nNew); for(i=0; inHash; i++){ PgHdr1 *pPage; PgHdr1 *pNext = p->apHash[i]; @@ -38154,9 +35861,8 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ assert( szExtra < 300 ); sz = sizeof(PCache1) + sizeof(PGroup)*separateCache; - pCache = (PCache1 *)sqlite3_malloc(sz); + pCache = (PCache1 *)sqlite3MallocZero(sz); if( pCache ){ - memset(pCache, 0, sz); if( separateCache ){ pGroup = (PGroup*)&pCache[1]; pGroup->mxPinned = 10; @@ -39034,7 +36740,7 @@ SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){ } /* -** Check to see if element iRowid was inserted into the the rowset as +** Check to see if element iRowid was inserted into the rowset as ** part of any insert batch prior to iBatch. Return 1 or 0. ** ** If this is the first test of a new batch and if there exist entires @@ -39318,7 +37024,7 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal); ** ** Definition: Two databases (or the same database at two points it time) ** are said to be "logically equivalent" if they give the same answer to -** all queries. Note in particular the the content of freelist leaf +** all queries. Note in particular the content of freelist leaf ** pages can be changed arbitarily without effecting the logical equivalence ** of the database. ** @@ -43092,7 +40798,7 @@ SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){ ** ** If the Pager.noSync flag is set, then this function is a no-op. ** Otherwise, the actions required depend on the journal-mode and the -** device characteristics of the the file-system, as follows: +** device characteristics of the file-system, as follows: ** ** * If the journal file is an in-memory journal file, no action need ** be taken. @@ -46323,14 +44029,15 @@ SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){ ** byte order of the host computer. ** ** The purpose of the wal-index is to answer this question quickly: Given -** a page number P, return the index of the last frame for page P in the WAL, -** or return NULL if there are no frames for page P in the WAL. +** a page number P and a maximum frame index M, return the index of the +** last frame in the wal before frame M for page P in the WAL, or return +** NULL if there are no frames for page P in the WAL prior to M. ** ** The wal-index consists of a header region, followed by an one or ** more index blocks. ** ** The wal-index header contains the total number of frames within the WAL -** in the the mxFrame field. +** in the mxFrame field. ** ** Each index block except for the first contains information on ** HASHTABLE_NPAGE frames. The first index block contains information on @@ -47378,6 +45085,7 @@ finished: pInfo->nBackfill = 0; pInfo->aReadMark[0] = 0; for(i=1; iaReadMark[i] = READMARK_NOT_USED; + if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame; /* If more than one frame was recovered from the log file, report an ** event via sqlite3_log(). This is to help with identifying performance @@ -47878,7 +45586,7 @@ static int walCheckpoint( assert( y<=pWal->hdr.mxFrame ); rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1); if( rc==SQLITE_OK ){ - pInfo->aReadMark[i] = READMARK_NOT_USED; + pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED); walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); }else if( rc==SQLITE_BUSY ){ mxSafeFrame = y; @@ -48791,7 +46499,8 @@ static int walRestartLog(Wal *pWal){ aSalt[1] = salt1; walIndexWriteHdr(pWal); pInfo->nBackfill = 0; - for(i=1; iaReadMark[i] = READMARK_NOT_USED; + pInfo->aReadMark[1] = 0; + for(i=2; iaReadMark[i] = READMARK_NOT_USED; assert( pInfo->aReadMark[0]==0 ); walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); }else if( rc!=SQLITE_BUSY ){ @@ -49794,6 +47503,7 @@ struct BtCursor { #ifndef SQLITE_OMIT_INCRBLOB u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */ #endif + u8 hints; /* As configured by CursorSetHints() */ i16 iPage; /* Index of current page in apPage */ u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */ MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ @@ -51678,7 +49388,7 @@ static int btreeInitPage(MemPage *pPage){ size = get2byte(&data[pc+2]); if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){ /* Free blocks must be in ascending order. And the last byte of - ** the free-block must lie on the database page. */ + ** the free-block must lie on the database page. */ return SQLITE_CORRUPT_BKPT; } nFree = nFree + size; @@ -52852,7 +50562,7 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ pBt->nTransaction++; #ifndef SQLITE_OMIT_SHARED_CACHE if( p->sharable ){ - assert( p->lock.pBtree==p && p->lock.iTable==1 ); + assert( p->lock.pBtree==p && p->lock.iTable==1 ); p->lock.eLock = READ_LOCK; p->lock.pNext = pBt->pLock; pBt->pLock = &p->lock; @@ -56143,7 +53853,8 @@ static int balance_nonroot( MemPage *pParent, /* Parent page of siblings being balanced */ int iParentIdx, /* Index of "the page" in pParent */ u8 *aOvflSpace, /* page-size bytes of space for parent ovfl */ - int isRoot /* True if pParent is a root-page */ + int isRoot, /* True if pParent is a root-page */ + int bBulk /* True if this call is part of a bulk load */ ){ BtShared *pBt; /* The whole database */ int nCell = 0; /* Number of cells in apCell[] */ @@ -56207,18 +53918,19 @@ static int balance_nonroot( i = pParent->nOverflow + pParent->nCell; if( i<2 ){ nxDiv = 0; - nOld = i+1; }else{ - nOld = 3; + assert( bBulk==0 || bBulk==1 ); if( iParentIdx==0 ){ nxDiv = 0; }else if( iParentIdx==i ){ - nxDiv = i-2; + nxDiv = i-2+bBulk; }else{ + assert( bBulk==0 ); nxDiv = iParentIdx-1; } - i = 2; + i = 2-bBulk; } + nOld = i+1; if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){ pRight = &pParent->aData[pParent->hdrOffset+8]; }else{ @@ -56298,7 +54010,7 @@ static int balance_nonroot( /* ** Load pointers to all cells on sibling pages and the divider cells ** into the local apCell[] array. Make copies of the divider cells - ** into space obtained from aSpace1[] and remove the the divider Cells + ** into space obtained from aSpace1[] and remove the divider cells ** from pParent. ** ** If the siblings are on leaf pages, then the child pointers of the @@ -56427,7 +54139,9 @@ static int balance_nonroot( d = r + 1 - leafData; assert( d0 ); - rc = allocateBtreePage(pBt, &pNew, &pgno, pgno, 0); + rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0); if( rc ) goto balance_cleanup; apNew[i] = pNew; nNew++; @@ -56686,6 +54400,7 @@ static int balance_nonroot( ** sibling page j. If the siblings are not leaf pages of an ** intkey b-tree, then cell i was a divider cell. */ assert( j+1 < ArraySize(apCopy) ); + assert( j+1 < nOld ); pOld = apCopy[++j]; iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow; if( pOld->nOverflow ){ @@ -56924,7 +54639,7 @@ static int balance(BtCursor *pCur){ ** pSpace buffer passed to the latter call to balance_nonroot(). */ u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize); - rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1); + rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, pCur->hints); if( pFree ){ /* If pFree is not NULL, it points to the pSpace buffer used ** by a previous call to balance_nonroot(). Its contents are @@ -58512,6 +56227,15 @@ SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ return rc; } +/* +** set the mask of hint flags for cursor pCsr. Currently the only valid +** values are 0 and BTREE_BULKLOAD. +*/ +SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){ + assert( mask==BTREE_BULKLOAD || mask==0 ); + pCsr->hints = mask; +} + /************** End of btree.c ***********************************************/ /************** Begin file backup.c ******************************************/ /* @@ -58678,7 +56402,7 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init( ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a ** call to sqlite3_backup_init() and is destroyed by a call to ** sqlite3_backup_finish(). */ - p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup)); + p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup)); if( !p ){ sqlite3Error(pDestDb, SQLITE_NOMEM, 0); } @@ -58686,7 +56410,6 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init( /* If the allocation succeeded, populate the new object. */ if( p ){ - memset(p, 0, sizeof(sqlite3_backup)); p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb); p->pDest = findBtree(pDestDb, pDestDb, zDestDb); p->pDestDb = pDestDb; @@ -59057,14 +56780,14 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ */ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){ sqlite3_backup **pp; /* Ptr to head of pagers backup list */ - MUTEX_LOGIC( sqlite3_mutex *mutex; ) /* Mutex to protect source database */ + sqlite3 *pSrcDb; /* Source database connection */ int rc; /* Value to return */ /* Enter the mutexes */ if( p==0 ) return SQLITE_OK; - sqlite3_mutex_enter(p->pSrcDb->mutex); + pSrcDb = p->pSrcDb; + sqlite3_mutex_enter(pSrcDb->mutex); sqlite3BtreeEnter(p->pSrc); - MUTEX_LOGIC( mutex = p->pSrcDb->mutex; ) if( p->pDestDb ){ sqlite3_mutex_enter(p->pDestDb->mutex); } @@ -59090,7 +56813,7 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){ /* Exit the mutexes and free the backup context structure. */ if( p->pDestDb ){ - sqlite3_mutex_leave(p->pDestDb->mutex); + sqlite3LeaveMutexAndCloseZombie(p->pDestDb); } sqlite3BtreeLeave(p->pSrc); if( p->pDestDb ){ @@ -59099,7 +56822,7 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){ ** sqlite3_backup_finish(). */ sqlite3_free(p); } - sqlite3_mutex_leave(mutex); + sqlite3LeaveMutexAndCloseZombie(pSrcDb); return rc; } @@ -61168,7 +58891,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int #ifndef NDEBUG /* -** Change the comment on the the most recently coded instruction. Or +** Change the comment on the most recently coded instruction. Or ** insert a No-op and add the comment to that new instruction. This ** makes the code easier to read during debugging. None of this happens ** in a production build. @@ -62863,6 +60586,7 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ if( NEVER(p==0) ) return; db = p->db; + assert( sqlite3_mutex_held(db->mutex) ); if( p->pPrev ){ p->pPrev->pNext = p->pNext; }else{ @@ -63702,17 +61426,11 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){ }else{ Vdbe *v = (Vdbe*)pStmt; sqlite3 *db = v->db; -#if SQLITE_THREADSAFE - sqlite3_mutex *mutex; -#endif if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT; -#if SQLITE_THREADSAFE - mutex = v->db->mutex; -#endif - sqlite3_mutex_enter(mutex); + sqlite3_mutex_enter(db->mutex); rc = sqlite3VdbeFinalize(v); rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(mutex); + sqlite3LeaveMutexAndCloseZombie(db); } return rc; } @@ -65115,9 +62833,8 @@ SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe *pVdbe){ if( pVdbe ){ Explain *p; sqlite3BeginBenignMalloc(); - p = sqlite3_malloc( sizeof(Explain) ); + p = (Explain *)sqlite3MallocZero( sizeof(Explain) ); if( p ){ - memset(p, 0, sizeof(*p)); p->pVdbe = pVdbe; sqlite3_free(pVdbe->pExplain); pVdbe->pExplain = p; @@ -66386,7 +64103,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec( } #endif - /* On any opcode with the "out2-prerelase" tag, free any + /* On any opcode with the "out2-prerelease" tag, free any ** external allocations out of mem[p2] and set mem[p2] to be ** an undefined integer. Opcodes will either fill in the integer ** value or convert mem[p2] to a different type. @@ -68898,6 +66615,9 @@ case OP_OpenWrite: { Db *pDb; #endif /* local variables moved into u.ax */ + assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 ); + assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 ); + if( p->expired ){ rc = SQLITE_ABORT; break; @@ -68921,7 +66641,7 @@ case OP_OpenWrite: { }else{ u.ax.wrFlag = 0; } - if( pOp->p5 ){ + if( pOp->p5 & OPFLAG_P2ISREG ){ assert( u.ax.p2>0 ); assert( u.ax.p2<=p->nMem ); pIn2 = &aMem[u.ax.p2]; @@ -68952,6 +66672,8 @@ case OP_OpenWrite: { u.ax.pCur->isOrdered = 1; rc = sqlite3BtreeCursor(u.ax.pX, u.ax.p2, u.ax.wrFlag, u.ax.pKeyInfo, u.ax.pCur->pCursor); u.ax.pCur->pKeyInfo = u.ax.pKeyInfo; + assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); + sqlite3BtreeCursorHints(u.ax.pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR)); /* Since it performs no memory allocation or IO, the only value that ** sqlite3BtreeCursor() may return is SQLITE_OK. */ @@ -72571,6 +70293,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ typedef struct VdbeSorterIter VdbeSorterIter; typedef struct SorterRecord SorterRecord; +typedef struct FileWriter FileWriter; /* ** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES: @@ -72668,6 +70391,24 @@ struct VdbeSorterIter { sqlite3_file *pFile; /* File iterator is reading from */ u8 *aAlloc; /* Allocated space */ u8 *aKey; /* Pointer to current key */ + u8 *aBuffer; /* Current read buffer */ + int nBuffer; /* Size of read buffer in bytes */ +}; + +/* +** An instance of this structure is used to organize the stream of records +** being written to files by the merge-sort code into aligned, page-sized +** blocks. Doing all I/O in aligned page-sized blocks helps I/O to go +** faster on many operating systems. +*/ +struct FileWriter { + int eFWErr; /* Non-zero if in an error state */ + u8 *aBuffer; /* Pointer to write buffer */ + int nBuffer; /* Size of write buffer in bytes */ + int iBufStart; /* First byte of buffer to write */ + int iBufEnd; /* Last byte of buffer to write */ + i64 iWriteOff; /* Offset of start of buffer in file */ + sqlite3_file *pFile; /* File to write to */ }; /* @@ -72693,9 +70434,123 @@ struct SorterRecord { */ static void vdbeSorterIterZero(sqlite3 *db, VdbeSorterIter *pIter){ sqlite3DbFree(db, pIter->aAlloc); + sqlite3DbFree(db, pIter->aBuffer); memset(pIter, 0, sizeof(VdbeSorterIter)); } +/* +** Read nByte bytes of data from the stream of data iterated by object p. +** If successful, set *ppOut to point to a buffer containing the data +** and return SQLITE_OK. Otherwise, if an error occurs, return an SQLite +** error code. +** +** The buffer indicated by *ppOut may only be considered valid until the +** next call to this function. +*/ +static int vdbeSorterIterRead( + sqlite3 *db, /* Database handle (for malloc) */ + VdbeSorterIter *p, /* Iterator */ + int nByte, /* Bytes of data to read */ + u8 **ppOut /* OUT: Pointer to buffer containing data */ +){ + int iBuf; /* Offset within buffer to read from */ + int nAvail; /* Bytes of data available in buffer */ + assert( p->aBuffer ); + + /* If there is no more data to be read from the buffer, read the next + ** p->nBuffer bytes of data from the file into it. Or, if there are less + ** than p->nBuffer bytes remaining in the PMA, read all remaining data. */ + iBuf = p->iReadOff % p->nBuffer; + if( iBuf==0 ){ + int nRead; /* Bytes to read from disk */ + int rc; /* sqlite3OsRead() return code */ + + /* Determine how many bytes of data to read. */ + nRead = (int)(p->iEof - p->iReadOff); + if( nRead>p->nBuffer ) nRead = p->nBuffer; + assert( nRead>0 ); + + /* Read data from the file. Return early if an error occurs. */ + rc = sqlite3OsRead(p->pFile, p->aBuffer, nRead, p->iReadOff); + assert( rc!=SQLITE_IOERR_SHORT_READ ); + if( rc!=SQLITE_OK ) return rc; + } + nAvail = p->nBuffer - iBuf; + + if( nByte<=nAvail ){ + /* The requested data is available in the in-memory buffer. In this + ** case there is no need to make a copy of the data, just return a + ** pointer into the buffer to the caller. */ + *ppOut = &p->aBuffer[iBuf]; + p->iReadOff += nByte; + }else{ + /* The requested data is not all available in the in-memory buffer. + ** In this case, allocate space at p->aAlloc[] to copy the requested + ** range into. Then return a copy of pointer p->aAlloc to the caller. */ + int nRem; /* Bytes remaining to copy */ + + /* Extend the p->aAlloc[] allocation if required. */ + if( p->nAllocnAlloc*2; + while( nByte>nNew ) nNew = nNew*2; + p->aAlloc = sqlite3DbReallocOrFree(db, p->aAlloc, nNew); + if( !p->aAlloc ) return SQLITE_NOMEM; + p->nAlloc = nNew; + } + + /* Copy as much data as is available in the buffer into the start of + ** p->aAlloc[]. */ + memcpy(p->aAlloc, &p->aBuffer[iBuf], nAvail); + p->iReadOff += nAvail; + nRem = nByte - nAvail; + + /* The following loop copies up to p->nBuffer bytes per iteration into + ** the p->aAlloc[] buffer. */ + while( nRem>0 ){ + int rc; /* vdbeSorterIterRead() return code */ + int nCopy; /* Number of bytes to copy */ + u8 *aNext; /* Pointer to buffer to copy data from */ + + nCopy = nRem; + if( nRem>p->nBuffer ) nCopy = p->nBuffer; + rc = vdbeSorterIterRead(db, p, nCopy, &aNext); + if( rc!=SQLITE_OK ) return rc; + assert( aNext!=p->aAlloc ); + memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy); + nRem -= nCopy; + } + + *ppOut = p->aAlloc; + } + + return SQLITE_OK; +} + +/* +** Read a varint from the stream of data accessed by p. Set *pnOut to +** the value read. +*/ +static int vdbeSorterIterVarint(sqlite3 *db, VdbeSorterIter *p, u64 *pnOut){ + int iBuf; + + iBuf = p->iReadOff % p->nBuffer; + if( iBuf && (p->nBuffer-iBuf)>=9 ){ + p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut); + }else{ + u8 aVarint[16], *a; + int i = 0, rc; + do{ + rc = vdbeSorterIterRead(db, p, 1, &a); + if( rc ) return rc; + aVarint[(i++)&0xf] = a[0]; + }while( (a[0]&0x80)!=0 ); + sqlite3GetVarint(aVarint, pnOut); + } + + return SQLITE_OK; +} + + /* ** Advance iterator pIter to the next key in its PMA. Return SQLITE_OK if ** no error occurs, or an SQLite error code if one does. @@ -72705,96 +70560,18 @@ static int vdbeSorterIterNext( VdbeSorterIter *pIter /* Iterator to advance */ ){ int rc; /* Return Code */ - int nRead; /* Number of bytes read */ - int nRec = 0; /* Size of record in bytes */ - int iOff = 0; /* Size of serialized size varint in bytes */ + u64 nRec = 0; /* Size of record in bytes */ - assert( pIter->iEof>=pIter->iReadOff ); - if( pIter->iEof-pIter->iReadOff>5 ){ - nRead = 5; - }else{ - nRead = (int)(pIter->iEof - pIter->iReadOff); - } - if( nRead<=0 ){ + if( pIter->iReadOff>=pIter->iEof ){ /* This is an EOF condition */ vdbeSorterIterZero(db, pIter); return SQLITE_OK; } - rc = sqlite3OsRead(pIter->pFile, pIter->aAlloc, nRead, pIter->iReadOff); + rc = vdbeSorterIterVarint(db, pIter, &nRec); if( rc==SQLITE_OK ){ - iOff = getVarint32(pIter->aAlloc, nRec); - if( (iOff+nRec)>nRead ){ - int nRead2; /* Number of extra bytes to read */ - if( (iOff+nRec)>pIter->nAlloc ){ - int nNew = pIter->nAlloc*2; - while( (iOff+nRec)>nNew ) nNew = nNew*2; - pIter->aAlloc = sqlite3DbReallocOrFree(db, pIter->aAlloc, nNew); - if( !pIter->aAlloc ) return SQLITE_NOMEM; - pIter->nAlloc = nNew; - } - - nRead2 = iOff + nRec - nRead; - rc = sqlite3OsRead( - pIter->pFile, &pIter->aAlloc[nRead], nRead2, pIter->iReadOff+nRead - ); - } - } - - assert( rc!=SQLITE_OK || nRec>0 ); - pIter->iReadOff += iOff+nRec; - pIter->nKey = nRec; - pIter->aKey = &pIter->aAlloc[iOff]; - return rc; -} - -/* -** Write a single varint, value iVal, to file-descriptor pFile. Return -** SQLITE_OK if successful, or an SQLite error code if some error occurs. -** -** The value of *piOffset when this function is called is used as the byte -** offset in file pFile to write to. Before returning, *piOffset is -** incremented by the number of bytes written. -*/ -static int vdbeSorterWriteVarint( - sqlite3_file *pFile, /* File to write to */ - i64 iVal, /* Value to write as a varint */ - i64 *piOffset /* IN/OUT: Write offset in file pFile */ -){ - u8 aVarint[9]; /* Buffer large enough for a varint */ - int nVarint; /* Number of used bytes in varint */ - int rc; /* Result of write() call */ - - nVarint = sqlite3PutVarint(aVarint, iVal); - rc = sqlite3OsWrite(pFile, aVarint, nVarint, *piOffset); - *piOffset += nVarint; - - return rc; -} - -/* -** Read a single varint from file-descriptor pFile. Return SQLITE_OK if -** successful, or an SQLite error code if some error occurs. -** -** The value of *piOffset when this function is called is used as the -** byte offset in file pFile from whence to read the varint. If successful -** (i.e. if no IO error occurs), then *piOffset is set to the offset of -** the first byte past the end of the varint before returning. *piVal is -** set to the integer value read. If an error occurs, the final values of -** both *piOffset and *piVal are undefined. -*/ -static int vdbeSorterReadVarint( - sqlite3_file *pFile, /* File to read from */ - i64 *piOffset, /* IN/OUT: Read offset in pFile */ - i64 *piVal /* OUT: Value read from file */ -){ - u8 aVarint[9]; /* Buffer large enough for a varint */ - i64 iOff = *piOffset; /* Offset in file to read from */ - int rc; /* Return code */ - - rc = sqlite3OsRead(pFile, aVarint, 9, iOff); - if( rc==SQLITE_OK ){ - *piOffset += getVarint(aVarint, (u64 *)piVal); + pIter->nKey = (int)nRec; + rc = vdbeSorterIterRead(db, pIter, (int)nRec, &pIter->aKey); } return rc; @@ -72808,27 +70585,52 @@ static int vdbeSorterReadVarint( */ static int vdbeSorterIterInit( sqlite3 *db, /* Database handle */ - VdbeSorter *pSorter, /* Sorter object */ + const VdbeSorter *pSorter, /* Sorter object */ i64 iStart, /* Start offset in pFile */ VdbeSorterIter *pIter, /* Iterator to populate */ i64 *pnByte /* IN/OUT: Increment this value by PMA size */ ){ - int rc; + int rc = SQLITE_OK; + int nBuf; + + nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt); assert( pSorter->iWriteOff>iStart ); assert( pIter->aAlloc==0 ); + assert( pIter->aBuffer==0 ); pIter->pFile = pSorter->pTemp1; pIter->iReadOff = iStart; pIter->nAlloc = 128; pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc); - if( !pIter->aAlloc ){ + pIter->nBuffer = nBuf; + pIter->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf); + + if( !pIter->aBuffer ){ rc = SQLITE_NOMEM; }else{ - i64 nByte; /* Total size of PMA in bytes */ - rc = vdbeSorterReadVarint(pSorter->pTemp1, &pIter->iReadOff, &nByte); - *pnByte += nByte; - pIter->iEof = pIter->iReadOff + nByte; + int iBuf; + + iBuf = iStart % nBuf; + if( iBuf ){ + int nRead = nBuf - iBuf; + if( (iStart + nRead) > pSorter->iWriteOff ){ + nRead = (int)(pSorter->iWriteOff - iStart); + } + rc = sqlite3OsRead( + pSorter->pTemp1, &pIter->aBuffer[iBuf], nRead, iStart + ); + assert( rc!=SQLITE_IOERR_SHORT_READ ); + } + + if( rc==SQLITE_OK ){ + u64 nByte; /* Size of PMA in bytes */ + pIter->iEof = pSorter->iWriteOff; + rc = vdbeSorterIterVarint(db, pIter, &nByte); + pIter->iEof = pIter->iReadOff + nByte; + *pnByte += nByte; + } } + if( rc==SQLITE_OK ){ rc = vdbeSorterIterNext(db, pIter); } @@ -72852,10 +70654,10 @@ static int vdbeSorterIterInit( ** has been allocated and contains an unpacked record that is used as key2. */ static void vdbeSorterCompare( - VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ + const VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ int bOmitRowid, /* Ignore rowid field at end of keys */ - void *pKey1, int nKey1, /* Left side of comparison */ - void *pKey2, int nKey2, /* Right side of comparison */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2, /* Right side of comparison */ int *pRes /* OUT: Result of comparison */ ){ KeyInfo *pKeyInfo = pCsr->pKeyInfo; @@ -72887,7 +70689,7 @@ static void vdbeSorterCompare( ** multiple b-tree segments. Parameter iOut is the index of the aTree[] ** value to recalculate. */ -static int vdbeSorterDoCompare(VdbeCursor *pCsr, int iOut){ +static int vdbeSorterDoCompare(const VdbeCursor *pCsr, int iOut){ VdbeSorter *pSorter = pCsr->pSorter; int i1; int i2; @@ -73013,7 +70815,7 @@ static int vdbeSorterOpenTempFile(sqlite3 *db, sqlite3_file **ppFile){ ** Set *ppOut to the head of the new list. */ static void vdbeSorterMerge( - VdbeCursor *pCsr, /* For pKeyInfo */ + const VdbeCursor *pCsr, /* For pKeyInfo */ SorterRecord *p1, /* First list to merge */ SorterRecord *p2, /* Second list to merge */ SorterRecord **ppOut /* OUT: Head of merged list */ @@ -73047,7 +70849,7 @@ static void vdbeSorterMerge( ** if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if an error ** occurs. */ -static int vdbeSorterSort(VdbeCursor *pCsr){ +static int vdbeSorterSort(const VdbeCursor *pCsr){ int i; SorterRecord **aSlot; SorterRecord *p; @@ -73080,6 +70882,91 @@ static int vdbeSorterSort(VdbeCursor *pCsr){ return SQLITE_OK; } +/* +** Initialize a file-writer object. +*/ +static void fileWriterInit( + sqlite3 *db, /* Database (for malloc) */ + sqlite3_file *pFile, /* File to write to */ + FileWriter *p, /* Object to populate */ + i64 iStart /* Offset of pFile to begin writing at */ +){ + int nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt); + + memset(p, 0, sizeof(FileWriter)); + p->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf); + if( !p->aBuffer ){ + p->eFWErr = SQLITE_NOMEM; + }else{ + p->iBufEnd = p->iBufStart = (iStart % nBuf); + p->iWriteOff = iStart - p->iBufStart; + p->nBuffer = nBuf; + p->pFile = pFile; + } +} + +/* +** Write nData bytes of data to the file-write object. Return SQLITE_OK +** if successful, or an SQLite error code if an error occurs. +*/ +static void fileWriterWrite(FileWriter *p, u8 *pData, int nData){ + int nRem = nData; + while( nRem>0 && p->eFWErr==0 ){ + int nCopy = nRem; + if( nCopy>(p->nBuffer - p->iBufEnd) ){ + nCopy = p->nBuffer - p->iBufEnd; + } + + memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy); + p->iBufEnd += nCopy; + if( p->iBufEnd==p->nBuffer ){ + p->eFWErr = sqlite3OsWrite(p->pFile, + &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, + p->iWriteOff + p->iBufStart + ); + p->iBufStart = p->iBufEnd = 0; + p->iWriteOff += p->nBuffer; + } + assert( p->iBufEndnBuffer ); + + nRem -= nCopy; + } +} + +/* +** Flush any buffered data to disk and clean up the file-writer object. +** The results of using the file-writer after this call are undefined. +** Return SQLITE_OK if flushing the buffered data succeeds or is not +** required. Otherwise, return an SQLite error code. +** +** Before returning, set *piEof to the offset immediately following the +** last byte written to the file. +*/ +static int fileWriterFinish(sqlite3 *db, FileWriter *p, i64 *piEof){ + int rc; + if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){ + p->eFWErr = sqlite3OsWrite(p->pFile, + &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, + p->iWriteOff + p->iBufStart + ); + } + *piEof = (p->iWriteOff + p->iBufEnd); + sqlite3DbFree(db, p->aBuffer); + rc = p->eFWErr; + memset(p, 0, sizeof(FileWriter)); + return rc; +} + +/* +** Write value iVal encoded as a varint to the file-write object. Return +** SQLITE_OK if successful, or an SQLite error code if an error occurs. +*/ +static void fileWriterWriteVarint(FileWriter *p, u64 iVal){ + int nByte; + u8 aByte[10]; + nByte = sqlite3PutVarint(aByte, iVal); + fileWriterWrite(p, aByte, nByte); +} /* ** Write the current contents of the in-memory linked-list to a PMA. Return @@ -73094,9 +70981,12 @@ static int vdbeSorterSort(VdbeCursor *pCsr){ ** Each record consists of a varint followed by a blob of data (the ** key). The varint is the number of bytes in the blob of data. */ -static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){ +static int vdbeSorterListToPMA(sqlite3 *db, const VdbeCursor *pCsr){ int rc = SQLITE_OK; /* Return code */ VdbeSorter *pSorter = pCsr->pSorter; + FileWriter writer; + + memset(&writer, 0, sizeof(FileWriter)); if( pSorter->nInMemory==0 ){ assert( pSorter->pRecord==0 ); @@ -73114,39 +71004,20 @@ static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){ } if( rc==SQLITE_OK ){ - i64 iOff = pSorter->iWriteOff; SorterRecord *p; SorterRecord *pNext = 0; - static const char eightZeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + fileWriterInit(db, pSorter->pTemp1, &writer, pSorter->iWriteOff); pSorter->nPMA++; - rc = vdbeSorterWriteVarint(pSorter->pTemp1, pSorter->nInMemory, &iOff); - for(p=pSorter->pRecord; rc==SQLITE_OK && p; p=pNext){ + fileWriterWriteVarint(&writer, pSorter->nInMemory); + for(p=pSorter->pRecord; p; p=pNext){ pNext = p->pNext; - rc = vdbeSorterWriteVarint(pSorter->pTemp1, p->nVal, &iOff); - - if( rc==SQLITE_OK ){ - rc = sqlite3OsWrite(pSorter->pTemp1, p->pVal, p->nVal, iOff); - iOff += p->nVal; - } - + fileWriterWriteVarint(&writer, p->nVal); + fileWriterWrite(&writer, p->pVal, p->nVal); sqlite3DbFree(db, p); } - - /* This assert verifies that unless an error has occurred, the size of - ** the PMA on disk is the same as the expected size stored in - ** pSorter->nInMemory. */ - assert( rc!=SQLITE_OK || pSorter->nInMemory==( - iOff-pSorter->iWriteOff-sqlite3VarintLen(pSorter->nInMemory) - )); - - pSorter->iWriteOff = iOff; - if( rc==SQLITE_OK ){ - /* Terminate each file with 8 extra bytes so that from any offset - ** in the file we can always read 9 bytes without a SHORT_READ error */ - rc = sqlite3OsWrite(pSorter->pTemp1, eightZeros, 8, iOff); - } pSorter->pRecord = p; + rc = fileWriterFinish(db, &writer, &pSorter->iWriteOff); } return rc; @@ -73157,7 +71028,7 @@ static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){ */ SQLITE_PRIVATE int sqlite3VdbeSorterWrite( sqlite3 *db, /* Database handle */ - VdbeCursor *pCsr, /* Sorter cursor */ + const VdbeCursor *pCsr, /* Sorter cursor */ Mem *pVal /* Memory cell containing record */ ){ VdbeSorter *pSorter = pCsr->pSorter; @@ -73191,8 +71062,14 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite( (pSorter->nInMemory>pSorter->mxPmaSize) || (pSorter->nInMemory>pSorter->mnPmaSize && sqlite3HeapNearlyFull()) )){ +#ifdef SQLITE_DEBUG + i64 nExpect = pSorter->iWriteOff + + sqlite3VarintLen(pSorter->nInMemory) + + pSorter->nInMemory; +#endif rc = vdbeSorterListToPMA(db, pCsr); pSorter->nInMemory = 0; + assert( rc!=SQLITE_OK || (nExpect==pSorter->iWriteOff) ); } return rc; @@ -73203,7 +71080,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite( */ static int vdbeSorterInitMerge( sqlite3 *db, /* Database handle */ - VdbeCursor *pCsr, /* Cursor handle for this sorter */ + const VdbeCursor *pCsr, /* Cursor handle for this sorter */ i64 *pnByte /* Sum of bytes in all opened PMAs */ ){ VdbeSorter *pSorter = pCsr->pSorter; @@ -73233,7 +71110,7 @@ static int vdbeSorterInitMerge( ** Once the sorter has been populated, this function is called to prepare ** for iterating through its contents in sorted order. */ -SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){ +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){ VdbeSorter *pSorter = pCsr->pSorter; int rc; /* Return code */ sqlite3_file *pTemp2 = 0; /* Second temp file to use */ @@ -73253,7 +71130,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *p return vdbeSorterSort(pCsr); } - /* Write the current b-tree to a PMA. Close the b-tree cursor. */ + /* Write the current in-memory list to a PMA. */ rc = vdbeSorterListToPMA(db, pCsr); if( rc!=SQLITE_OK ) return rc; @@ -73275,8 +71152,12 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *p rc==SQLITE_OK && iNew*SORTER_MAX_MERGE_COUNTnPMA; iNew++ ){ + int rc2; /* Return code from fileWriterFinish() */ + FileWriter writer; /* Object used to write to disk */ i64 nWrite; /* Number of bytes in new PMA */ + memset(&writer, 0, sizeof(FileWriter)); + /* If there are SORTER_MAX_MERGE_COUNT or less PMAs in file pTemp1, ** initialize an iterator for each of them and break out of the loop. ** These iterators will be incrementally merged as the VDBE layer calls @@ -73298,23 +71179,20 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *p rc = vdbeSorterOpenTempFile(db, &pTemp2); } - if( rc==SQLITE_OK ){ - rc = vdbeSorterWriteVarint(pTemp2, nWrite, &iWrite2); - } - if( rc==SQLITE_OK ){ int bEof = 0; + fileWriterInit(db, pTemp2, &writer, iWrite2); + fileWriterWriteVarint(&writer, nWrite); while( rc==SQLITE_OK && bEof==0 ){ - int nToWrite; VdbeSorterIter *pIter = &pSorter->aIter[ pSorter->aTree[1] ]; assert( pIter->pFile ); - nToWrite = pIter->nKey + sqlite3VarintLen(pIter->nKey); - rc = sqlite3OsWrite(pTemp2, pIter->aAlloc, nToWrite, iWrite2); - iWrite2 += nToWrite; - if( rc==SQLITE_OK ){ - rc = sqlite3VdbeSorterNext(db, pCsr, &bEof); - } + + fileWriterWriteVarint(&writer, pIter->nKey); + fileWriterWrite(&writer, pIter->aKey, pIter->nKey); + rc = sqlite3VdbeSorterNext(db, pCsr, &bEof); } + rc2 = fileWriterFinish(db, &writer, &iWrite2); + if( rc==SQLITE_OK ) rc = rc2; } } @@ -73341,7 +71219,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *p /* ** Advance to the next element in the sorter. */ -SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){ +SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){ VdbeSorter *pSorter = pCsr->pSorter; int rc; /* Return code */ @@ -73371,7 +71249,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbE ** current key. */ static void *vdbeSorterRowkey( - VdbeSorter *pSorter, /* Sorter object */ + const VdbeSorter *pSorter, /* Sorter object */ int *pnKey /* OUT: Size of current key in bytes */ ){ void *pKey; @@ -73390,7 +71268,7 @@ static void *vdbeSorterRowkey( /* ** Copy the current sorter key into the memory cell pOut. */ -SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){ +SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){ VdbeSorter *pSorter = pCsr->pSorter; void *pKey; int nKey; /* Sorter key to copy into pOut */ @@ -73416,7 +71294,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){ ** key. */ SQLITE_PRIVATE int sqlite3VdbeSorterCompare( - VdbeCursor *pCsr, /* Sorter cursor */ + const VdbeCursor *pCsr, /* Sorter cursor */ Mem *pVal, /* Value to compare to current sorter key */ int *pRes /* OUT: Result of comparison */ ){ @@ -74059,13 +71937,19 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){ int rc; if( p==0 || pWalker->xSelectCallback==0 ) return WRC_Continue; rc = WRC_Continue; - while( p ){ + pWalker->walkerDepth++; + while( p ){ rc = pWalker->xSelectCallback(pWalker, p); if( rc ) break; - if( sqlite3WalkSelectExpr(pWalker, p) ) return WRC_Abort; - if( sqlite3WalkSelectFrom(pWalker, p) ) return WRC_Abort; + if( sqlite3WalkSelectExpr(pWalker, p) + || sqlite3WalkSelectFrom(pWalker, p) + ){ + pWalker->walkerDepth--; + return WRC_Abort; + } p = p->pPrior; } + pWalker->walkerDepth--; return rc & WRC_Abort; } @@ -74090,6 +71974,29 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){ /* #include */ /* #include */ +/* +** Walk the expression tree pExpr and increase the aggregate function +** depth (the Expr.op2 field) by N on every TK_AGG_FUNCTION node. +** This needs to occur when copying a TK_AGG_FUNCTION node from an +** outer query into an inner subquery. +** +** incrAggFunctionDepth(pExpr,n) is the main routine. incrAggDepth(..) +** is a helper function - a callback for the tree walker. +*/ +static int incrAggDepth(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.i; + return WRC_Continue; +} +static void incrAggFunctionDepth(Expr *pExpr, int N){ + if( N>0 ){ + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = incrAggDepth; + w.u.i = N; + sqlite3WalkExpr(&w, pExpr); + } +} + /* ** Turn the pExpr expression into an alias for the iCol-th column of the ** result set in pEList. @@ -74116,13 +72023,20 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){ ** The result of random()%5 in the GROUP BY clause is probably different ** from the result in the result-set. We might fix this someday. Or ** then again, we might not... +** +** The nSubquery parameter specifies how many levels of subquery the +** alias is removed from the original expression. The usually value is +** zero but it might be more if the alias is contained within a subquery +** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION +** structures must be increased by the nSubquery amount. */ static void resolveAlias( Parse *pParse, /* Parsing context */ ExprList *pEList, /* A result set */ int iCol, /* A column in the result set. 0..pEList->nExpr-1 */ Expr *pExpr, /* Transform this into an alias to the result set */ - const char *zType /* "GROUP" or "ORDER" or "" */ + const char *zType, /* "GROUP" or "ORDER" or "" */ + int nSubquery /* Number of subqueries that the label is moving */ ){ Expr *pOrig; /* The iCol-th column of the result set */ Expr *pDup; /* Copy of pOrig */ @@ -74135,6 +72049,7 @@ static void resolveAlias( db = pParse->db; if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){ pDup = sqlite3ExprDup(db, pOrig, 0); + incrAggFunctionDepth(pDup, nSubquery); pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0); if( pDup==0 ) return; if( pEList->a[iCol].iAlias==0 ){ @@ -74223,9 +72138,10 @@ static int lookupName( NameContext *pNC, /* The name context used to resolve the name */ Expr *pExpr /* Make this EXPR node point to the selected column */ ){ - int i, j; /* Loop counters */ + int i, j; /* Loop counters */ int cnt = 0; /* Number of matching column names */ int cntTab = 0; /* Number of matching table names */ + int nSubquery = 0; /* How many levels of subquery */ sqlite3 *db = pParse->db; /* The database connection */ struct SrcList_item *pItem; /* Use for looping over pSrcList items */ struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ @@ -74387,7 +72303,7 @@ static int lookupName( sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); return WRC_Abort; } - resolveAlias(pParse, pEList, j, pExpr, ""); + resolveAlias(pParse, pEList, j, pExpr, "", nSubquery); cnt = 1; pMatch = 0; assert( zTab==0 && zDb==0 ); @@ -74401,6 +72317,7 @@ static int lookupName( */ if( cnt==0 ){ pNC = pNC->pNext; + nSubquery++; } } @@ -74640,13 +72557,19 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ nId, zId); pNC->nErr++; } - if( is_agg ){ - pExpr->op = TK_AGG_FUNCTION; - pNC->ncFlags |= NC_HasAgg; - } if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg; sqlite3WalkExprList(pWalker, pList); - if( is_agg ) pNC->ncFlags |= NC_AllowAgg; + if( is_agg ){ + NameContext *pNC2 = pNC; + pExpr->op = TK_AGG_FUNCTION; + pExpr->op2 = 0; + while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){ + pExpr->op2++; + pNC2 = pNC2->pNext; + } + if( pNC2 ) pNC2->ncFlags |= NC_HasAgg; + pNC->ncFlags |= NC_AllowAgg; + } /* FIX ME: Compute pExpr->affinity based on the expected return ** type of the function */ @@ -74925,7 +72848,7 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy( resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); return 1; } - resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType); + resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType,0); } } return 0; @@ -77003,7 +74926,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( assert( !isRowid ); sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); - dest.affinity = (u8)affinity; + dest.affSdst = (u8)affinity; assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); pExpr->x.pSelect->iLimit = 0; if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){ @@ -77096,11 +75019,11 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( sqlite3SelectDestInit(&dest, 0, ++pParse->nMem); if( pExpr->op==TK_SELECT ){ dest.eDest = SRT_Mem; - sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iParm); + sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm); VdbeComment((v, "Init subquery result")); }else{ dest.eDest = SRT_Exists; - sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iParm); + sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); VdbeComment((v, "Init EXISTS result")); } sqlite3ExprDelete(pParse->db, pSel->pLimit); @@ -77110,7 +75033,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( if( sqlite3Select(pParse, pSel, &dest) ){ return 0; } - rReg = dest.iParm; + rReg = dest.iSDParm; ExprSetIrreducible(pExpr); break; } @@ -78425,9 +76348,12 @@ SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){ }else{ pFarg = pExpr->x.pList; } - sqlite3ExplainPrintf(pOut, "%sFUNCTION:%s(", - op==TK_AGG_FUNCTION ? "AGG_" : "", - pExpr->u.zToken); + if( op==TK_AGG_FUNCTION ){ + sqlite3ExplainPrintf(pOut, "AGG_FUNCTION%d:%s(", + pExpr->op2, pExpr->u.zToken); + }else{ + sqlite3ExplainPrintf(pOut, "FUNCTION:%s(", pExpr->u.zToken); + } if( pFarg ){ sqlite3ExplainExprList(pOut, pFarg); } @@ -79118,38 +77044,60 @@ SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){ } /* -** This is the expression callback for sqlite3FunctionUsesOtherSrc(). -** -** Determine if an expression references any table other than one of the -** tables in pWalker->u.pSrcList and abort if it does. +** An instance of the following structure is used by the tree walker +** to count references to table columns in the arguments of an +** aggregate function, in order to implement the +** sqlite3FunctionThisSrc() routine. */ -static int exprUsesOtherSrc(Walker *pWalker, Expr *pExpr){ - if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){ +struct SrcCount { + SrcList *pSrc; /* One particular FROM clause in a nested query */ + int nThis; /* Number of references to columns in pSrcList */ + int nOther; /* Number of references to columns in other FROM clauses */ +}; + +/* +** Count the number of references to columns. +*/ +static int exprSrcCount(Walker *pWalker, Expr *pExpr){ + /* The NEVER() on the second term is because sqlite3FunctionUsesThisSrc() + ** is always called before sqlite3ExprAnalyzeAggregates() and so the + ** TK_COLUMNs have not yet been converted into TK_AGG_COLUMN. If + ** sqlite3FunctionUsesThisSrc() is used differently in the future, the + ** NEVER() will need to be removed. */ + if( pExpr->op==TK_COLUMN || NEVER(pExpr->op==TK_AGG_COLUMN) ){ int i; - SrcList *pSrc = pWalker->u.pSrcList; + struct SrcCount *p = pWalker->u.pSrcCount; + SrcList *pSrc = p->pSrc; for(i=0; inSrc; i++){ - if( pExpr->iTable==pSrc->a[i].iCursor ) return WRC_Continue; + if( pExpr->iTable==pSrc->a[i].iCursor ) break; + } + if( inSrc ){ + p->nThis++; + }else{ + p->nOther++; } - return WRC_Abort; - }else{ - return WRC_Continue; } + return WRC_Continue; } /* -** Determine if any of the arguments to the pExpr Function references -** any SrcList other than pSrcList. Return true if they do. Return -** false if pExpr has no argument or has only constant arguments or -** only references tables named in pSrcList. +** Determine if any of the arguments to the pExpr Function reference +** pSrcList. Return true if they do. Also return true if the function +** has no arguments or has only constant arguments. Return false if pExpr +** references columns but not columns of tables found in pSrcList. */ -static int sqlite3FunctionUsesOtherSrc(Expr *pExpr, SrcList *pSrcList){ +SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){ Walker w; + struct SrcCount cnt; assert( pExpr->op==TK_AGG_FUNCTION ); memset(&w, 0, sizeof(w)); - w.xExprCallback = exprUsesOtherSrc; - w.u.pSrcList = pSrcList; - if( sqlite3WalkExprList(&w, pExpr->x.pList)!=WRC_Continue ) return 1; - return 0; + w.xExprCallback = exprSrcCount; + w.u.pSrcCount = &cnt; + cnt.pSrc = pSrcList; + cnt.nThis = 0; + cnt.nOther = 0; + sqlite3WalkExprList(&w, pExpr->x.pList); + return cnt.nThis>0 || cnt.nOther==0; } /* @@ -79268,7 +77216,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ } case TK_AGG_FUNCTION: { if( (pNC->ncFlags & NC_InAggFunc)==0 - && !sqlite3FunctionUsesOtherSrc(pExpr, pSrcList) + && pWalker->walkerDepth==pExpr->op2 ){ /* Check to see if pExpr is a duplicate of another aggregate ** function that is already in the pAggInfo structure @@ -80424,7 +78372,7 @@ static void openStatTable( "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols ); aRoot[i] = pParse->regRoot; - aCreateTbl[i] = 1; + aCreateTbl[i] = OPFLAG_P2ISREG; }else{ /* The table already exists. If zWhere is not NULL, delete all entries ** associated with the table zWhere. If zWhere is NULL, delete the @@ -80504,12 +78452,11 @@ static void stat3Init( nRow = (tRowcnt)sqlite3_value_int64(argv[0]); mxSample = sqlite3_value_int(argv[1]); n = sizeof(*p) + sizeof(p->a[0])*mxSample; - p = sqlite3_malloc( n ); + p = sqlite3MallocZero( n ); if( p==0 ){ sqlite3_result_error_nomem(context); return; } - memset(p, 0, n); p->a = (struct Stat3Sample*)&p[1]; p->nRow = nRow; p->mxSample = mxSample; @@ -82719,7 +80666,7 @@ SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ if( !db || db->pnBytesFreed==0 ){ char *zName = pIndex->zName; TESTONLY ( Index *pOld = ) sqlite3HashInsert( - &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0 + &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0 ); assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); assert( pOld==pIndex || pOld==0 ); @@ -83766,7 +81713,7 @@ SQLITE_PRIVATE void sqlite3EndTable( assert(pParse->nTab==1); sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); - sqlite3VdbeChangeP5(v, 1); + sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); pParse->nTab = 2; sqlite3SelectDestInit(&dest, SRT_Table, 1); sqlite3Select(pParse, pSelect, &dest); @@ -84582,9 +82529,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ pKey = sqlite3IndexKeyinfo(pParse, pIndex); sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, (char *)pKey, P4_KEYINFO_HANDOFF); - if( memRootPage>=0 ){ - sqlite3VdbeChangeP5(v, 1); - } + sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0)); #ifndef SQLITE_OMIT_MERGE_SORT /* Open the sorter cursor if we are to use one. */ @@ -84723,7 +82668,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( assert( pName && pName->z ); #ifndef SQLITE_OMIT_TEMPDB - /* If the index name was unqualified, check if the the table + /* If the index name was unqualified, check if the table ** is a temp table. If so, set the database to 1. Do not do this ** if initialising a database schema. */ @@ -86877,7 +84822,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( */ sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); pWInfo = sqlite3WhereBegin( - pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK + pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK, 0 ); if( pWInfo==0 ) goto delete_from_cleanup; regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, iRowid, 0); @@ -88021,8 +85966,19 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ assert( argc==1 ); UNUSED_PARAMETER(argc); switch( sqlite3_value_type(argv[0]) ){ - case SQLITE_INTEGER: case SQLITE_FLOAT: { + double r1, r2; + char zBuf[50]; + r1 = sqlite3_value_double(argv[0]); + sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1); + sqlite3AtoF(zBuf, &r2, 20, SQLITE_UTF8); + if( r1!=r2 ){ + sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.20e", r1); + } + sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); + break; + } + case SQLITE_INTEGER: { sqlite3_result_value(context, argv[0]); break; } @@ -89334,7 +87290,7 @@ static void fkScanChildren( ** clause. If the constraint is not deferred, throw an exception for ** each row found. Otherwise, for deferred constraints, increment the ** deferred constraint counter by nIncr for each row selected. */ - pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0); + pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0); if( nIncr>0 && pFKey->isDeferred==0 ){ sqlite3ParseToplevel(pParse)->mayAbort = 1; } @@ -90592,7 +88548,7 @@ SQLITE_PRIVATE void sqlite3Insert( VdbeComment((v, "SELECT eof flag")); sqlite3SelectDestInit(&dest, SRT_Coroutine, ++pParse->nMem); addrSelect = sqlite3VdbeCurrentAddr(v)+2; - sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iParm); + sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iSDParm); j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); VdbeComment((v, "Jump over SELECT coroutine")); @@ -90603,15 +88559,15 @@ SQLITE_PRIVATE void sqlite3Insert( goto insert_cleanup; } sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */ - sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm); /* yield X */ + sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); /* yield X */ sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort); VdbeComment((v, "End of SELECT coroutine")); sqlite3VdbeJumpHere(v, j1); /* label B: */ - regFromSelect = dest.iMem; + regFromSelect = dest.iSdst; assert( pSelect->pEList ); nColumn = pSelect->pEList->nExpr; - assert( dest.nMem==nColumn ); + assert( dest.nSdst==nColumn ); /* Set useTempTable to TRUE if the result of the SELECT statement ** should be written into a temporary table (template 4). Set to @@ -90647,7 +88603,7 @@ SQLITE_PRIVATE void sqlite3Insert( regRec = sqlite3GetTempReg(pParse); regTempRowid = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn); - addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm); + addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); addrIf = sqlite3VdbeAddOp1(v, OP_If, regEof); sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec); sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid); @@ -90784,7 +88740,7 @@ SQLITE_PRIVATE void sqlite3Insert( ** goto C ** D: ... */ - addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm); + addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); addrInsTop = sqlite3VdbeAddOp1(v, OP_If, regEof); } @@ -91266,7 +89222,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( case OE_Replace: { /* If there are DELETE triggers on this table and the ** recursive-triggers flag is set, call GenerateRowDelete() to - ** remove the conflicting row from the the table. This will fire + ** remove the conflicting row from the table. This will fire ** the triggers and remove both the table and index b-tree entries. ** ** Otherwise, if there are no triggers or the recursive-triggers @@ -94267,6 +92223,19 @@ SQLITE_PRIVATE void sqlite3Pragma( int isQuick = (sqlite3Tolower(zLeft[0])=='q'); + /* If the PRAGMA command was of the form "PRAGMA .integrity_check", + ** then iDb is set to the index of the database identified by . + ** In this case, the integrity of database iDb only is verified by + ** the VDBE created below. + ** + ** Otherwise, if the command was simply "PRAGMA integrity_check" (or + ** "PRAGMA quick_check"), then iDb is set to 0. In this case, set iDb + ** to -1 here, to indicate that the VDBE should verify the integrity + ** of all attached databases. */ + assert( iDb>=0 ); + assert( iDb==0 || pId2->z ); + if( pId2->z==0 ) iDb = -1; + /* Initialize the VDBE program */ if( sqlite3ReadSchema(pParse) ) goto pragma_out; pParse->nMem = 6; @@ -94290,6 +92259,7 @@ SQLITE_PRIVATE void sqlite3Pragma( int cnt = 0; if( OMIT_TEMPDB && i==1 ) continue; + if( iDb>=0 && i!=iDb ) continue; sqlite3CodeVerifySchema(pParse, i); addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */ @@ -94301,7 +92271,7 @@ SQLITE_PRIVATE void sqlite3Pragma( ** Begin by filling registers 2, 3, ... with the root pages numbers ** for all tables and indices in the database. */ - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, i, 0) ); pTbls = &db->aDb[i].pSchema->tblHash; for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); @@ -95625,10 +93595,10 @@ static void clearSelect(sqlite3 *db, Select *p){ */ SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){ pDest->eDest = (u8)eDest; - pDest->iParm = iParm; - pDest->affinity = 0; - pDest->iMem = 0; - pDest->nMem = 0; + pDest->iSDParm = iParm; + pDest->affSdst = 0; + pDest->iSdst = 0; + pDest->nSdst = 0; } @@ -96140,7 +94110,7 @@ static void selectInnerLoop( int hasDistinct; /* True if the DISTINCT keyword is present */ int regResult; /* Start of memory holding result set */ int eDest = pDest->eDest; /* How to dispose of results */ - int iParm = pDest->iParm; /* First argument to disposal method */ + int iParm = pDest->iSDParm; /* First argument to disposal method */ int nResultCol; /* Number of result columns */ assert( v ); @@ -96158,14 +94128,14 @@ static void selectInnerLoop( }else{ nResultCol = pEList->nExpr; } - if( pDest->iMem==0 ){ - pDest->iMem = pParse->nMem+1; - pDest->nMem = nResultCol; + if( pDest->iSdst==0 ){ + pDest->iSdst = pParse->nMem+1; + pDest->nSdst = nResultCol; pParse->nMem += nResultCol; }else{ - assert( pDest->nMem==nResultCol ); + assert( pDest->nSdst==nResultCol ); } - regResult = pDest->iMem; + regResult = pDest->iSdst; if( nColumn>0 ){ for(i=0; iaffinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity); + p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst); if( pOrderBy ){ /* At first glance you would think we could optimize out the ** ORDER BY in this case since the order of entries in the set @@ -96299,7 +94269,7 @@ static void selectInnerLoop( pushOntoSorter(pParse, pOrderBy, p, r1); sqlite3ReleaseTempReg(pParse, r1); }else if( eDest==SRT_Coroutine ){ - sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm); + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); }else{ sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn); sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn); @@ -96479,7 +94449,7 @@ static void generateSortTail( ExprList *pOrderBy = p->pOrderBy; int eDest = pDest->eDest; - int iParm = pDest->iParm; + int iParm = pDest->iSDParm; int regRow; int regRowid; @@ -96538,17 +94508,17 @@ static void generateSortTail( testcase( eDest==SRT_Output ); testcase( eDest==SRT_Coroutine ); for(i=0; iiMem+i ); - sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i); + assert( regRow!=pDest->iSdst+i ); + sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iSdst+i); if( i==0 ){ sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); } } if( eDest==SRT_Output ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn); - sqlite3ExprCacheAffinityChange(pParse, pDest->iMem, nColumn); + sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn); + sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn); }else{ - sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm); + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); } break; } @@ -97199,7 +95169,7 @@ static int multiSelect( */ if( dest.eDest==SRT_EphemTab ){ assert( p->pEList ); - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, p->pEList->nExpr); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr); sqlite3VdbeChangeP5(v, BTREE_UNORDERED); dest.eDest = SRT_Table; } @@ -97285,7 +95255,7 @@ static int multiSelect( ** of a 3-way or more compound */ assert( p->pLimit==0 ); /* Not allowed on leftward elements */ assert( p->pOffset==0 ); /* Not allowed on leftward elements */ - unionTab = dest.iParm; + unionTab = dest.iSDParm; }else{ /* We will need to create our own temporary table to hold the ** intermediate results. @@ -97342,7 +95312,7 @@ static int multiSelect( /* Convert the data in the temporary table into whatever form ** it is that we currently need. */ - assert( unionTab==dest.iParm || dest.eDest!=priorOp ); + assert( unionTab==dest.iSDParm || dest.eDest!=priorOp ); if( dest.eDest!=priorOp ){ int iCont, iBreak, iStart; assert( p->pEList ); @@ -97406,7 +95376,7 @@ static int multiSelect( p->pLimit = 0; pOffset = p->pOffset; p->pOffset = 0; - intersectdest.iParm = tab2; + intersectdest.iSDParm = tab2; explainSetInteger(iSub2, pParse->iNextSelectId); rc = sqlite3Select(pParse, p, &intersectdest); testcase( rc!=SQLITE_OK ); @@ -97500,8 +95470,8 @@ static int multiSelect( } multi_select_end: - pDest->iMem = dest.iMem; - pDest->nMem = dest.nMem; + pDest->iSdst = dest.iSdst; + pDest->nSdst = dest.nSdst; sqlite3SelectDelete(db, pDelete); return rc; } @@ -97511,8 +95481,8 @@ multi_select_end: ** Code an output subroutine for a coroutine implementation of a ** SELECT statment. ** -** The data to be output is contained in pIn->iMem. There are -** pIn->nMem columns to be output. pDest is where the output should +** The data to be output is contained in pIn->iSdst. There are +** pIn->nSdst columns to be output. pDest is where the output should ** be sent. ** ** regReturn is the number of the register holding the subroutine @@ -97550,16 +95520,16 @@ static int generateOutputSubroutine( if( regPrev ){ int j1, j2; j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); - j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem, + j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst, (char*)pKeyInfo, p4type); sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); sqlite3VdbeJumpHere(v, j1); - sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem); + sqlite3ExprCodeCopy(pParse, pIn->iSdst, regPrev+1, pIn->nSdst); sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); } if( pParse->db->mallocFailed ) return 0; - /* Suppress the the first OFFSET entries if there is an OFFSET clause + /* Suppress the first OFFSET entries if there is an OFFSET clause */ codeOffset(v, p, iContinue); @@ -97572,9 +95542,9 @@ static int generateOutputSubroutine( int r2 = sqlite3GetTempReg(pParse); testcase( pDest->eDest==SRT_Table ); testcase( pDest->eDest==SRT_EphemTab ); - sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, pIn->nMem, r1); - sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iParm, r2); - sqlite3VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2); + sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1); + sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2); + sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2); sqlite3VdbeChangeP5(v, OPFLAG_APPEND); sqlite3ReleaseTempReg(pParse, r2); sqlite3ReleaseTempReg(pParse, r1); @@ -97588,13 +95558,13 @@ static int generateOutputSubroutine( */ case SRT_Set: { int r1; - assert( pIn->nMem==1 ); + assert( pIn->nSdst==1 ); p->affinity = - sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity); + sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst); r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iMem, 1, r1, &p->affinity, 1); - sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, 1); - sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iParm, r1); + sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &p->affinity, 1); + sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1); sqlite3ReleaseTempReg(pParse, r1); break; } @@ -97603,7 +95573,7 @@ static int generateOutputSubroutine( /* If any row exist in the result set, record that fact and abort. */ case SRT_Exists: { - sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iParm); + sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iSDParm); /* The LIMIT clause will terminate the loop for us */ break; } @@ -97614,23 +95584,23 @@ static int generateOutputSubroutine( ** of the scan loop. */ case SRT_Mem: { - assert( pIn->nMem==1 ); - sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iParm, 1); + assert( pIn->nSdst==1 ); + sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1); /* The LIMIT clause will jump out of the loop for us */ break; } #endif /* #ifndef SQLITE_OMIT_SUBQUERY */ /* The results are stored in a sequence of registers - ** starting at pDest->iMem. Then the co-routine yields. + ** starting at pDest->iSdst. Then the co-routine yields. */ case SRT_Coroutine: { - if( pDest->iMem==0 ){ - pDest->iMem = sqlite3GetTempRange(pParse, pIn->nMem); - pDest->nMem = pIn->nMem; + if( pDest->iSdst==0 ){ + pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst); + pDest->nSdst = pIn->nSdst; } - sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iMem, pDest->nMem); - sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm); + sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst); + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); break; } @@ -97644,8 +95614,8 @@ static int generateOutputSubroutine( */ default: { assert( pDest->eDest==SRT_Output ); - sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iMem, pIn->nMem); - sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, pIn->nMem); + sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst); + sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst); break; } } @@ -98064,7 +96034,7 @@ static int multiSelectOrderBy( */ sqlite3VdbeResolveLabel(v, labelCmpr); sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); - sqlite3VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, nOrderBy, + sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy, (char*)pKeyMerge, P4_KEYINFO_HANDOFF); sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); @@ -98278,6 +96248,12 @@ static void substSelect( ** operators have an implied DISTINCT which is disallowed by ** restriction (4). ** +** Also, each component of the sub-query must return the same number +** of result columns. This is actually a requirement for any compound +** SELECT statement, but all the code here does is make sure that no +** such (illegal) sub-query is flattened. The caller will detect the +** syntax error and return a detailed message. +** ** (18) If the sub-query is a compound select, then all terms of the ** ORDER by clause of the parent must be simple references to ** columns of the sub-query. @@ -98421,6 +96397,7 @@ static int flattenSubquery( if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 || (pSub1->pPrior && pSub1->op!=TK_ALL) || pSub1->pSrc->nSrc<1 + || pSub->pEList->nExpr!=pSub1->pEList->nExpr ){ return 0; } @@ -98738,7 +96715,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ if( IsVirtual(pTab) ) return 0; if( pExpr->op!=TK_AGG_FUNCTION ) return 0; - if( pAggInfo->nFunc==0 ) return 0; + if( NEVER(pAggInfo->nFunc==0) ) return 0; if( (pAggInfo->aFunc[0].pFunc->flags&SQLITE_FUNC_COUNT)==0 ) return 0; if( pExpr->flags&EP_Distinct ) return 0; @@ -99110,7 +97087,7 @@ static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){ /* -** This routine sets of a SELECT statement for processing. The +** This routine sets up a SELECT statement for processing. The ** following is accomplished: ** ** * VDBE Cursor numbers are assigned to all FROM-clause terms. @@ -99142,7 +97119,8 @@ SQLITE_PRIVATE void sqlite3SelectPrep( ** ** The aggregate accumulator is a set of memory cells that hold ** intermediate results while calculating an aggregate. This -** routine simply stores NULLs in all of those memory cells. +** routine generates code that stores NULLs in all of those memory +** cells. */ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ Vdbe *v = pParse->pVdbe; @@ -99310,23 +97288,24 @@ static void explainSimpleCount( ** ** SRT_Mem Only valid if the result is a single column. ** Store the first column of the first result row -** in register pDest->iParm then abandon the rest +** in register pDest->iSDParm then abandon the rest ** of the query. This destination implies "LIMIT 1". ** ** SRT_Set The result must be a single column. Store each -** row of result as the key in table pDest->iParm. -** Apply the affinity pDest->affinity before storing +** row of result as the key in table pDest->iSDParm. +** Apply the affinity pDest->affSdst before storing ** results. Used to implement "IN (SELECT ...)". ** -** SRT_Union Store results as a key in a temporary table pDest->iParm. +** SRT_Union Store results as a key in a temporary table +** identified by pDest->iSDParm. ** -** SRT_Except Remove results from the temporary table pDest->iParm. +** SRT_Except Remove results from the temporary table pDest->iSDParm. ** -** SRT_Table Store results in temporary table pDest->iParm. +** SRT_Table Store results in temporary table pDest->iSDParm. ** This is like SRT_EphemTab except that the table ** is assumed to already be open. ** -** SRT_EphemTab Create an temporary table pDest->iParm and store +** SRT_EphemTab Create an temporary table pDest->iSDParm and store ** the result there. The cursor is left open after ** returning. This is like SRT_Table except that ** this destination uses OP_OpenEphemeral to create @@ -99334,9 +97313,9 @@ static void explainSimpleCount( ** ** SRT_Coroutine Generate a co-routine that returns a new row of ** results each time it is invoked. The entry point -** of the co-routine is stored in register pDest->iParm. +** of the co-routine is stored in register pDest->iSDParm. ** -** SRT_Exists Store a 1 in memory cell pDest->iParm if the result +** SRT_Exists Store a 1 in memory cell pDest->iSDParm if the result ** set is not empty. ** ** SRT_Discard Throw the results away. This is used by SELECT @@ -99580,7 +97559,7 @@ SQLITE_PRIVATE int sqlite3Select( /* If the output is destined for a temporary table, open that table. */ if( pDest->eDest==SRT_EphemTab ){ - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iParm, pEList->nExpr); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); } /* Set the limiter. @@ -99611,7 +97590,7 @@ SQLITE_PRIVATE int sqlite3Select( ExprList *pDist = (isDistinct ? p->pEList : 0); /* Begin the database scan. */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, pDist, 0); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, pDist, 0,0); if( pWInfo==0 ) goto select_end; if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut; @@ -99784,7 +97763,7 @@ SQLITE_PRIVATE int sqlite3Select( ** in the right order to begin with. */ sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0, 0); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0, 0, 0); if( pWInfo==0 ) goto select_end; if( pGroupBy==0 ){ /* The optimizer is able to deliver rows in group by order so @@ -100053,7 +98032,7 @@ SQLITE_PRIVATE int sqlite3Select( ** of output. */ resetAccumulator(pParse, &sAggInfo); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax, 0, flag); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax,0,flag,0); if( pWInfo==0 ){ sqlite3ExprListDelete(db, pDel); goto select_end; @@ -100525,7 +98504,7 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( iDb = 1; pName = pName1; }else{ - /* Figure out the db that the the trigger will be created in */ + /* Figure out the db that the trigger will be created in */ iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); if( iDb<0 ){ goto trigger_cleanup; @@ -101853,7 +99832,7 @@ SQLITE_PRIVATE void sqlite3Update( */ sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid); pWInfo = sqlite3WhereBegin( - pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED + pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, 0 ); if( pWInfo==0 ) goto update_cleanup; okOnePass = pWInfo->okOnePass; @@ -102694,7 +100673,7 @@ SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){ assert( db ); assert( pVTab->nRef>0 ); - assert( sqlite3SafetyCheckOk(db) ); + assert( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ZOMBIE ); pVTab->nRef--; if( pVTab->nRef==0 ){ @@ -107282,7 +105261,7 @@ static int codeAllEqualityTerms( int r1; int k = pIdx->aiColumn[j]; pTerm = findTerm(pWC, iCur, k, notReady, pLevel->plan.wsFlags, pIdx); - if( NEVER(pTerm==0) ) break; + if( pTerm==0 ) break; /* The following true for indices with redundant columns. ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */ testcase( (pTerm->wtFlags & TERM_CODED)!=0 ); @@ -107957,6 +105936,8 @@ static Bitmask codeOneLoopStart( */ WhereClause *pOrWc; /* The OR-clause broken out into subterms */ SrcList *pOrTab; /* Shortened table list or OR-clause generation */ + Index *pCov = 0; /* Potential covering index (or NULL) */ + int iCovCur = pParse->nTab++; /* Cursor used for index scans (if any) */ int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */ int regRowset = 0; /* Register for RowSet object */ @@ -107975,7 +105956,7 @@ static Bitmask codeOneLoopStart( pLevel->op = OP_Return; pLevel->p1 = regReturn; - /* Set up a new SrcList ni pOrTab containing the table being scanned + /* Set up a new SrcList in pOrTab containing the table being scanned ** by this loop in the a[0] slot and all notReady tables in a[1..] slots. ** This becomes the SrcList in the recursive call to sqlite3WhereBegin(). */ @@ -108052,8 +106033,10 @@ static Bitmask codeOneLoopStart( /* Loop through table entries that match term pOrTerm. */ pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY | - WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY); + WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur); + assert( pSubWInfo || pParse->nErr || pParse->db->mallocFailed ); if( pSubWInfo ){ + WhereLevel *pLvl; explainOneScan( pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 ); @@ -108074,11 +106057,36 @@ static Bitmask codeOneLoopStart( */ if( pSubWInfo->untestedTerms ) untestedTerms = 1; + /* If all of the OR-connected terms are optimized using the same + ** index, and the index is opened using the same cursor number + ** by each call to sqlite3WhereBegin() made by this loop, it may + ** be possible to use that index as a covering index. + ** + ** If the call to sqlite3WhereBegin() above resulted in a scan that + ** uses an index, and this is either the first OR-connected term + ** processed or the index is the same as that used by all previous + ** terms, set pCov to the candidate covering index. Otherwise, set + ** pCov to NULL to indicate that no candidate covering index will + ** be available. + */ + pLvl = &pSubWInfo->a[0]; + if( (pLvl->plan.wsFlags & WHERE_INDEXED)!=0 + && (pLvl->plan.wsFlags & WHERE_TEMP_INDEX)==0 + && (ii==0 || pLvl->plan.u.pIdx==pCov) + ){ + assert( pLvl->iIdxCur==iCovCur ); + pCov = pLvl->plan.u.pIdx; + }else{ + pCov = 0; + } + /* Finish the loop through table entries that match term pOrTerm. */ sqlite3WhereEnd(pSubWInfo); } } } + pLevel->u.pCovidx = pCov; + pLevel->iIdxCur = iCovCur; if( pAndExpr ){ pAndExpr->pLeft = 0; sqlite3ExprDelete(pParse->db, pAndExpr); @@ -108296,7 +106304,8 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( Expr *pWhere, /* The WHERE clause */ ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */ ExprList *pDistinct, /* The select-list for DISTINCT queries - or NULL */ - u16 wctrlFlags /* One of the WHERE_* flags defined in sqliteInt.h */ + u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */ + int iIdxCur /* If WHERE_ONETABLE_ONLY is set, index cursor number */ ){ int i; /* Loop counter */ int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */ @@ -108616,7 +106625,13 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( testcase( bestPlan.plan.wsFlags & WHERE_INDEXED ); testcase( bestPlan.plan.wsFlags & WHERE_TEMP_INDEX ); if( bestPlan.plan.wsFlags & (WHERE_INDEXED|WHERE_TEMP_INDEX) ){ - pLevel->iIdxCur = pParse->nTab++; + if( (wctrlFlags & WHERE_ONETABLE_ONLY) + && (bestPlan.plan.wsFlags & WHERE_TEMP_INDEX)==0 + ){ + pLevel->iIdxCur = iIdxCur; + }else{ + pLevel->iIdxCur = pParse->nTab++; + } }else{ pLevel->iIdxCur = -1; } @@ -108717,10 +106732,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ Index *pIx = pLevel->plan.u.pIdx; KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx); - int iIdxCur = pLevel->iIdxCur; + int iIndexCur = pLevel->iIdxCur; assert( pIx->pSchema==pTab->pSchema ); - assert( iIdxCur>=0 ); - sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIx->tnum, iDb, + assert( iIndexCur>=0 ); + sqlite3VdbeAddOp4(v, OP_OpenRead, iIndexCur, pIx->tnum, iDb, (char*)pKey, P4_KEYINFO_HANDOFF); VdbeComment((v, "%s", pIx->zName)); } @@ -108868,6 +106883,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ */ assert( pWInfo->nLevel==1 || pWInfo->nLevel==pTabList->nSrc ); for(i=0, pLevel=pWInfo->a; inLevel; i++, pLevel++){ + Index *pIdx = 0; struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; Table *pTab = pTabItem->pTab; assert( pTab!=0 ); @@ -108897,12 +106913,15 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ ** that reference the table and converts them into opcodes that ** reference the index. */ - if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 && !db->mallocFailed){ + if( pLevel->plan.wsFlags & WHERE_INDEXED ){ + pIdx = pLevel->plan.u.pIdx; + }else if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){ + pIdx = pLevel->u.pCovidx; + } + if( pIdx && !db->mallocFailed){ int k, j, last; VdbeOp *pOp; - Index *pIdx = pLevel->plan.u.pIdx; - assert( pIdx!=0 ); pOp = sqlite3VdbeGetOp(v, pWInfo->iTop); last = sqlite3VdbeCurrentAddr(v); for(k=pWInfo->iTop; kmutex) ); + if( db->pVdbe ) return 1; + for(j=0; jnDb; j++){ + Btree *pBt = db->aDb[j].pBt; + if( pBt && sqlite3BtreeIsInBackup(pBt) ) return 1; + } + return 0; +} + /* ** Close an existing SQLite database */ -SQLITE_API int sqlite3_close(sqlite3 *db){ - HashElem *i; /* Hash table iterator */ - int j; - +static int sqlite3Close(sqlite3 *db, int forceZombie){ if( !db ){ return SQLITE_OK; } @@ -114377,25 +112408,63 @@ SQLITE_API int sqlite3_close(sqlite3 *db){ */ sqlite3VtabRollback(db); - /* If there are any outstanding VMs, return SQLITE_BUSY. */ - if( db->pVdbe ){ - sqlite3Error(db, SQLITE_BUSY, - "unable to close due to unfinalised statements"); + /* Legacy behavior (sqlite3_close() behavior) is to return + ** SQLITE_BUSY if the connection can not be closed immediately. + */ + if( !forceZombie && connectionIsBusy(db) ){ + sqlite3Error(db, SQLITE_BUSY, "unable to close due to unfinalized " + "statements or unfinished backups"); sqlite3_mutex_leave(db->mutex); return SQLITE_BUSY; } - assert( sqlite3SafetyCheckSickOrOk(db) ); - for(j=0; jnDb; j++){ - Btree *pBt = db->aDb[j].pBt; - if( pBt && sqlite3BtreeIsInBackup(pBt) ){ - sqlite3Error(db, SQLITE_BUSY, - "unable to close due to unfinished backup operation"); - sqlite3_mutex_leave(db->mutex); - return SQLITE_BUSY; - } + /* Convert the connection into a zombie and then close it. + */ + db->magic = SQLITE_MAGIC_ZOMBIE; + sqlite3LeaveMutexAndCloseZombie(db); + return SQLITE_OK; +} + +/* +** Two variations on the public interface for closing a database +** connection. The sqlite3_close() version returns SQLITE_BUSY and +** leaves the connection option if there are unfinalized prepared +** statements or unfinished sqlite3_backups. The sqlite3_close_v2() +** version forces the connection to become a zombie if there are +** unclosed resources, and arranges for deallocation when the last +** prepare statement or sqlite3_backup closes. +*/ +SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); } +SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); } + + +/* +** Close the mutex on database connection db. +** +** Furthermore, if database connection db is a zombie (meaning that there +** has been a prior call to sqlite3_close(db) or sqlite3_close_v2(db)) and +** every sqlite3_stmt has now been finalized and every sqlite3_backup has +** finished, then free all resources. +*/ +SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ + HashElem *i; /* Hash table iterator */ + int j; + + /* If there are outstanding sqlite3_stmt or sqlite3_backup objects + ** or if the connection has not yet been closed by sqlite3_close_v2(), + ** then just leave the mutex and return. + */ + if( db->magic!=SQLITE_MAGIC_ZOMBIE || connectionIsBusy(db) ){ + sqlite3_mutex_leave(db->mutex); + return; } + /* If we reach this point, it means that the database connection has + ** closed all sqlite3_stmt and sqlite3_backup objects and has been + ** pased to sqlite3_close (meaning that it is a zombie). Therefore, + ** go ahead and free all resources. + */ + /* Free any outstanding Savepoint structures. */ sqlite3CloseSavepoints(db); @@ -114483,7 +112552,6 @@ SQLITE_API int sqlite3_close(sqlite3 *db){ sqlite3_free(db->lookaside.pStart); } sqlite3_free(db); - return SQLITE_OK; } /* @@ -118027,10 +116095,20 @@ SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int* SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **); SQLITE_PRIVATE int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **); +#ifndef SQLITE_DISABLE_FTS4_DEFERRED SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *); SQLITE_PRIVATE int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int); SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *); SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *); +SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *); +#else +# define sqlite3Fts3FreeDeferredTokens(x) +# define sqlite3Fts3DeferToken(x,y,z) SQLITE_OK +# define sqlite3Fts3CacheDeferredDoclists(x) SQLITE_OK +# define sqlite3Fts3FreeDeferredDoclists(x) +# define sqlite3Fts3DeferredTokenList(x,y,z) SQLITE_OK +#endif + SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *); SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *, int *); @@ -118139,8 +116217,6 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iC SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *); SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr); -SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *); - /* fts3_unicode2.c (functions generated by parsing unicode text files) */ #ifdef SQLITE_ENABLE_FTS4_UNICODE61 SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int); @@ -122298,6 +120374,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){ fts3EvalAllocateReaders(pCsr, pCsr->pExpr, &nToken, &nOr, &rc); /* Determine which, if any, tokens in the expression should be deferred. */ +#ifndef SQLITE_DISABLE_FTS4_DEFERRED if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){ Fts3TokenAndCost *aTC; Fts3Expr **apOr; @@ -122328,6 +120405,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){ sqlite3_free(aTC); } } +#endif fts3EvalStartReaders(pCsr, pCsr->pExpr, 1, &rc); return rc; @@ -122711,6 +120789,7 @@ static int fts3EvalTestExpr( break; default: { +#ifndef SQLITE_DISABLE_FTS4_DEFERRED if( pCsr->pDeferred && (pExpr->iDocid==pCsr->iPrevId || pExpr->bDeferred) ){ @@ -122722,7 +120801,9 @@ static int fts3EvalTestExpr( *pRc = fts3EvalDeferredPhrase(pCsr, pPhrase); bHit = (pPhrase->doclist.pList!=0); pExpr->iDocid = pCsr->iPrevId; - }else{ + }else +#endif + { bHit = (pExpr->bEof==0 && pExpr->iDocid==pCsr->iPrevId); } break; @@ -129421,7 +127502,7 @@ static int fts3SegmentMerge( if( iLevel==FTS3_SEGCURSOR_ALL ){ /* This call is to merge all segments in the database to a single - ** segment. The level of the new segment is equal to the the numerically + ** segment. The level of the new segment is equal to the numerically ** greatest segment level currently present in the database for this ** index. The idx of the new segment is always 0. */ if( csr.nSegment==1 ){ @@ -130051,7 +128132,7 @@ static int fts3IncrmergePush( pNode->key.n = nTerm; } }else{ - /* Otherwise, flush the the current node of layer iLayer to disk. + /* Otherwise, flush the current node of layer iLayer to disk. ** Then allocate a new, empty sibling node. The key will be written ** into the parent of this node. */ rc = fts3WriteSegment(p, pNode->iBlock, pNode->block.a, pNode->block.n); @@ -131498,6 +129579,7 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ return rc; } +#ifndef SQLITE_DISABLE_FTS4_DEFERRED /* ** Delete all cached deferred doclists. Deferred doclists are cached ** (allocated) by the sqlite3Fts3CacheDeferredDoclists() function. @@ -131635,6 +129717,7 @@ SQLITE_PRIVATE int sqlite3Fts3DeferToken( return SQLITE_OK; } +#endif /* ** SQLite value pRowid contains the rowid of a row that may or may not be @@ -133899,7 +131982,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){ } assert( aEntry[0]=aEntry[iRes] ); - return (c >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF))); + return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF))); } return 1; } @@ -138179,7 +136262,7 @@ static int icuNext( while( iStartaChar, iWhite, pCsr->nChar, c); + U16_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c); if( u_isspace(c) ){ iStart = iWhite; }else{ diff --git a/db/sqlite3/src/sqlite3.h b/db/sqlite3/src/sqlite3.h index 0a1cf9db7dbf..8c994c1e04ee 100644 --- a/db/sqlite3/src/sqlite3.h +++ b/db/sqlite3/src/sqlite3.h @@ -107,9 +107,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.7.13" -#define SQLITE_VERSION_NUMBER 3007013 -#define SQLITE_SOURCE_ID "2012-06-11 02:05:22 f5b5a13f7394dc143aa136f1d4faba6839eaa6dc" +#define SQLITE_VERSION "3.7.14" +#define SQLITE_VERSION_NUMBER 3007014 +#define SQLITE_SOURCE_ID "2012-09-03 15:42:36 c0d89d4a9752922f9e367362366efde4f1b06f2a" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -219,7 +219,8 @@ SQLITE_API int sqlite3_threadsafe(void); ** the opaque structure named "sqlite3". It is useful to think of an sqlite3 ** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and ** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()] -** is its destructor. There are many other interfaces (such as +** and [sqlite3_close_v2()] are its destructors. There are many other +** interfaces (such as ** [sqlite3_prepare_v2()], [sqlite3_create_function()], and ** [sqlite3_busy_timeout()] to name but three) that are methods on an ** sqlite3 object. @@ -266,28 +267,46 @@ typedef sqlite_uint64 sqlite3_uint64; /* ** CAPI3REF: Closing A Database Connection ** -** ^The sqlite3_close() routine is the destructor for the [sqlite3] object. -** ^Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is -** successfully destroyed and all associated resources are deallocated. +** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors +** for the [sqlite3] object. +** ^Calls to sqlite3_close() and sqlite3_close_v2() return SQLITE_OK if +** the [sqlite3] object is successfully destroyed and all associated +** resources are deallocated. ** -** Applications must [sqlite3_finalize | finalize] all [prepared statements] -** and [sqlite3_blob_close | close] all [BLOB handles] associated with -** the [sqlite3] object prior to attempting to close the object. ^If +** ^If the database connection is associated with unfinalized prepared +** statements or unfinished sqlite3_backup objects then sqlite3_close() +** will leave the database connection open and return [SQLITE_BUSY]. +** ^If sqlite3_close_v2() is called with unfinalized prepared statements +** and unfinished sqlite3_backups, then the database connection becomes +** an unusable "zombie" which will automatically be deallocated when the +** last prepared statement is finalized or the last sqlite3_backup is +** finished. The sqlite3_close_v2() interface is intended for use with +** host languages that are garbage collected, and where the order in which +** destructors are called is arbitrary. +** +** Applications should [sqlite3_finalize | finalize] all [prepared statements], +** [sqlite3_blob_close | close] all [BLOB handles], and +** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated +** with the [sqlite3] object prior to attempting to close the object. ^If ** sqlite3_close() is called on a [database connection] that still has -** outstanding [prepared statements] or [BLOB handles], then it returns -** SQLITE_BUSY. +** outstanding [prepared statements], [BLOB handles], and/or +** [sqlite3_backup] objects then it returns SQLITE_OK but the deallocation +** of resources is deferred until all [prepared statements], [BLOB handles], +** and [sqlite3_backup] objects are also destroyed. ** -** ^If [sqlite3_close()] is invoked while a transaction is open, +** ^If an [sqlite3] object is destroyed while a transaction is open, ** the transaction is automatically rolled back. ** -** The C parameter to [sqlite3_close(C)] must be either a NULL +** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)] +** must be either a NULL ** pointer or an [sqlite3] object pointer obtained ** from [sqlite3_open()], [sqlite3_open16()], or ** [sqlite3_open_v2()], and not previously closed. -** ^Calling sqlite3_close() with a NULL pointer argument is a -** harmless no-op. +** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer +** argument is a harmless no-op. */ -SQLITE_API int sqlite3_close(sqlite3 *); +SQLITE_API int sqlite3_close(sqlite3*); +SQLITE_API int sqlite3_close_v2(sqlite3*); /* ** The type for a callback function. @@ -498,7 +517,7 @@ SQLITE_API int sqlite3_exec( ** CAPI3REF: Device Characteristics ** ** The xDeviceCharacteristics method of the [sqlite3_io_methods] -** object returns an integer which is a vector of the these +** object returns an integer which is a vector of these ** bit values expressing I/O characteristics of the mass storage ** device that holds the file that the [sqlite3_io_methods] ** refers to. @@ -2648,6 +2667,12 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** codepage is currently defined. Filenames containing international ** characters must be converted to UTF-8 prior to passing them into ** sqlite3_open() or sqlite3_open_v2(). +** +** Note to Windows Runtime users: The temporary directory must be set +** prior to calling sqlite3_open() or sqlite3_open_v2(). Otherwise, various +** features that require the use of temporary files may fail. +** +** See also: [sqlite3_temp_directory] */ SQLITE_API int sqlite3_open( const char *filename, /* Database filename (UTF-8) */ @@ -3140,8 +3165,11 @@ typedef struct sqlite3_context sqlite3_context; ** ^(In those routines that have a fourth argument, its value is the ** number of bytes in the parameter. To be clear: the value is the ** number of bytes in the value, not the number of characters.)^ -** ^If the fourth parameter is negative, the length of the string is +** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16() +** is negative, then the length of the string is ** the number of bytes up to the first zero terminator. +** If the fourth parameter to sqlite3_bind_blob() is negative, then +** the behavior is undefined. ** If a non-negative fourth parameter is provided to sqlite3_bind_text() ** or sqlite3_bind_text16() then that parameter must be the byte offset ** where the NUL terminator would occur assuming the string were NUL @@ -4138,11 +4166,11 @@ typedef void (*sqlite3_destructor_type)(void*); ** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() ** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. ** -** ^The sqlite3_result_toobig() interface causes SQLite to throw an error -** indicating that a string or BLOB is too long to represent. +** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an +** error indicating that a string or BLOB is too long to represent. ** -** ^The sqlite3_result_nomem() interface causes SQLite to throw an error -** indicating that a memory allocation failed. +** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an +** error indicating that a memory allocation failed. ** ** ^The sqlite3_result_int() interface sets the return value ** of the application-defined function to be the 32-bit signed integer @@ -4449,6 +4477,21 @@ SQLITE_API int sqlite3_sleep(int); ** Hence, if this variable is modified directly, either it should be ** made NULL or made to point to memory obtained from [sqlite3_malloc] ** or else the use of the [temp_store_directory pragma] should be avoided. +** +** Note to Windows Runtime users: The temporary directory must be set +** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various +** features that require the use of temporary files may fail. Here is an +** example of how to do this using C++ with the Windows Runtime: +** +**
    +** LPCWSTR zPath = Windows::Storage::ApplicationData::Current->
    +**       TemporaryFolder->Path->Data();
    +** char zPathBuf[MAX_PATH + 1];
    +** memset(zPathBuf, 0, sizeof(zPathBuf));
    +** WideCharToMultiByte(CP_UTF8, 0, zPath, -1, zPathBuf, sizeof(zPathBuf),
    +**       NULL, NULL);
    +** sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf);
    +** 
    */ SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory; @@ -5494,7 +5537,6 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** implementations are available in the SQLite core: ** **
      -**
    • SQLITE_MUTEX_OS2 **
    • SQLITE_MUTEX_PTHREADS **
    • SQLITE_MUTEX_W32 **
    • SQLITE_MUTEX_NOOP @@ -5502,9 +5544,9 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** ** ^The SQLITE_MUTEX_NOOP implementation is a set of routines ** that does no real locking and is appropriate for use in -** a single-threaded application. ^The SQLITE_MUTEX_OS2, -** SQLITE_MUTEX_PTHREADS, and SQLITE_MUTEX_W32 implementations -** are appropriate for use on OS/2, Unix, and Windows. +** a single-threaded application. ^The SQLITE_MUTEX_PTHREADS and +** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix +** and Windows. ** ** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor ** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex diff --git a/db/sqlite3/src/test_quota.c b/db/sqlite3/src/test_quota.c index 6fd7329f88ec..2ce46acdc06c 100644 --- a/db/sqlite3/src/test_quota.c +++ b/db/sqlite3/src/test_quota.c @@ -48,7 +48,7 @@ /* ** Figure out if we are dealing with Unix, Windows, or some other ** operating system. After the following block of preprocess macros, -** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, and SQLITE_OS_OTHER +** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, and SQLITE_OS_OTHER ** will defined to either 1 or 0. One of the four will be 1. The other ** three will be 0. */ @@ -58,8 +58,6 @@ # define SQLITE_OS_UNIX 0 # undef SQLITE_OS_WIN # define SQLITE_OS_WIN 0 -# undef SQLITE_OS_OS2 -# define SQLITE_OS_OS2 0 # else # undef SQLITE_OS_OTHER # endif @@ -71,20 +69,12 @@ || defined(__MINGW32__) || defined(__BORLANDC__) # define SQLITE_OS_WIN 1 # define SQLITE_OS_UNIX 0 -# define SQLITE_OS_OS2 0 -# elif defined(__EMX__) || defined(_OS2) || defined(OS2) \ - || defined(_OS2_) || defined(__OS2__) -# define SQLITE_OS_WIN 0 -# define SQLITE_OS_UNIX 0 -# define SQLITE_OS_OS2 1 # else # define SQLITE_OS_WIN 0 # define SQLITE_OS_UNIX 1 -# define SQLITE_OS_OS2 0 # endif # else # define SQLITE_OS_UNIX 0 -# define SQLITE_OS_OS2 0 # endif #else # ifndef SQLITE_OS_WIN diff --git a/dom/alarm/AlarmHalService.cpp b/dom/alarm/AlarmHalService.cpp index 33350dccdf73..851c1a4f34ff 100644 --- a/dom/alarm/AlarmHalService.cpp +++ b/dom/alarm/AlarmHalService.cpp @@ -16,12 +16,17 @@ void AlarmHalService::Init() { mAlarmEnabled = RegisterTheOneAlarmObserver(this); + if (!mAlarmEnabled) { + return; + } + RegisterSystemTimeChangeObserver(this); } /* virtual */ AlarmHalService::~AlarmHalService() { if (mAlarmEnabled) { UnregisterTheOneAlarmObserver(); + UnregisterSystemTimeChangeObserver(this); } } @@ -48,7 +53,6 @@ AlarmHalService::SetAlarm(int32_t aSeconds, int32_t aNanoseconds, bool* aStatus) } bool status = hal::SetAlarm(aSeconds, aNanoseconds); - if (status) { *aStatus = status; return NS_OK; @@ -74,9 +78,19 @@ AlarmHalService::SetTimezoneChangedCb(nsITimezoneChangedCb* aTimeZoneChangedCb) void AlarmHalService::Notify(const mozilla::void_t& aVoid) { - if (mAlarmFiredCb) { - mAlarmFiredCb->OnAlarmFired(); + if (!mAlarmFiredCb) { + return; } + mAlarmFiredCb->OnAlarmFired(); +} + +void +AlarmHalService::Notify(const SystemTimeChange& aReason) +{ + if (aReason != SYS_TIME_CHANGE_TZ || !mTimezoneChangedCb) { + return; + } + mTimezoneChangedCb->OnTimezoneChanged(GetTimezoneOffset(false)); } int32_t diff --git a/dom/alarm/AlarmHalService.h b/dom/alarm/AlarmHalService.h index 24ba23b4a4bf..5bdcb2184456 100644 --- a/dom/alarm/AlarmHalService.h +++ b/dom/alarm/AlarmHalService.h @@ -19,8 +19,11 @@ namespace mozilla { namespace dom { namespace alarm { +using namespace hal; + class AlarmHalService : public nsIAlarmHalService, - mozilla::hal::AlarmObserver + public AlarmObserver, + public SystemTimeObserver { public: NS_DECL_ISUPPORTS @@ -34,17 +37,14 @@ public: // Implementing hal::AlarmObserver void Notify(const mozilla::void_t& aVoid); + // Implementing hal::SystemTimeObserver + void Notify(const SystemTimeChange& aReason); + private: bool mAlarmEnabled; - nsCOMPtr mAlarmFiredCb; static StaticRefPtr sSingleton; - // TODO The mTimezoneChangedCb would be called - // when a timezone-changed event is detected - // at run-time. To do so, we can register a - // timezone-changed observer, see bug 714358. - // We need to adjust the alarm time respect to - // the correct timezone where user is located. + nsCOMPtr mAlarmFiredCb; nsCOMPtr mTimezoneChangedCb; int32_t GetTimezoneOffset(bool aIgnoreDST); diff --git a/dom/apps/src/Webapps.js b/dom/apps/src/Webapps.js index 1cc6cf3709ac..87c0a641ed94 100644 --- a/dom/apps/src/Webapps.js +++ b/dom/apps/src/Webapps.js @@ -31,25 +31,6 @@ function WebappsRegistry() { WebappsRegistry.prototype = { __proto__: DOMRequestIpcHelper.prototype, - __exposedProps__: { - install: 'r', -#ifdef MOZ_PHOENIX -# Firefox Desktop: installPackage not implemented -#elifdef ANDROID -#ifndef MOZ_WIDGET_GONK -# Firefox Android (Fennec): installPackage not implemented -#else -# B2G Gonk: installPackage implemented - installPackage: 'r', -#endif -#else -# B2G Desktop and others: installPackage implementation status varies - installPackage: 'r', -#endif - getSelf: 'r', - getInstalled: 'r', - mgmt: 'r' - }, /** from https://developer.mozilla.org/en/OpenWebApps/The_Manifest * only the name property is mandatory @@ -274,20 +255,6 @@ function WebappsApplication() { WebappsApplication.prototype = { __proto__: DOMRequestIpcHelper.prototype, - __exposedProps__: { - origin: 'r', - manifest: 'r', - manifestURL: 'r', - installOrigin: 'r', - installTime: 'r', - status: 'r', - progress: 'r', - onprogress: 'rw', - launch: 'r', - receipts: 'r', - removable: 'r', - uninstall: 'r' - }, init: function(aWindow, aApp) { this.origin = aApp.origin; diff --git a/dom/base/nsDOMClassInfo.h b/dom/base/nsDOMClassInfo.h index a87c7255426a..cc5dff0366ac 100644 --- a/dom/base/nsDOMClassInfo.h +++ b/dom/base/nsDOMClassInfo.h @@ -82,7 +82,7 @@ struct nsExternalDOMClassInfoData : public nsDOMClassInfoData }; -typedef PRUptrdiff PtrBits; +typedef uintptr_t PtrBits; // To be used with the nsDOMClassInfoData::mCachedClassInfo pointer. // The low bit is set when we created a generic helper for an external diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 3d8bfc61fce5..80868ec2fd44 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -2812,7 +2812,7 @@ nsDOMWindowUtils::ExitFullscreen() } NS_IMETHODIMP -nsDOMWindowUtils::SelectAtPoint(float aX, float aY, PRUint32 aSelectBehavior, +nsDOMWindowUtils::SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior, bool *_retval) { *_retval = false; @@ -2885,7 +2885,7 @@ nsDOMWindowUtils::SelectAtPoint(float aX, float aY, PRUint32 aSelectBehavior, } NS_IMETHODIMP -nsDOMWindowUtils::LoadSheet(nsIURI *aSheetURI, PRUint32 aSheetType) +nsDOMWindowUtils::LoadSheet(nsIURI *aSheetURI, uint32_t aSheetType) { if (!IsUniversalXPConnectCapable()) { return NS_ERROR_DOM_SECURITY_ERR; @@ -2916,7 +2916,7 @@ nsDOMWindowUtils::LoadSheet(nsIURI *aSheetURI, PRUint32 aSheetType) } NS_IMETHODIMP -nsDOMWindowUtils::RemoveSheet(nsIURI *aSheetURI, PRUint32 aSheetType) +nsDOMWindowUtils::RemoveSheet(nsIURI *aSheetURI, uint32_t aSheetType) { if (!IsUniversalXPConnectCapable()) { return NS_ERROR_DOM_SECURITY_ERR; diff --git a/dom/base/nsWrapperCache.h b/dom/base/nsWrapperCache.h index de5c65ac2a35..c6eb58002d1e 100644 --- a/dom/base/nsWrapperCache.h +++ b/dom/base/nsWrapperCache.h @@ -12,7 +12,7 @@ struct JSObject; struct JSContext; class XPCWrappedNativeScope; -typedef PRUptrdiff PtrBits; +typedef uintptr_t PtrBits; namespace mozilla { namespace dom { diff --git a/dom/messages/SystemMessageInternal.js b/dom/messages/SystemMessageInternal.js index a7ee06d89cfe..4663f3a35f21 100644 --- a/dom/messages/SystemMessageInternal.js +++ b/dom/messages/SystemMessageInternal.js @@ -41,13 +41,31 @@ function SystemMessageInternal() { SystemMessageInternal.prototype = { sendMessage: function sendMessage(aType, aMessage, aPageURI, aManifestURI) { - this._sendMessage(aType, aMessage, aPageURI.spec, aManifestURI.spec); + debug("Broadcasting " + aType + " " + JSON.stringify(aMessage)); + ppmm.broadcastAsyncMessage("SystemMessageManager:Message" , { type: aType, + msg: aMessage, + manifest: aManifestURI.spec }); + this._pages.forEach(function sendMess_openPage(aPage) { + if (aPage.type != aType || + aPage.manifest != aManifestURI.spec || + aPage.uri != aPageURI.spec) { + return; + } + + this._processPage(aPage, aMessage); + }.bind(this)) }, broadcastMessage: function broadcastMessage(aType, aMessage) { + debug("Broadcasting " + aType + " " + JSON.stringify(aMessage)); + // Find pages that registered an handler for this type. this._pages.forEach(function(aPage) { if (aPage.type == aType) { - this._sendMessage(aType, aMessage, aPage.uri, aPage.manifest); + ppmm.broadcastAsyncMessage("SystemMessageManager:Message" , { type: aType, + msg: aMessage, + manifest: aPage.manifest }); + + this._processPage(aPage, aMessage); } }.bind(this)) }, @@ -101,33 +119,20 @@ SystemMessageInternal.prototype = { } }, - _sendMessage: function _sendMessage(aType, aMessage, aPageURI, aManifestURI) { - debug("Broadcasting " + aType + " " + JSON.stringify(aMessage)); - ppmm.broadcastAsyncMessage("SystemMessageManager:Message" , { type: aType, - msg: aMessage, - manifest: aManifestURI }); + _processPage: function _processPage(aPage, aMessage) { + // Queue the message for the page. + aPage.pending.push(aMessage); + if (aPage.pending.length > kMaxPendingMessages) { + aPage.pending.splice(0, 1); + } - // Queue the message for pages that registered an handler for this type. - this._pages.forEach(function sendMess_openPage(aPage) { - if (aPage.type != aType || - aPage.manifest != aManifestURI || - aPage.uri != aPageURI) { - return; - } - - aPage.pending.push(aMessage); - if (aPage.pending.length > kMaxPendingMessages) { - aPage.pending.splice(0, 1); - } - - // We don't need to send the full object to observers. - let page = { uri: aPage.uri, - manifest: aPage.manifest, - type: aPage.type, - target: aMessage.target }; - debug("Asking to open " + JSON.stringify(page)); - Services.obs.notifyObservers(this, "system-messages-open-app", JSON.stringify(page)); - }.bind(this)) + // We don't need to send the full object to observers. + let page = { uri: aPage.uri, + manifest: aPage.manifest, + type: aPage.type, + target: aMessage.target }; + debug("Asking to open " + JSON.stringify(page)); + Services.obs.notifyObservers(this, "system-messages-open-app", JSON.stringify(page)); }, classID: Components.ID("{70589ca5-91ac-4b9e-b839-d6a88167d714}"), diff --git a/dom/network/interfaces/nsIDOMMobileConnection.idl b/dom/network/interfaces/nsIDOMMobileConnection.idl index 1eedb5f9a13f..c0e36a9faa95 100644 --- a/dom/network/interfaces/nsIDOMMobileConnection.idl +++ b/dom/network/interfaces/nsIDOMMobileConnection.idl @@ -347,9 +347,14 @@ interface nsIDOMMozMobileCellInfo: nsISupports readonly attribute unsigned long gsmCellId; }; -[scriptable, uuid(109c1117-1199-47aa-aad2-ea9f456220fa)] +[scriptable, uuid(8854ee5f-8ffa-45c1-84d6-e87d82de6ae8)] interface nsIDOMMozMobileICCInfo : nsISupports { + /** + * Integrated Circuit Card Identifier. + */ + readonly attribute DOMString iccid; + /** * Mobile Country Code (MCC) of the subscriber's home network. */ diff --git a/dom/network/tests/marionette/test_mobile_iccinfo.js b/dom/network/tests/marionette/test_mobile_iccinfo.js index 51af4d3f500c..c296ae6a6680 100644 --- a/dom/network/tests/marionette/test_mobile_iccinfo.js +++ b/dom/network/tests/marionette/test_mobile_iccinfo.js @@ -9,6 +9,10 @@ let connection = navigator.mozMobileConnection; ok(connection instanceof MozMobileConnection, "connection is instanceof " + connection.constructor); +// The emulator's hard coded iccid value. +// See it here {B2G_HOME}/external/qemu/telephony/sim_card.c#L299. +is(connection.iccInfo.iccid, 89014103211118510720); + // The emulator's hard coded mcc and mnc codes. // See it here {B2G_HOME}/external/qemu/telephony/android_modem.c#L2465. is(connection.iccInfo.mcc, 310); diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index 24ae5fb1c77a..1bef46932c9d 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -31,7 +31,7 @@ #include "nsIURL.h" #include "nsXPIDLString.h" #include "nsReadableUtils.h" -#include "nsIProtocolProxyService.h" +#include "nsIProtocolProxyService2.h" #include "nsIStreamConverterService.h" #include "nsIFile.h" #if defined(XP_MACOSX) @@ -743,12 +743,17 @@ nsresult nsPluginHost::FindProxyForURL(const char* url, char* *result) nsCOMPtr uriIn; nsCOMPtr proxyService; + nsCOMPtr proxyService2; nsCOMPtr ioService; proxyService = do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &res); if (NS_FAILED(res) || !proxyService) return res; + proxyService2 = do_QueryInterface(proxyService, &res); + if (NS_FAILED(res) || !proxyService) + return res; + ioService = do_GetService(NS_IOSERVICE_CONTRACTID, &res); if (NS_FAILED(res) || !ioService) return res; @@ -760,7 +765,8 @@ nsresult nsPluginHost::FindProxyForURL(const char* url, char* *result) nsCOMPtr pi; - res = proxyService->Resolve(uriIn, 0, getter_AddRefs(pi)); + // Remove this with bug 778201 + res = proxyService2->DeprecatedBlockingResolve(uriIn, 0, getter_AddRefs(pi)); if (NS_FAILED(res)) return res; diff --git a/dom/system/gonk/RILContentHelper.js b/dom/system/gonk/RILContentHelper.js index 4e6823cde5b0..0b3fea61a39d 100644 --- a/dom/system/gonk/RILContentHelper.js +++ b/dom/system/gonk/RILContentHelper.js @@ -106,6 +106,7 @@ MobileICCInfo.prototype = { // nsIDOMMozMobileICCInfo + iccid: null, mcc: 0, mnc: 0 }; @@ -231,8 +232,9 @@ RILContentHelper.prototype = { Ci.nsIRILContentHelper]}), updateICCInfo: function updateICCInfo(srcInfo, destInfo) { - destInfo.mcc = srcInfo.mcc; - destInfo.mnc = srcInfo.mnc; + for (let key in srcInfo) { + destInfo[key] = srcInfo[key]; + } }, updateConnectionInfo: function updateConnectionInfo(srcInfo, destInfo) { diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js index e5962839a645..62609a71f618 100644 --- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -1080,7 +1080,12 @@ RadioInterfaceLayer.prototype = { handleICCInfoChange: function handleICCInfoChange(message) { let oldIcc = this.rilContext.icc; this.rilContext.icc = message; - if (oldIcc && (oldIcc.mcc == message.mcc || oldIcc.mnc == message.mnc)) { + + let iccInfoChanged = !oldIcc || + oldIcc.iccid != message.iccid || + oldIcc.mcc != message.mcc || + oldIcc.mnc != message.mnc; + if (!iccInfoChanged) { return; } // RIL:IccInfoChanged corresponds to a DOM event that gets fired only diff --git a/dom/system/gonk/ril_worker.js b/dom/system/gonk/ril_worker.js index aeb557424bd2..8da90a04597e 100644 --- a/dom/system/gonk/ril_worker.js +++ b/dom/system/gonk/ril_worker.js @@ -1059,6 +1059,7 @@ let RIL = { * Fetch ICC records. */ fetchICCRecords: function fetchICCRecords() { + this.getICCID(); this.getIMSI(); this.getMSISDN(); this.getAD(); @@ -1091,6 +1092,35 @@ let RIL = { Buf.sendParcel(); }, + /** + * Read the ICCD from the ICC card. + */ + getICCID: function getICCID() { + function callback() { + let length = Buf.readUint32(); + this.iccInfo.iccid = GsmPDUHelper.readSwappedNibbleBcdString(length / 2); + Buf.readStringDelimiter(length); + + if (DEBUG) debug("ICCID: " + this.iccInfo.iccid); + if (this.iccInfo.iccid) { + this._handleICCInfoChange(); + } + } + + this.iccIO({ + command: ICC_COMMAND_GET_RESPONSE, + fileId: ICC_EF_ICCID, + pathId: this._getPathIdForICCRecord(ICC_EF_ICCID), + p1: 0, // For GET_RESPONSE, p1 = 0 + p2: 0, // For GET_RESPONSE, p2 = 0 + p3: GET_RESPONSE_EF_SIZE_BYTES, + data: null, + pin2: null, + type: EF_TYPE_TRANSPARENT, + callback: callback, + }); + }, + /** * Read the MSISDN from the ICC. */ @@ -2329,10 +2359,20 @@ let RIL = { return null; } + // Here we handle only file ids that are common to RUIM, SIM, USIM + // and other types of ICC cards. + switch (fileId) { + case ICC_EF_ICCID: + return EF_PATH_MF_SIM; + case ICC_EF_ADN: + return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM; + case ICC_EF_PBR: + return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK; + } + switch (app.app_type) { case CARD_APPTYPE_SIM: switch (fileId) { - case ICC_EF_ADN: case ICC_EF_FDN: case ICC_EF_MSISDN: return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM; @@ -2341,21 +2381,16 @@ let RIL = { case ICC_EF_MBDN: case ICC_EF_UST: return EF_PATH_MF_SIM + EF_PATH_DF_GSM; - case ICC_EF_PBR: - return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK; } case CARD_APPTYPE_USIM: switch (fileId) { case ICC_EF_AD: + case ICC_EF_FDN: case ICC_EF_MBDN: case ICC_EF_UST: case ICC_EF_MSISDN: return EF_PATH_MF_SIM + EF_PATH_ADF_USIM; - case ICC_EF_ADN: - case ICC_EF_FDN: - return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM; - case ICC_EF_PBR: - return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK; + default: // The file ids in USIM phone book entries are decided by the // card manufacturer. So if we don't match any of the cases diff --git a/extensions/cookie/nsCookiePermission.cpp b/extensions/cookie/nsCookiePermission.cpp index 9b7b4dde3b3d..50555381ab52 100644 --- a/extensions/cookie/nsCookiePermission.cpp +++ b/extensions/cookie/nsCookiePermission.cpp @@ -4,8 +4,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - #include "nsCookiePermission.h" + +#include "mozIThirdPartyUtil.h" #include "nsICookie2.h" #include "nsIServiceManager.h" #include "nsICookiePromptService.h" @@ -64,6 +65,8 @@ nsCookiePermission::Init() nsresult rv; mPermMgr = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv); if (NS_FAILED(rv)) return false; + mThirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID, &rv); + if (NS_FAILED(rv)) return false; // failure to access the pref service is non-fatal... nsCOMPtr prefBranch = @@ -167,29 +170,15 @@ nsCookiePermission::CanAccess(nsIURI *aURI, // finally, check with permission manager... rv = mPermMgr->TestPermission(aURI, kPermissionType, (uint32_t *) aResult); if (NS_SUCCEEDED(rv)) { - switch (*aResult) { - // if we have one of the publicly-available values, just return it - case nsIPermissionManager::UNKNOWN_ACTION: // ACCESS_DEFAULT - case nsIPermissionManager::ALLOW_ACTION: // ACCESS_ALLOW - case nsIPermissionManager::DENY_ACTION: // ACCESS_DENY - break; - - // ACCESS_SESSION means the cookie can be accepted; the session - // downgrade will occur in CanSetCookie(). - case nsICookiePermission::ACCESS_SESSION: - *aResult = ACCESS_ALLOW; - break; - - // ack, an unknown type! just use the defaults. - default: - *aResult = ACCESS_DEFAULT; + if (*aResult == nsICookiePermission::ACCESS_SESSION) { + *aResult = nsICookiePermission::ACCESS_ALLOW; } } return rv; } -NS_IMETHODIMP +NS_IMETHODIMP nsCookiePermission::CanSetCookie(nsIURI *aURI, nsIChannel *aChannel, nsICookie2 *aCookie, @@ -207,34 +196,42 @@ nsCookiePermission::CanSetCookie(nsIURI *aURI, uint32_t perm; mPermMgr->TestPermission(aURI, kPermissionType, &perm); + bool isThirdParty = false; switch (perm) { case nsICookiePermission::ACCESS_SESSION: *aIsSession = true; - case nsIPermissionManager::ALLOW_ACTION: // ACCESS_ALLOW + case nsICookiePermission::ACCESS_ALLOW: *aResult = true; break; - case nsIPermissionManager::DENY_ACTION: // ACCESS_DENY + case nsICookiePermission::ACCESS_DENY: *aResult = false; break; + case nsICookiePermission::ACCESS_ALLOW_FIRST_PARTY_ONLY: + mThirdPartyUtil->IsThirdPartyChannel(aChannel, aURI, &isThirdParty); + // If it's third party, we can't set the cookie + if (isThirdParty) + *aResult = false; + break; + default: // the permission manager has nothing to say about this cookie - // so, we apply the default prefs to it. NS_ASSERTION(perm == nsIPermissionManager::UNKNOWN_ACTION, "unknown permission"); - + // now we need to figure out what type of accept policy we're dealing with // if we accept cookies normally, just bail and return if (mCookiesLifetimePolicy == ACCEPT_NORMALLY) { *aResult = true; return NS_OK; } - + // declare this here since it'll be used in all of the remaining cases int64_t currentTime = PR_Now() / PR_USEC_PER_SEC; int64_t delta = *aExpiry - currentTime; - + // check whether the user wants to be prompted if (mCookiesLifetimePolicy == ASK_BEFORE_ACCEPT) { // if it's a session cookie and the user wants to accept these @@ -245,7 +242,7 @@ nsCookiePermission::CanSetCookie(nsIURI *aURI, *aResult = true; return NS_OK; } - + // default to rejecting, in case the prompting process fails *aResult = false; diff --git a/extensions/cookie/nsCookiePermission.h b/extensions/cookie/nsCookiePermission.h index 0655c94b6142..953e821c4da5 100644 --- a/extensions/cookie/nsCookiePermission.h +++ b/extensions/cookie/nsCookiePermission.h @@ -11,6 +11,7 @@ #include "nsCOMPtr.h" #include "prlong.h" #include "nsIPrivateBrowsingService.h" +#include "mozIThirdPartyUtil.h" class nsIPrefBranch; @@ -22,7 +23,7 @@ public: NS_DECL_NSICOOKIEPERMISSION NS_DECL_NSIOBSERVER - nsCookiePermission() + nsCookiePermission() : mCookiesLifetimeSec(LL_MAXINT) , mCookiesLifetimePolicy(0) // ACCEPT_NORMALLY , mCookiesAlwaysAcceptSession(false) @@ -33,11 +34,12 @@ public: void PrefChanged(nsIPrefBranch *, const char *); private: - bool EnsureInitialized() { return mPermMgr != NULL || Init(); }; - bool InPrivateBrowsing(); + bool EnsureInitialized() { return (mPermMgr != NULL && mThirdPartyUtil != NULL) || Init(); }; + bool InPrivateBrowsing(); nsCOMPtr mPermMgr; nsCOMPtr mPBService; + nsCOMPtr mThirdPartyUtil; int64_t mCookiesLifetimeSec; // lifetime limit specified in seconds uint8_t mCookiesLifetimePolicy; // pref for how long cookies are stored diff --git a/extensions/cookie/test/unit/test_cookies_thirdparty.js b/extensions/cookie/test/unit/test_cookies_thirdparty.js index 85a215d810c7..87967c39b86f 100644 --- a/extensions/cookie/test/unit/test_cookies_thirdparty.js +++ b/extensions/cookie/test/unit/test_cookies_thirdparty.js @@ -32,7 +32,7 @@ function run_test() { // Force the channel URI to be used when determining the originating URI of // the channel. var httpchannel1 = channel1.QueryInterface(Ci.nsIHttpChannelInternal); - var httpchannel2 = channel1.QueryInterface(Ci.nsIHttpChannelInternal); + var httpchannel2 = channel2.QueryInterface(Ci.nsIHttpChannelInternal); httpchannel1.forceAllowThirdPartyCookie = true; httpchannel2.forceAllowThirdPartyCookie = true; @@ -49,5 +49,27 @@ function run_test() { Services.cookies.removeAll(); do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]); Services.cookies.removeAll(); + + // Test per-site 3rd party cookies with cookies enabled + Services.prefs.setIntPref("network.cookie.cookieBehavior", 0); + var kPermissionType = "cookie"; + var ALLOW_FIRST_PARTY_ONLY = 9; + // ALLOW_FIRST_PARTY_ONLY overrides + Services.permissions.add(uri1, kPermissionType, ALLOW_FIRST_PARTY_ONLY); + do_set_cookies(uri1, channel1, true, [0, 1, 1, 2]); + Services.cookies.removeAll(); + do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]); + Services.cookies.removeAll(); + + // Test per-site 3rd party cookies with 3rd party cookies disabled + Services.prefs.setIntPref("network.cookie.cookieBehavior", 1); + do_set_cookies(uri1, channel1, true, [0, 1, 1, 2]); + Services.cookies.removeAll(); + // No preference has been set for uri2, but it should act as if + // ALLOW_FIRST_PARTY_ONLY has been set + do_set_cookies(uri2, channel2, true, [0, 1, 1, 2]); + Services.cookies.removeAll(); + do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]); + Services.cookies.removeAll(); } diff --git a/extensions/cookie/test/unit/test_cookies_thirdparty_session.js b/extensions/cookie/test/unit/test_cookies_thirdparty_session.js index 33fd84318414..a7b027ba81a5 100644 --- a/extensions/cookie/test/unit/test_cookies_thirdparty_session.js +++ b/extensions/cookie/test/unit/test_cookies_thirdparty_session.js @@ -35,7 +35,7 @@ function do_run_test() { // Force the channel URI to be used when determining the originating URI of // the channel. var httpchannel1 = channel1.QueryInterface(Ci.nsIHttpChannelInternal); - var httpchannel2 = channel1.QueryInterface(Ci.nsIHttpChannelInternal); + var httpchannel2 = channel2.QueryInterface(Ci.nsIHttpChannelInternal); httpchannel1.forceAllowThirdPartyCookie = true; httpchannel2.forceAllowThirdPartyCookie = true; @@ -73,4 +73,3 @@ function do_run_test() { finish_test(); } - diff --git a/gfx/layers/ipc/AsyncPanZoomController.cpp b/gfx/layers/ipc/AsyncPanZoomController.cpp index 0dd610b3a74d..51a27a1c488d 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.cpp +++ b/gfx/layers/ipc/AsyncPanZoomController.cpp @@ -952,6 +952,27 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr } else { mContentPainterStatus = CONTENT_IDLE; } + } else { + // No paint was requested, but we got one anyways. One possible cause of this + // is that content could have fired a scrollTo(). In this case, we should take + // the new scroll offset. Document/viewport changes are handled elsewhere. + // Also note that, since NotifyLayersUpdated() is called whenever there's a + // layers update, we didn't necessarily get a new scroll offset, but we're + // updating our local copy of it anyways just in case. + switch (mState) { + case NOTHING: + case FLING: + case TOUCHING: + case WAITING_LISTENERS: + // FIXME/bug 784908: Scroll offset is stored in layer pixels in the rest + // of the layers code, but we want it in CSS pixels. + mFrameMetrics.mViewportScrollOffset = + aViewportFrame.mViewportScrollOffset / aViewportFrame.mResolution.width; + break; + // Don't clobber if we're in other states. + default: + break; + } } if (aIsFirstPaint || mFrameMetrics.IsDefault()) { diff --git a/gfx/qcms/qcmstypes.h b/gfx/qcms/qcmstypes.h index 9bacf8799ac6..4653ae2646a2 100644 --- a/gfx/qcms/qcmstypes.h +++ b/gfx/qcms/qcmstypes.h @@ -29,7 +29,7 @@ typedef uint64_t uint64_t; /* OS/2's stdlib typdefs uintptr_t. So we'll just include that so we don't collide */ #include #elif !defined(__intptr_t_defined) && !defined(_UINTPTR_T_DEFINED) -typedef PRUptrdiff uintptr_t; +typedef unsigned long uintptr_t; #endif #endif diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index 95ef2d2726e4..0dc866bcce3a 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -1064,7 +1064,7 @@ private: float x, y, width, height; }; - typedef PRUptrdiff PtrBits; + typedef uintptr_t PtrBits; enum { BLOCK_SIZE_BITS = 7, BLOCK_SIZE = 1 << BLOCK_SIZE_BITS }; // 128-glyph blocks class GlyphWidths { diff --git a/gfx/ycbcr/convert.patch b/gfx/ycbcr/convert.patch index 86f28a5ce7aa..2881ce72d37d 100644 --- a/gfx/ycbcr/convert.patch +++ b/gfx/ycbcr/convert.patch @@ -322,7 +322,7 @@ diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp uint8 yuvbuf[16 + kFilterBufferSize * 3 + 16]; uint8* ybuf = - reinterpret_cast(reinterpret_cast(yuvbuf + 15) & ~15); -+ reinterpret_cast(reinterpret_cast(yuvbuf + 15) & ~15); ++ reinterpret_cast(reinterpret_cast(yuvbuf + 15) & ~15); uint8* ubuf = ybuf + kFilterBufferSize; uint8* vbuf = ubuf + kFilterBufferSize; // TODO(fbarchard): Fixed point math is off by 1 on negatives. diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp index a46783e3e430..8b35e989082a 100644 --- a/gfx/ycbcr/yuv_convert.cpp +++ b/gfx/ycbcr/yuv_convert.cpp @@ -252,7 +252,7 @@ NS_GFX_(void) ScaleYCbCrToRGB32(const uint8* y_buf, // after the end for SSE2 version. uint8 yuvbuf[16 + kFilterBufferSize * 3 + 16]; uint8* ybuf = - reinterpret_cast(reinterpret_cast(yuvbuf + 15) & ~15); + reinterpret_cast(reinterpret_cast(yuvbuf + 15) & ~15); uint8* ubuf = ybuf + kFilterBufferSize; uint8* vbuf = ubuf + kFilterBufferSize; // TODO(fbarchard): Fixed point math is off by 1 on negatives. diff --git a/hal/gonk/GonkHal.cpp b/hal/gonk/GonkHal.cpp index ea5ed339d785..be8b6eed80a7 100644 --- a/hal/gonk/GonkHal.cpp +++ b/hal/gonk/GonkHal.cpp @@ -59,6 +59,28 @@ #define NsecPerMsec 1000000 #define NsecPerSec 1000000000 +// The header linux/oom.h is not available in bionic libc. We +// redefine some of its constants here. + +#ifndef OOM_DISABLE +#define OOM_DISABLE (-17) +#endif + +#ifndef OOM_ADJUST_MIN +#define OOM_ADJUST_MIN (-16) +#endif + +#ifndef OOM_ADJUST_MAX +#define OOM_ADJUST_MAX 15 +#endif + +#ifndef OOM_SCORE_ADJ_MIN +#define OOM_SCORE_ADJ_MIN (-1000) +#endif + +#ifndef OOM_SCORE_ADJ_MAX +#define OOM_SCORE_ADJ_MAX 1000 +#endif using namespace mozilla; using namespace mozilla::hal; @@ -89,7 +111,7 @@ public: } os->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, /* weak ref */ true); - } + } NS_DECL_ISUPPORTS NS_DECL_NSIRUNNABLE NS_DECL_NSIOBSERVER @@ -371,19 +393,21 @@ bool ReadFromFile(const char *filename, char (&buf)[n]) return true; } -void WriteToFile(const char *filename, const char *toWrite) +bool WriteToFile(const char *filename, const char *toWrite) { int fd = open(filename, O_WRONLY); ScopedClose autoClose(fd); if (fd < 0) { HAL_LOG(("Unable to open file %s.", filename)); - return; + return false; } if (write(fd, toWrite, strlen(toWrite)) < 0) { HAL_LOG(("Unable to write to file %s.", filename)); - return; + return false; } + + return true; } // We can write to screenEnabledFilename to enable/disable the screen, but when @@ -568,9 +592,9 @@ GetLight(hal::LightType light, hal::LightConfiguration* aConfig) } /** - * clock_settime() is not exposed through bionic. + * clock_settime() is not exposed through bionic. * we define the new function to set system time. - * The result is the same as using clock_settime() system call. + * The result is the same as using clock_settime() system call. */ static int sys_clock_settime(clockid_t clk_id, const struct timespec *tp) @@ -578,16 +602,16 @@ sys_clock_settime(clockid_t clk_id, const struct timespec *tp) return syscall(__NR_clock_settime, clk_id, tp); } -void +void AdjustSystemClock(int32_t aDeltaMilliseconds) { if (aDeltaMilliseconds == 0) { return; } - + struct timespec now; - - // Preventing context switch before setting system clock + + // Preventing context switch before setting system clock sched_yield(); clock_gettime(CLOCK_REALTIME, &now); now.tv_sec += aDeltaMilliseconds/1000; @@ -601,18 +625,18 @@ AdjustSystemClock(int32_t aDeltaMilliseconds) if (now.tv_nsec < 0) { now.tv_nsec += NsecPerSec; - now.tv_sec -= 1; + now.tv_sec -= 1; } - // we need to have root privilege. + // we need to have root privilege. if (sys_clock_settime(CLOCK_REALTIME, &now) != 0) { NS_ERROR("sys_clock_settime failed"); return; } - + hal::NotifySystemTimeChange(hal::SYS_TIME_CHANGE_CLOCK); } -void +void SetTimezone(const nsCString& aTimezoneSpec) { if (aTimezoneSpec.Equals(GetTimezone())) { @@ -620,13 +644,13 @@ SetTimezone(const nsCString& aTimezoneSpec) } property_set("persist.sys.timezone", aTimezoneSpec.get()); - // this function is automatically called by the other time conversion - // functions that depend on the timezone. To be safe, we call it manually. + // this function is automatically called by the other time conversion + // functions that depend on the timezone. To be safe, we call it manually. tzset(); hal::NotifySystemTimeChange(hal::SYS_TIME_CHANGE_TZ); } -nsCString +nsCString GetTimezone() { char timezone[32]; @@ -704,7 +728,7 @@ private: }; // Runs on alarm-watcher thread. -static void +static void DestroyAlarmData(void* aData) { AlarmData* alarmData = static_cast(aData); @@ -720,7 +744,7 @@ void ShutDownAlarm(int aSigno) return; } -static void* +static void* WaitForAlarm(void* aData) { pthread_cleanup_push(DestroyAlarmData, aData); @@ -738,7 +762,7 @@ WaitForAlarm(void* aData) alarmTypeFlags = ioctl(alarmData->mFd, ANDROID_ALARM_WAIT); } while (alarmTypeFlags < 0 && errno == EINTR && !alarmData->mShuttingDown); - if (!alarmData->mShuttingDown && + if (!alarmData->mShuttingDown && alarmTypeFlags >= 0 && (alarmTypeFlags & ANDROID_ALARM_RTC_WAKEUP_MASK)) { NS_DispatchToMainThread(new AlarmFiredEvent(alarmData->mGeneration)); } @@ -826,6 +850,23 @@ SetAlarm(int32_t aSeconds, int32_t aNanoseconds) return true; } +static int +oomAdjOfOomScoreAdj(int aOomScoreAdj) +{ + // Convert OOM adjustment from the domain of /proc//oom_score_adj + // to thew domain of /proc//oom_adj. + + int adj; + + if (aOomScoreAdj < 0) { + adj = (OOM_DISABLE * aOomScoreAdj) / OOM_SCORE_ADJ_MIN; + } else { + adj = (OOM_ADJUST_MAX * aOomScoreAdj) / OOM_SCORE_ADJ_MAX; + } + + return adj; +} + void SetProcessPriority(int aPid, ProcessPriority aPriority) { @@ -849,13 +890,34 @@ SetProcessPriority(int aPid, ProcessPriority aPriority) // Notice that you can disable oom_adj and renice by deleting the prefs // hal.processPriorityManager{foreground,background,master}{OomAdjust,Nice}. - int32_t oomAdj = 0; + int32_t oomScoreAdj = 0; nsresult rv = Preferences::GetInt(nsPrintfCString( - "hal.processPriorityManager.gonk.%sOomAdjust", priorityStr).get(), &oomAdj); + "hal.processPriorityManager.gonk.%sOomScoreAdjust", + priorityStr).get(), &oomScoreAdj); + if (NS_SUCCEEDED(rv)) { - HAL_LOG(("Setting oom_adj for pid %d to %d", aPid, oomAdj)); - WriteToFile(nsPrintfCString("/proc/%d/oom_adj", aPid).get(), - nsPrintfCString("%d", oomAdj).get()); + + int clampedOomScoreAdj = clamped(oomScoreAdj, OOM_SCORE_ADJ_MIN, + OOM_SCORE_ADJ_MAX); + if(clampedOomScoreAdj != oomScoreAdj) { + HAL_LOG(("Clamping OOM adjustment for pid %d to %d", + aPid, clampedOomScoreAdj)); + } else { + HAL_LOG(("Setting OOM adjustment for pid %d to %d", + aPid, clampedOomScoreAdj)); + } + + // We try the newer interface first, and fall back to the older interface + // on failure. + + if (!WriteToFile(nsPrintfCString("/proc/%d/oom_score_adj", aPid).get(), + nsPrintfCString("%d", clampedOomScoreAdj).get())) + { + int oomAdj = oomAdjOfOomScoreAdj(clampedOomScoreAdj); + + WriteToFile(nsPrintfCString("/proc/%d/oom_adj", aPid).get(), + nsPrintfCString("%d", oomAdj).get()); + } } int32_t nice = 0; diff --git a/image/decoders/nsJPEGDecoder.cpp b/image/decoders/nsJPEGDecoder.cpp index 5f9ac96c2c4f..8fa8200f2171 100644 --- a/image/decoders/nsJPEGDecoder.cpp +++ b/image/decoders/nsJPEGDecoder.cpp @@ -21,21 +21,14 @@ extern "C" { #include "iccjpeg.h" - -/* Colorspace conversion (copied from jpegint.h) */ -struct jpeg_color_deconverter { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, color_convert, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows)); -}; - -METHODDEF(void) -ycc_rgb_convert_argb (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows); } +#if defined(IS_BIG_ENDIAN) +#define MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB JCS_EXT_XRGB +#else +#define MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB JCS_EXT_BGRX +#endif + static void cmyk_convert_rgb(JSAMPROW row, JDIMENSION width); namespace mozilla { @@ -331,7 +324,14 @@ nsJPEGDecoder::WriteInternal(const char *aBuffer, uint32_t aCount) case JCS_GRAYSCALE: case JCS_RGB: case JCS_YCbCr: - mInfo.out_color_space = JCS_RGB; + // if we're not color managing we can decode directly to + // MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB + if (mCMSMode != eCMSMode_All) { + mInfo.out_color_space = MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB; + mInfo.out_color_components = 4; + } else { + mInfo.out_color_space = JCS_RGB; + } break; case JCS_CMYK: case JCS_YCCK: @@ -399,13 +399,6 @@ nsJPEGDecoder::WriteInternal(const char *aBuffer, uint32_t aCount) return; /* I/O suspension */ } - /* Force to use our YCbCr to Packed RGB converter when possible */ - if (!mTransform && (mCMSMode != eCMSMode_All) && - mInfo.jpeg_color_space == JCS_YCbCr && mInfo.out_color_space == JCS_RGB) { - /* Special case for the most common case: transform from YCbCr direct into packed ARGB */ - mInfo.out_color_components = 4; /* Packed ARGB pixels are always 4 bytes...*/ - mInfo.cconvert->color_convert = ycc_rgb_convert_argb; - } /* If this is a progressive JPEG ... */ mState = mInfo.buffered_image ? JPEG_DECOMPRESS_PROGRESSIVE : JPEG_DECOMPRESS_SEQUENTIAL; @@ -551,7 +544,7 @@ nsJPEGDecoder::OutputScanlines(bool* suspend) uint32_t *imageRow = ((uint32_t*)mImageData) + (mInfo.output_scanline * mInfo.output_width); - if (mInfo.cconvert->color_convert == ycc_rgb_convert_argb) { + if (mInfo.out_color_space == MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB) { /* Special case: scanline will be directly converted into packed ARGB */ if (jpeg_read_scanlines(&mInfo, (JSAMPARRAY)&imageRow, 1) != 1) { *suspend = true; /* suspend */ @@ -861,280 +854,6 @@ term_source (j_decompress_ptr jd) } // namespace mozilla -/**************** YCbCr -> Cairo's RGB24/ARGB32 conversion: most common case **************/ - -/* - * YCbCr is defined per CCIR 601-1, except that Cb and Cr are - * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. - * The conversion equations to be implemented are therefore - * R = Y + 1.40200 * Cr - * G = Y - 0.34414 * Cb - 0.71414 * Cr - * B = Y + 1.77200 * Cb - * where Cb and Cr represent the incoming values less CENTERJSAMPLE. - * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) - * - * To avoid floating-point arithmetic, we represent the fractional constants - * as integers scaled up by 2^16 (about 4 digits precision); we have to divide - * the products by 2^16, with appropriate rounding, to get the correct answer. - * Notice that Y, being an integral input, does not contribute any fraction - * so it need not participate in the rounding. - * - * For even more speed, we avoid doing any multiplications in the inner loop - * by precalculating the constants times Cb and Cr for all possible values. - * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); - * for 12-bit samples it is still acceptable. It's not very reasonable for - * 16-bit samples, but if you want lossless storage you shouldn't be changing - * colorspace anyway. - * The Cr=>R and Cb=>B values can be rounded to integers in advance; the - * values for the G calculation are left scaled up, since we must add them - * together before rounding. - */ - -#define SCALEBITS 16 /* speediest right-shift on some machines */ - -/* Use static tables for color processing. */ -/* Four tables, each 256 entries of 4 bytes totals 4K which is not bad... */ - -const int Cr_r_tab[(MAXJSAMPLE+1) * sizeof(int)] ={ - -0xb3, -0xb2, -0xb1, -0xaf, -0xae, -0xac, - -0xab, -0xaa, -0xa8, -0xa7, -0xa5, -0xa4, - -0xa3, -0xa1, -0xa0, -0x9e, -0x9d, -0x9c, - -0x9a, -0x99, -0x97, -0x96, -0x95, -0x93, - -0x92, -0x90, -0x8f, -0x8e, -0x8c, -0x8b, - -0x89, -0x88, -0x87, -0x85, -0x84, -0x82, - -0x81, -0x80, -0x7e, -0x7d, -0x7b, -0x7a, - -0x79, -0x77, -0x76, -0x74, -0x73, -0x72, - -0x70, -0x6f, -0x6d, -0x6c, -0x6b, -0x69, - -0x68, -0x66, -0x65, -0x64, -0x62, -0x61, - -0x5f, -0x5e, -0x5d, -0x5b, -0x5a, -0x58, - -0x57, -0x56, -0x54, -0x53, -0x51, -0x50, - -0x4f, -0x4d, -0x4c, -0x4a, -0x49, -0x48, - -0x46, -0x45, -0x43, -0x42, -0x40, -0x3f, - -0x3e, -0x3c, -0x3b, -0x39, -0x38, -0x37, - -0x35, -0x34, -0x32, -0x31, -0x30, -0x2e, - -0x2d, -0x2b, -0x2a, -0x29, -0x27, -0x26, - -0x24, -0x23, -0x22, -0x20, -0x1f, -0x1d, - -0x1c, -0x1b, -0x19, -0x18, -0x16, -0x15, - -0x14, -0x12, -0x11, -0x0f, -0x0e, -0x0d, - -0x0b, -0x0a, -0x08, -0x07, -0x06, -0x04, - -0x03, -0x01, 0x00, 0x01, 0x03, 0x04, - 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0d, - 0x0e, 0x0f, 0x11, 0x12, 0x14, 0x15, - 0x16, 0x18, 0x19, 0x1b, 0x1c, 0x1d, - 0x1f, 0x20, 0x22, 0x23, 0x24, 0x26, - 0x27, 0x29, 0x2a, 0x2b, 0x2d, 0x2e, - 0x30, 0x31, 0x32, 0x34, 0x35, 0x37, - 0x38, 0x39, 0x3b, 0x3c, 0x3e, 0x3f, - 0x40, 0x42, 0x43, 0x45, 0x46, 0x48, - 0x49, 0x4a, 0x4c, 0x4d, 0x4f, 0x50, - 0x51, 0x53, 0x54, 0x56, 0x57, 0x58, - 0x5a, 0x5b, 0x5d, 0x5e, 0x5f, 0x61, - 0x62, 0x64, 0x65, 0x66, 0x68, 0x69, - 0x6b, 0x6c, 0x6d, 0x6f, 0x70, 0x72, - 0x73, 0x74, 0x76, 0x77, 0x79, 0x7a, - 0x7b, 0x7d, 0x7e, 0x80, 0x81, 0x82, - 0x84, 0x85, 0x87, 0x88, 0x89, 0x8b, - 0x8c, 0x8e, 0x8f, 0x90, 0x92, 0x93, - 0x95, 0x96, 0x97, 0x99, 0x9a, 0x9c, - 0x9d, 0x9e, 0xa0, 0xa1, 0xa3, 0xa4, - 0xa5, 0xa7, 0xa8, 0xaa, 0xab, 0xac, - 0xae, 0xaf, 0xb1, 0xb2, - }; - -const int Cb_b_tab[(MAXJSAMPLE+1) * sizeof(int)] ={ - -0xe3, -0xe1, -0xdf, -0xde, -0xdc, -0xda, - -0xd8, -0xd6, -0xd5, -0xd3, -0xd1, -0xcf, - -0xce, -0xcc, -0xca, -0xc8, -0xc6, -0xc5, - -0xc3, -0xc1, -0xbf, -0xbe, -0xbc, -0xba, - -0xb8, -0xb7, -0xb5, -0xb3, -0xb1, -0xaf, - -0xae, -0xac, -0xaa, -0xa8, -0xa7, -0xa5, - -0xa3, -0xa1, -0x9f, -0x9e, -0x9c, -0x9a, - -0x98, -0x97, -0x95, -0x93, -0x91, -0x90, - -0x8e, -0x8c, -0x8a, -0x88, -0x87, -0x85, - -0x83, -0x81, -0x80, -0x7e, -0x7c, -0x7a, - -0x78, -0x77, -0x75, -0x73, -0x71, -0x70, - -0x6e, -0x6c, -0x6a, -0x69, -0x67, -0x65, - -0x63, -0x61, -0x60, -0x5e, -0x5c, -0x5a, - -0x59, -0x57, -0x55, -0x53, -0x52, -0x50, - -0x4e, -0x4c, -0x4a, -0x49, -0x47, -0x45, - -0x43, -0x42, -0x40, -0x3e, -0x3c, -0x3a, - -0x39, -0x37, -0x35, -0x33, -0x32, -0x30, - -0x2e, -0x2c, -0x2b, -0x29, -0x27, -0x25, - -0x23, -0x22, -0x20, -0x1e, -0x1c, -0x1b, - -0x19, -0x17, -0x15, -0x13, -0x12, -0x10, - -0x0e, -0x0c, -0x0b, -0x09, -0x07, -0x05, - -0x04, -0x02, 0x00, 0x02, 0x04, 0x05, - 0x07, 0x09, 0x0b, 0x0c, 0x0e, 0x10, - 0x12, 0x13, 0x15, 0x17, 0x19, 0x1b, - 0x1c, 0x1e, 0x20, 0x22, 0x23, 0x25, - 0x27, 0x29, 0x2b, 0x2c, 0x2e, 0x30, - 0x32, 0x33, 0x35, 0x37, 0x39, 0x3a, - 0x3c, 0x3e, 0x40, 0x42, 0x43, 0x45, - 0x47, 0x49, 0x4a, 0x4c, 0x4e, 0x50, - 0x52, 0x53, 0x55, 0x57, 0x59, 0x5a, - 0x5c, 0x5e, 0x60, 0x61, 0x63, 0x65, - 0x67, 0x69, 0x6a, 0x6c, 0x6e, 0x70, - 0x71, 0x73, 0x75, 0x77, 0x78, 0x7a, - 0x7c, 0x7e, 0x80, 0x81, 0x83, 0x85, - 0x87, 0x88, 0x8a, 0x8c, 0x8e, 0x90, - 0x91, 0x93, 0x95, 0x97, 0x98, 0x9a, - 0x9c, 0x9e, 0x9f, 0xa1, 0xa3, 0xa5, - 0xa7, 0xa8, 0xaa, 0xac, 0xae, 0xaf, - 0xb1, 0xb3, 0xb5, 0xb7, 0xb8, 0xba, - 0xbc, 0xbe, 0xbf, 0xc1, 0xc3, 0xc5, - 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xcf, - 0xd1, 0xd3, 0xd5, 0xd6, 0xd8, 0xda, - 0xdc, 0xde, 0xdf, 0xe1, - }; - -const int Cr_g_tab[(MAXJSAMPLE+1) * sizeof(int)] ={ - 0x5b6900, 0x5ab22e, 0x59fb5c, 0x59448a, 0x588db8, 0x57d6e6, - 0x572014, 0x566942, 0x55b270, 0x54fb9e, 0x5444cc, 0x538dfa, - 0x52d728, 0x522056, 0x516984, 0x50b2b2, 0x4ffbe0, 0x4f450e, - 0x4e8e3c, 0x4dd76a, 0x4d2098, 0x4c69c6, 0x4bb2f4, 0x4afc22, - 0x4a4550, 0x498e7e, 0x48d7ac, 0x4820da, 0x476a08, 0x46b336, - 0x45fc64, 0x454592, 0x448ec0, 0x43d7ee, 0x43211c, 0x426a4a, - 0x41b378, 0x40fca6, 0x4045d4, 0x3f8f02, 0x3ed830, 0x3e215e, - 0x3d6a8c, 0x3cb3ba, 0x3bfce8, 0x3b4616, 0x3a8f44, 0x39d872, - 0x3921a0, 0x386ace, 0x37b3fc, 0x36fd2a, 0x364658, 0x358f86, - 0x34d8b4, 0x3421e2, 0x336b10, 0x32b43e, 0x31fd6c, 0x31469a, - 0x308fc8, 0x2fd8f6, 0x2f2224, 0x2e6b52, 0x2db480, 0x2cfdae, - 0x2c46dc, 0x2b900a, 0x2ad938, 0x2a2266, 0x296b94, 0x28b4c2, - 0x27fdf0, 0x27471e, 0x26904c, 0x25d97a, 0x2522a8, 0x246bd6, - 0x23b504, 0x22fe32, 0x224760, 0x21908e, 0x20d9bc, 0x2022ea, - 0x1f6c18, 0x1eb546, 0x1dfe74, 0x1d47a2, 0x1c90d0, 0x1bd9fe, - 0x1b232c, 0x1a6c5a, 0x19b588, 0x18feb6, 0x1847e4, 0x179112, - 0x16da40, 0x16236e, 0x156c9c, 0x14b5ca, 0x13fef8, 0x134826, - 0x129154, 0x11da82, 0x1123b0, 0x106cde, 0x0fb60c, 0x0eff3a, - 0x0e4868, 0x0d9196, 0x0cdac4, 0x0c23f2, 0x0b6d20, 0x0ab64e, - 0x09ff7c, 0x0948aa, 0x0891d8, 0x07db06, 0x072434, 0x066d62, - 0x05b690, 0x04ffbe, 0x0448ec, 0x03921a, 0x02db48, 0x022476, - 0x016da4, 0x00b6d2, 0x000000, -0x00b6d2, -0x016da4, -0x022476, - -0x02db48, -0x03921a, -0x0448ec, -0x04ffbe, -0x05b690, -0x066d62, - -0x072434, -0x07db06, -0x0891d8, -0x0948aa, -0x09ff7c, -0x0ab64e, - -0x0b6d20, -0x0c23f2, -0x0cdac4, -0x0d9196, -0x0e4868, -0x0eff3a, - -0x0fb60c, -0x106cde, -0x1123b0, -0x11da82, -0x129154, -0x134826, - -0x13fef8, -0x14b5ca, -0x156c9c, -0x16236e, -0x16da40, -0x179112, - -0x1847e4, -0x18feb6, -0x19b588, -0x1a6c5a, -0x1b232c, -0x1bd9fe, - -0x1c90d0, -0x1d47a2, -0x1dfe74, -0x1eb546, -0x1f6c18, -0x2022ea, - -0x20d9bc, -0x21908e, -0x224760, -0x22fe32, -0x23b504, -0x246bd6, - -0x2522a8, -0x25d97a, -0x26904c, -0x27471e, -0x27fdf0, -0x28b4c2, - -0x296b94, -0x2a2266, -0x2ad938, -0x2b900a, -0x2c46dc, -0x2cfdae, - -0x2db480, -0x2e6b52, -0x2f2224, -0x2fd8f6, -0x308fc8, -0x31469a, - -0x31fd6c, -0x32b43e, -0x336b10, -0x3421e2, -0x34d8b4, -0x358f86, - -0x364658, -0x36fd2a, -0x37b3fc, -0x386ace, -0x3921a0, -0x39d872, - -0x3a8f44, -0x3b4616, -0x3bfce8, -0x3cb3ba, -0x3d6a8c, -0x3e215e, - -0x3ed830, -0x3f8f02, -0x4045d4, -0x40fca6, -0x41b378, -0x426a4a, - -0x43211c, -0x43d7ee, -0x448ec0, -0x454592, -0x45fc64, -0x46b336, - -0x476a08, -0x4820da, -0x48d7ac, -0x498e7e, -0x4a4550, -0x4afc22, - -0x4bb2f4, -0x4c69c6, -0x4d2098, -0x4dd76a, -0x4e8e3c, -0x4f450e, - -0x4ffbe0, -0x50b2b2, -0x516984, -0x522056, -0x52d728, -0x538dfa, - -0x5444cc, -0x54fb9e, -0x55b270, -0x566942, -0x572014, -0x57d6e6, - -0x588db8, -0x59448a, -0x59fb5c, -0x5ab22e, - }; - -const int Cb_g_tab[(MAXJSAMPLE+1) * sizeof(int)] ={ - 0x2c8d00, 0x2c34e6, 0x2bdccc, 0x2b84b2, 0x2b2c98, 0x2ad47e, - 0x2a7c64, 0x2a244a, 0x29cc30, 0x297416, 0x291bfc, 0x28c3e2, - 0x286bc8, 0x2813ae, 0x27bb94, 0x27637a, 0x270b60, 0x26b346, - 0x265b2c, 0x260312, 0x25aaf8, 0x2552de, 0x24fac4, 0x24a2aa, - 0x244a90, 0x23f276, 0x239a5c, 0x234242, 0x22ea28, 0x22920e, - 0x2239f4, 0x21e1da, 0x2189c0, 0x2131a6, 0x20d98c, 0x208172, - 0x202958, 0x1fd13e, 0x1f7924, 0x1f210a, 0x1ec8f0, 0x1e70d6, - 0x1e18bc, 0x1dc0a2, 0x1d6888, 0x1d106e, 0x1cb854, 0x1c603a, - 0x1c0820, 0x1bb006, 0x1b57ec, 0x1affd2, 0x1aa7b8, 0x1a4f9e, - 0x19f784, 0x199f6a, 0x194750, 0x18ef36, 0x18971c, 0x183f02, - 0x17e6e8, 0x178ece, 0x1736b4, 0x16de9a, 0x168680, 0x162e66, - 0x15d64c, 0x157e32, 0x152618, 0x14cdfe, 0x1475e4, 0x141dca, - 0x13c5b0, 0x136d96, 0x13157c, 0x12bd62, 0x126548, 0x120d2e, - 0x11b514, 0x115cfa, 0x1104e0, 0x10acc6, 0x1054ac, 0x0ffc92, - 0x0fa478, 0x0f4c5e, 0x0ef444, 0x0e9c2a, 0x0e4410, 0x0debf6, - 0x0d93dc, 0x0d3bc2, 0x0ce3a8, 0x0c8b8e, 0x0c3374, 0x0bdb5a, - 0x0b8340, 0x0b2b26, 0x0ad30c, 0x0a7af2, 0x0a22d8, 0x09cabe, - 0x0972a4, 0x091a8a, 0x08c270, 0x086a56, 0x08123c, 0x07ba22, - 0x076208, 0x0709ee, 0x06b1d4, 0x0659ba, 0x0601a0, 0x05a986, - 0x05516c, 0x04f952, 0x04a138, 0x04491e, 0x03f104, 0x0398ea, - 0x0340d0, 0x02e8b6, 0x02909c, 0x023882, 0x01e068, 0x01884e, - 0x013034, 0x00d81a, 0x008000, 0x0027e6, -0x003034, -0x00884e, - -0x00e068, -0x013882, -0x01909c, -0x01e8b6, -0x0240d0, -0x0298ea, - -0x02f104, -0x03491e, -0x03a138, -0x03f952, -0x04516c, -0x04a986, - -0x0501a0, -0x0559ba, -0x05b1d4, -0x0609ee, -0x066208, -0x06ba22, - -0x07123c, -0x076a56, -0x07c270, -0x081a8a, -0x0872a4, -0x08cabe, - -0x0922d8, -0x097af2, -0x09d30c, -0x0a2b26, -0x0a8340, -0x0adb5a, - -0x0b3374, -0x0b8b8e, -0x0be3a8, -0x0c3bc2, -0x0c93dc, -0x0cebf6, - -0x0d4410, -0x0d9c2a, -0x0df444, -0x0e4c5e, -0x0ea478, -0x0efc92, - -0x0f54ac, -0x0facc6, -0x1004e0, -0x105cfa, -0x10b514, -0x110d2e, - -0x116548, -0x11bd62, -0x12157c, -0x126d96, -0x12c5b0, -0x131dca, - -0x1375e4, -0x13cdfe, -0x142618, -0x147e32, -0x14d64c, -0x152e66, - -0x158680, -0x15de9a, -0x1636b4, -0x168ece, -0x16e6e8, -0x173f02, - -0x17971c, -0x17ef36, -0x184750, -0x189f6a, -0x18f784, -0x194f9e, - -0x19a7b8, -0x19ffd2, -0x1a57ec, -0x1ab006, -0x1b0820, -0x1b603a, - -0x1bb854, -0x1c106e, -0x1c6888, -0x1cc0a2, -0x1d18bc, -0x1d70d6, - -0x1dc8f0, -0x1e210a, -0x1e7924, -0x1ed13e, -0x1f2958, -0x1f8172, - -0x1fd98c, -0x2031a6, -0x2089c0, -0x20e1da, -0x2139f4, -0x21920e, - -0x21ea28, -0x224242, -0x229a5c, -0x22f276, -0x234a90, -0x23a2aa, - -0x23fac4, -0x2452de, -0x24aaf8, -0x250312, -0x255b2c, -0x25b346, - -0x260b60, -0x26637a, -0x26bb94, -0x2713ae, -0x276bc8, -0x27c3e2, - -0x281bfc, -0x287416, -0x28cc30, -0x29244a, -0x297c64, -0x29d47e, - -0x2a2c98, -0x2a84b2, -0x2adccc, -0x2b34e6, - }; - - -/* We assume that right shift corresponds to signed division by 2 with - * rounding towards minus infinity. This is correct for typical "arithmetic - * shift" instructions that shift in copies of the sign bit. But some - * C compilers implement >> with an unsigned shift. For these machines you - * must define RIGHT_SHIFT_IS_UNSIGNED. - * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity. - * It is only applied with constant shift counts. SHIFT_TEMPS must be - * included in the variables of any routine using RIGHT_SHIFT. - */ - -#ifdef RIGHT_SHIFT_IS_UNSIGNED -#define SHIFT_TEMPS INT32 shift_temp; -#define RIGHT_SHIFT(x,shft) \ - ((shift_temp = (x)) < 0 ? \ - (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \ - (shift_temp >> (shft))) -#else -#define SHIFT_TEMPS -#define RIGHT_SHIFT(x,shft) ((x) >> (shft)) -#endif - - -METHODDEF(void) -ycc_rgb_convert_argb (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows) -{ - JDIMENSION num_cols = cinfo->output_width; - JSAMPLE * range_limit = cinfo->sample_range_limit; - - SHIFT_TEMPS - - /* This is used if we don't have SSE2 */ - - while (--num_rows >= 0) { - JSAMPROW inptr0 = input_buf[0][input_row]; - JSAMPROW inptr1 = input_buf[1][input_row]; - JSAMPROW inptr2 = input_buf[2][input_row]; - input_row++; - uint32_t *outptr = (uint32_t *) *output_buf++; - for (JDIMENSION col = 0; col < num_cols; col++) { - int y = GETJSAMPLE(inptr0[col]); - int cb = GETJSAMPLE(inptr1[col]); - int cr = GETJSAMPLE(inptr2[col]); - JSAMPLE * range_limit_y = range_limit + y; - /* Range-limiting is essential due to noise introduced by DCT losses. */ - outptr[col] = 0xFF000000 | - ( range_limit_y[Cr_r_tab[cr]] << 16 ) | - ( range_limit_y[((int) RIGHT_SHIFT(Cb_g_tab[cb] + Cr_g_tab[cr], SCALEBITS))] << 8 ) | - ( range_limit_y[Cb_b_tab[cb]] ); - } - } -} - - /**************** Inverted CMYK -> RGB conversion **************/ /* * Input is (Inverted) CMYK stored as 4 bytes per pixel. diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 75ce62c22c00..7c0012523416 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -45,14 +45,6 @@ GetBuildConfiguration(JSContext *cx, unsigned argc, jsval *vp) if (!JS_SetProperty(cx, info, "exact-rooting", &value)) return false; -#ifdef JSGC_ROOT_ANALYSIS - value = BooleanValue(true); -#else - value = BooleanValue(false); -#endif - if (!JS_SetProperty(cx, info, "rooting-analysis", &value)) - return false; - #ifdef DEBUG value = BooleanValue(true); #else @@ -82,7 +74,7 @@ GetBuildConfiguration(JSContext *cx, unsigned argc, jsval *vp) #else value = BooleanValue(false); #endif - if (!JS_SetProperty(cx, info, "has-gczeal", &value)) + if (!JS_SetProperty(cx, info, "threadsafe", &value)) return false; #ifdef JS_MORE_DETERMINISTIC diff --git a/js/src/configure.in b/js/src/configure.in index 1024491fa384..846482c72263 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -2222,11 +2222,6 @@ MOZ_ARG_ENABLE_BOOL(methodjit-spew, ENABLE_METHODJIT_SPEW=1, ENABLE_METHODJIT_SPEW= ) -MOZ_ARG_DISABLE_BOOL(ion, -[ --disable-ion Disable use of IONMonkey compiler], - ENABLE_ION=, - ENABLE_ION=1 ) - AC_SUBST(ENABLE_METHODJIT) AC_SUBST(ENABLE_METHODJIT_SPEW) diff --git a/js/src/frontend/NameFunctions.cpp b/js/src/frontend/NameFunctions.cpp index fa142c9f8beb..7cf2a36cd6fc 100644 --- a/js/src/frontend/NameFunctions.cpp +++ b/js/src/frontend/NameFunctions.cpp @@ -173,9 +173,9 @@ class NameResolver * listed, then it is skipped. Otherwise an intelligent name is guessed to * assign to the function's displayAtom field */ - JSAtom *resolveFun(ParseNode *pn, JSAtom *prefix) { + JSAtom *resolveFun(ParseNode *pn, HandleAtom prefix) { JS_ASSERT(pn != NULL && pn->isKind(PNK_FUNCTION)); - JSFunction *fun = pn->pn_funbox->fun(); + RootedFunction fun(cx, pn->pn_funbox->fun()); if (nparents == 0) return NULL; @@ -268,12 +268,13 @@ class NameResolver * ParseNode instance given. The prefix is for each subsequent name, and * should initially be NULL. */ - void resolve(ParseNode *cur, JSAtom *prefix = NULL) { + void resolve(ParseNode *cur, HandleAtom prefixArg = NullPtr()) { + RootedAtom prefix(cx, prefixArg); if (cur == NULL) return; if (cur->isKind(PNK_FUNCTION) && cur->isArity(PN_FUNC)) { - JSAtom *prefix2 = resolveFun(cur, prefix); + RootedAtom prefix2(cx, resolveFun(cur, prefix)); /* * If a function looks like (function(){})() where the parent node * of the definition of the function is a call, then it shouldn't diff --git a/js/src/gc/Root.h b/js/src/gc/Root.h index c89a63dc7b9e..31803437f6f2 100644 --- a/js/src/gc/Root.h +++ b/js/src/gc/Root.h @@ -234,16 +234,22 @@ class MutableHandle : public MutableHandleBase void operator =(S v) MOZ_DELETE; }; -typedef MutableHandle MutableHandleObject; -typedef MutableHandle MutableHandleValue; -typedef MutableHandle MutableHandleId; +typedef MutableHandle MutableHandleObject; +typedef MutableHandle MutableHandleFunction; +typedef MutableHandle MutableHandleScript; +typedef MutableHandle MutableHandleString; +typedef MutableHandle MutableHandleId; +typedef MutableHandle MutableHandleValue; /* * Raw pointer used as documentation that a parameter does not need to be * rooted. */ typedef JSObject * RawObject; +typedef JSFunction * RawFunction; +typedef JSScript * RawScript; typedef JSString * RawString; +typedef jsid RawId; typedef Value RawValue; /* diff --git a/js/src/ion/CodeGenerator.cpp b/js/src/ion/CodeGenerator.cpp index f41567afcfe6..73c81f2c980a 100644 --- a/js/src/ion/CodeGenerator.cpp +++ b/js/src/ion/CodeGenerator.cpp @@ -2401,7 +2401,7 @@ CodeGenerator::emitArrayPopShift(LInstruction *lir, const MArrayPopShift *mir, R Register elementsTemp, Register lengthTemp, TypedOrValueRegister out) { OutOfLineCode *ool; - typedef bool (*pf)(JSContext *, JSObject *, Value *); + typedef bool (*pf)(JSContext *, HandleObject, MutableHandleValue); if (mir->mode() == MArrayPopShift::Pop) { static const VMFunction Info = FunctionInfo(ion::ArrayPopDense); @@ -2498,7 +2498,7 @@ bool CodeGenerator::emitArrayPush(LInstruction *lir, const MArrayPush *mir, Register obj, ConstantOrRegister value, Register elementsTemp, Register length) { - typedef bool (*pf)(JSContext *, JSObject *, HandleValue, uint32_t *); + typedef bool (*pf)(JSContext *, HandleObject, HandleValue, uint32_t *); static const VMFunction Info = FunctionInfo(ion::ArrayPushDense); OutOfLineCode *ool = oolCallVM(Info, lir, (ArgList(), obj, value), StoreRegisterTo(length)); if (!ool) diff --git a/js/src/ion/Ion.cpp b/js/src/ion/Ion.cpp index 67df596a53ee..b2011e8bad1a 100644 --- a/js/src/ion/Ion.cpp +++ b/js/src/ion/Ion.cpp @@ -53,7 +53,7 @@ JS_STATIC_ASSERT(sizeof(IonCode) % gc::Cell::CellSize == 0); #ifdef JS_THREADSAFE static bool IonTLSInitialized = false; -static PRUintn IonTLSIndex; +static unsigned IonTLSIndex; static inline IonContext * CurrentIonContext() diff --git a/js/src/ion/IonBuilder.cpp b/js/src/ion/IonBuilder.cpp index d601e760d5c0..648920e9a7ee 100644 --- a/js/src/ion/IonBuilder.cpp +++ b/js/src/ion/IonBuilder.cpp @@ -3661,6 +3661,41 @@ IonBuilder::jsop_funapply(uint32 argc) return pushTypeBarrier(apply, types, barrier); } +// Get the builtin RegExp.prototype.test function. +static bool +GetBuiltinRegExpTest(JSContext *cx, JSScript *script, JSFunction **result) +{ + JS_ASSERT(*result == NULL); + + // Get the builtin RegExp.prototype object. + RootedObject proto(cx, script->global().getOrCreateRegExpPrototype(cx)); + if (!proto) + return false; + + // Get the |test| property. Note that we use lookupProperty, not getProperty, + // to avoid calling a getter. + RootedShape shape(cx); + RootedObject holder(cx); + if (!JSObject::lookupProperty(cx, proto, cx->runtime->atomState.testAtom, &holder, &shape)) + return false; + + if (proto != holder || !shape || !shape->hasDefaultGetter() || !shape->hasSlot()) + return true; + + // The RegExp.prototype.test property is writable, so we have to ensure + // we got the builtin function. + Value val = holder->getSlot(shape->slot()); + if (!val.isObject()) + return true; + + JSObject *obj = &val.toObject(); + if (!obj->isFunction() || obj->toFunction()->maybeNative() != regexp_test) + return true; + + *result = obj->toFunction(); + return true; +} + bool IonBuilder::jsop_call(uint32 argc, bool constructing) { @@ -3689,7 +3724,21 @@ IonBuilder::jsop_call(uint32 argc, bool constructing) return inlineScriptedCall(targets, argc, constructing, types, barrier); } - RootedFunction target(cx, numTargets == 1 ? targets[0]->toFunction() : NULL); + RootedFunction target(cx, NULL); + if (numTargets == 1) { + target = targets[0]->toFunction(); + + // Call RegExp.test instead of RegExp.exec if the result will not be used + // or will only be used to test for existence. + if (target->maybeNative() == regexp_exec && !CallResultEscapes(pc)) { + JSFunction *newTarget = NULL; + if (!GetBuiltinRegExpTest(cx, script, &newTarget)) + return false; + if (newTarget) + target = newTarget; + } + } + return makeCallBarrier(target, argc, constructing, types, barrier); } diff --git a/js/src/ion/IonMacroAssembler.h b/js/src/ion/IonMacroAssembler.h index 6be9ffe1d2bc..372896403195 100644 --- a/js/src/ion/IonMacroAssembler.h +++ b/js/src/ion/IonMacroAssembler.h @@ -339,17 +339,18 @@ class MacroAssembler : public MacroAssemblerSpecific JS_ASSERT(type == MIRType_Value || type == MIRType_String || type == MIRType_Object); Label done; + JSContext *cx = GetIonContext()->cx; + IonCode *preBarrier = cx->compartment->ionCompartment()->preBarrier(cx); + if (!preBarrier) { + enoughMemory_ = false; + return; + } + if (type == MIRType_Value) branchTestGCThing(Assembler::NotEqual, address, &done); Push(PreBarrierReg); computeEffectiveAddress(address, PreBarrierReg); - - JSContext *cx = GetIonContext()->cx; - IonCode *preBarrier = cx->compartment->ionCompartment()->preBarrier(cx); - if (!preBarrier) - enoughMemory_ = false; - call(preBarrier); Pop(PreBarrierReg); diff --git a/js/src/ion/VMFunctions.cpp b/js/src/ion/VMFunctions.cpp index 7ed860e436fd..cb94a416e5aa 100644 --- a/js/src/ion/VMFunctions.cpp +++ b/js/src/ion/VMFunctions.cpp @@ -276,28 +276,32 @@ NewInitObject(JSContext *cx, HandleObject templateObject) } bool -ArrayPopDense(JSContext *cx, JSObject *obj, Value *rval) +ArrayPopDense(JSContext *cx, HandleObject obj, MutableHandleValue rval) { - AutoDetectInvalidation adi(cx, rval); + JS_ASSERT(obj->isDenseArray()); - Value argv[3] = { UndefinedValue(), ObjectValue(*obj) }; + AutoDetectInvalidation adi(cx, rval.address()); + + Value argv[] = { UndefinedValue(), ObjectValue(*obj) }; + AutoValueArray ava(cx, argv, 2); if (!js::array_pop(cx, 0, argv)) return false; // If the result is |undefined|, the array was probably empty and we // have to monitor the return value. - *rval = argv[0]; - if (rval->isUndefined()) - types::TypeScript::Monitor(cx, *rval); + rval.set(argv[0]); + if (rval.isUndefined()) + types::TypeScript::Monitor(cx, rval); return true; } bool -ArrayPushDense(JSContext *cx, JSObject *obj, HandleValue v, uint32_t *length) +ArrayPushDense(JSContext *cx, HandleObject obj, HandleValue v, uint32_t *length) { JS_ASSERT(obj->isDenseArray()); - Value argv[3] = { UndefinedValue(), ObjectValue(*obj), v }; + Value argv[] = { UndefinedValue(), ObjectValue(*obj), v }; + AutoValueArray ava(cx, argv, 3); if (!js::array_push(cx, 1, argv)) return false; @@ -306,19 +310,22 @@ ArrayPushDense(JSContext *cx, JSObject *obj, HandleValue v, uint32_t *length) } bool -ArrayShiftDense(JSContext *cx, JSObject *obj, Value *rval) +ArrayShiftDense(JSContext *cx, HandleObject obj, MutableHandleValue rval) { - AutoDetectInvalidation adi(cx, rval); + JS_ASSERT(obj->isDenseArray()); - Value argv[3] = { UndefinedValue(), ObjectValue(*obj) }; + AutoDetectInvalidation adi(cx, rval.address()); + + Value argv[] = { UndefinedValue(), ObjectValue(*obj) }; + AutoValueArray ava(cx, argv, 2); if (!js::array_shift(cx, 0, argv)) return false; // If the result is |undefined|, the array was probably empty and we // have to monitor the return value. - *rval = argv[0]; - if (rval->isUndefined()) - types::TypeScript::Monitor(cx, *rval); + rval.set(argv[0]); + if (rval.isUndefined()) + types::TypeScript::Monitor(cx, rval); return true; } diff --git a/js/src/ion/VMFunctions.h b/js/src/ion/VMFunctions.h index d3c46339cc70..abe676f852c0 100644 --- a/js/src/ion/VMFunctions.h +++ b/js/src/ion/VMFunctions.h @@ -426,9 +426,9 @@ bool IteratorMore(JSContext *cx, HandleObject obj, JSBool *res); JSObject *NewInitArray(JSContext *cx, uint32_t count, types::TypeObject *type); JSObject *NewInitObject(JSContext *cx, HandleObject templateObject); -bool ArrayPopDense(JSContext *cx, JSObject *obj, Value *rval); -bool ArrayPushDense(JSContext *cx, JSObject *obj, HandleValue v, uint32_t *length); -bool ArrayShiftDense(JSContext *cx, JSObject *obj, Value *rval); +bool ArrayPopDense(JSContext *cx, HandleObject obj, MutableHandleValue rval); +bool ArrayPushDense(JSContext *cx, HandleObject obj, HandleValue v, uint32_t *length); +bool ArrayShiftDense(JSContext *cx, HandleObject obj, MutableHandleValue rval); bool SetProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, HandleValue value, bool strict, bool isSetName); diff --git a/js/src/jit-test/tests/basic/bug727223.js b/js/src/jit-test/tests/basic/bug727223.js new file mode 100644 index 000000000000..5011c134df02 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug727223.js @@ -0,0 +1,15 @@ +try { + mjitChunkLimit(1) + function x() {} +} catch (e) {} +(function() { + for (let c in [0, 0, 0]) { + let c + for (y in decodeURI()) { + (function() { + c + }()) + } + } +}()) + diff --git a/js/src/jit-test/tests/ion/regexp-exec.js b/js/src/jit-test/tests/ion/regexp-exec.js new file mode 100644 index 000000000000..d9cec788efb6 --- /dev/null +++ b/js/src/jit-test/tests/ion/regexp-exec.js @@ -0,0 +1,20 @@ +// RegExp.exec -> RegExp.test optimization should use the builtin test method. +function f() { + var res = 0; + for (var i=0; i<100; i++) { + if (/a/.exec("a")) + res++; + } + assertEq(res, 100); +} +delete RegExp.prototype.test; +gc(); +f(); + +RegExp.prototype.test = function() { assertEq(0, 1); } +gc(); +f(); + +Object.defineProperty(RegExp.prototype, "test", {get: function() { assertEq(0, 1); }}); +gc(); +f(); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 853bab791082..2495d4f21faa 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -7101,7 +7101,7 @@ JS_SetGCZeal(JSContext *cx, uint8_t zeal, uint32_t frequency) " 3: GC when the window paints (browser only)\n" " 4: Verify pre write barriers between instructions\n" " 5: Verify pre write barriers between paints\n" - " 6: Verify stack rooting (ignoring XML and Reflect)\n" + " 6: Verify stack rooting (ignoring XML)\n" " 7: Verify stack rooting (all roots)\n" " 8: Incremental GC in two slices: 1) mark roots 2) finish collection\n" " 9: Incremental GC in two slices: 1) mark all 2) new marking and finish\n" diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index 92721dc3bc6d..dd9d74f25775 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -287,18 +287,18 @@ fun_resolve(JSContext *cx, HandleObject obj, HandleId id, unsigned flags, if (JSID_IS_ATOM(id, cx->runtime->atomState.classPrototypeAtom)) { /* - * Native or "built-in" functions do not have a .prototype property per - * ECMA-262, or (Object.prototype, Function.prototype, etc.) have that - * property created eagerly. + * Built-in functions do not have a .prototype property per ECMA-262, + * or (Object.prototype, Function.prototype, etc.) have that property + * created eagerly. * * ES5 15.3.4: the non-native function object named Function.prototype * does not have a .prototype property. * * ES5 15.3.4.5: bound functions don't have a prototype property. The - * isNative() test covers this case because bound functions are native - * functions by definition/construction. + * isBuiltin() test covers this case because bound functions are native + * (and thus built-in) functions by definition/construction. */ - if (fun->isNative() || fun->isFunctionPrototype()) + if (fun->isBuiltin() || fun->isFunctionPrototype()) return true; if (!ResolveInterpretedFunctionPrototype(cx, fun)) diff --git a/js/src/jsfun.h b/js/src/jsfun.h index 822b720bcde2..2ee04dba70bc 100644 --- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -81,6 +81,7 @@ struct JSFunction : public JSObject bool isInterpreted() const { return flags & JSFUN_INTERPRETED; } bool isNative() const { return !isInterpreted(); } bool isSelfHostedBuiltin() const { return flags & JSFUN_SELF_HOSTED; } + bool isBuiltin() const { return isNative() || isSelfHostedBuiltin(); } bool isSelfHostedConstructor() const { return flags & JSFUN_SELF_HOSTED_CTOR; } bool isNativeConstructor() const { return flags & JSFUN_CONSTRUCTOR; } bool isHeavyweight() const { return JSFUN_HEAVYWEIGHT_TEST(flags); } diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp index 62a52e445e43..76e0ecc38cf8 100644 --- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -5639,7 +5639,7 @@ js_DecompileFunction(JSPrinter *jp) if (fun->hasDefaults()) { // Since bug 781422, this code is completely wrong. If you ever have - // the unfortunate task of reenabling the decompiler, you'll have to + // the unenviable task of reenabling the decompiler, you'll have to // completely rewrite defaults decompiling. MOZ_CRASH(); diff --git a/js/src/jsprvtd.h b/js/src/jsprvtd.h index 1516c75ac073..3bbd10a17a5f 100644 --- a/js/src/jsprvtd.h +++ b/js/src/jsprvtd.h @@ -216,6 +216,9 @@ typedef JS::Handle HandleAtom; typedef JS::Handle HandlePropertyName; typedef JS::MutableHandle MutableHandleShape; +typedef JS::MutableHandle MutableHandleAtom; + +typedef JSAtom * RawAtom; typedef JS::Rooted RootedShape; typedef JS::Rooted RootedBaseShape; diff --git a/js/src/jsreflect.cpp b/js/src/jsreflect.cpp index 7e48369e47b0..2da1c2b1366d 100644 --- a/js/src/jsreflect.cpp +++ b/js/src/jsreflect.cpp @@ -125,7 +125,6 @@ typedef AutoValueVector NodeVector; return false; \ JS_END_MACRO - /* * Builder class that constructs JavaScript AST node objects. See: * @@ -138,18 +137,19 @@ class NodeBuilder JSContext *cx; bool saveLoc; /* save source location information? */ char const *src; /* source filename or null */ - Value srcval; /* source filename JS value or null */ + RootedValue srcval; /* source filename JS value or null */ Value callbacks[AST_LIMIT]; /* user-specified callbacks */ - Value userv; /* user-specified builder object or null */ + AutoValueArray callbacksRoots; /* for rooting |callbacks| */ + RootedValue userv; /* user-specified builder object or null */ + RootedValue undefinedVal; /* a rooted undefined val, used by opt() */ public: NodeBuilder(JSContext *c, bool l, char const *s) - : cx(c), saveLoc(l), src(s) { - } - - bool init(JSObject *userobj_ = NULL) { - RootedObject userobj(cx, userobj_); + : cx(c), saveLoc(l), src(s), srcval(c), callbacks(), + callbacksRoots(c, callbacks, AST_LIMIT), userv(c), undefinedVal(c, UndefinedValue()) + { } + bool init(HandleObject userobj = NullPtr()) { if (src) { if (!atomValue(src, &srcval)) return false; @@ -167,15 +167,15 @@ class NodeBuilder userv.setObject(*userobj); - RootedValue nullValue(cx, NullValue()); + RootedValue nullVal(cx, NullValue()); RootedValue funv(cx); for (unsigned i = 0; i < AST_LIMIT; i++) { const char *name = callbackNames[i]; - JSAtom *atom = Atomize(cx, name, strlen(name)); + RootedAtom atom(cx, Atomize(cx, name, strlen(name))); if (!atom) return false; RootedId id(cx, AtomToId(atom)); - if (!baseops::GetPropertyDefault(cx, userobj, id, nullValue, &funv)) + if (!baseops::GetPropertyDefault(cx, userobj, id, nullVal, &funv)) return false; if (funv.isNullOrUndefined()) { @@ -196,133 +196,154 @@ class NodeBuilder } private: - bool callback(Value fun, TokenPos *pos, Value *dst) { + bool callback(HandleValue fun, TokenPos *pos, MutableHandleValue dst) { if (saveLoc) { - Value loc; + RootedValue loc(cx); if (!newNodeLoc(pos, &loc)) return false; Value argv[] = { loc }; - return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst); + AutoValueArray ava(cx, argv, 1); + return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst.address()); } Value argv[] = { NullValue() }; /* no zero-length arrays allowed! */ - return Invoke(cx, userv, fun, 0, argv, dst); + AutoValueArray ava(cx, argv, 1); + return Invoke(cx, userv, fun, 0, argv, dst.address()); } - bool callback(Value fun, Value v1, TokenPos *pos, Value *dst) { + bool callback(HandleValue fun, HandleValue v1, TokenPos *pos, MutableHandleValue dst) { if (saveLoc) { - Value loc; + RootedValue loc(cx); if (!newNodeLoc(pos, &loc)) return false; Value argv[] = { v1, loc }; - return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst); + AutoValueArray ava(cx, argv, 2); + return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst.address()); } Value argv[] = { v1 }; - return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst); + AutoValueArray ava(cx, argv, 1); + return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst.address()); } - bool callback(Value fun, Value v1, Value v2, TokenPos *pos, Value *dst) { + bool callback(HandleValue fun, HandleValue v1, HandleValue v2, TokenPos *pos, + MutableHandleValue dst) { if (saveLoc) { - Value loc; + RootedValue loc(cx); if (!newNodeLoc(pos, &loc)) return false; Value argv[] = { v1, v2, loc }; - return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst); + AutoValueArray ava(cx, argv, 3); + return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst.address()); } Value argv[] = { v1, v2 }; - return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst); + AutoValueArray ava(cx, argv, 2); + return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst.address()); } - bool callback(Value fun, Value v1, Value v2, Value v3, TokenPos *pos, Value *dst) { + bool callback(HandleValue fun, HandleValue v1, HandleValue v2, HandleValue v3, TokenPos *pos, + MutableHandleValue dst) { if (saveLoc) { - Value loc; + RootedValue loc(cx); if (!newNodeLoc(pos, &loc)) return false; Value argv[] = { v1, v2, v3, loc }; - return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst); + AutoValueArray ava(cx, argv, 4); + return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst.address()); } Value argv[] = { v1, v2, v3 }; - return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst); + AutoValueArray ava(cx, argv, 3); + return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst.address()); } - bool callback(Value fun, Value v1, Value v2, Value v3, Value v4, TokenPos *pos, Value *dst) { + bool callback(HandleValue fun, HandleValue v1, HandleValue v2, HandleValue v3, HandleValue v4, + TokenPos *pos, MutableHandleValue dst) { if (saveLoc) { - Value loc; + RootedValue loc(cx); if (!newNodeLoc(pos, &loc)) return false; Value argv[] = { v1, v2, v3, v4, loc }; - return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst); + AutoValueArray ava(cx, argv, 5); + return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst.address()); } Value argv[] = { v1, v2, v3, v4 }; - return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst); + AutoValueArray ava(cx, argv, 4); + return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst.address()); } - bool callback(Value fun, Value v1, Value v2, Value v3, Value v4, Value v5, - TokenPos *pos, Value *dst) { + bool callback(HandleValue fun, HandleValue v1, HandleValue v2, HandleValue v3, HandleValue v4, + HandleValue v5, TokenPos *pos, MutableHandleValue dst) { if (saveLoc) { - Value loc; + RootedValue loc(cx); if (!newNodeLoc(pos, &loc)) return false; Value argv[] = { v1, v2, v3, v4, v5, loc }; - return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst); + AutoValueArray ava(cx, argv, 6); + return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst.address()); } Value argv[] = { v1, v2, v3, v4, v5 }; - return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst); + AutoValueArray ava(cx, argv, 5); + return Invoke(cx, userv, fun, ArrayLength(argv), argv, dst.address()); } - Value opt(Value v) { + // WARNING: Returning a Handle is non-standard, but it works in this case + // because both |v| and |undefinedVal| are definitely rooted on a previous + // stack frame (i.e. we're just choosing between two already-rooted + // values). + HandleValue opt(HandleValue v) { JS_ASSERT_IF(v.isMagic(), v.whyMagic() == JS_SERIALIZE_NO_NODE); - return v.isMagic(JS_SERIALIZE_NO_NODE) ? UndefinedValue() : v; + return v.isMagic(JS_SERIALIZE_NO_NODE) ? undefinedVal : v; } - bool atomValue(const char *s, Value *dst) { + bool atomValue(const char *s, MutableHandleValue dst) { /* * Bug 575416: instead of Atomize, lookup constant atoms in tbl file */ - JSAtom *atom = Atomize(cx, s, strlen(s)); + RootedAtom atom(cx, Atomize(cx, s, strlen(s))); if (!atom) return false; - dst->setString(atom); + dst.setString(atom); return true; } - bool newObject(JSObject **dst) { - JSObject *nobj = NewBuiltinClassInstance(cx, &ObjectClass); + bool newObject(MutableHandleObject dst) { + RootedObject nobj(cx, NewBuiltinClassInstance(cx, &ObjectClass)); if (!nobj) return false; - *dst = nobj; + dst.set(nobj); return true; } - bool newArray(NodeVector &elts, Value *dst); + bool newArray(NodeVector &elts, MutableHandleValue dst); - bool newNode(ASTType type, TokenPos *pos, JSObject **dst); + bool newNode(ASTType type, TokenPos *pos, MutableHandleObject dst); - bool newNode(ASTType type, TokenPos *pos, Value *dst) { - JSObject *node; + bool newNode(ASTType type, TokenPos *pos, MutableHandleValue dst) { + RootedObject node(cx); return newNode(type, pos, &node) && setResult(node, dst); } - bool newNode(ASTType type, TokenPos *pos, const char *childName, Value child, Value *dst) { - JSObject *node; + bool newNode(ASTType type, TokenPos *pos, + const char *childName, HandleValue child, + MutableHandleValue dst) { + RootedObject node(cx); return newNode(type, pos, &node) && setProperty(node, childName, child) && setResult(node, dst); } bool newNode(ASTType type, TokenPos *pos, - const char *childName1, Value child1, - const char *childName2, Value child2, - Value *dst) { - JSObject *node; + const char *childName1, HandleValue child1, + const char *childName2, HandleValue child2, + MutableHandleValue dst) { + RootedObject node(cx); return newNode(type, pos, &node) && setProperty(node, childName1, child1) && setProperty(node, childName2, child2) && @@ -330,11 +351,11 @@ class NodeBuilder } bool newNode(ASTType type, TokenPos *pos, - const char *childName1, Value child1, - const char *childName2, Value child2, - const char *childName3, Value child3, - Value *dst) { - JSObject *node; + const char *childName1, HandleValue child1, + const char *childName2, HandleValue child2, + const char *childName3, HandleValue child3, + MutableHandleValue dst) { + RootedObject node(cx); return newNode(type, pos, &node) && setProperty(node, childName1, child1) && setProperty(node, childName2, child2) && @@ -343,12 +364,12 @@ class NodeBuilder } bool newNode(ASTType type, TokenPos *pos, - const char *childName1, Value child1, - const char *childName2, Value child2, - const char *childName3, Value child3, - const char *childName4, Value child4, - Value *dst) { - JSObject *node; + const char *childName1, HandleValue child1, + const char *childName2, HandleValue child2, + const char *childName3, HandleValue child3, + const char *childName4, HandleValue child4, + MutableHandleValue dst) { + RootedObject node(cx); return newNode(type, pos, &node) && setProperty(node, childName1, child1) && setProperty(node, childName2, child2) && @@ -358,13 +379,13 @@ class NodeBuilder } bool newNode(ASTType type, TokenPos *pos, - const char *childName1, Value child1, - const char *childName2, Value child2, - const char *childName3, Value child3, - const char *childName4, Value child4, - const char *childName5, Value child5, - Value *dst) { - JSObject *node; + const char *childName1, HandleValue child1, + const char *childName2, HandleValue child2, + const char *childName3, HandleValue child3, + const char *childName4, HandleValue child4, + const char *childName5, HandleValue child5, + MutableHandleValue dst) { + RootedObject node(cx); return newNode(type, pos, &node) && setProperty(node, childName1, child1) && setProperty(node, childName2, child2) && @@ -375,15 +396,15 @@ class NodeBuilder } bool newNode(ASTType type, TokenPos *pos, - const char *childName1, Value child1, - const char *childName2, Value child2, - const char *childName3, Value child3, - const char *childName4, Value child4, - const char *childName5, Value child5, - const char *childName6, Value child6, - const char *childName7, Value child7, - Value *dst) { - JSObject *node; + const char *childName1, HandleValue child1, + const char *childName2, HandleValue child2, + const char *childName3, HandleValue child3, + const char *childName4, HandleValue child4, + const char *childName5, HandleValue child5, + const char *childName6, HandleValue child6, + const char *childName7, HandleValue child7, + MutableHandleValue dst) { + RootedObject node(cx); return newNode(type, pos, &node) && setProperty(node, childName1, child1) && setProperty(node, childName2, child2) && @@ -395,44 +416,41 @@ class NodeBuilder setResult(node, dst); } - bool listNode(ASTType type, const char *propName, NodeVector &elts, TokenPos *pos, Value *dst) { - Value array; + bool listNode(ASTType type, const char *propName, NodeVector &elts, TokenPos *pos, + MutableHandleValue dst) { + RootedValue array(cx); if (!newArray(elts, &array)) return false; - Value cb = callbacks[type]; + RootedValue cb(cx, callbacks[type]); if (!cb.isNull()) return callback(cb, array, pos, dst); return newNode(type, pos, propName, array, dst); } - bool setProperty(JSObject *objArg, const char *name, Value valArg) { - RootedObject obj(cx, objArg); - RootedValue val(cx, valArg); + bool setProperty(HandleObject obj, const char *name, HandleValue val) { JS_ASSERT_IF(val.isMagic(), val.whyMagic() == JS_SERIALIZE_NO_NODE); - /* Represent "no node" as null and ensure users are not exposed to magic values. */ - if (val.isMagic(JS_SERIALIZE_NO_NODE)) - val.setNull(); - /* * Bug 575416: instead of Atomize, lookup constant atoms in tbl file */ - JSAtom *atom = Atomize(cx, name, strlen(name)); + RootedAtom atom(cx, Atomize(cx, name, strlen(name))); if (!atom) return false; - return JSObject::defineProperty(cx, obj, atom->asPropertyName(), val); + /* Represent "no node" as null and ensure users are not exposed to magic values. */ + RootedValue optVal(cx, val.isMagic(JS_SERIALIZE_NO_NODE) ? NullValue() : val); + return JSObject::defineProperty(cx, obj, atom->asPropertyName(), optVal); } - bool newNodeLoc(TokenPos *pos, Value *dst); + bool newNodeLoc(TokenPos *pos, MutableHandleValue dst); - bool setNodeLoc(JSObject *obj, TokenPos *pos); + bool setNodeLoc(HandleObject node, TokenPos *pos); - bool setResult(JSObject *obj, Value *dst) { + bool setResult(HandleObject obj, MutableHandleValue dst) { JS_ASSERT(obj); - dst->setObject(*obj); + dst.setObject(*obj); return true; } @@ -442,191 +460,210 @@ class NodeBuilder * arguments a nullable token position and a non-nullable, rooted * outparam. * - * All Value arguments are rooted. Any Value arguments representing - * optional subnodes may be a JS_SERIALIZE_NO_NODE magic value. + * Any Value arguments representing optional subnodes may be a + * JS_SERIALIZE_NO_NODE magic value. */ /* * misc nodes */ - bool program(NodeVector &elts, TokenPos *pos, Value *dst); + bool program(NodeVector &elts, TokenPos *pos, MutableHandleValue dst); - bool literal(Value val, TokenPos *pos, Value *dst); + bool literal(HandleValue val, TokenPos *pos, MutableHandleValue dst); - bool identifier(Value name, TokenPos *pos, Value *dst); + bool identifier(HandleValue name, TokenPos *pos, MutableHandleValue dst); bool function(ASTType type, TokenPos *pos, - Value id, NodeVector &args, NodeVector &defaults, - Value body, Value rest, bool isGenerator, bool isExpression, - Value *dst); + HandleValue id, NodeVector &args, NodeVector &defaults, + HandleValue body, HandleValue rest, bool isGenerator, bool isExpression, + MutableHandleValue dst); - bool variableDeclarator(Value id, Value init, TokenPos *pos, Value *dst); + bool variableDeclarator(HandleValue id, HandleValue init, TokenPos *pos, + MutableHandleValue dst); - bool switchCase(Value expr, NodeVector &elts, TokenPos *pos, Value *dst); + bool switchCase(HandleValue expr, NodeVector &elts, TokenPos *pos, MutableHandleValue dst); - bool catchClause(Value var, Value guard, Value body, TokenPos *pos, Value *dst); + bool catchClause(HandleValue var, HandleValue guard, HandleValue body, TokenPos *pos, + MutableHandleValue dst); - bool propertyInitializer(Value key, Value val, PropKind kind, TokenPos *pos, Value *dst); + bool propertyInitializer(HandleValue key, HandleValue val, PropKind kind, TokenPos *pos, + MutableHandleValue dst); /* * statements */ - bool blockStatement(NodeVector &elts, TokenPos *pos, Value *dst); + bool blockStatement(NodeVector &elts, TokenPos *pos, MutableHandleValue dst); - bool expressionStatement(Value expr, TokenPos *pos, Value *dst); + bool expressionStatement(HandleValue expr, TokenPos *pos, MutableHandleValue dst); - bool emptyStatement(TokenPos *pos, Value *dst); + bool emptyStatement(TokenPos *pos, MutableHandleValue dst); - bool ifStatement(Value test, Value cons, Value alt, TokenPos *pos, Value *dst); + bool ifStatement(HandleValue test, HandleValue cons, HandleValue alt, TokenPos *pos, + MutableHandleValue dst); - bool breakStatement(Value label, TokenPos *pos, Value *dst); + bool breakStatement(HandleValue label, TokenPos *pos, MutableHandleValue dst); - bool continueStatement(Value label, TokenPos *pos, Value *dst); + bool continueStatement(HandleValue label, TokenPos *pos, MutableHandleValue dst); - bool labeledStatement(Value label, Value stmt, TokenPos *pos, Value *dst); + bool labeledStatement(HandleValue label, HandleValue stmt, TokenPos *pos, + MutableHandleValue dst); - bool throwStatement(Value arg, TokenPos *pos, Value *dst); + bool throwStatement(HandleValue arg, TokenPos *pos, MutableHandleValue dst); - bool returnStatement(Value arg, TokenPos *pos, Value *dst); + bool returnStatement(HandleValue arg, TokenPos *pos, MutableHandleValue dst); - bool forStatement(Value init, Value test, Value update, Value stmt, - TokenPos *pos, Value *dst); + bool forStatement(HandleValue init, HandleValue test, HandleValue update, HandleValue stmt, + TokenPos *pos, MutableHandleValue dst); - bool forInStatement(Value var, Value expr, Value stmt, - bool isForEach, TokenPos *pos, Value *dst); + bool forInStatement(HandleValue var, HandleValue expr, HandleValue stmt, + bool isForEach, TokenPos *pos, MutableHandleValue dst); - bool forOfStatement(Value var, Value expr, Value stmt, TokenPos *pos, Value *dst); + bool forOfStatement(HandleValue var, HandleValue expr, HandleValue stmt, TokenPos *pos, + MutableHandleValue dst); + bool withStatement(HandleValue expr, HandleValue stmt, TokenPos *pos, MutableHandleValue dst); - bool withStatement(Value expr, Value stmt, TokenPos *pos, Value *dst); + bool whileStatement(HandleValue test, HandleValue stmt, TokenPos *pos, MutableHandleValue dst); - bool whileStatement(Value test, Value stmt, TokenPos *pos, Value *dst); + bool doWhileStatement(HandleValue stmt, HandleValue test, TokenPos *pos, + MutableHandleValue dst); - bool doWhileStatement(Value stmt, Value test, TokenPos *pos, Value *dst); + bool switchStatement(HandleValue disc, NodeVector &elts, bool lexical, TokenPos *pos, + MutableHandleValue dst); - bool switchStatement(Value disc, NodeVector &elts, bool lexical, TokenPos *pos, Value *dst); + bool tryStatement(HandleValue body, NodeVector &guarded, HandleValue unguarded, + HandleValue finally, TokenPos *pos, MutableHandleValue dst); - bool tryStatement(Value body, NodeVector &guarded, Value unguarded, Value finally, TokenPos *pos, Value *dst); + bool debuggerStatement(TokenPos *pos, MutableHandleValue dst); - bool debuggerStatement(TokenPos *pos, Value *dst); - - bool letStatement(NodeVector &head, Value stmt, TokenPos *pos, Value *dst); + bool letStatement(NodeVector &head, HandleValue stmt, TokenPos *pos, MutableHandleValue dst); /* * expressions */ - bool binaryExpression(BinaryOperator op, Value left, Value right, TokenPos *pos, Value *dst); + bool binaryExpression(BinaryOperator op, HandleValue left, HandleValue right, TokenPos *pos, + MutableHandleValue dst); - bool unaryExpression(UnaryOperator op, Value expr, TokenPos *pos, Value *dst); + bool unaryExpression(UnaryOperator op, HandleValue expr, TokenPos *pos, MutableHandleValue dst); - bool assignmentExpression(AssignmentOperator op, Value lhs, Value rhs, - TokenPos *pos, Value *dst); + bool assignmentExpression(AssignmentOperator op, HandleValue lhs, HandleValue rhs, + TokenPos *pos, MutableHandleValue dst); - bool updateExpression(Value expr, bool incr, bool prefix, TokenPos *pos, Value *dst); + bool updateExpression(HandleValue expr, bool incr, bool prefix, TokenPos *pos, + MutableHandleValue dst); - bool logicalExpression(bool lor, Value left, Value right, TokenPos *pos, Value *dst); + bool logicalExpression(bool lor, HandleValue left, HandleValue right, TokenPos *pos, + MutableHandleValue dst); - bool conditionalExpression(Value test, Value cons, Value alt, TokenPos *pos, Value *dst); + bool conditionalExpression(HandleValue test, HandleValue cons, HandleValue alt, TokenPos *pos, + MutableHandleValue dst); - bool sequenceExpression(NodeVector &elts, TokenPos *pos, Value *dst); + bool sequenceExpression(NodeVector &elts, TokenPos *pos, MutableHandleValue dst); - bool newExpression(Value callee, NodeVector &args, TokenPos *pos, Value *dst); + bool newExpression(HandleValue callee, NodeVector &args, TokenPos *pos, MutableHandleValue dst); - bool callExpression(Value callee, NodeVector &args, TokenPos *pos, Value *dst); + bool callExpression(HandleValue callee, NodeVector &args, TokenPos *pos, + MutableHandleValue dst); - bool memberExpression(bool computed, Value expr, Value member, TokenPos *pos, Value *dst); + bool memberExpression(bool computed, HandleValue expr, HandleValue member, TokenPos *pos, + MutableHandleValue dst); - bool arrayExpression(NodeVector &elts, TokenPos *pos, Value *dst); + bool arrayExpression(NodeVector &elts, TokenPos *pos, MutableHandleValue dst); - bool spreadExpression(Value expr, TokenPos *pos, Value *dst); + bool spreadExpression(HandleValue expr, TokenPos *pos, MutableHandleValue dst); - bool objectExpression(NodeVector &elts, TokenPos *pos, Value *dst); + bool objectExpression(NodeVector &elts, TokenPos *pos, MutableHandleValue dst); - bool thisExpression(TokenPos *pos, Value *dst); + bool thisExpression(TokenPos *pos, MutableHandleValue dst); - bool yieldExpression(Value arg, TokenPos *pos, Value *dst); + bool yieldExpression(HandleValue arg, TokenPos *pos, MutableHandleValue dst); - bool comprehensionBlock(Value patt, Value src, bool isForEach, TokenPos *pos, Value *dst); + bool comprehensionBlock(HandleValue patt, HandleValue src, bool isForEach, TokenPos *pos, + MutableHandleValue dst); - bool comprehensionExpression(Value body, NodeVector &blocks, Value filter, - TokenPos *pos, Value *dst); + bool comprehensionExpression(HandleValue body, NodeVector &blocks, HandleValue filter, + TokenPos *pos, MutableHandleValue dst); - bool generatorExpression(Value body, NodeVector &blocks, Value filter, - TokenPos *pos, Value *dst); + bool generatorExpression(HandleValue body, NodeVector &blocks, HandleValue filter, + TokenPos *pos, MutableHandleValue dst); - bool letExpression(NodeVector &head, Value expr, TokenPos *pos, Value *dst); + bool letExpression(NodeVector &head, HandleValue expr, TokenPos *pos, MutableHandleValue dst); /* * declarations */ - bool variableDeclaration(NodeVector &elts, VarDeclKind kind, TokenPos *pos, Value *dst); + bool variableDeclaration(NodeVector &elts, VarDeclKind kind, TokenPos *pos, + MutableHandleValue dst); /* * patterns */ - bool arrayPattern(NodeVector &elts, TokenPos *pos, Value *dst); + bool arrayPattern(NodeVector &elts, TokenPos *pos, MutableHandleValue dst); - bool objectPattern(NodeVector &elts, TokenPos *pos, Value *dst); + bool objectPattern(NodeVector &elts, TokenPos *pos, MutableHandleValue dst); - bool propertyPattern(Value key, Value patt, TokenPos *pos, Value *dst); + bool propertyPattern(HandleValue key, HandleValue patt, TokenPos *pos, MutableHandleValue dst); /* * xml */ - bool xmlAnyName(TokenPos *pos, Value *dst); + bool xmlAnyName(TokenPos *pos, MutableHandleValue dst); - bool xmlEscapeExpression(Value expr, TokenPos *pos, Value *dst); + bool xmlEscapeExpression(HandleValue expr, TokenPos *pos, MutableHandleValue dst); - bool xmlDefaultNamespace(Value ns, TokenPos *pos, Value *dst); + bool xmlDefaultNamespace(HandleValue ns, TokenPos *pos, MutableHandleValue dst); - bool xmlFilterExpression(Value left, Value right, TokenPos *pos, Value *dst); + bool xmlFilterExpression(HandleValue left, HandleValue right, TokenPos *pos, + MutableHandleValue dst); - bool xmlAttributeSelector(Value expr, bool computed, TokenPos *pos, Value *dst); + bool xmlAttributeSelector(HandleValue expr, bool computed, TokenPos *pos, + MutableHandleValue dst); - bool xmlQualifiedIdentifier(Value left, Value right, bool computed, TokenPos *pos, Value *dst); + bool xmlQualifiedIdentifier(HandleValue left, HandleValue right, bool computed, TokenPos *pos, + MutableHandleValue dst); - bool xmlFunctionQualifiedIdentifier(Value right, bool computed, TokenPos *pos, Value *dst); + bool xmlFunctionQualifiedIdentifier(HandleValue right, bool computed, TokenPos *pos, + MutableHandleValue dst); - bool xmlElement(NodeVector &elts, TokenPos *pos, Value *dst); + bool xmlElement(NodeVector &elts, TokenPos *pos, MutableHandleValue dst); - bool xmlText(Value text, TokenPos *pos, Value *dst); + bool xmlText(HandleValue text, TokenPos *pos, MutableHandleValue dst); - bool xmlList(NodeVector &elts, TokenPos *pos, Value *dst); + bool xmlList(NodeVector &elts, TokenPos *pos, MutableHandleValue dst); - bool xmlStartTag(NodeVector &elts, TokenPos *pos, Value *dst); + bool xmlStartTag(NodeVector &elts, TokenPos *pos, MutableHandleValue dst); - bool xmlEndTag(NodeVector &elts, TokenPos *pos, Value *dst); + bool xmlEndTag(NodeVector &elts, TokenPos *pos, MutableHandleValue dst); - bool xmlPointTag(NodeVector &elts, TokenPos *pos, Value *dst); + bool xmlPointTag(NodeVector &elts, TokenPos *pos, MutableHandleValue dst); - bool xmlName(Value text, TokenPos *pos, Value *dst); + bool xmlName(HandleValue text, TokenPos *pos, MutableHandleValue dst); - bool xmlName(NodeVector &elts, TokenPos *pos, Value *dst); + bool xmlName(NodeVector &elts, TokenPos *pos, MutableHandleValue dst); - bool xmlAttribute(Value text, TokenPos *pos, Value *dst); + bool xmlAttribute(HandleValue text, TokenPos *pos, MutableHandleValue dst); - bool xmlCdata(Value text, TokenPos *pos, Value *dst); + bool xmlCdata(HandleValue text, TokenPos *pos, MutableHandleValue dst); - bool xmlComment(Value text, TokenPos *pos, Value *dst); + bool xmlComment(HandleValue text, TokenPos *pos, MutableHandleValue dst); - bool xmlPI(Value target, Value content, TokenPos *pos, Value *dst); + bool xmlPI(HandleValue target, HandleValue content, TokenPos *pos, MutableHandleValue dst); }; bool -NodeBuilder::newNode(ASTType type, TokenPos *pos, JSObject **dst) +NodeBuilder::newNode(ASTType type, TokenPos *pos, MutableHandleObject dst) { JS_ASSERT(type > AST_ERROR && type < AST_LIMIT); - Value tv; - - JSObject *node = NewBuiltinClassInstance(cx, &ObjectClass); + RootedValue tv(cx); + RootedObject node(cx, NewBuiltinClassInstance(cx, &ObjectClass)); if (!node || !setNodeLoc(node, pos) || !atomValue(nodeTypeNames[type], &tv) || @@ -634,19 +671,19 @@ NodeBuilder::newNode(ASTType type, TokenPos *pos, JSObject **dst) return false; } - *dst = node; + dst.set(node); return true; } bool -NodeBuilder::newArray(NodeVector &elts, Value *dst) +NodeBuilder::newArray(NodeVector &elts, MutableHandleValue dst) { const size_t len = elts.length(); if (len > UINT32_MAX) { js_ReportAllocationOverflow(cx); return false; } - Rooted array(cx, NewDenseAllocatedArray(cx, uint32_t(len))); + RootedObject array(cx, NewDenseAllocatedArray(cx, uint32_t(len))); if (!array) return false; @@ -663,72 +700,87 @@ NodeBuilder::newArray(NodeVector &elts, Value *dst) return false; } - dst->setObject(*array); + dst.setObject(*array); return true; } bool -NodeBuilder::newNodeLoc(TokenPos *pos, Value *dst) +NodeBuilder::newNodeLoc(TokenPos *pos, MutableHandleValue dst) { if (!pos) { - dst->setNull(); + dst.setNull(); return true; } - JSObject *loc, *to; - Value tv; + RootedObject loc(cx); + RootedObject to(cx); + RootedValue val(cx); if (!newObject(&loc)) return false; - dst->setObject(*loc); + dst.setObject(*loc); - return newObject(&to) && - setProperty(loc, "start", ObjectValue(*to)) && - (tv.setNumber(pos->begin.lineno), true) && - setProperty(to, "line", tv) && - (tv.setNumber(pos->begin.index), true) && - setProperty(to, "column", tv) && + if (!newObject(&to)) + return false; + val.setObject(*to); + if (!setProperty(loc, "start", val)) + return false; + val.setNumber(pos->begin.lineno); + if (!setProperty(to, "line", val)) + return false; + val.setNumber(pos->begin.index); + if (!setProperty(to, "column", val)) + return false; - newObject(&to) && - setProperty(loc, "end", ObjectValue(*to)) && - (tv.setNumber(pos->end.lineno), true) && - setProperty(to, "line", tv) && - (tv.setNumber(pos->end.index), true) && - setProperty(to, "column", tv) && + if (!newObject(&to)) + return false; + val.setObject(*to); + if (!setProperty(loc, "end", val)) + return false; + val.setNumber(pos->end.lineno); + if (!setProperty(to, "line", val)) + return false; + val.setNumber(pos->end.index); + if (!setProperty(to, "column", val)) + return false; - setProperty(loc, "source", srcval); + if (!setProperty(loc, "source", srcval)) + return false; + + return true; } bool -NodeBuilder::setNodeLoc(JSObject *node, TokenPos *pos) +NodeBuilder::setNodeLoc(HandleObject node, TokenPos *pos) { if (!saveLoc) { - setProperty(node, "loc", NullValue()); + RootedValue nullVal(cx, NullValue()); + setProperty(node, "loc", nullVal); return true; } - Value loc; + RootedValue loc(cx); return newNodeLoc(pos, &loc) && setProperty(node, "loc", loc); } bool -NodeBuilder::program(NodeVector &elts, TokenPos *pos, Value *dst) +NodeBuilder::program(NodeVector &elts, TokenPos *pos, MutableHandleValue dst) { return listNode(AST_PROGRAM, "body", elts, pos, dst); } bool -NodeBuilder::blockStatement(NodeVector &elts, TokenPos *pos, Value *dst) +NodeBuilder::blockStatement(NodeVector &elts, TokenPos *pos, MutableHandleValue dst) { return listNode(AST_BLOCK_STMT, "body", elts, pos, dst); } bool -NodeBuilder::expressionStatement(Value expr, TokenPos *pos, Value *dst) +NodeBuilder::expressionStatement(HandleValue expr, TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_EXPR_STMT]; + RootedValue cb(cx, callbacks[AST_EXPR_STMT]); if (!cb.isNull()) return callback(cb, expr, pos, dst); @@ -736,9 +788,9 @@ NodeBuilder::expressionStatement(Value expr, TokenPos *pos, Value *dst) } bool -NodeBuilder::emptyStatement(TokenPos *pos, Value *dst) +NodeBuilder::emptyStatement(TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_EMPTY_STMT]; + RootedValue cb(cx, callbacks[AST_EMPTY_STMT]); if (!cb.isNull()) return callback(cb, pos, dst); @@ -746,9 +798,10 @@ NodeBuilder::emptyStatement(TokenPos *pos, Value *dst) } bool -NodeBuilder::ifStatement(Value test, Value cons, Value alt, TokenPos *pos, Value *dst) +NodeBuilder::ifStatement(HandleValue test, HandleValue cons, HandleValue alt, TokenPos *pos, + MutableHandleValue dst) { - Value cb = callbacks[AST_IF_STMT]; + RootedValue cb(cx, callbacks[AST_IF_STMT]); if (!cb.isNull()) return callback(cb, test, cons, opt(alt), pos, dst); @@ -760,9 +813,9 @@ NodeBuilder::ifStatement(Value test, Value cons, Value alt, TokenPos *pos, Value } bool -NodeBuilder::breakStatement(Value label, TokenPos *pos, Value *dst) +NodeBuilder::breakStatement(HandleValue label, TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_BREAK_STMT]; + RootedValue cb(cx, callbacks[AST_BREAK_STMT]); if (!cb.isNull()) return callback(cb, opt(label), pos, dst); @@ -770,9 +823,9 @@ NodeBuilder::breakStatement(Value label, TokenPos *pos, Value *dst) } bool -NodeBuilder::continueStatement(Value label, TokenPos *pos, Value *dst) +NodeBuilder::continueStatement(HandleValue label, TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_CONTINUE_STMT]; + RootedValue cb(cx, callbacks[AST_CONTINUE_STMT]); if (!cb.isNull()) return callback(cb, opt(label), pos, dst); @@ -780,9 +833,10 @@ NodeBuilder::continueStatement(Value label, TokenPos *pos, Value *dst) } bool -NodeBuilder::labeledStatement(Value label, Value stmt, TokenPos *pos, Value *dst) +NodeBuilder::labeledStatement(HandleValue label, HandleValue stmt, TokenPos *pos, + MutableHandleValue dst) { - Value cb = callbacks[AST_LAB_STMT]; + RootedValue cb(cx, callbacks[AST_LAB_STMT]); if (!cb.isNull()) return callback(cb, label, stmt, pos, dst); @@ -793,9 +847,9 @@ NodeBuilder::labeledStatement(Value label, Value stmt, TokenPos *pos, Value *dst } bool -NodeBuilder::throwStatement(Value arg, TokenPos *pos, Value *dst) +NodeBuilder::throwStatement(HandleValue arg, TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_THROW_STMT]; + RootedValue cb(cx, callbacks[AST_THROW_STMT]); if (!cb.isNull()) return callback(cb, arg, pos, dst); @@ -803,9 +857,9 @@ NodeBuilder::throwStatement(Value arg, TokenPos *pos, Value *dst) } bool -NodeBuilder::returnStatement(Value arg, TokenPos *pos, Value *dst) +NodeBuilder::returnStatement(HandleValue arg, TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_RETURN_STMT]; + RootedValue cb(cx, callbacks[AST_RETURN_STMT]); if (!cb.isNull()) return callback(cb, opt(arg), pos, dst); @@ -813,10 +867,10 @@ NodeBuilder::returnStatement(Value arg, TokenPos *pos, Value *dst) } bool -NodeBuilder::forStatement(Value init, Value test, Value update, Value stmt, - TokenPos *pos, Value *dst) +NodeBuilder::forStatement(HandleValue init, HandleValue test, HandleValue update, HandleValue stmt, + TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_FOR_STMT]; + RootedValue cb(cx, callbacks[AST_FOR_STMT]); if (!cb.isNull()) return callback(cb, opt(init), opt(test), opt(update), stmt, pos, dst); @@ -829,25 +883,28 @@ NodeBuilder::forStatement(Value init, Value test, Value update, Value stmt, } bool -NodeBuilder::forInStatement(Value var, Value expr, Value stmt, bool isForEach, - TokenPos *pos, Value *dst) +NodeBuilder::forInStatement(HandleValue var, HandleValue expr, HandleValue stmt, bool isForEach, + TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_FOR_IN_STMT]; + RootedValue isForEachVal(cx, BooleanValue(isForEach)); + + RootedValue cb(cx, callbacks[AST_FOR_IN_STMT]); if (!cb.isNull()) - return callback(cb, var, expr, stmt, BooleanValue(isForEach), pos, dst); + return callback(cb, var, expr, stmt, isForEachVal, pos, dst); return newNode(AST_FOR_IN_STMT, pos, "left", var, "right", expr, "body", stmt, - "each", BooleanValue(isForEach), + "each", isForEachVal, dst); } bool -NodeBuilder::forOfStatement(Value var, Value expr, Value stmt, TokenPos *pos, Value *dst) +NodeBuilder::forOfStatement(HandleValue var, HandleValue expr, HandleValue stmt, TokenPos *pos, + MutableHandleValue dst) { - Value cb = callbacks[AST_FOR_OF_STMT]; + RootedValue cb(cx, callbacks[AST_FOR_OF_STMT]); if (!cb.isNull()) return callback(cb, var, expr, stmt, pos, dst); @@ -859,9 +916,10 @@ NodeBuilder::forOfStatement(Value var, Value expr, Value stmt, TokenPos *pos, Va } bool -NodeBuilder::withStatement(Value expr, Value stmt, TokenPos *pos, Value *dst) +NodeBuilder::withStatement(HandleValue expr, HandleValue stmt, TokenPos *pos, + MutableHandleValue dst) { - Value cb = callbacks[AST_WITH_STMT]; + RootedValue cb(cx, callbacks[AST_WITH_STMT]); if (!cb.isNull()) return callback(cb, expr, stmt, pos, dst); @@ -872,9 +930,10 @@ NodeBuilder::withStatement(Value expr, Value stmt, TokenPos *pos, Value *dst) } bool -NodeBuilder::whileStatement(Value test, Value stmt, TokenPos *pos, Value *dst) +NodeBuilder::whileStatement(HandleValue test, HandleValue stmt, TokenPos *pos, + MutableHandleValue dst) { - Value cb = callbacks[AST_WHILE_STMT]; + RootedValue cb(cx, callbacks[AST_WHILE_STMT]); if (!cb.isNull()) return callback(cb, test, stmt, pos, dst); @@ -885,9 +944,10 @@ NodeBuilder::whileStatement(Value test, Value stmt, TokenPos *pos, Value *dst) } bool -NodeBuilder::doWhileStatement(Value stmt, Value test, TokenPos *pos, Value *dst) +NodeBuilder::doWhileStatement(HandleValue stmt, HandleValue test, TokenPos *pos, + MutableHandleValue dst) { - Value cb = callbacks[AST_DO_STMT]; + RootedValue cb(cx, callbacks[AST_DO_STMT]); if (!cb.isNull()) return callback(cb, stmt, test, pos, dst); @@ -898,32 +958,35 @@ NodeBuilder::doWhileStatement(Value stmt, Value test, TokenPos *pos, Value *dst) } bool -NodeBuilder::switchStatement(Value disc, NodeVector &elts, bool lexical, TokenPos *pos, Value *dst) +NodeBuilder::switchStatement(HandleValue disc, NodeVector &elts, bool lexical, TokenPos *pos, + MutableHandleValue dst) { - Value array; + RootedValue array(cx); if (!newArray(elts, &array)) return false; - Value cb = callbacks[AST_SWITCH_STMT]; + RootedValue lexicalVal(cx, BooleanValue(lexical)); + + RootedValue cb(cx, callbacks[AST_SWITCH_STMT]); if (!cb.isNull()) - return callback(cb, disc, array, BooleanValue(lexical), pos, dst); + return callback(cb, disc, array, lexicalVal, pos, dst); return newNode(AST_SWITCH_STMT, pos, "discriminant", disc, "cases", array, - "lexical", BooleanValue(lexical), + "lexical", lexicalVal, dst); } bool -NodeBuilder::tryStatement(Value body, NodeVector &guarded, Value unguarded, Value finally, - TokenPos *pos, Value *dst) +NodeBuilder::tryStatement(HandleValue body, NodeVector &guarded, HandleValue unguarded, + HandleValue finally, TokenPos *pos, MutableHandleValue dst) { - Value guardedHandlers; + RootedValue guardedHandlers(cx); if (!newArray(guarded, &guardedHandlers)) return false; - Value cb = callbacks[AST_TRY_STMT]; + RootedValue cb(cx, callbacks[AST_TRY_STMT]); if (!cb.isNull()) return callback(cb, body, guardedHandlers, unguarded, opt(finally), pos, dst); @@ -936,9 +999,9 @@ NodeBuilder::tryStatement(Value body, NodeVector &guarded, Value unguarded, Valu } bool -NodeBuilder::debuggerStatement(TokenPos *pos, Value *dst) +NodeBuilder::debuggerStatement(TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_DEBUGGER_STMT]; + RootedValue cb(cx, callbacks[AST_DEBUGGER_STMT]); if (!cb.isNull()) return callback(cb, pos, dst); @@ -946,15 +1009,16 @@ NodeBuilder::debuggerStatement(TokenPos *pos, Value *dst) } bool -NodeBuilder::binaryExpression(BinaryOperator op, Value left, Value right, TokenPos *pos, Value *dst) +NodeBuilder::binaryExpression(BinaryOperator op, HandleValue left, HandleValue right, TokenPos *pos, + MutableHandleValue dst) { JS_ASSERT(op > BINOP_ERR && op < BINOP_LIMIT); - Value opName; + RootedValue opName(cx); if (!atomValue(binopNames[op], &opName)) return false; - Value cb = callbacks[AST_BINARY_EXPR]; + RootedValue cb(cx, callbacks[AST_BINARY_EXPR]); if (!cb.isNull()) return callback(cb, opName, left, right, pos, dst); @@ -966,36 +1030,38 @@ NodeBuilder::binaryExpression(BinaryOperator op, Value left, Value right, TokenP } bool -NodeBuilder::unaryExpression(UnaryOperator unop, Value expr, TokenPos *pos, Value *dst) +NodeBuilder::unaryExpression(UnaryOperator unop, HandleValue expr, TokenPos *pos, + MutableHandleValue dst) { JS_ASSERT(unop > UNOP_ERR && unop < UNOP_LIMIT); - Value opName; + RootedValue opName(cx); if (!atomValue(unopNames[unop], &opName)) return false; - Value cb = callbacks[AST_UNARY_EXPR]; + RootedValue cb(cx, callbacks[AST_UNARY_EXPR]); if (!cb.isNull()) return callback(cb, opName, expr, pos, dst); + RootedValue trueVal(cx, BooleanValue(true)); return newNode(AST_UNARY_EXPR, pos, "operator", opName, "argument", expr, - "prefix", BooleanValue(true), + "prefix", trueVal, dst); } bool -NodeBuilder::assignmentExpression(AssignmentOperator aop, Value lhs, Value rhs, - TokenPos *pos, Value *dst) +NodeBuilder::assignmentExpression(AssignmentOperator aop, HandleValue lhs, HandleValue rhs, + TokenPos *pos, MutableHandleValue dst) { JS_ASSERT(aop > AOP_ERR && aop < AOP_LIMIT); - Value opName; + RootedValue opName(cx); if (!atomValue(aopNames[aop], &opName)) return false; - Value cb = callbacks[AST_ASSIGN_EXPR]; + RootedValue cb(cx, callbacks[AST_ASSIGN_EXPR]); if (!cb.isNull()) return callback(cb, opName, lhs, rhs, pos, dst); @@ -1007,31 +1073,35 @@ NodeBuilder::assignmentExpression(AssignmentOperator aop, Value lhs, Value rhs, } bool -NodeBuilder::updateExpression(Value expr, bool incr, bool prefix, TokenPos *pos, Value *dst) +NodeBuilder::updateExpression(HandleValue expr, bool incr, bool prefix, TokenPos *pos, + MutableHandleValue dst) { - Value opName; + RootedValue opName(cx); if (!atomValue(incr ? "++" : "--", &opName)) return false; - Value cb = callbacks[AST_UPDATE_EXPR]; + RootedValue prefixVal(cx, BooleanValue(prefix)); + + RootedValue cb(cx, callbacks[AST_UPDATE_EXPR]); if (!cb.isNull()) - return callback(cb, expr, opName, BooleanValue(prefix), pos, dst); + return callback(cb, expr, opName, prefixVal, pos, dst); return newNode(AST_UPDATE_EXPR, pos, "operator", opName, "argument", expr, - "prefix", BooleanValue(prefix), + "prefix", prefixVal, dst); } bool -NodeBuilder::logicalExpression(bool lor, Value left, Value right, TokenPos *pos, Value *dst) +NodeBuilder::logicalExpression(bool lor, HandleValue left, HandleValue right, TokenPos *pos, + MutableHandleValue dst) { - Value opName; + RootedValue opName(cx); if (!atomValue(lor ? "||" : "&&", &opName)) return false; - Value cb = callbacks[AST_LOGICAL_EXPR]; + RootedValue cb(cx, callbacks[AST_LOGICAL_EXPR]); if (!cb.isNull()) return callback(cb, opName, left, right, pos, dst); @@ -1043,9 +1113,10 @@ NodeBuilder::logicalExpression(bool lor, Value left, Value right, TokenPos *pos, } bool -NodeBuilder::conditionalExpression(Value test, Value cons, Value alt, TokenPos *pos, Value *dst) +NodeBuilder::conditionalExpression(HandleValue test, HandleValue cons, HandleValue alt, + TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_COND_EXPR]; + RootedValue cb(cx, callbacks[AST_COND_EXPR]); if (!cb.isNull()) return callback(cb, test, cons, alt, pos, dst); @@ -1057,19 +1128,20 @@ NodeBuilder::conditionalExpression(Value test, Value cons, Value alt, TokenPos * } bool -NodeBuilder::sequenceExpression(NodeVector &elts, TokenPos *pos, Value *dst) +NodeBuilder::sequenceExpression(NodeVector &elts, TokenPos *pos, MutableHandleValue dst) { return listNode(AST_LIST_EXPR, "expressions", elts, pos, dst); } bool -NodeBuilder::callExpression(Value callee, NodeVector &args, TokenPos *pos, Value *dst) +NodeBuilder::callExpression(HandleValue callee, NodeVector &args, TokenPos *pos, + MutableHandleValue dst) { - Value array; + RootedValue array(cx); if (!newArray(args, &array)) return false; - Value cb = callbacks[AST_CALL_EXPR]; + RootedValue cb(cx, callbacks[AST_CALL_EXPR]); if (!cb.isNull()) return callback(cb, callee, array, pos, dst); @@ -1080,13 +1152,14 @@ NodeBuilder::callExpression(Value callee, NodeVector &args, TokenPos *pos, Value } bool -NodeBuilder::newExpression(Value callee, NodeVector &args, TokenPos *pos, Value *dst) +NodeBuilder::newExpression(HandleValue callee, NodeVector &args, TokenPos *pos, + MutableHandleValue dst) { - Value array; + RootedValue array(cx); if (!newArray(args, &array)) return false; - Value cb = callbacks[AST_NEW_EXPR]; + RootedValue cb(cx, callbacks[AST_NEW_EXPR]); if (!cb.isNull()) return callback(cb, callee, array, pos, dst); @@ -1097,27 +1170,30 @@ NodeBuilder::newExpression(Value callee, NodeVector &args, TokenPos *pos, Value } bool -NodeBuilder::memberExpression(bool computed, Value expr, Value member, TokenPos *pos, Value *dst) +NodeBuilder::memberExpression(bool computed, HandleValue expr, HandleValue member, TokenPos *pos, + MutableHandleValue dst) { - Value cb = callbacks[AST_MEMBER_EXPR]; + RootedValue computedVal(cx, BooleanValue(computed)); + + RootedValue cb(cx, callbacks[AST_MEMBER_EXPR]); if (!cb.isNull()) - return callback(cb, BooleanValue(computed), expr, member, pos, dst); + return callback(cb, computedVal, expr, member, pos, dst); return newNode(AST_MEMBER_EXPR, pos, "object", expr, "property", member, - "computed", BooleanValue(computed), + "computed", computedVal, dst); } bool -NodeBuilder::arrayExpression(NodeVector &elts, TokenPos *pos, Value *dst) +NodeBuilder::arrayExpression(NodeVector &elts, TokenPos *pos, MutableHandleValue dst) { return listNode(AST_ARRAY_EXPR, "elements", elts, pos, dst); } bool -NodeBuilder::spreadExpression(Value expr, TokenPos *pos, Value *dst) +NodeBuilder::spreadExpression(HandleValue expr, TokenPos *pos, MutableHandleValue dst) { return newNode(AST_SPREAD_EXPR, pos, "expression", expr, @@ -1125,13 +1201,14 @@ NodeBuilder::spreadExpression(Value expr, TokenPos *pos, Value *dst) } bool -NodeBuilder::propertyPattern(Value key, Value patt, TokenPos *pos, Value *dst) +NodeBuilder::propertyPattern(HandleValue key, HandleValue patt, TokenPos *pos, + MutableHandleValue dst) { - Value kindName; + RootedValue kindName(cx); if (!atomValue("init", &kindName)) return false; - Value cb = callbacks[AST_PROP_PATT]; + RootedValue cb(cx, callbacks[AST_PROP_PATT]); if (!cb.isNull()) return callback(cb, key, patt, pos, dst); @@ -1143,9 +1220,10 @@ NodeBuilder::propertyPattern(Value key, Value patt, TokenPos *pos, Value *dst) } bool -NodeBuilder::propertyInitializer(Value key, Value val, PropKind kind, TokenPos *pos, Value *dst) +NodeBuilder::propertyInitializer(HandleValue key, HandleValue val, PropKind kind, TokenPos *pos, + MutableHandleValue dst) { - Value kindName; + RootedValue kindName(cx); if (!atomValue(kind == PROP_INIT ? "init" : kind == PROP_GETTER @@ -1154,7 +1232,7 @@ NodeBuilder::propertyInitializer(Value key, Value val, PropKind kind, TokenPos * return false; } - Value cb = callbacks[AST_PROPERTY]; + RootedValue cb(cx, callbacks[AST_PROPERTY]); if (!cb.isNull()) return callback(cb, kindName, key, val, pos, dst); @@ -1166,15 +1244,15 @@ NodeBuilder::propertyInitializer(Value key, Value val, PropKind kind, TokenPos * } bool -NodeBuilder::objectExpression(NodeVector &elts, TokenPos *pos, Value *dst) +NodeBuilder::objectExpression(NodeVector &elts, TokenPos *pos, MutableHandleValue dst) { return listNode(AST_OBJECT_EXPR, "properties", elts, pos, dst); } bool -NodeBuilder::thisExpression(TokenPos *pos, Value *dst) +NodeBuilder::thisExpression(TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_THIS_EXPR]; + RootedValue cb(cx, callbacks[AST_THIS_EXPR]); if (!cb.isNull()) return callback(cb, pos, dst); @@ -1182,9 +1260,9 @@ NodeBuilder::thisExpression(TokenPos *pos, Value *dst) } bool -NodeBuilder::yieldExpression(Value arg, TokenPos *pos, Value *dst) +NodeBuilder::yieldExpression(HandleValue arg, TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_YIELD_EXPR]; + RootedValue cb(cx, callbacks[AST_YIELD_EXPR]); if (!cb.isNull()) return callback(cb, opt(arg), pos, dst); @@ -1192,28 +1270,31 @@ NodeBuilder::yieldExpression(Value arg, TokenPos *pos, Value *dst) } bool -NodeBuilder::comprehensionBlock(Value patt, Value src, bool isForEach, TokenPos *pos, Value *dst) +NodeBuilder::comprehensionBlock(HandleValue patt, HandleValue src, bool isForEach, TokenPos *pos, + MutableHandleValue dst) { - Value cb = callbacks[AST_COMP_BLOCK]; + RootedValue isForEachVal(cx, BooleanValue(isForEach)); + + RootedValue cb(cx, callbacks[AST_COMP_BLOCK]); if (!cb.isNull()) - return callback(cb, patt, src, BooleanValue(isForEach), pos, dst); + return callback(cb, patt, src, isForEachVal, pos, dst); return newNode(AST_COMP_BLOCK, pos, "left", patt, "right", src, - "each", BooleanValue(isForEach), + "each", isForEachVal, dst); } bool -NodeBuilder::comprehensionExpression(Value body, NodeVector &blocks, Value filter, - TokenPos *pos, Value *dst) +NodeBuilder::comprehensionExpression(HandleValue body, NodeVector &blocks, HandleValue filter, + TokenPos *pos, MutableHandleValue dst) { - Value array; + RootedValue array(cx); if (!newArray(blocks, &array)) return false; - Value cb = callbacks[AST_COMP_EXPR]; + RootedValue cb(cx, callbacks[AST_COMP_EXPR]); if (!cb.isNull()) return callback(cb, body, array, opt(filter), pos, dst); @@ -1225,13 +1306,14 @@ NodeBuilder::comprehensionExpression(Value body, NodeVector &blocks, Value filte } bool -NodeBuilder::generatorExpression(Value body, NodeVector &blocks, Value filter, TokenPos *pos, Value *dst) +NodeBuilder::generatorExpression(HandleValue body, NodeVector &blocks, HandleValue filter, + TokenPos *pos, MutableHandleValue dst) { - Value array; + RootedValue array(cx); if (!newArray(blocks, &array)) return false; - Value cb = callbacks[AST_GENERATOR_EXPR]; + RootedValue cb(cx, callbacks[AST_GENERATOR_EXPR]); if (!cb.isNull()) return callback(cb, body, array, opt(filter), pos, dst); @@ -1243,13 +1325,14 @@ NodeBuilder::generatorExpression(Value body, NodeVector &blocks, Value filter, T } bool -NodeBuilder::letExpression(NodeVector &head, Value expr, TokenPos *pos, Value *dst) +NodeBuilder::letExpression(NodeVector &head, HandleValue expr, TokenPos *pos, + MutableHandleValue dst) { - Value array; + RootedValue array(cx); if (!newArray(head, &array)) return false; - Value cb = callbacks[AST_LET_EXPR]; + RootedValue cb(cx, callbacks[AST_LET_EXPR]); if (!cb.isNull()) return callback(cb, array, expr, pos, dst); @@ -1260,13 +1343,13 @@ NodeBuilder::letExpression(NodeVector &head, Value expr, TokenPos *pos, Value *d } bool -NodeBuilder::letStatement(NodeVector &head, Value stmt, TokenPos *pos, Value *dst) +NodeBuilder::letStatement(NodeVector &head, HandleValue stmt, TokenPos *pos, MutableHandleValue dst) { - Value array; + RootedValue array(cx); if (!newArray(head, &array)) return false; - Value cb = callbacks[AST_LET_STMT]; + RootedValue cb(cx, callbacks[AST_LET_STMT]); if (!cb.isNull()) return callback(cb, array, stmt, pos, dst); @@ -1277,11 +1360,12 @@ NodeBuilder::letStatement(NodeVector &head, Value stmt, TokenPos *pos, Value *ds } bool -NodeBuilder::variableDeclaration(NodeVector &elts, VarDeclKind kind, TokenPos *pos, Value *dst) +NodeBuilder::variableDeclaration(NodeVector &elts, VarDeclKind kind, TokenPos *pos, + MutableHandleValue dst) { JS_ASSERT(kind > VARDECL_ERR && kind < VARDECL_LIMIT); - Value array, kindName; + RootedValue array(cx), kindName(cx); if (!newArray(elts, &array) || !atomValue(kind == VARDECL_CONST ? "const" @@ -1291,7 +1375,7 @@ NodeBuilder::variableDeclaration(NodeVector &elts, VarDeclKind kind, TokenPos *p return false; } - Value cb = callbacks[AST_VAR_DECL]; + RootedValue cb(cx, callbacks[AST_VAR_DECL]); if (!cb.isNull()) return callback(cb, kindName, array, pos, dst); @@ -1302,9 +1386,10 @@ NodeBuilder::variableDeclaration(NodeVector &elts, VarDeclKind kind, TokenPos *p } bool -NodeBuilder::variableDeclarator(Value id, Value init, TokenPos *pos, Value *dst) +NodeBuilder::variableDeclarator(HandleValue id, HandleValue init, TokenPos *pos, + MutableHandleValue dst) { - Value cb = callbacks[AST_VAR_DTOR]; + RootedValue cb(cx, callbacks[AST_VAR_DTOR]); if (!cb.isNull()) return callback(cb, id, opt(init), pos, dst); @@ -1312,13 +1397,13 @@ NodeBuilder::variableDeclarator(Value id, Value init, TokenPos *pos, Value *dst) } bool -NodeBuilder::switchCase(Value expr, NodeVector &elts, TokenPos *pos, Value *dst) +NodeBuilder::switchCase(HandleValue expr, NodeVector &elts, TokenPos *pos, MutableHandleValue dst) { - Value array; + RootedValue array(cx); if (!newArray(elts, &array)) return false; - Value cb = callbacks[AST_CASE]; + RootedValue cb(cx, callbacks[AST_CASE]); if (!cb.isNull()) return callback(cb, opt(expr), array, pos, dst); @@ -1329,9 +1414,10 @@ NodeBuilder::switchCase(Value expr, NodeVector &elts, TokenPos *pos, Value *dst) } bool -NodeBuilder::catchClause(Value var, Value guard, Value body, TokenPos *pos, Value *dst) +NodeBuilder::catchClause(HandleValue var, HandleValue guard, HandleValue body, TokenPos *pos, + MutableHandleValue dst) { - Value cb = callbacks[AST_CATCH]; + RootedValue cb(cx, callbacks[AST_CATCH]); if (!cb.isNull()) return callback(cb, var, opt(guard), body, pos, dst); @@ -1343,9 +1429,9 @@ NodeBuilder::catchClause(Value var, Value guard, Value body, TokenPos *pos, Valu } bool -NodeBuilder::literal(Value val, TokenPos *pos, Value *dst) +NodeBuilder::literal(HandleValue val, TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_LITERAL]; + RootedValue cb(cx, callbacks[AST_LITERAL]); if (!cb.isNull()) return callback(cb, val, pos, dst); @@ -1353,9 +1439,9 @@ NodeBuilder::literal(Value val, TokenPos *pos, Value *dst) } bool -NodeBuilder::identifier(Value name, TokenPos *pos, Value *dst) +NodeBuilder::identifier(HandleValue name, TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_IDENTIFIER]; + RootedValue cb(cx, callbacks[AST_IDENTIFIER]); if (!cb.isNull()) return callback(cb, name, pos, dst); @@ -1363,34 +1449,36 @@ NodeBuilder::identifier(Value name, TokenPos *pos, Value *dst) } bool -NodeBuilder::objectPattern(NodeVector &elts, TokenPos *pos, Value *dst) +NodeBuilder::objectPattern(NodeVector &elts, TokenPos *pos, MutableHandleValue dst) { return listNode(AST_OBJECT_PATT, "properties", elts, pos, dst); } bool -NodeBuilder::arrayPattern(NodeVector &elts, TokenPos *pos, Value *dst) +NodeBuilder::arrayPattern(NodeVector &elts, TokenPos *pos, MutableHandleValue dst) { return listNode(AST_ARRAY_PATT, "elements", elts, pos, dst); } bool NodeBuilder::function(ASTType type, TokenPos *pos, - Value id, NodeVector &args, NodeVector &defaults, - Value body, Value rest, + HandleValue id, NodeVector &args, NodeVector &defaults, + HandleValue body, HandleValue rest, bool isGenerator, bool isExpression, - Value *dst) + MutableHandleValue dst) { - Value array, defarray; + RootedValue array(cx), defarray(cx); if (!newArray(args, &array)) return false; if (!newArray(defaults, &defarray)) return false; - Value cb = callbacks[type]; + RootedValue isGeneratorVal(cx, BooleanValue(isGenerator)); + RootedValue isExpressionVal(cx, BooleanValue(isExpression)); + + RootedValue cb(cx, callbacks[type]); if (!cb.isNull()) { - return callback(cb, opt(id), array, body, BooleanValue(isGenerator), - BooleanValue(isExpression), pos, dst); + return callback(cb, opt(id), array, body, isGeneratorVal, isExpressionVal, pos, dst); } return newNode(type, pos, @@ -1399,15 +1487,15 @@ NodeBuilder::function(ASTType type, TokenPos *pos, "defaults", defarray, "body", body, "rest", rest, - "generator", BooleanValue(isGenerator), - "expression", BooleanValue(isExpression), + "generator", isGeneratorVal, + "expression", isExpressionVal, dst); } bool -NodeBuilder::xmlAnyName(TokenPos *pos, Value *dst) +NodeBuilder::xmlAnyName(TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_XMLANYNAME]; + RootedValue cb(cx, callbacks[AST_XMLANYNAME]); if (!cb.isNull()) return callback(cb, pos, dst); @@ -1415,9 +1503,9 @@ NodeBuilder::xmlAnyName(TokenPos *pos, Value *dst) } bool -NodeBuilder::xmlEscapeExpression(Value expr, TokenPos *pos, Value *dst) +NodeBuilder::xmlEscapeExpression(HandleValue expr, TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_XMLESCAPE]; + RootedValue cb(cx, callbacks[AST_XMLESCAPE]); if (!cb.isNull()) return callback(cb, expr, pos, dst); @@ -1425,9 +1513,10 @@ NodeBuilder::xmlEscapeExpression(Value expr, TokenPos *pos, Value *dst) } bool -NodeBuilder::xmlFilterExpression(Value left, Value right, TokenPos *pos, Value *dst) +NodeBuilder::xmlFilterExpression(HandleValue left, HandleValue right, TokenPos *pos, + MutableHandleValue dst) { - Value cb = callbacks[AST_XMLFILTER]; + RootedValue cb(cx, callbacks[AST_XMLFILTER]); if (!cb.isNull()) return callback(cb, left, right, pos, dst); @@ -1435,9 +1524,9 @@ NodeBuilder::xmlFilterExpression(Value left, Value right, TokenPos *pos, Value * } bool -NodeBuilder::xmlDefaultNamespace(Value ns, TokenPos *pos, Value *dst) +NodeBuilder::xmlDefaultNamespace(HandleValue ns, TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_XMLDEFAULT]; + RootedValue cb(cx, callbacks[AST_XMLDEFAULT]); if (!cb.isNull()) return callback(cb, ns, pos, dst); @@ -1445,56 +1534,64 @@ NodeBuilder::xmlDefaultNamespace(Value ns, TokenPos *pos, Value *dst) } bool -NodeBuilder::xmlAttributeSelector(Value expr, bool computed, TokenPos *pos, Value *dst) +NodeBuilder::xmlAttributeSelector(HandleValue expr, bool computed, TokenPos *pos, + MutableHandleValue dst) { - Value cb = callbacks[AST_XMLATTR_SEL]; + RootedValue computedVal(cx, BooleanValue(computed)); + + RootedValue cb(cx, callbacks[AST_XMLATTR_SEL]); if (!cb.isNull()) - return callback(cb, expr, BooleanValue(computed), pos, dst); + return callback(cb, expr, computedVal, pos, dst); return newNode(AST_XMLATTR_SEL, pos, "attribute", expr, - "computed", BooleanValue(computed), + "computed", computedVal, dst); } bool -NodeBuilder::xmlFunctionQualifiedIdentifier(Value right, bool computed, TokenPos *pos, Value *dst) +NodeBuilder::xmlFunctionQualifiedIdentifier(HandleValue right, bool computed, TokenPos *pos, + MutableHandleValue dst) { - Value cb = callbacks[AST_XMLFUNCQUAL]; + RootedValue computedVal(cx, BooleanValue(computed)); + + RootedValue cb(cx, callbacks[AST_XMLFUNCQUAL]); if (!cb.isNull()) - return callback(cb, right, BooleanValue(computed), pos, dst); + return callback(cb, right, computedVal, pos, dst); return newNode(AST_XMLFUNCQUAL, pos, "right", right, - "computed", BooleanValue(computed), + "computed", computedVal, dst); } bool -NodeBuilder::xmlQualifiedIdentifier(Value left, Value right, bool computed, - TokenPos *pos, Value *dst) +NodeBuilder::xmlQualifiedIdentifier(HandleValue left, HandleValue right, bool computed, + TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_XMLQUAL]; + RootedValue computedVal(cx, BooleanValue(computed)); + + RootedValue cb(cx, callbacks[AST_XMLQUAL]); if (!cb.isNull()) - return callback(cb, left, right, BooleanValue(computed), pos, dst); + return callback(cb, left, right, computedVal, pos, dst); return newNode(AST_XMLQUAL, pos, "left", left, "right", right, - "computed", BooleanValue(computed), + "computed", computedVal, dst); } bool -NodeBuilder::xmlElement(NodeVector &elts, TokenPos *pos, Value *dst) +NodeBuilder::xmlElement(NodeVector &elts, TokenPos *pos, MutableHandleValue dst) { return listNode(AST_XMLELEM, "contents", elts, pos, dst); } bool -NodeBuilder::xmlText(Value text, TokenPos *pos, Value *dst) +NodeBuilder::xmlText(HandleValue text, TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_XMLTEXT]; + RootedValue cb(cx, callbacks[AST_XMLTEXT]); if (!cb.isNull()) return callback(cb, text, pos, dst); @@ -1502,33 +1599,33 @@ NodeBuilder::xmlText(Value text, TokenPos *pos, Value *dst) } bool -NodeBuilder::xmlList(NodeVector &elts, TokenPos *pos, Value *dst) +NodeBuilder::xmlList(NodeVector &elts, TokenPos *pos, MutableHandleValue dst) { return listNode(AST_XMLLIST, "contents", elts, pos, dst); } bool -NodeBuilder::xmlStartTag(NodeVector &elts, TokenPos *pos, Value *dst) +NodeBuilder::xmlStartTag(NodeVector &elts, TokenPos *pos, MutableHandleValue dst) { return listNode(AST_XMLSTART, "contents", elts, pos, dst); } bool -NodeBuilder::xmlEndTag(NodeVector &elts, TokenPos *pos, Value *dst) +NodeBuilder::xmlEndTag(NodeVector &elts, TokenPos *pos, MutableHandleValue dst) { return listNode(AST_XMLEND, "contents", elts, pos, dst); } bool -NodeBuilder::xmlPointTag(NodeVector &elts, TokenPos *pos, Value *dst) +NodeBuilder::xmlPointTag(NodeVector &elts, TokenPos *pos, MutableHandleValue dst) { return listNode(AST_XMLPOINT, "contents", elts, pos, dst); } bool -NodeBuilder::xmlName(Value text, TokenPos *pos, Value *dst) +NodeBuilder::xmlName(HandleValue text, TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_XMLNAME]; + RootedValue cb(cx, callbacks[AST_XMLNAME]); if (!cb.isNull()) return callback(cb, text, pos, dst); @@ -1536,15 +1633,15 @@ NodeBuilder::xmlName(Value text, TokenPos *pos, Value *dst) } bool -NodeBuilder::xmlName(NodeVector &elts, TokenPos *pos, Value *dst) +NodeBuilder::xmlName(NodeVector &elts, TokenPos *pos, MutableHandleValue dst) { - return listNode(AST_XMLNAME, "contents", elts, pos ,dst); + return listNode(AST_XMLNAME, "contents", elts, pos, dst); } bool -NodeBuilder::xmlAttribute(Value text, TokenPos *pos, Value *dst) +NodeBuilder::xmlAttribute(HandleValue text, TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_XMLATTR]; + RootedValue cb(cx, callbacks[AST_XMLATTR]); if (!cb.isNull()) return callback(cb, text, pos, dst); @@ -1552,9 +1649,9 @@ NodeBuilder::xmlAttribute(Value text, TokenPos *pos, Value *dst) } bool -NodeBuilder::xmlCdata(Value text, TokenPos *pos, Value *dst) +NodeBuilder::xmlCdata(HandleValue text, TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_XMLCDATA]; + RootedValue cb(cx, callbacks[AST_XMLCDATA]); if (!cb.isNull()) return callback(cb, text, pos, dst); @@ -1562,9 +1659,9 @@ NodeBuilder::xmlCdata(Value text, TokenPos *pos, Value *dst) } bool -NodeBuilder::xmlComment(Value text, TokenPos *pos, Value *dst) +NodeBuilder::xmlComment(HandleValue text, TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_XMLCOMMENT]; + RootedValue cb(cx, callbacks[AST_XMLCOMMENT]); if (!cb.isNull()) return callback(cb, text, pos, dst); @@ -1572,9 +1669,9 @@ NodeBuilder::xmlComment(Value text, TokenPos *pos, Value *dst) } bool -NodeBuilder::xmlPI(Value target, Value contents, TokenPos *pos, Value *dst) +NodeBuilder::xmlPI(HandleValue target, HandleValue contents, TokenPos *pos, MutableHandleValue dst) { - Value cb = callbacks[AST_XMLPI]; + RootedValue cb(cx, callbacks[AST_XMLPI]); if (!cb.isNull()) return callback(cb, target, contents, pos, dst); @@ -1598,7 +1695,7 @@ class ASTSerializer NodeBuilder builder; DebugOnly lineno; - Value atomContents(JSAtom *atom) { + RawValue unrootedAtomContents(RawAtom atom) { return StringValue(atom ? atom : cx->runtime->atomState.emptyAtom); } @@ -1609,73 +1706,74 @@ class ASTSerializer bool statements(ParseNode *pn, NodeVector &elts); bool expressions(ParseNode *pn, NodeVector &elts); bool xmls(ParseNode *pn, NodeVector &elts); - bool leftAssociate(ParseNode *pn, Value *dst); + bool leftAssociate(ParseNode *pn, MutableHandleValue dst); bool functionArgs(ParseNode *pn, ParseNode *pnargs, ParseNode *pndestruct, ParseNode *pnbody, - NodeVector &args, NodeVector &defaults, Value *rest); + NodeVector &args, NodeVector &defaults, MutableHandleValue rest); - bool sourceElement(ParseNode *pn, Value *dst); + bool sourceElement(ParseNode *pn, MutableHandleValue dst); - bool declaration(ParseNode *pn, Value *dst); - bool variableDeclaration(ParseNode *pn, bool let, Value *dst); - bool variableDeclarator(ParseNode *pn, VarDeclKind *pkind, Value *dst); - bool let(ParseNode *pn, bool expr, Value *dst); + bool declaration(ParseNode *pn, MutableHandleValue dst); + bool variableDeclaration(ParseNode *pn, bool let, MutableHandleValue dst); + bool variableDeclarator(ParseNode *pn, VarDeclKind *pkind, MutableHandleValue dst); + bool let(ParseNode *pn, bool expr, MutableHandleValue dst); - bool optStatement(ParseNode *pn, Value *dst) { + bool optStatement(ParseNode *pn, MutableHandleValue dst) { if (!pn) { - dst->setMagic(JS_SERIALIZE_NO_NODE); + dst.setMagic(JS_SERIALIZE_NO_NODE); return true; } return statement(pn, dst); } - bool forInit(ParseNode *pn, Value *dst); - bool forOfOrIn(ParseNode *loop, ParseNode *head, Value var, Value stmt, Value *dst); - bool statement(ParseNode *pn, Value *dst); - bool blockStatement(ParseNode *pn, Value *dst); - bool switchStatement(ParseNode *pn, Value *dst); - bool switchCase(ParseNode *pn, Value *dst); - bool tryStatement(ParseNode *pn, Value *dst); - bool catchClause(ParseNode *pn, bool *isGuarded, Value *dst); + bool forInit(ParseNode *pn, MutableHandleValue dst); + bool forOfOrIn(ParseNode *loop, ParseNode *head, HandleValue var, HandleValue stmt, + MutableHandleValue dst); + bool statement(ParseNode *pn, MutableHandleValue dst); + bool blockStatement(ParseNode *pn, MutableHandleValue dst); + bool switchStatement(ParseNode *pn, MutableHandleValue dst); + bool switchCase(ParseNode *pn, MutableHandleValue dst); + bool tryStatement(ParseNode *pn, MutableHandleValue dst); + bool catchClause(ParseNode *pn, bool *isGuarded, MutableHandleValue dst); - bool optExpression(ParseNode *pn, Value *dst) { + bool optExpression(ParseNode *pn, MutableHandleValue dst) { if (!pn) { - dst->setMagic(JS_SERIALIZE_NO_NODE); + dst.setMagic(JS_SERIALIZE_NO_NODE); return true; } return expression(pn, dst); } - bool expression(ParseNode *pn, Value *dst); + bool expression(ParseNode *pn, MutableHandleValue dst); - bool propertyName(ParseNode *pn, Value *dst); - bool property(ParseNode *pn, Value *dst); + bool propertyName(ParseNode *pn, MutableHandleValue dst); + bool property(ParseNode *pn, MutableHandleValue dst); - bool optIdentifier(JSAtom *atom, TokenPos *pos, Value *dst) { + bool optIdentifier(HandleAtom atom, TokenPos *pos, MutableHandleValue dst) { if (!atom) { - dst->setMagic(JS_SERIALIZE_NO_NODE); + dst.setMagic(JS_SERIALIZE_NO_NODE); return true; } return identifier(atom, pos, dst); } - bool identifier(JSAtom *atom, TokenPos *pos, Value *dst); - bool identifier(ParseNode *pn, Value *dst); - bool literal(ParseNode *pn, Value *dst); + bool identifier(HandleAtom atom, TokenPos *pos, MutableHandleValue dst); + bool identifier(ParseNode *pn, MutableHandleValue dst); + bool literal(ParseNode *pn, MutableHandleValue dst); - bool pattern(ParseNode *pn, VarDeclKind *pkind, Value *dst); - bool arrayPattern(ParseNode *pn, VarDeclKind *pkind, Value *dst); - bool objectPattern(ParseNode *pn, VarDeclKind *pkind, Value *dst); + bool pattern(ParseNode *pn, VarDeclKind *pkind, MutableHandleValue dst); + bool arrayPattern(ParseNode *pn, VarDeclKind *pkind, MutableHandleValue dst); + bool objectPattern(ParseNode *pn, VarDeclKind *pkind, MutableHandleValue dst); - bool function(ParseNode *pn, ASTType type, Value *dst); + bool function(ParseNode *pn, ASTType type, MutableHandleValue dst); bool functionArgsAndBody(ParseNode *pn, NodeVector &args, NodeVector &defaults, - Value *body, Value *rest); - bool functionBody(ParseNode *pn, TokenPos *pos, Value *dst); + MutableHandleValue body, MutableHandleValue rest); + bool functionBody(ParseNode *pn, TokenPos *pos, MutableHandleValue dst); - bool comprehensionBlock(ParseNode *pn, Value *dst); - bool comprehension(ParseNode *pn, Value *dst); - bool generatorExpression(ParseNode *pn, Value *dst); + bool comprehensionBlock(ParseNode *pn, MutableHandleValue dst); + bool comprehension(ParseNode *pn, MutableHandleValue dst); + bool generatorExpression(ParseNode *pn, MutableHandleValue dst); - bool xml(ParseNode *pn, Value *dst); + bool xml(ParseNode *pn, MutableHandleValue dst); public: ASTSerializer(JSContext *c, bool l, char const *src, uint32_t ln) @@ -1686,7 +1784,7 @@ class ASTSerializer #endif {} - bool init(JSObject *userobj) { + bool init(HandleObject userobj) { return builder.init(userobj); } @@ -1694,7 +1792,7 @@ class ASTSerializer parser = p; } - bool program(ParseNode *pn, Value *dst); + bool program(ParseNode *pn, MutableHandleValue dst); }; AssignmentOperator @@ -1820,7 +1918,7 @@ ASTSerializer::statements(ParseNode *pn, NodeVector &elts) for (ParseNode *next = pn->pn_head; next; next = next->pn_next) { JS_ASSERT(pn->pn_pos.encloses(next->pn_pos)); - Value elt; + RootedValue elt(cx); if (!sourceElement(next, &elt)) return false; elts.infallibleAppend(elt); @@ -1838,7 +1936,7 @@ ASTSerializer::expressions(ParseNode *pn, NodeVector &elts) for (ParseNode *next = pn->pn_head; next; next = next->pn_next) { JS_ASSERT(pn->pn_pos.encloses(next->pn_pos)); - Value elt; + RootedValue elt(cx); if (!expression(next, &elt)) return false; elts.infallibleAppend(elt); @@ -1856,7 +1954,7 @@ ASTSerializer::xmls(ParseNode *pn, NodeVector &elts) for (ParseNode *next = pn->pn_head; next; next = next->pn_next) { JS_ASSERT(pn->pn_pos.encloses(next->pn_pos)); - Value elt; + RootedValue elt(cx); if (!xml(next, &elt)) return false; elts.infallibleAppend(elt); @@ -1866,7 +1964,7 @@ ASTSerializer::xmls(ParseNode *pn, NodeVector &elts) } bool -ASTSerializer::blockStatement(ParseNode *pn, Value *dst) +ASTSerializer::blockStatement(ParseNode *pn, MutableHandleValue dst) { JS_ASSERT(pn->isKind(PNK_STATEMENTLIST)); @@ -1876,7 +1974,7 @@ ASTSerializer::blockStatement(ParseNode *pn, Value *dst) } bool -ASTSerializer::program(ParseNode *pn, Value *dst) +ASTSerializer::program(ParseNode *pn, MutableHandleValue dst) { JS_ASSERT(pn->pn_pos.begin.lineno == lineno); @@ -1886,14 +1984,14 @@ ASTSerializer::program(ParseNode *pn, Value *dst) } bool -ASTSerializer::sourceElement(ParseNode *pn, Value *dst) +ASTSerializer::sourceElement(ParseNode *pn, MutableHandleValue dst) { /* SpiderMonkey allows declarations even in pure statement contexts. */ return statement(pn, dst); } bool -ASTSerializer::declaration(ParseNode *pn, Value *dst) +ASTSerializer::declaration(ParseNode *pn, MutableHandleValue dst) { JS_ASSERT(pn->isKind(PNK_FUNCTION) || pn->isKind(PNK_VAR) || @@ -1915,7 +2013,7 @@ ASTSerializer::declaration(ParseNode *pn, Value *dst) } bool -ASTSerializer::variableDeclaration(ParseNode *pn, bool let, Value *dst) +ASTSerializer::variableDeclaration(ParseNode *pn, bool let, MutableHandleValue dst) { JS_ASSERT(let ? pn->isKind(PNK_LET) : (pn->isKind(PNK_VAR) || pn->isKind(PNK_CONST))); @@ -1926,9 +2024,10 @@ ASTSerializer::variableDeclaration(ParseNode *pn, bool let, Value *dst) /* In a for-in context, variable declarations contain just a single pattern. */ if (pn->pn_xflags & PNX_FORINVAR) { - Value patt, child; + RootedValue patt(cx), child(cx); + RootedValue nullVal(cx, NullValue()); return pattern(pn->pn_head, &kind, &patt) && - builder.variableDeclarator(patt, NullValue(), &pn->pn_head->pn_pos, &child) && + builder.variableDeclarator(patt, nullVal, &pn->pn_head->pn_pos, &child) && dtors.append(child) && builder.variableDeclaration(dtors, kind, &pn->pn_pos, dst); } @@ -1936,7 +2035,7 @@ ASTSerializer::variableDeclaration(ParseNode *pn, bool let, Value *dst) if (!dtors.reserve(pn->pn_count)) return false; for (ParseNode *next = pn->pn_head; next; next = next->pn_next) { - Value child; + RootedValue child(cx); if (!variableDeclarator(next, &kind, &child)) return false; dtors.infallibleAppend(child); @@ -1946,7 +2045,7 @@ ASTSerializer::variableDeclaration(ParseNode *pn, bool let, Value *dst) } bool -ASTSerializer::variableDeclarator(ParseNode *pn, VarDeclKind *pkind, Value *dst) +ASTSerializer::variableDeclarator(ParseNode *pn, VarDeclKind *pkind, MutableHandleValue dst) { /* A destructuring declarator is always a PNK_ASSIGN. */ JS_ASSERT(pn->isKind(PNK_NAME) || pn->isKind(PNK_ASSIGN)); @@ -1966,14 +2065,14 @@ ASTSerializer::variableDeclarator(ParseNode *pn, VarDeclKind *pkind, Value *dst) JS_ASSERT(pn->pn_pos.encloses(pnright->pn_pos)); } - Value left, right; + RootedValue left(cx), right(cx); return pattern(pnleft, pkind, &left) && optExpression(pnright, &right) && builder.variableDeclarator(left, right, &pn->pn_pos, dst); } bool -ASTSerializer::let(ParseNode *pn, bool expr, Value *dst) +ASTSerializer::let(ParseNode *pn, bool expr, MutableHandleValue dst) { JS_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos)); JS_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos)); @@ -1991,7 +2090,7 @@ ASTSerializer::let(ParseNode *pn, bool expr, Value *dst) VarDeclKind kind = VARDECL_LET_HEAD; for (ParseNode *next = letHead->pn_head; next; next = next->pn_next) { - Value child; + RootedValue child(cx); /* * Unlike in |variableDeclaration|, this does not update |kind|; since let-heads do * not contain const declarations, declarators should never have PND_CONST set. @@ -2001,7 +2100,7 @@ ASTSerializer::let(ParseNode *pn, bool expr, Value *dst) dtors.infallibleAppend(child); } - Value v; + RootedValue v(cx); return expr ? expression(letBody->pn_expr, &v) && builder.letExpression(dtors, v, &pn->pn_pos, dst) @@ -2010,14 +2109,14 @@ ASTSerializer::let(ParseNode *pn, bool expr, Value *dst) } bool -ASTSerializer::switchCase(ParseNode *pn, Value *dst) +ASTSerializer::switchCase(ParseNode *pn, MutableHandleValue dst) { JS_ASSERT_IF(pn->pn_left, pn->pn_pos.encloses(pn->pn_left->pn_pos)); JS_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos)); NodeVector stmts(cx); - Value expr; + RootedValue expr(cx); return optExpression(pn->pn_left, &expr) && statements(pn->pn_right, stmts) && @@ -2025,12 +2124,12 @@ ASTSerializer::switchCase(ParseNode *pn, Value *dst) } bool -ASTSerializer::switchStatement(ParseNode *pn, Value *dst) +ASTSerializer::switchStatement(ParseNode *pn, MutableHandleValue dst) { JS_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos)); JS_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos)); - Value disc; + RootedValue disc(cx); if (!expression(pn->pn_left, &disc)) return false; @@ -2051,10 +2150,7 @@ ASTSerializer::switchStatement(ParseNode *pn, Value *dst) return false; for (ParseNode *next = listNode->pn_head; next; next = next->pn_next) { - Value child; -#ifdef __GNUC__ /* quell GCC overwarning */ - child = UndefinedValue(); -#endif + RootedValue child(cx); if (!switchCase(next, &child)) return false; cases.infallibleAppend(child); @@ -2064,13 +2160,13 @@ ASTSerializer::switchStatement(ParseNode *pn, Value *dst) } bool -ASTSerializer::catchClause(ParseNode *pn, bool *isGuarded, Value *dst) +ASTSerializer::catchClause(ParseNode *pn, bool *isGuarded, MutableHandleValue dst) { JS_ASSERT(pn->pn_pos.encloses(pn->pn_kid1->pn_pos)); JS_ASSERT_IF(pn->pn_kid2, pn->pn_pos.encloses(pn->pn_kid2->pn_pos)); JS_ASSERT(pn->pn_pos.encloses(pn->pn_kid3->pn_pos)); - Value var, guard, body; + RootedValue var(cx), guard(cx), body(cx); if (!pattern(pn->pn_kid1, NULL, &var) || !optExpression(pn->pn_kid2, &guard)) { @@ -2084,25 +2180,25 @@ ASTSerializer::catchClause(ParseNode *pn, bool *isGuarded, Value *dst) } bool -ASTSerializer::tryStatement(ParseNode *pn, Value *dst) +ASTSerializer::tryStatement(ParseNode *pn, MutableHandleValue dst) { JS_ASSERT(pn->pn_pos.encloses(pn->pn_kid1->pn_pos)); JS_ASSERT_IF(pn->pn_kid2, pn->pn_pos.encloses(pn->pn_kid2->pn_pos)); JS_ASSERT_IF(pn->pn_kid3, pn->pn_pos.encloses(pn->pn_kid3->pn_pos)); - Value body; + RootedValue body(cx); if (!statement(pn->pn_kid1, &body)) return false; NodeVector guarded(cx); - Value unguarded = NullValue(); + RootedValue unguarded(cx, NullValue()); if (pn->pn_kid2) { if (!guarded.reserve(pn->pn_kid2->pn_count)) return false; for (ParseNode *next = pn->pn_kid2->pn_head; next; next = next->pn_next) { - Value clause; + RootedValue clause(cx); bool isGuarded; if (!catchClause(next->pn_expr, &isGuarded, &clause)) return false; @@ -2113,16 +2209,16 @@ ASTSerializer::tryStatement(ParseNode *pn, Value *dst) } } - Value finally; + RootedValue finally(cx); return optStatement(pn->pn_kid3, &finally) && builder.tryStatement(body, guarded, unguarded, finally, &pn->pn_pos, dst); } bool -ASTSerializer::forInit(ParseNode *pn, Value *dst) +ASTSerializer::forInit(ParseNode *pn, MutableHandleValue dst) { if (!pn) { - dst->setMagic(JS_SERIALIZE_NO_NODE); + dst.setMagic(JS_SERIALIZE_NO_NODE); return true; } @@ -2132,9 +2228,10 @@ ASTSerializer::forInit(ParseNode *pn, Value *dst) } bool -ASTSerializer::forOfOrIn(ParseNode *loop, ParseNode *head, Value var, Value stmt, Value *dst) +ASTSerializer::forOfOrIn(ParseNode *loop, ParseNode *head, HandleValue var, HandleValue stmt, + MutableHandleValue dst) { - Value expr; + RootedValue expr(cx); bool isForEach = loop->pn_iflags & JSITER_FOREACH; bool isForOf = loop->pn_iflags & JSITER_FOR_OF; JS_ASSERT(!isForOf || !isForEach); @@ -2145,7 +2242,7 @@ ASTSerializer::forOfOrIn(ParseNode *loop, ParseNode *head, Value var, Value stmt } bool -ASTSerializer::statement(ParseNode *pn, Value *dst) +ASTSerializer::statement(ParseNode *pn, MutableHandleValue dst) { JS_CHECK_RECURSION(cx, return false); switch (pn->getKind()) { @@ -2165,7 +2262,7 @@ ASTSerializer::statement(ParseNode *pn, Value *dst) case PNK_SEMI: if (pn->pn_kid) { - Value expr; + RootedValue expr(cx); return expression(pn->pn_kid, &expr) && builder.expressionStatement(expr, &pn->pn_pos, dst); } @@ -2186,7 +2283,7 @@ ASTSerializer::statement(ParseNode *pn, Value *dst) JS_ASSERT(pn->pn_pos.encloses(pn->pn_kid2->pn_pos)); JS_ASSERT_IF(pn->pn_kid3, pn->pn_pos.encloses(pn->pn_kid3->pn_pos)); - Value test, cons, alt; + RootedValue test(cx), cons(cx), alt(cx); return expression(pn->pn_kid1, &test) && statement(pn->pn_kid2, &cons) && @@ -2206,7 +2303,7 @@ ASTSerializer::statement(ParseNode *pn, Value *dst) JS_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos)); JS_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos)); - Value expr, stmt; + RootedValue expr(cx), stmt(cx); return expression(pn->pn_left, &expr) && statement(pn->pn_right, &stmt) && @@ -2220,7 +2317,7 @@ ASTSerializer::statement(ParseNode *pn, Value *dst) JS_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos)); JS_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos)); - Value stmt, test; + RootedValue stmt(cx), test(cx); return statement(pn->pn_left, &stmt) && expression(pn->pn_right, &test) && @@ -2238,12 +2335,12 @@ ASTSerializer::statement(ParseNode *pn, Value *dst) JS_ASSERT_IF(head->pn_kid2, head->pn_pos.encloses(head->pn_kid2->pn_pos)); JS_ASSERT_IF(head->pn_kid3, head->pn_pos.encloses(head->pn_kid3->pn_pos)); - Value stmt; + RootedValue stmt(cx); if (!statement(pn->pn_right, &stmt)) return false; if (head->isKind(PNK_FORIN)) { - Value var; + RootedValue var(cx); return (!head->pn_kid1 ? pattern(head->pn_kid2, NULL, &var) : head->pn_kid1->isKind(PNK_LEXICALSCOPE) @@ -2252,7 +2349,7 @@ ASTSerializer::statement(ParseNode *pn, Value *dst) forOfOrIn(pn, head, var, stmt, dst); } - Value init, test, update; + RootedValue init(cx), test(cx), update(cx); return forInit(head->pn_kid1, &init) && optExpression(head->pn_kid2, &test) && @@ -2270,14 +2367,14 @@ ASTSerializer::statement(ParseNode *pn, Value *dst) LOCAL_ASSERT(prelude->isKind(PNK_VAR) && loop->isKind(PNK_FOR)); - Value var; + RootedValue var(cx); if (!variableDeclaration(prelude, false, &var)) return false; ParseNode *head = loop->pn_left; JS_ASSERT(head->isKind(PNK_FORIN)); - Value stmt; + RootedValue stmt(cx); return statement(loop->pn_right, &stmt) && forOfOrIn(loop, head, var, stmt, dst); } @@ -2285,9 +2382,9 @@ ASTSerializer::statement(ParseNode *pn, Value *dst) case PNK_BREAK: case PNK_CONTINUE: { - Value label; - - return optIdentifier(pn->pn_atom, NULL, &label) && + RootedValue label(cx); + RootedAtom pnAtom(cx, pn->pn_atom); + return optIdentifier(pnAtom, NULL, &label) && (pn->isKind(PNK_BREAK) ? builder.breakStatement(label, &pn->pn_pos, dst) : builder.continueStatement(label, &pn->pn_pos, dst)); @@ -2297,9 +2394,9 @@ ASTSerializer::statement(ParseNode *pn, Value *dst) { JS_ASSERT(pn->pn_pos.encloses(pn->pn_expr->pn_pos)); - Value label, stmt; - - return identifier(pn->pn_atom, NULL, &label) && + RootedValue label(cx), stmt(cx); + RootedAtom pnAtom(cx, pn->pn_atom); + return identifier(pnAtom, NULL, &label) && statement(pn->pn_expr, &stmt) && builder.labeledStatement(label, stmt, &pn->pn_pos, dst); } @@ -2309,7 +2406,7 @@ ASTSerializer::statement(ParseNode *pn, Value *dst) { JS_ASSERT_IF(pn->pn_kid, pn->pn_pos.encloses(pn->pn_kid->pn_pos)); - Value arg; + RootedValue arg(cx); return optExpression(pn->pn_kid, &arg) && (pn->isKind(PNK_THROW) @@ -2327,7 +2424,7 @@ ASTSerializer::statement(ParseNode *pn, Value *dst) LOCAL_ASSERT(pn->isArity(PN_UNARY)); - Value ns; + RootedValue ns(cx); return expression(pn->pn_kid, &ns) && builder.xmlDefaultNamespace(ns, &pn->pn_pos, dst); @@ -2343,7 +2440,7 @@ ASTSerializer::statement(ParseNode *pn, Value *dst) } bool -ASTSerializer::leftAssociate(ParseNode *pn, Value *dst) +ASTSerializer::leftAssociate(ParseNode *pn, MutableHandleValue dst) { JS_ASSERT(pn->isArity(PN_LIST)); JS_ASSERT(pn->pn_count >= 1); @@ -2353,11 +2450,11 @@ ASTSerializer::leftAssociate(ParseNode *pn, Value *dst) bool logop = lor || (kind == PNK_AND); ParseNode *head = pn->pn_head; - Value left; + RootedValue left(cx); if (!expression(head, &left)) return false; for (ParseNode *next = head->pn_next; next; next = next->pn_next) { - Value right; + RootedValue right(cx); if (!expression(next, &right)) return false; @@ -2375,12 +2472,12 @@ ASTSerializer::leftAssociate(ParseNode *pn, Value *dst) } } - *dst = left; + dst.set(left); return true; } bool -ASTSerializer::comprehensionBlock(ParseNode *pn, Value *dst) +ASTSerializer::comprehensionBlock(ParseNode *pn, MutableHandleValue dst) { LOCAL_ASSERT(pn->isArity(PN_BINARY)); @@ -2390,14 +2487,14 @@ ASTSerializer::comprehensionBlock(ParseNode *pn, Value *dst) bool isForEach = pn->pn_iflags & JSITER_FOREACH; - Value patt, src; + RootedValue patt(cx), src(cx); return pattern(in->pn_kid2, NULL, &patt) && expression(in->pn_kid3, &src) && builder.comprehensionBlock(patt, src, isForEach, &in->pn_pos, dst); } bool -ASTSerializer::comprehension(ParseNode *pn, Value *dst) +ASTSerializer::comprehension(ParseNode *pn, MutableHandleValue dst) { LOCAL_ASSERT(pn->isKind(PNK_FOR)); @@ -2405,13 +2502,13 @@ ASTSerializer::comprehension(ParseNode *pn, Value *dst) ParseNode *next = pn; while (next->isKind(PNK_FOR)) { - Value block; + RootedValue block(cx); if (!comprehensionBlock(next, &block) || !blocks.append(block)) return false; next = next->pn_right; } - Value filter = MagicValue(JS_SERIALIZE_NO_NODE); + RootedValue filter(cx, MagicValue(JS_SERIALIZE_NO_NODE)); if (next->isKind(PNK_IF)) { if (!optExpression(next->pn_kid1, &filter)) @@ -2425,14 +2522,14 @@ ASTSerializer::comprehension(ParseNode *pn, Value *dst) LOCAL_ASSERT(next->isKind(PNK_ARRAYPUSH)); - Value body; + RootedValue body(cx); return expression(next->pn_kid, &body) && builder.comprehensionExpression(body, blocks, filter, &pn->pn_pos, dst); } bool -ASTSerializer::generatorExpression(ParseNode *pn, Value *dst) +ASTSerializer::generatorExpression(ParseNode *pn, MutableHandleValue dst) { LOCAL_ASSERT(pn->isKind(PNK_FOR)); @@ -2440,13 +2537,13 @@ ASTSerializer::generatorExpression(ParseNode *pn, Value *dst) ParseNode *next = pn; while (next->isKind(PNK_FOR)) { - Value block; + RootedValue block(cx); if (!comprehensionBlock(next, &block) || !blocks.append(block)) return false; next = next->pn_right; } - Value filter = MagicValue(JS_SERIALIZE_NO_NODE); + RootedValue filter(cx, MagicValue(JS_SERIALIZE_NO_NODE)); if (next->isKind(PNK_IF)) { if (!optExpression(next->pn_kid1, &filter)) @@ -2458,14 +2555,14 @@ ASTSerializer::generatorExpression(ParseNode *pn, Value *dst) next->pn_kid->isKind(PNK_YIELD) && next->pn_kid->pn_kid); - Value body; + RootedValue body(cx); return expression(next->pn_kid->pn_kid, &body) && builder.generatorExpression(body, blocks, filter, &pn->pn_pos, dst); } bool -ASTSerializer::expression(ParseNode *pn, Value *dst) +ASTSerializer::expression(ParseNode *pn, MutableHandleValue dst) { JS_CHECK_RECURSION(cx, return false); switch (pn->getKind()) { @@ -2485,7 +2582,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) JS_ASSERT(pn->pn_pos.encloses(pn->pn_kid2->pn_pos)); JS_ASSERT(pn->pn_pos.encloses(pn->pn_kid3->pn_pos)); - Value test, cons, alt; + RootedValue test(cx), cons(cx), alt(cx); return expression(pn->pn_kid1, &test) && expression(pn->pn_kid2, &cons) && @@ -2500,7 +2597,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) JS_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos)); JS_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos)); - Value left, right; + RootedValue left(cx), right(cx); return expression(pn->pn_left, &left) && expression(pn->pn_right, &right) && builder.logicalExpression(pn->isKind(PNK_OR), left, right, &pn->pn_pos, dst); @@ -2514,7 +2611,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) JS_ASSERT(pn->pn_pos.encloses(pn->pn_kid->pn_pos)); bool inc = pn->isKind(PNK_PREINCREMENT); - Value expr; + RootedValue expr(cx); return expression(pn->pn_kid, &expr) && builder.updateExpression(expr, inc, true, &pn->pn_pos, dst); } @@ -2525,7 +2622,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) JS_ASSERT(pn->pn_pos.encloses(pn->pn_kid->pn_pos)); bool inc = pn->isKind(PNK_POSTINCREMENT); - Value expr; + RootedValue expr(cx); return expression(pn->pn_kid, &expr) && builder.updateExpression(expr, inc, false, &pn->pn_pos, dst); } @@ -2549,7 +2646,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) AssignmentOperator op = aop(pn->getOp()); LOCAL_ASSERT(op > AOP_ERR && op < AOP_LIMIT); - Value lhs, rhs; + RootedValue lhs(cx), rhs(cx); return pattern(pn->pn_left, NULL, &lhs) && expression(pn->pn_right, &rhs) && builder.assignmentExpression(op, lhs, rhs, &pn->pn_pos, dst); @@ -2584,7 +2681,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) BinaryOperator op = binop(pn->getKind(), pn->getOp()); LOCAL_ASSERT(op > BINOP_ERR && op < BINOP_LIMIT); - Value left, right; + RootedValue left(cx), right(cx); return expression(pn->pn_left, &left) && expression(pn->pn_right, &right) && builder.binaryExpression(op, left, right, &pn->pn_pos, dst); @@ -2603,7 +2700,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) UnaryOperator op = unop(pn->getKind(), pn->getOp()); LOCAL_ASSERT(op > UNOP_ERR && op < UNOP_LIMIT); - Value expr; + RootedValue expr(cx); return expression(pn->pn_kid, &expr) && builder.unaryExpression(op, expr, &pn->pn_pos, dst); } @@ -2619,7 +2716,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) ParseNode *next = pn->pn_head; JS_ASSERT(pn->pn_pos.encloses(next->pn_pos)); - Value callee; + RootedValue callee(cx); if (!expression(next, &callee)) return false; @@ -2630,7 +2727,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) for (next = next->pn_next; next; next = next->pn_next) { JS_ASSERT(pn->pn_pos.encloses(next->pn_pos)); - Value arg; + RootedValue arg(cx); if (!expression(next, &arg)) return false; args.infallibleAppend(arg); @@ -2646,9 +2743,10 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) { JS_ASSERT(pn->pn_pos.encloses(pn->pn_expr->pn_pos)); - Value expr, id; + RootedValue expr(cx), id(cx); + RootedAtom pnAtom(cx, pn->pn_atom); return expression(pn->pn_expr, &expr) && - identifier(pn->pn_atom, NULL, &id) && + identifier(pnAtom, NULL, &id) && builder.memberExpression(false, expr, id, &pn->pn_pos, dst); } @@ -2657,7 +2755,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) JS_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos)); JS_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos)); - Value left, right; + RootedValue left(cx), right(cx); return expression(pn->pn_left, &left) && expression(pn->pn_right, &right) && builder.memberExpression(true, left, right, &pn->pn_pos, dst); @@ -2675,7 +2773,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) if (next->isKind(PNK_COMMA) && next->pn_count == 0) { elts.infallibleAppend(NullValue()); } else { - Value expr; + RootedValue expr(cx); if (!expression(next, &expr)) return false; elts.infallibleAppend(expr); @@ -2687,7 +2785,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) case PNK_SPREAD: { - Value expr; + RootedValue expr(cx); return expression(pn->pn_kid, &expr) && builder.spreadExpression(expr, &pn->pn_pos, dst); } @@ -2706,7 +2804,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) for (ParseNode *next = pn->pn_head; next; next = next->pn_next) { JS_ASSERT(pn->pn_pos.encloses(next->pn_pos)); - Value prop; + RootedValue prop(cx); if (!property(next, &prop)) return false; elts.infallibleAppend(prop); @@ -2733,7 +2831,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) { JS_ASSERT_IF(pn->pn_kid, pn->pn_pos.encloses(pn->pn_kid->pn_pos)); - Value arg; + RootedValue arg(cx); return optExpression(pn->pn_kid, &arg) && builder.yieldExpression(arg, &pn->pn_pos, dst); } @@ -2762,7 +2860,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) case PNK_DBLCOLON: { - Value right; + RootedValue right(cx); LOCAL_ASSERT(pn->isArity(PN_NAME) || pn->isArity(PN_BINARY)); @@ -2783,14 +2881,15 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) computed = false; pnleft = pn->pn_expr; - if (!identifier(pn->pn_atom, NULL, &right)) + RootedAtom pnAtom(cx, pn->pn_atom); + if (!identifier(pnAtom, NULL, &right)) return false; } if (pnleft->isKind(PNK_FUNCTIONNS)) return builder.xmlFunctionQualifiedIdentifier(right, computed, &pn->pn_pos, dst); - Value left; + RootedValue left(cx); return expression(pnleft, &left) && builder.xmlQualifiedIdentifier(left, right, computed, &pn->pn_pos, dst); } @@ -2799,7 +2898,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) { JS_ASSERT(pn->pn_pos.encloses(pn->pn_kid->pn_pos)); - Value expr; + RootedValue expr(cx); ParseNode *kid = pn->pn_kid; bool computed = ((!kid->isKind(PNK_NAME) || !kid->isOp(JSOP_QNAMEPART)) && !kid->isKind(PNK_DBLCOLON) && @@ -2813,7 +2912,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) JS_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos)); JS_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos)); - Value left, right; + RootedValue left(cx), right(cx); return expression(pn->pn_left, &left) && expression(pn->pn_right, &right) && builder.xmlFilterExpression(left, right, &pn->pn_pos, dst); @@ -2830,7 +2929,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst) } bool -ASTSerializer::xml(ParseNode *pn, Value *dst) +ASTSerializer::xml(ParseNode *pn, MutableHandleValue dst) { JS_CHECK_RECURSION(cx, return false); switch (pn->getKind()) { @@ -2839,7 +2938,7 @@ ASTSerializer::xml(ParseNode *pn, Value *dst) { JS_ASSERT(pn->pn_pos.encloses(pn->pn_kid->pn_pos)); - Value expr; + RootedValue expr(cx); return expression(pn->pn_kid, &expr) && builder.xmlEscapeExpression(expr, &pn->pn_pos, dst); } @@ -2885,12 +2984,16 @@ ASTSerializer::xml(ParseNode *pn, Value *dst) } case PNK_XMLTEXT: - case PNK_XMLSPACE: - return builder.xmlText(atomContents(pn->pn_atom), &pn->pn_pos, dst); + case PNK_XMLSPACE: { + RootedValue atomContentsVal(cx, unrootedAtomContents(pn->pn_atom)); + return builder.xmlText(atomContentsVal, &pn->pn_pos, dst); + } case PNK_XMLNAME: - if (pn->isArity(PN_NULLARY)) - return builder.xmlName(atomContents(pn->pn_atom), &pn->pn_pos, dst); + if (pn->isArity(PN_NULLARY)) { + RootedValue atomContentsVal(cx, unrootedAtomContents(pn->pn_atom)); + return builder.xmlName(atomContentsVal, &pn->pn_pos, dst); + } LOCAL_ASSERT(pn->isArity(PN_LIST)); @@ -2900,19 +3003,27 @@ ASTSerializer::xml(ParseNode *pn, Value *dst) builder.xmlName(elts, &pn->pn_pos, dst); } - case PNK_XMLATTR: - return builder.xmlAttribute(atomContents(pn->pn_atom), &pn->pn_pos, dst); + case PNK_XMLATTR: { + RootedValue atomContentsVal(cx, unrootedAtomContents(pn->pn_atom)); + return builder.xmlAttribute(atomContentsVal, &pn->pn_pos, dst); + } - case PNK_XMLCDATA: - return builder.xmlCdata(atomContents(pn->pn_atom), &pn->pn_pos, dst); + case PNK_XMLCDATA: { + RootedValue atomContentsVal(cx, unrootedAtomContents(pn->pn_atom)); + return builder.xmlCdata(atomContentsVal, &pn->pn_pos, dst); + } - case PNK_XMLCOMMENT: - return builder.xmlComment(atomContents(pn->pn_atom), &pn->pn_pos, dst); + case PNK_XMLCOMMENT: { + RootedValue atomContentsVal(cx, unrootedAtomContents(pn->pn_atom)); + return builder.xmlComment(atomContentsVal, &pn->pn_pos, dst); + } case PNK_XMLPI: { XMLProcessingInstruction &pi = pn->as(); - return builder.xmlPI(atomContents(pi.target()), - atomContents(pi.data()), + RootedValue targetAtomContentsVal(cx, unrootedAtomContents(pi.target())); + RootedValue dataAtomContentsVal(cx, unrootedAtomContents(pi.data())); + return builder.xmlPI(targetAtomContentsVal, + dataAtomContentsVal, &pi.pn_pos, dst); } @@ -2924,7 +3035,7 @@ ASTSerializer::xml(ParseNode *pn, Value *dst) } bool -ASTSerializer::propertyName(ParseNode *pn, Value *dst) +ASTSerializer::propertyName(ParseNode *pn, MutableHandleValue dst) { if (pn->isKind(PNK_NAME)) return identifier(pn, dst); @@ -2935,7 +3046,7 @@ ASTSerializer::propertyName(ParseNode *pn, Value *dst) } bool -ASTSerializer::property(ParseNode *pn, Value *dst) +ASTSerializer::property(ParseNode *pn, MutableHandleValue dst) { PropKind kind; switch (pn->getOp()) { @@ -2955,16 +3066,16 @@ ASTSerializer::property(ParseNode *pn, Value *dst) LOCAL_NOT_REACHED("unexpected object-literal property"); } - Value key, val; + RootedValue key(cx), val(cx); return propertyName(pn->pn_left, &key) && expression(pn->pn_right, &val) && builder.propertyInitializer(key, val, kind, &pn->pn_pos, dst); } bool -ASTSerializer::literal(ParseNode *pn, Value *dst) +ASTSerializer::literal(ParseNode *pn, MutableHandleValue dst) { - Value val; + RootedValue val(cx); switch (pn->getKind()) { case PNK_STRING: val.setString(pn->pn_atom); @@ -2972,14 +3083,14 @@ ASTSerializer::literal(ParseNode *pn, Value *dst) case PNK_REGEXP: { - JSObject *re1 = pn->pn_objbox ? pn->pn_objbox->object : NULL; + RootedObject re1(cx, pn->pn_objbox ? pn->pn_objbox->object : NULL); LOCAL_ASSERT(re1 && re1->isRegExp()); RootedObject proto(cx); if (!js_GetClassPrototype(cx, JSProto_RegExp, &proto)) return false; - JSObject *re2 = CloneRegExpObject(cx, re1, proto); + RootedObject re2(cx, CloneRegExpObject(cx, re1, proto)); if (!re2) return false; @@ -3011,7 +3122,7 @@ ASTSerializer::literal(ParseNode *pn, Value *dst) } bool -ASTSerializer::arrayPattern(ParseNode *pn, VarDeclKind *pkind, Value *dst) +ASTSerializer::arrayPattern(ParseNode *pn, VarDeclKind *pkind, MutableHandleValue dst) { JS_ASSERT(pn->isKind(PNK_ARRAY)); @@ -3026,7 +3137,7 @@ ASTSerializer::arrayPattern(ParseNode *pn, VarDeclKind *pkind, Value *dst) if (next->isKind(PNK_COMMA)) { elts.infallibleAppend(NullValue()); } else { - Value patt; + RootedValue patt(cx); if (!pattern(next, pkind, &patt)) return false; elts.infallibleAppend(patt); @@ -3037,7 +3148,7 @@ ASTSerializer::arrayPattern(ParseNode *pn, VarDeclKind *pkind, Value *dst) } bool -ASTSerializer::objectPattern(ParseNode *pn, VarDeclKind *pkind, Value *dst) +ASTSerializer::objectPattern(ParseNode *pn, VarDeclKind *pkind, MutableHandleValue dst) { JS_ASSERT(pn->isKind(PNK_OBJECT)); @@ -3048,7 +3159,7 @@ ASTSerializer::objectPattern(ParseNode *pn, VarDeclKind *pkind, Value *dst) for (ParseNode *next = pn->pn_head; next; next = next->pn_next) { LOCAL_ASSERT(next->isOp(JSOP_INITPROP)); - Value key, patt, prop; + RootedValue key(cx), patt(cx), prop(cx); if (!propertyName(next->pn_left, &key) || !pattern(next->pn_right, pkind, &patt) || !builder.propertyPattern(key, patt, &next->pn_pos, &prop)) { @@ -3062,7 +3173,7 @@ ASTSerializer::objectPattern(ParseNode *pn, VarDeclKind *pkind, Value *dst) } bool -ASTSerializer::pattern(ParseNode *pn, VarDeclKind *pkind, Value *dst) +ASTSerializer::pattern(ParseNode *pn, VarDeclKind *pkind, MutableHandleValue dst) { JS_CHECK_RECURSION(cx, return false); switch (pn->getKind()) { @@ -3083,24 +3194,26 @@ ASTSerializer::pattern(ParseNode *pn, VarDeclKind *pkind, Value *dst) } bool -ASTSerializer::identifier(JSAtom *atom, TokenPos *pos, Value *dst) +ASTSerializer::identifier(HandleAtom atom, TokenPos *pos, MutableHandleValue dst) { - return builder.identifier(atomContents(atom), pos, dst); + RootedValue atomContentsVal(cx, unrootedAtomContents(atom)); + return builder.identifier(atomContentsVal, pos, dst); } bool -ASTSerializer::identifier(ParseNode *pn, Value *dst) +ASTSerializer::identifier(ParseNode *pn, MutableHandleValue dst) { LOCAL_ASSERT(pn->isArity(PN_NAME) || pn->isArity(PN_NULLARY)); LOCAL_ASSERT(pn->pn_atom); - return identifier(pn->pn_atom, &pn->pn_pos, dst); + RootedAtom pnAtom(cx, pn->pn_atom); + return identifier(pnAtom, &pn->pn_pos, dst); } bool -ASTSerializer::function(ParseNode *pn, ASTType type, Value *dst) +ASTSerializer::function(ParseNode *pn, ASTType type, MutableHandleValue dst) { - JSFunction *func = pn->pn_funbox->fun(); + RootedFunction func(cx, pn->pn_funbox->fun()); bool isGenerator = #if JS_HAS_GENERATORS @@ -3116,15 +3229,15 @@ ASTSerializer::function(ParseNode *pn, ASTType type, Value *dst) false; #endif - Value id; - if (!optIdentifier(func->atom(), NULL, &id)) + RootedValue id(cx); + RootedAtom funcAtom(cx, func->atom()); + if (!optIdentifier(funcAtom, NULL, &id)) return false; NodeVector args(cx); NodeVector defaults(cx); - Value body; - Value rest; + RootedValue body(cx), rest(cx); if (func->hasRest()) rest.setUndefined(); else @@ -3135,8 +3248,8 @@ ASTSerializer::function(ParseNode *pn, ASTType type, Value *dst) } bool -ASTSerializer::functionArgsAndBody(ParseNode *pn, NodeVector &args, - NodeVector &defaults, Value *body, Value *rest) +ASTSerializer::functionArgsAndBody(ParseNode *pn, NodeVector &args, NodeVector &defaults, + MutableHandleValue body, MutableHandleValue rest) { ParseNode *pnargs; ParseNode *pnbody; @@ -3197,12 +3310,12 @@ ASTSerializer::functionArgsAndBody(ParseNode *pn, NodeVector &args, bool ASTSerializer::functionArgs(ParseNode *pn, ParseNode *pnargs, ParseNode *pndestruct, ParseNode *pnbody, NodeVector &args, NodeVector &defaults, - Value *rest) + MutableHandleValue rest) { uint32_t i = 0; ParseNode *arg = pnargs ? pnargs->pn_head : NULL; ParseNode *destruct = pndestruct ? pndestruct->pn_head : NULL; - Value node; + RootedValue node(cx); /* * Arguments are found in potentially two different places: 1) the @@ -3233,13 +3346,13 @@ ASTSerializer::functionArgs(ParseNode *pn, ParseNode *pnargs, ParseNode *pndestr ParseNode *argName = arg->isKind(PNK_NAME) ? arg : arg->pn_left; if (!identifier(argName, &node)) return false; - if (rest->isUndefined() && arg->pn_next == pnbody) - rest->setObject(node.toObject()); + if (rest.isUndefined() && arg->pn_next == pnbody) + rest.setObject(node.toObject()); else if (!args.append(node)) return false; if (arg->pn_dflags & PND_DEFAULT) { ParseNode *expr = arg->isDefn() ? arg->expr() : arg->pn_kid->pn_right; - Value def; + RootedValue def(cx); if (!expression(expr, &def) || !defaults.append(def)) return false; } @@ -3249,19 +3362,19 @@ ASTSerializer::functionArgs(ParseNode *pn, ParseNode *pnargs, ParseNode *pndestr } ++i; } - JS_ASSERT(!rest->isUndefined()); + JS_ASSERT(!rest.isUndefined()); return true; } bool -ASTSerializer::functionBody(ParseNode *pn, TokenPos *pos, Value *dst) +ASTSerializer::functionBody(ParseNode *pn, TokenPos *pos, MutableHandleValue dst) { NodeVector elts(cx); /* We aren't sure how many elements there are up front, so we'll check each append. */ for (ParseNode *next = pn; next; next = next->pn_next) { - Value child; + RootedValue child(cx); if (!sourceElement(next, &child) || !elts.append(child)) return false; } @@ -3274,15 +3387,13 @@ ASTSerializer::functionBody(ParseNode *pn, TokenPos *pos, Value *dst) static JSBool reflect_parse(JSContext *cx, uint32_t argc, jsval *vp) { - cx->runtime->gcExactScanningEnabled = false; - if (argc < 1) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED, "Reflect.parse", "0", "s"); return JS_FALSE; } - JSString *src = ToString(cx, JS_ARGV(cx, vp)[0]); + RootedString src(cx, ToString(cx, JS_ARGV(cx, vp)[0])); if (!src) return JS_FALSE; @@ -3291,7 +3402,7 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp) uint32_t lineno = 1; bool loc = true; - JSObject *builder = NULL; + RootedObject builder(cx); RootedValue arg(cx, argc > 1 ? JS_ARGV(cx, vp)[1] : UndefinedValue()); @@ -3317,12 +3428,12 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp) if (loc) { /* config.source */ RootedId sourceId(cx, NameToId(cx->runtime->atomState.sourceAtom)); - RootedValue nullValue(cx, NullValue()); - if (!baseops::GetPropertyDefault(cx, config, sourceId, nullValue, &prop)) + RootedValue nullVal(cx, NullValue()); + if (!baseops::GetPropertyDefault(cx, config, sourceId, nullVal, &prop)) return JS_FALSE; if (!prop.isNullOrUndefined()) { - JSString *str = ToString(cx, prop); + RootedString str(cx, ToString(cx, prop)); if (!str) return JS_FALSE; @@ -3348,8 +3459,8 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp) /* config.builder */ RootedId builderId(cx, NameToId(cx->runtime->atomState.builderAtom)); - RootedValue nullValue(cx, NullValue()); - if (!baseops::GetPropertyDefault(cx, config, builderId, nullValue, &prop)) + RootedValue nullVal(cx, NullValue()); + if (!baseops::GetPropertyDefault(cx, config, builderId, nullVal, &prop)) return JS_FALSE; if (!prop.isNullOrUndefined()) { @@ -3384,7 +3495,7 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp) if (!pn) return JS_FALSE; - Value val; + RootedValue val(cx); if (!serialize.program(pn, &val)) { JS_SET_RVAL(cx, vp, JSVAL_NULL); return JS_FALSE; diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index b6d5cd4e8c45..008c823ff182 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -4432,7 +4432,7 @@ GENERATE_JSOPTION_GETTER_SETTER(Relimit, JSOPTION_RELIMIT) GENERATE_JSOPTION_GETTER_SETTER(Methodjit, JSOPTION_METHODJIT) GENERATE_JSOPTION_GETTER_SETTER(Methodjit_always, JSOPTION_METHODJIT_ALWAYS) GENERATE_JSOPTION_GETTER_SETTER(Strict_mode, JSOPTION_STRICT_MODE) -GENERATE_JSOPTION_GETTER_SETTER(Ion, JSOPTION_ION); +GENERATE_JSOPTION_GETTER_SETTER(Ion, JSOPTION_ION) #undef GENERATE_JSOPTION_GETTER_SETTER diff --git a/js/xpconnect/src/XPCStack.cpp b/js/xpconnect/src/XPCStack.cpp index 09e5ab849412..99ff377f9b18 100644 --- a/js/xpconnect/src/XPCStack.cpp +++ b/js/xpconnect/src/XPCStack.cpp @@ -16,7 +16,7 @@ public: static nsresult CreateStack(JSContext* cx, XPCJSStackFrame** stack); - static nsresult CreateStackFrameLocation(PRUint32 aLanguage, + static nsresult CreateStackFrameLocation(uint32_t aLanguage, const char* aFilename, const char* aFunctionName, int32_t aLineNumber, @@ -93,7 +93,6 @@ nsresult XPCJSStackFrame::CreateStack(JSContext* cx, XPCJSStackFrame** stack) { static const unsigned MAX_FRAMES = 100; - unsigned numFrames = 0; nsRefPtr first = new XPCJSStackFrame(); nsRefPtr self = first; diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index a30e7154e178..b6999f3fb5ac 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -13,6 +13,7 @@ #ifndef NSDISPLAYLIST_H_ #define NSDISPLAYLIST_H_ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsIFrame.h" #include "nsPoint.h" @@ -1406,7 +1407,7 @@ public: } #endif - virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) { + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE { mPaint(mFrame, aCtx, mVisibleRect, ToReferenceFrame()); } NS_DISPLAY_DECL_NAME(mName, mType) @@ -1457,7 +1458,7 @@ public: } #endif - virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) { + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE { mFrame->PresContext()->PresShell()->PaintCount(mFrameName, aCtx, mFrame->PresContext(), mFrame, ToReferenceFrame(), @@ -1523,12 +1524,12 @@ public: } #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE { *aSnap = false; // The caret returns a rect in the coordinates of mFrame. return mCaret->GetCaretRect() + ToReferenceFrame(); } - virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; NS_DISPLAY_DECL_NAME("Caret", TYPE_CARET) protected: nsRefPtr mCaret; @@ -1550,11 +1551,11 @@ public: } #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); - virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion); + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER) }; @@ -1584,10 +1585,10 @@ public: } #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aSnap) { + bool* aSnap) MOZ_OVERRIDE { *aSnap = false; nsRegion result; if (NS_GET_A(mColor) == 255) { @@ -1596,13 +1597,13 @@ public: return result; } - virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) + virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE { *aColor = mColor; return true; } - virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; NS_DISPLAY_DECL_NAME("SolidColor", TYPE_SOLID_COLOR) @@ -1634,26 +1635,26 @@ public: virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aParameters); + const ContainerParameters& aParameters) MOZ_OVERRIDE; virtual already_AddRefed BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aContainerParameters); + const ContainerParameters& aContainerParameters) MOZ_OVERRIDE; virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, - HitTestState* aState, nsTArray *aOutFrames); + HitTestState* aState, nsTArray *aOutFrames) MOZ_OVERRIDE; virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion); + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aSnap); + bool* aSnap) MOZ_OVERRIDE; virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder, - nsIFrame* aFrame); - virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor); - virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder); - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); - virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); - virtual uint32_t GetPerFrameKey(); + nsIFrame* aFrame) MOZ_OVERRIDE; + virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE; + virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; + virtual uint32_t GetPerFrameKey() MOZ_OVERRIDE; NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND) // Returns the value of GetUnderlyingFrame()->IsThemed(), but cached bool IsThemed() { return mIsThemed; } @@ -1699,11 +1700,11 @@ public: } #endif - virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion); + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; NS_DISPLAY_DECL_NAME("BoxShadowOuter", TYPE_BOX_SHADOW_OUTER) private: @@ -1725,10 +1726,10 @@ public: } #endif - virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion); + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; NS_DISPLAY_DECL_NAME("BoxShadowInner", TYPE_BOX_SHADOW_INNER) private: @@ -1750,11 +1751,11 @@ public: } #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); - virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion); + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; NS_DISPLAY_DECL_NAME("Outline", TYPE_OUTLINE) }; @@ -1774,7 +1775,7 @@ public: #endif virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, - HitTestState* aState, nsTArray *aOutFrames); + HitTestState* aState, nsTArray *aOutFrames) MOZ_OVERRIDE; NS_DISPLAY_DECL_NAME("EventReceiver", TYPE_EVENT_RECEIVER) }; @@ -1817,22 +1818,22 @@ public: mBounds = mList.GetBounds(aBuilder); } virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, - HitTestState* aState, nsTArray *aOutFrames); - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); + HitTestState* aState, nsTArray *aOutFrames) MOZ_OVERRIDE; + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aSnap); - virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor); + bool* aSnap) MOZ_OVERRIDE; + virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE; virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder, - nsIFrame* aFrame); - virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); + nsIFrame* aFrame) MOZ_OVERRIDE; + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion); - virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) { + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE { NS_WARNING("This list should already have been flattened!!!"); return false; } - virtual void GetMergedFrames(nsTArray* aFrames) + virtual void GetMergedFrames(nsTArray* aFrames) MOZ_OVERRIDE { aFrames->AppendElements(mMergedFrames); } @@ -1840,7 +1841,7 @@ public: virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder); - virtual nsDisplayList* GetList() { return &mList; } + virtual nsDisplayList* GetList() MOZ_OVERRIDE { return &mList; } /** * This creates a copy of this item, but wrapping aItem instead of @@ -1926,17 +1927,17 @@ public: #endif virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aSnap); + bool* aSnap) MOZ_OVERRIDE; virtual already_AddRefed BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aContainerParameters); + const ContainerParameters& aContainerParameters) MOZ_OVERRIDE; virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aParameters); + const ContainerParameters& aParameters) MOZ_OVERRIDE; virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion); - virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem); + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE; NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY) bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder); @@ -1956,14 +1957,14 @@ public: virtual already_AddRefed BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aContainerParameters); + const ContainerParameters& aContainerParameters) MOZ_OVERRIDE; virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aParameters) + const ContainerParameters& aParameters) MOZ_OVERRIDE { return mozilla::LAYER_ACTIVE_FORCE; } - virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE { // Don't allow merging, each sublist must have its own layer return false; @@ -1986,14 +1987,14 @@ public: virtual already_AddRefed BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aContainerParameters); + const ContainerParameters& aContainerParameters) MOZ_OVERRIDE; virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aParameters) + const ContainerParameters& aParameters) MOZ_OVERRIDE { return mozilla::LAYER_ACTIVE; } - virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem); + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE; NS_DISPLAY_DECL_NAME("FixedPosition", TYPE_FIXED_POSITION) @@ -2049,20 +2050,20 @@ public: virtual already_AddRefed BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aContainerParameters); + const ContainerParameters& aContainerParameters) MOZ_OVERRIDE; virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion); + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aParameters); + const ContainerParameters& aParameters) MOZ_OVERRIDE; virtual bool TryMerge(nsDisplayListBuilder* aBuilder, - nsDisplayItem* aItem); + nsDisplayItem* aItem) MOZ_OVERRIDE; - virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder); + virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; // Get the number of nsDisplayScrollLayers for a scroll frame. Note that this // number does not include nsDisplayScrollInfoLayers. If this number is not 1 @@ -2101,12 +2102,12 @@ public: virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aParameters); + const ContainerParameters& aParameters) MOZ_OVERRIDE; virtual bool TryMerge(nsDisplayListBuilder* aBuilder, - nsDisplayItem* aItem); + nsDisplayItem* aItem) MOZ_OVERRIDE; - virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder); + virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; }; /** @@ -2129,12 +2130,12 @@ public: virtual ~nsDisplayClip(); #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); - virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion); - virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem); + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE; NS_DISPLAY_DECL_NAME("Clip", TYPE_CLIP) virtual uint32_t GetPerFrameKey() { return 0; } @@ -2142,7 +2143,7 @@ public: void SetClipRect(const nsRect& aRect) { mClip = aRect; } virtual nsDisplayWrapList* WrapWithClone(nsDisplayListBuilder* aBuilder, - nsDisplayItem* aItem); + nsDisplayItem* aItem) MOZ_OVERRIDE; protected: nsRect mClip; @@ -2170,13 +2171,13 @@ public: #endif virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aSnap); + bool* aSnap) MOZ_OVERRIDE; virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, - HitTestState* aState, nsTArray *aOutFrames); + HitTestState* aState, nsTArray *aOutFrames) MOZ_OVERRIDE; virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion); - virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem); + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE; NS_DISPLAY_DECL_NAME("ClipRoundedRect", TYPE_CLIP_ROUNDED_RECT) virtual nsDisplayWrapList* WrapWithClone(nsDisplayListBuilder* aBuilder, @@ -2210,16 +2211,16 @@ public: virtual ~nsDisplayZoom(); #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); - virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, - HitTestState* aState, nsTArray *aOutFrames); + HitTestState* aState, nsTArray *aOutFrames) MOZ_OVERRIDE; virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion); + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aParameters) + const ContainerParameters& aParameters) MOZ_OVERRIDE { return mozilla::LAYER_ACTIVE; } @@ -2247,17 +2248,17 @@ public: #endif virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aSnap); + bool* aSnap) MOZ_OVERRIDE; virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, - HitTestState* aState, nsTArray *aOutFrames); - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + HitTestState* aState, nsTArray *aOutFrames) MOZ_OVERRIDE; + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE { *aSnap = false; return mEffectsBounds + ToReferenceFrame(); } virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion); - virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem); + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE; NS_DISPLAY_DECL_NAME("SVGEffects", TYPE_SVG_EFFECTS) virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, @@ -2266,7 +2267,7 @@ public: virtual already_AddRefed BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aContainerParameters); + const ContainerParameters& aContainerParameters) MOZ_OVERRIDE; void PaintAsLayer(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx, @@ -2335,23 +2336,23 @@ public: nsDisplayWrapList* GetStoredList() { return &mStoredList; } virtual void HitTest(nsDisplayListBuilder *aBuilder, const nsRect& aRect, - HitTestState *aState, nsTArray *aOutFrames); - virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder, bool* aSnap); + HitTestState *aState, nsTArray *aOutFrames) MOZ_OVERRIDE; + virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder, bool* aSnap) MOZ_OVERRIDE; virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder *aBuilder, - bool* aSnap); - virtual bool IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor); + bool* aSnap) MOZ_OVERRIDE; + virtual bool IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor) MOZ_OVERRIDE; virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aParameters); + const ContainerParameters& aParameters) MOZ_OVERRIDE; virtual already_AddRefed BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aContainerParameters); + const ContainerParameters& aContainerParameters) MOZ_OVERRIDE; virtual bool ComputeVisibility(nsDisplayListBuilder *aBuilder, nsRegion *aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion); - virtual bool TryMerge(nsDisplayListBuilder *aBuilder, nsDisplayItem *aItem); + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; + virtual bool TryMerge(nsDisplayListBuilder *aBuilder, nsDisplayItem *aItem) MOZ_OVERRIDE; - virtual uint32_t GetPerFrameKey() { return (mIndex << nsDisplayItem::TYPE_BITS) | nsDisplayItem::GetPerFrameKey(); } + virtual uint32_t GetPerFrameKey() MOZ_OVERRIDE { return (mIndex << nsDisplayItem::TYPE_BITS) | nsDisplayItem::GetPerFrameKey(); } enum { INDEX_MAX = PR_UINT32_MAX >> nsDisplayItem::TYPE_BITS @@ -2454,7 +2455,7 @@ public: static bool ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, bool aLogAnimations = false); - bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder); + bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; private: nsDisplayWrapList mStoredList; diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h index 4e3bc7729765..b57ce35592b3 100644 --- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -8,6 +8,7 @@ #ifndef nsPresContext_h___ #define nsPresContext_h___ +#include "mozilla/Attributes.h" #include "nsISupports.h" #include "nsColor.h" #include "nsCoord.h" @@ -1259,7 +1260,7 @@ public: */ void DidApplyPluginGeometryUpdates(); - virtual bool IsRoot() { return true; } + virtual bool IsRoot() MOZ_OVERRIDE { return true; } /** * Call this after reflow and scrolling to ensure that the geometry diff --git a/layout/base/nsPresShell.h b/layout/base/nsPresShell.h index bc4add15f29b..8217a243d616 100644 --- a/layout/base/nsPresShell.h +++ b/layout/base/nsPresShell.h @@ -613,7 +613,7 @@ protected: mPresShell = nullptr; } } - virtual void WillRefresh(mozilla::TimeStamp aTime) { + virtual void WillRefresh(mozilla::TimeStamp aTime) MOZ_OVERRIDE { if (mPresShell) mPresShell->ProcessSynthMouseMoveEvent(mFromScroll); } diff --git a/layout/base/nsQuoteList.h b/layout/base/nsQuoteList.h index 46e163bb1a86..aae3e7ea9759 100644 --- a/layout/base/nsQuoteList.h +++ b/layout/base/nsQuoteList.h @@ -8,6 +8,7 @@ #ifndef nsQuoteList_h___ #define nsQuoteList_h___ +#include "mozilla/Attributes.h" #include "nsGenConList.h" struct nsQuoteNode : public nsGenConNode { @@ -31,7 +32,7 @@ struct nsQuoteNode : public nsGenConNode { } virtual bool InitTextFrame(nsGenConList* aList, - nsIFrame* aPseudoFrame, nsIFrame* aTextFrame); + nsIFrame* aPseudoFrame, nsIFrame* aTextFrame) MOZ_OVERRIDE; // is this 'open-quote' or 'no-open-quote'? bool IsOpenQuote() { diff --git a/layout/forms/nsComboboxControlFrame.h b/layout/forms/nsComboboxControlFrame.h index 0c3fe7242eb9..919f82b3f67e 100644 --- a/layout/forms/nsComboboxControlFrame.h +++ b/layout/forms/nsComboboxControlFrame.h @@ -21,6 +21,7 @@ //Mark used to indicate when onchange has been fired for current combobox item #define NS_SKIP_NOTIFY_INDEX -2 +#include "mozilla/Attributes.h" #include "nsBlockFrame.h" #include "nsIFormControlFrame.h" #include "nsIComboboxControlFrame.h" @@ -60,21 +61,21 @@ public: // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements); virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, - uint32_t aFilter); - virtual nsIFrame* CreateFrameFor(nsIContent* aContent); + uint32_t aFilter) MOZ_OVERRIDE; + virtual nsIFrame* CreateFrameFor(nsIContent* aContent) MOZ_OVERRIDE; #ifdef ACCESSIBILITY - virtual already_AddRefed CreateAccessible(); + virtual already_AddRefed CreateAccessible() MOZ_OVERRIDE; #endif - virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); + virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; - virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext); + virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aCX, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; NS_IMETHOD HandleEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent, @@ -82,16 +83,16 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; void PaintFocus(nsRenderingContext& aRenderingContext, nsPoint aPt); // XXXbz this is only needed to prevent the quirk percent height stuff from // leaking out of the combobox. We may be able to get rid of this as more // things move to IsFrameOfType. - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; - virtual bool IsFrameOfType(uint32_t aFlags) const + virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE { return nsBlockFrame::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock)); @@ -102,19 +103,19 @@ public: } #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); - virtual const nsFrameList& GetChildList(ChildListID aListID) const; - virtual void GetChildLists(nsTArray* aLists) const; + nsFrameList& aChildList) MOZ_OVERRIDE; + virtual const nsFrameList& GetChildList(ChildListID aListID) const MOZ_OVERRIDE; + virtual void GetChildLists(nsTArray* aLists) const MOZ_OVERRIDE; virtual nsIFrame* GetContentInsertionFrame(); // nsIFormControlFrame - virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue); - virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const; + virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) MOZ_OVERRIDE; + virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const MOZ_OVERRIDE; /** * Inform the control that it got (or lost) focus. * If it lost focus, the dropdown menu will be rolled up if needed, @@ -130,13 +131,13 @@ public: /** * @note This method might destroy |this|. */ - virtual void ShowDropDown(bool aDoDropDown); - virtual nsIFrame* GetDropDown(); - virtual void SetDropDown(nsIFrame* aDropDownFrame); + virtual void ShowDropDown(bool aDoDropDown) MOZ_OVERRIDE; + virtual nsIFrame* GetDropDown() MOZ_OVERRIDE; + virtual void SetDropDown(nsIFrame* aDropDownFrame) MOZ_OVERRIDE; /** * @note This method might destroy |this|. */ - virtual void RollupFromList(); + virtual void RollupFromList() MOZ_OVERRIDE; /** * Return the available space above and below this frame for @@ -147,20 +148,20 @@ public: void GetAvailableDropdownSpace(nscoord* aAbove, nscoord* aBelow, nsPoint* aTranslation); - virtual int32_t GetIndexOfDisplayArea(); + virtual int32_t GetIndexOfDisplayArea() MOZ_OVERRIDE; /** * @note This method might destroy |this|. */ - NS_IMETHOD RedisplaySelectedText(); - virtual int32_t UpdateRecentIndex(int32_t aIndex); - virtual void OnContentReset(); + NS_IMETHOD RedisplaySelectedText() MOZ_OVERRIDE; + virtual int32_t UpdateRecentIndex(int32_t aIndex) MOZ_OVERRIDE; + virtual void OnContentReset() MOZ_OVERRIDE; // nsISelectControlFrame NS_IMETHOD AddOption(int32_t index); - NS_IMETHOD RemoveOption(int32_t index); - NS_IMETHOD DoneAddingChildren(bool aIsDone); - NS_IMETHOD OnOptionSelected(int32_t aIndex, bool aSelected); - NS_IMETHOD OnSetSelectedIndex(int32_t aOldIndex, int32_t aNewIndex); + NS_IMETHOD RemoveOption(int32_t index) MOZ_OVERRIDE; + NS_IMETHOD DoneAddingChildren(bool aIsDone) MOZ_OVERRIDE; + NS_IMETHOD OnOptionSelected(int32_t aIndex, bool aSelected) MOZ_OVERRIDE; + NS_IMETHOD OnSetSelectedIndex(int32_t aOldIndex, int32_t aNewIndex) MOZ_OVERRIDE; //nsIRollupListener /** @@ -188,8 +189,8 @@ public: { return 0; } //nsIStatefulFrame - NS_IMETHOD SaveState(SpecialStateID aStateID, nsPresState** aState); - NS_IMETHOD RestoreState(nsPresState* aState); + NS_IMETHOD SaveState(SpecialStateID aStateID, nsPresState** aState) MOZ_OVERRIDE; + NS_IMETHOD RestoreState(nsPresState* aState) MOZ_OVERRIDE; static bool ToolkitHasNativePopup(); diff --git a/layout/forms/nsFileControlFrame.cpp b/layout/forms/nsFileControlFrame.cpp index c2caeabe43b4..98e4bbbcddb9 100644 --- a/layout/forms/nsFileControlFrame.cpp +++ b/layout/forms/nsFileControlFrame.cpp @@ -370,12 +370,11 @@ nsFileControlFrame::CaptureMouseListener::HandleEvent(nsIDOMEvent* aMouseEvent) // Tell our input element that this update of the value is a user // initiated change. Otherwise it'll think that the value is being set by // a script and not fire onchange when it should. - + inputElement->SetFiles(newFiles, true); - - // Should fire a change event here since the SetFiles() call above ensures - // a different value from the mFocusedValue of the inputElement. - inputElement->FireChangeEventIfNeeded(); + nsContentUtils::DispatchTrustedEvent(content->OwnerDoc(), content, + NS_LITERAL_STRING("change"), true, + false); } return NS_OK; @@ -434,9 +433,10 @@ nsFileControlFrame::BrowseMouseListener::HandleEvent(nsIDOMEvent* aEvent) nsCOMPtr fileList; dataTransfer->GetFiles(getter_AddRefs(fileList)); - inputElement->SetFiles(fileList, true); - inputElement->FireChangeEventIfNeeded(); + nsContentUtils::DispatchTrustedEvent(content->OwnerDoc(), content, + NS_LITERAL_STRING("change"), true, + false); } return NS_OK; diff --git a/layout/forms/nsFileControlFrame.h b/layout/forms/nsFileControlFrame.h index b7e68c2c294b..20a47f943acc 100644 --- a/layout/forms/nsFileControlFrame.h +++ b/layout/forms/nsFileControlFrame.h @@ -6,6 +6,7 @@ #ifndef nsFileControlFrame_h___ #define nsFileControlFrame_h___ +#include "mozilla/Attributes.h" #include "nsBlockFrame.h" #include "nsIFormControlFrame.h" #include "nsIDOMEventListener.h" @@ -36,32 +37,32 @@ public: // nsIFormControlFrame virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue); - virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const; + virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const MOZ_OVERRIDE; virtual void SetFocus(bool aOn, bool aRepaint); - virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); + virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; virtual void ContentStatesChanged(nsEventStates aStates); virtual bool IsLeaf() const; // nsIAnonymousContentCreator - virtual nsresult CreateAnonymousContent(nsTArray& aElements); + virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, - uint32_t aFilter); + uint32_t aFilter) MOZ_OVERRIDE; #ifdef ACCESSIBILITY - virtual already_AddRefed CreateAccessible(); + virtual already_AddRefed CreateAccessible() MOZ_OVERRIDE; #endif typedef bool (*AcceptAttrCallback)(const nsAString&, void*); @@ -137,13 +138,13 @@ protected: static bool IsValidDropData(nsIDOMDragEvent* aEvent); }; - virtual bool IsFrameOfType(uint32_t aFlags) const + virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE { return nsBlockFrame::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock)); } - virtual int GetSkipSides() const; + virtual int GetSkipSides() const MOZ_OVERRIDE; /** * The text box input. diff --git a/layout/forms/nsFormControlFrame.h b/layout/forms/nsFormControlFrame.h index 48f0ff48c55c..bc4adc51afff 100644 --- a/layout/forms/nsFormControlFrame.h +++ b/layout/forms/nsFormControlFrame.h @@ -6,6 +6,7 @@ #ifndef nsFormControlFrame_h___ #define nsFormControlFrame_h___ +#include "mozilla/Attributes.h" #include "nsIFormControlFrame.h" #include "nsLeafFrame.h" @@ -42,7 +43,7 @@ public: */ NS_IMETHOD HandleEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; virtual nscoord GetBaseline() const; @@ -53,7 +54,7 @@ public: NS_IMETHOD Reflow(nsPresContext* aCX, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; virtual void DestroyFrom(nsIFrame* aDestructRoot); @@ -62,9 +63,9 @@ public: virtual void SetFocus(bool aOn = true, bool aRepaint = false); // nsIFormControlFrame - virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue); + virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) MOZ_OVERRIDE; - virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const; + virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const MOZ_OVERRIDE; // AccessKey Helper function static nsresult RegUnRegAccessKey(nsIFrame * aFrame, bool aDoReg); @@ -79,8 +80,8 @@ protected: virtual ~nsFormControlFrame(); - virtual nscoord GetIntrinsicWidth(); - virtual nscoord GetIntrinsicHeight(); + virtual nscoord GetIntrinsicWidth() MOZ_OVERRIDE; + virtual nscoord GetIntrinsicHeight() MOZ_OVERRIDE; // //------------------------------------------------------------------------------------- diff --git a/layout/forms/nsGfxButtonControlFrame.h b/layout/forms/nsGfxButtonControlFrame.h index 086247672a53..5b205b7ad94f 100644 --- a/layout/forms/nsGfxButtonControlFrame.h +++ b/layout/forms/nsGfxButtonControlFrame.h @@ -6,6 +6,7 @@ #ifndef nsGfxButtonControlFrame_h___ #define nsGfxButtonControlFrame_h___ +#include "mozilla/Attributes.h" #include "nsFormControlFrame.h" #include "nsHTMLButtonControlFrame.h" #include "nsCOMPtr.h" @@ -28,16 +29,16 @@ public: nsGfxButtonControlFrame(nsStyleContext* aContext); - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; NS_IMETHOD HandleEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; virtual nsIAtom* GetType() const; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif NS_DECL_QUERYFRAME @@ -45,11 +46,11 @@ public: // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements); virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, - uint32_t aFilter); - virtual nsIFrame* CreateFrameFor(nsIContent* aContent); + uint32_t aFilter) MOZ_OVERRIDE; + virtual nsIFrame* CreateFrameFor(nsIContent* aContent) MOZ_OVERRIDE; // nsIFormControlFrame - virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const; + virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, @@ -58,7 +59,7 @@ public: virtual bool IsLeaf() const; - virtual nsIFrame* GetContentInsertionFrame(); + virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE; protected: nsresult GetDefaultLabel(nsXPIDLString& aLabel) const; @@ -67,7 +68,7 @@ protected: bool IsFileBrowseButton(int32_t type) const; // Browse button of file input - virtual bool IsInput() { return true; } + virtual bool IsInput() MOZ_OVERRIDE { return true; } private: nsCOMPtr mTextContent; }; diff --git a/layout/forms/nsGfxCheckboxControlFrame.h b/layout/forms/nsGfxCheckboxControlFrame.h index 2acf3a8a3e61..4ad53eda683b 100644 --- a/layout/forms/nsGfxCheckboxControlFrame.h +++ b/layout/forms/nsGfxCheckboxControlFrame.h @@ -5,6 +5,7 @@ #ifndef nsGfxCheckboxControlFrame_h___ #define nsGfxCheckboxControlFrame_h___ +#include "mozilla/Attributes.h" #include "nsFormControlFrame.h" #ifdef ACCESSIBILITY @@ -20,17 +21,17 @@ public: virtual ~nsGfxCheckboxControlFrame(); #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const { + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { return MakeFrameName(NS_LITERAL_STRING("CheckboxControl"), aResult); } #endif NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; #ifdef ACCESSIBILITY - virtual already_AddRefed CreateAccessible(); + virtual already_AddRefed CreateAccessible() MOZ_OVERRIDE; #endif protected: diff --git a/layout/forms/nsGfxRadioControlFrame.h b/layout/forms/nsGfxRadioControlFrame.h index 5cbe16f008b1..f7d56237571c 100644 --- a/layout/forms/nsGfxRadioControlFrame.h +++ b/layout/forms/nsGfxRadioControlFrame.h @@ -6,6 +6,7 @@ #ifndef nsGfxRadioControlFrame_h___ #define nsGfxRadioControlFrame_h___ +#include "mozilla/Attributes.h" #include "nsFormControlFrame.h" #ifdef ACCESSIBILITY @@ -28,7 +29,7 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; }; #endif diff --git a/layout/forms/nsHTMLButtonControlFrame.h b/layout/forms/nsHTMLButtonControlFrame.h index 53707a6cbeee..5b4c25f9a7b1 100644 --- a/layout/forms/nsHTMLButtonControlFrame.h +++ b/layout/forms/nsHTMLButtonControlFrame.h @@ -6,6 +6,7 @@ #ifndef nsHTMLButtonControlFrame_h___ #define nsHTMLButtonControlFrame_h___ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsContainerFrame.h" #include "nsIFormControlFrame.h" @@ -29,54 +30,54 @@ public: nsHTMLButtonControlFrame(nsStyleContext* aContext); ~nsHTMLButtonControlFrame(); - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; NS_DECL_QUERYFRAME NS_DECL_FRAMEARENA_HELPERS NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; - virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); + virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; - virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext); + virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; NS_IMETHOD HandleEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* asPrevInFlow); + nsIFrame* asPrevInFlow) MOZ_OVERRIDE; virtual nsStyleContext* GetAdditionalStyleContext(int32_t aIndex) const; virtual void SetAdditionalStyleContext(int32_t aIndex, - nsStyleContext* aStyleContext); + nsStyleContext* aStyleContext) MOZ_OVERRIDE; NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; #ifdef ACCESSIBILITY - virtual already_AddRefed CreateAccessible(); + virtual already_AddRefed CreateAccessible() MOZ_OVERRIDE; #endif - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const { + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { return MakeFrameName(NS_LITERAL_STRING("HTMLButtonControl"), aResult); } #endif @@ -85,8 +86,8 @@ public: // nsIFormControlFrame void SetFocus(bool aOn, bool aRepaint); - virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue); - virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const; + virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) MOZ_OVERRIDE; + virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const MOZ_OVERRIDE; // Inserted child content gets its frames parented by our child block virtual nsIFrame* GetContentInsertionFrame() { diff --git a/layout/forms/nsLegendFrame.h b/layout/forms/nsLegendFrame.h index f4fc309a136f..508793bb9f12 100644 --- a/layout/forms/nsLegendFrame.h +++ b/layout/forms/nsLegendFrame.h @@ -6,6 +6,7 @@ #ifndef nsLegendFrame_h___ #define nsLegendFrame_h___ +#include "mozilla/Attributes.h" #include "nsBlockFrame.h" class nsLegendFrame : public nsBlockFrame { @@ -19,14 +20,14 @@ public: NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif int32_t GetAlign(); diff --git a/layout/forms/nsListControlFrame.h b/layout/forms/nsListControlFrame.h index 9a47290b93d3..a74726b64639 100644 --- a/layout/forms/nsListControlFrame.h +++ b/layout/forms/nsListControlFrame.h @@ -16,6 +16,7 @@ //#define DO_PIXELS #endif +#include "mozilla/Attributes.h" #include "nsGfxScrollFrame.h" #include "nsIFormControlFrame.h" #include "nsIListControlFrame.h" @@ -53,15 +54,15 @@ public: nsEventStatus* aEventStatus); NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; - virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext); - virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); + virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; + virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aCX, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, @@ -70,7 +71,7 @@ public: NS_IMETHOD DidReflow(nsPresContext* aPresContext, const nsHTMLReflowState* aReflowState, nsDidReflowStatus aStatus); - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, @@ -83,7 +84,7 @@ public: * * @see nsGkAtoms::scrollFrame */ - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; virtual bool IsFrameOfType(uint32_t aFlags) const { @@ -93,74 +94,74 @@ public: virtual void InvalidateInternal(const nsRect& aDamageRect, nscoord aX, nscoord aY, nsIFrame* aForChild, - uint32_t aFlags); + uint32_t aFlags) MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif // nsIFormControlFrame - virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue); - virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const; + virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) MOZ_OVERRIDE; + virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const MOZ_OVERRIDE; virtual void SetFocus(bool aOn = true, bool aRepaint = false); - virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const; - virtual bool ShouldPropagateComputedHeightToScrolledContent() const; + virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const MOZ_OVERRIDE; + virtual bool ShouldPropagateComputedHeightToScrolledContent() const MOZ_OVERRIDE; // for accessibility purposes #ifdef ACCESSIBILITY - virtual already_AddRefed CreateAccessible(); + virtual already_AddRefed CreateAccessible() MOZ_OVERRIDE; #endif // nsContainerFrame - virtual int GetSkipSides() const; + virtual int GetSkipSides() const MOZ_OVERRIDE; // nsIListControlFrame virtual void SetComboboxFrame(nsIFrame* aComboboxFrame); - virtual int32_t GetSelectedIndex(); - virtual already_AddRefed GetCurrentOption(); + virtual int32_t GetSelectedIndex() MOZ_OVERRIDE; + virtual already_AddRefed GetCurrentOption() MOZ_OVERRIDE; /** * Gets the text of the currently selected item. * If the there are zero items then an empty string is returned * If there is nothing selected, then the 0th item's text is returned. */ - virtual void GetOptionText(int32_t aIndex, nsAString & aStr); + virtual void GetOptionText(int32_t aIndex, nsAString & aStr) MOZ_OVERRIDE; - virtual void CaptureMouseEvents(bool aGrabMouseEvents); - virtual nscoord GetHeightOfARow(); - virtual int32_t GetNumberOfOptions(); - virtual void AboutToDropDown(); + virtual void CaptureMouseEvents(bool aGrabMouseEvents) MOZ_OVERRIDE; + virtual nscoord GetHeightOfARow() MOZ_OVERRIDE; + virtual int32_t GetNumberOfOptions() MOZ_OVERRIDE; + virtual void AboutToDropDown() MOZ_OVERRIDE; /** * @note This method might destroy |this|. */ - virtual void AboutToRollup(); + virtual void AboutToRollup() MOZ_OVERRIDE; /** * Dispatch a DOM onchange event synchroniously. * @note This method might destroy |this|. */ - virtual void FireOnChange(); + virtual void FireOnChange() MOZ_OVERRIDE; /** * Makes aIndex the selected option of a combobox list. * @note This method might destroy |this|. */ - virtual void ComboboxFinish(int32_t aIndex); - virtual void OnContentReset(); + virtual void ComboboxFinish(int32_t aIndex) MOZ_OVERRIDE; + virtual void OnContentReset() MOZ_OVERRIDE; // nsISelectControlFrame NS_IMETHOD AddOption(int32_t index); - NS_IMETHOD RemoveOption(int32_t index); - NS_IMETHOD DoneAddingChildren(bool aIsDone); + NS_IMETHOD RemoveOption(int32_t index) MOZ_OVERRIDE; + NS_IMETHOD DoneAddingChildren(bool aIsDone) MOZ_OVERRIDE; /** * Gets the content (an option) by index and then set it as * being selected or not selected. */ - NS_IMETHOD OnOptionSelected(int32_t aIndex, bool aSelected); - NS_IMETHOD OnSetSelectedIndex(int32_t aOldIndex, int32_t aNewIndex); + NS_IMETHOD OnOptionSelected(int32_t aIndex, bool aSelected) MOZ_OVERRIDE; + NS_IMETHOD OnSetSelectedIndex(int32_t aOldIndex, int32_t aNewIndex) MOZ_OVERRIDE; // mouse event listeners (both ) nsresult MouseDown(nsIDOMEvent* aMouseEvent); // might destroy |this| diff --git a/layout/forms/nsMeterFrame.h b/layout/forms/nsMeterFrame.h index 7628c0ecd854..de3e7efbe7cd 100644 --- a/layout/forms/nsMeterFrame.h +++ b/layout/forms/nsMeterFrame.h @@ -6,6 +6,7 @@ #ifndef nsMeterFrame_h___ #define nsMeterFrame_h___ +#include "mozilla/Attributes.h" #include "nsContainerFrame.h" #include "nsIAnonymousContentCreator.h" #include "nsCOMPtr.h" @@ -22,7 +23,7 @@ public: nsMeterFrame(nsStyleContext* aContext); virtual ~nsMeterFrame(); - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aCX, nsHTMLReflowMetrics& aDesiredSize, @@ -35,12 +36,12 @@ public: } #endif - virtual bool IsLeaf() const { return true; } + virtual bool IsLeaf() const MOZ_OVERRIDE { return true; } // nsIAnonymousContentCreator - virtual nsresult CreateAnonymousContent(nsTArray& aElements); + virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, - uint32_t aFilter); + uint32_t aFilter) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, @@ -49,7 +50,7 @@ public: virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext, nsSize aCBSize, nscoord aAvailableWidth, nsSize aMargin, nsSize aBorder, - nsSize aPadding, bool aShrinkWrap); + nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE; virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext); diff --git a/layout/forms/nsProgressFrame.h b/layout/forms/nsProgressFrame.h index 0c8c12580c49..503cd5e73196 100644 --- a/layout/forms/nsProgressFrame.h +++ b/layout/forms/nsProgressFrame.h @@ -6,6 +6,7 @@ #ifndef nsProgressFrame_h___ #define nsProgressFrame_h___ +#include "mozilla/Attributes.h" #include "nsContainerFrame.h" #include "nsIAnonymousContentCreator.h" #include "nsCOMPtr.h" @@ -23,11 +24,11 @@ public: nsProgressFrame(nsStyleContext* aContext); virtual ~nsProgressFrame(); - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aCX, nsHTMLReflowMetrics& aDesiredSize, @@ -40,12 +41,12 @@ public: } #endif - virtual bool IsLeaf() const { return true; } + virtual bool IsLeaf() const MOZ_OVERRIDE { return true; } // nsIAnonymousContentCreator - virtual nsresult CreateAnonymousContent(nsTArray& aElements); + virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, - uint32_t aFilter); + uint32_t aFilter) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, @@ -54,7 +55,7 @@ public: virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext, nsSize aCBSize, nscoord aAvailableWidth, nsSize aMargin, nsSize aBorder, - nsSize aPadding, bool aShrinkWrap); + nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE; virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext); diff --git a/layout/forms/nsSelectsAreaFrame.h b/layout/forms/nsSelectsAreaFrame.h index 3fdd256a2142..c660de171425 100644 --- a/layout/forms/nsSelectsAreaFrame.h +++ b/layout/forms/nsSelectsAreaFrame.h @@ -5,6 +5,7 @@ #ifndef nsSelectsAreaFrame_h___ #define nsSelectsAreaFrame_h___ +#include "mozilla/Attributes.h" #include "nsBlockFrame.h" class nsSelectsAreaFrame : public nsBlockFrame @@ -16,7 +17,7 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; nsresult BuildDisplayListInternal(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, @@ -25,7 +26,7 @@ public: NS_IMETHOD Reflow(nsPresContext* aCX, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; nscoord HeightOfARow() const { return mHeightOfARow; } diff --git a/layout/forms/nsTextControlFrame.h b/layout/forms/nsTextControlFrame.h index e6814de6ad22..e6d1a08ff1d5 100644 --- a/layout/forms/nsTextControlFrame.h +++ b/layout/forms/nsTextControlFrame.h @@ -6,6 +6,7 @@ #ifndef nsTextControlFrame_h___ #define nsTextControlFrame_h___ +#include "mozilla/Attributes.h" #include "nsContainerFrame.h" #include "nsBlockFrame.h" #include "nsIFormControlFrame.h" @@ -45,7 +46,7 @@ public: nsTextControlFrame(nsIPresShell* aShell, nsStyleContext* aContext); virtual ~nsTextControlFrame(); - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; virtual nsIScrollableFrame* GetScrollTargetFrame() { if (!IsScrollable()) @@ -59,7 +60,7 @@ public: virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext, nsSize aCBSize, nscoord aAvailableWidth, nsSize aMargin, nsSize aBorder, - nsSize aPadding, bool aShrinkWrap); + nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, @@ -94,14 +95,14 @@ public: } // nsIAnonymousContentCreator - virtual nsresult CreateAnonymousContent(nsTArray& aElements); + virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, - uint32_t aFilter); + uint32_t aFilter) MOZ_OVERRIDE; // Utility methods to set current widget state NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; //==== BEGIN NSIFORMCONTROLFRAME virtual void SetFocus(bool aOn , bool aRepaint); @@ -113,34 +114,34 @@ public: //==== NSITEXTCONTROLFRAME - NS_IMETHOD GetEditor(nsIEditor **aEditor); - NS_IMETHOD GetTextLength(int32_t* aTextLength); - NS_IMETHOD SetSelectionStart(int32_t aSelectionStart); - NS_IMETHOD SetSelectionEnd(int32_t aSelectionEnd); + NS_IMETHOD GetEditor(nsIEditor **aEditor) MOZ_OVERRIDE; + NS_IMETHOD GetTextLength(int32_t* aTextLength) MOZ_OVERRIDE; + NS_IMETHOD SetSelectionStart(int32_t aSelectionStart) MOZ_OVERRIDE; + NS_IMETHOD SetSelectionEnd(int32_t aSelectionEnd) MOZ_OVERRIDE; NS_IMETHOD SetSelectionRange(int32_t aSelectionStart, int32_t aSelectionEnd, - SelectionDirection aDirection = eNone); + SelectionDirection aDirection = eNone) MOZ_OVERRIDE; NS_IMETHOD GetSelectionRange(int32_t* aSelectionStart, int32_t* aSelectionEnd, - SelectionDirection* aDirection = nullptr); - NS_IMETHOD GetOwnedSelectionController(nsISelectionController** aSelCon); - virtual nsFrameSelection* GetOwnedFrameSelection(); + SelectionDirection* aDirection = nullptr) MOZ_OVERRIDE; + NS_IMETHOD GetOwnedSelectionController(nsISelectionController** aSelCon) MOZ_OVERRIDE; + virtual nsFrameSelection* GetOwnedFrameSelection() MOZ_OVERRIDE; - nsresult GetPhonetic(nsAString& aPhonetic); + nsresult GetPhonetic(nsAString& aPhonetic) MOZ_OVERRIDE; /** * Ensure mEditor is initialized with the proper flags and the default value. * @throws NS_ERROR_NOT_INITIALIZED if mEditor has not been created * @throws various and sundry other things */ - virtual nsresult EnsureEditorInitialized(); + virtual nsresult EnsureEditorInitialized() MOZ_OVERRIDE; //==== END NSITEXTCONTROLFRAME //==== NSISTATEFULFRAME - NS_IMETHOD SaveState(SpecialStateID aStateID, nsPresState** aState); - NS_IMETHOD RestoreState(nsPresState* aState); + NS_IMETHOD SaveState(SpecialStateID aStateID, nsPresState** aState) MOZ_OVERRIDE; + NS_IMETHOD RestoreState(nsPresState* aState) MOZ_OVERRIDE; //=== END NSISTATEFULFRAME @@ -343,7 +344,7 @@ protected: nsSize& aIntrinsicSize, float aFontSizeInflation); - nsresult ScrollSelectionIntoView(); + nsresult ScrollSelectionIntoView() MOZ_OVERRIDE; private: //helper methods diff --git a/layout/generic/nsBulletFrame.h b/layout/generic/nsBulletFrame.h index b97905deb159..96df3cceffdc 100644 --- a/layout/generic/nsBulletFrame.h +++ b/layout/generic/nsBulletFrame.h @@ -8,6 +8,7 @@ #ifndef nsBulletFrame_h___ #define nsBulletFrame_h___ +#include "mozilla/Attributes.h" #include "nsFrame.h" #include "nsStyleContext.h" @@ -65,19 +66,19 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists); - virtual nsIAtom* GetType() const; - virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext); + virtual nsIAtom* GetType() const MOZ_OVERRIDE; + virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif // nsIHTMLReflow NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aMetrics, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); - virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); - virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext); + nsReflowStatus& aStatus) MOZ_OVERRIDE; + virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; + virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; // nsBulletFrame int32_t SetListItemOrdinal(int32_t aNextOrdinal, bool* aChanged, @@ -108,8 +109,8 @@ public: void PaintBullet(nsRenderingContext& aRenderingContext, nsPoint aPt, const nsRect& aDirtyRect); - virtual bool IsEmpty(); - virtual bool IsSelfEmpty(); + virtual bool IsEmpty() MOZ_OVERRIDE; + virtual bool IsSelfEmpty() MOZ_OVERRIDE; virtual nscoord GetBaseline() const; float GetFontSizeInflation() const; diff --git a/layout/generic/nsCanvasFrame.h b/layout/generic/nsCanvasFrame.h index e8c77933a95d..f39550d9446e 100644 --- a/layout/generic/nsCanvasFrame.h +++ b/layout/generic/nsCanvasFrame.h @@ -8,6 +8,7 @@ #ifndef nsCanvasFrame_h___ #define nsCanvasFrame_h___ +#include "mozilla/Attributes.h" #include "nsContainerFrame.h" #include "nsIScrollPositionListener.h" #include "nsDisplayList.h" @@ -41,21 +42,21 @@ public: virtual void DestroyFrom(nsIFrame* aDestructRoot); NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; - virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); - virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext); + virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; + virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; virtual bool IsFrameOfType(uint32_t aFlags) const { return nsContainerFrame::IsFrameOfType(aFlags & @@ -69,7 +70,7 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; void PaintFocus(nsRenderingContext& aRenderingContext, nsPoint aPt); @@ -82,11 +83,11 @@ public: * * @see nsGkAtoms::canvasFrame */ - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; virtual nsresult StealFrame(nsPresContext* aPresContext, nsIFrame* aChild, - bool aForceNormal) + bool aForceNormal) MOZ_OVERRIDE { NS_ASSERTION(!aForceNormal, "No-one should be passing this in here"); @@ -100,10 +101,10 @@ public: } #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif NS_IMETHOD GetContentForEvent(nsEvent* aEvent, - nsIContent** aContent); + nsIContent** aContent) MOZ_OVERRIDE; nsRect CanvasArea() const; @@ -131,21 +132,21 @@ public: virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion) + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE { return NS_GET_A(mExtraBackgroundColor) > 0 || nsDisplayBackground::ComputeVisibility(aBuilder, aVisibleRegion, aAllowVisibleRegionExpansion); } virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aSnap) + bool* aSnap) MOZ_OVERRIDE { if (NS_GET_A(mExtraBackgroundColor) == 255) { return nsRegion(GetBounds(aBuilder, aSnap)); } return nsDisplayBackground::GetOpaqueRegion(aBuilder, aSnap); } - virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) + virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE { nscolor background; if (!nsDisplayBackground::IsUniform(aBuilder, &background)) @@ -156,21 +157,21 @@ public: *aColor = mExtraBackgroundColor; return true; } - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE { nsCanvasFrame* frame = static_cast(mFrame); *aSnap = true; return frame->CanvasArea() + ToReferenceFrame(); } virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, - HitTestState* aState, nsTArray *aOutFrames) + HitTestState* aState, nsTArray *aOutFrames) MOZ_OVERRIDE { // We need to override so we don't consider border-radius. aOutFrames->AppendElement(mFrame); } virtual void Paint(nsDisplayListBuilder* aBuilder, - nsRenderingContext* aCtx); + nsRenderingContext* aCtx) MOZ_OVERRIDE; void SetExtraBackgroundColor(nscolor aColor) { diff --git a/layout/generic/nsContainerFrame.h b/layout/generic/nsContainerFrame.h index ce9d4264e29a..765ffb4e6020 100644 --- a/layout/generic/nsContainerFrame.h +++ b/layout/generic/nsContainerFrame.h @@ -8,6 +8,7 @@ #ifndef nsContainerFrame_h___ #define nsContainerFrame_h___ +#include "mozilla/Attributes.h" #include "nsSplittableFrame.h" #include "nsFrameList.h" #include "nsLayoutUtils.h" @@ -53,27 +54,27 @@ public: nsIFrame* aParent, nsIFrame* aPrevInFlow); NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; NS_IMETHOD AppendFrames(ChildListID aListID, nsFrameList& aFrameList); NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, nsFrameList& aFrameList); NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; - virtual const nsFrameList& GetChildList(ChildListID aList) const; - virtual void GetChildLists(nsTArray* aLists) const; - virtual void DestroyFrom(nsIFrame* aDestructRoot); - virtual void ChildIsDirty(nsIFrame* aChild); + virtual const nsFrameList& GetChildList(ChildListID aList) const MOZ_OVERRIDE; + virtual void GetChildLists(nsTArray* aLists) const MOZ_OVERRIDE; + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + virtual void ChildIsDirty(nsIFrame* aChild) MOZ_OVERRIDE; virtual bool IsLeaf() const; - virtual bool PeekOffsetNoAmount(bool aForward, int32_t* aOffset); + virtual bool PeekOffsetNoAmount(bool aForward, int32_t* aOffset) MOZ_OVERRIDE; virtual bool PeekOffsetCharacter(bool aForward, int32_t* aOffset, - bool aRespectClusters = true); + bool aRespectClusters = true) MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD List(FILE* out, int32_t aIndent) const; + NS_IMETHOD List(FILE* out, int32_t aIndent) const MOZ_OVERRIDE; #endif // nsContainerFrame methods @@ -182,7 +183,7 @@ public: virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext, nsSize aCBSize, nscoord aAvailableWidth, nsSize aMargin, nsSize aBorder, - nsSize aPadding, bool aShrinkWrap); + nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE; /** * Invokes the WillReflow() function, positions the frame and its view (if diff --git a/layout/generic/nsFirstLetterFrame.h b/layout/generic/nsFirstLetterFrame.h index 22dc513804a2..3d3601c8499a 100644 --- a/layout/generic/nsFirstLetterFrame.h +++ b/layout/generic/nsFirstLetterFrame.h @@ -8,6 +8,7 @@ /* rendering object for CSS :first-letter pseudo-element */ +#include "mozilla/Attributes.h" #include "nsContainerFrame.h" class nsFirstLetterFrame : public nsContainerFrame { @@ -20,17 +21,17 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* aPrevInFlow); + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; bool IsFloating() const { return GetStateBits() & NS_FRAME_OUT_OF_FLOW; } @@ -42,12 +43,12 @@ public: ~(nsIFrame::eBidiInlineContainer)); } - virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); - virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext); + virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; + virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext, - InlineMinWidthData *aData); + InlineMinWidthData *aData) MOZ_OVERRIDE; virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext, - InlinePrefWidthData *aData); + InlinePrefWidthData *aData) MOZ_OVERRIDE; virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext, nsSize aCBSize, nscoord aAvailableWidth, nsSize aMargin, nsSize aBorder, nsSize aPadding, @@ -55,16 +56,16 @@ public: NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; - virtual bool CanContinueTextRun() const; + virtual bool CanContinueTextRun() const MOZ_OVERRIDE; virtual nscoord GetBaseline() const; //override of nsFrame method NS_IMETHOD GetChildFrameContainingOffset(int32_t inContentOffset, bool inHint, int32_t* outFrameContentOffset, - nsIFrame **outChildFrame); + nsIFrame **outChildFrame) MOZ_OVERRIDE; nscoord GetFirstLetterBaseline() const { return mBaseline; } diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index ea068d1bf4b8..81439468532f 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -5632,13 +5632,13 @@ NS_IMETHODIMP nsFrame::DumpRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent) { IndentBy(out, aIndent); - fprintf(out, "\n", - (unsigned long long)GetDebugStateBits(), PRUptrdiff(mParent)); + fprintf(out, "\" state=\"%016llx\" parent=\"%p\">\n", + (unsigned long long)GetDebugStateBits(), (void*)mParent); aIndent++; DumpBaseRegressionData(aPresContext, out, aIndent); @@ -5655,12 +5655,12 @@ nsFrame::DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t { if (GetNextSibling()) { IndentBy(out, aIndent); - fprintf(out, "\n", PRUptrdiff(GetNextSibling())); + fprintf(out, "\n", (void*)GetNextSibling()); } if (HasView()) { IndentBy(out, aIndent); - fprintf(out, "\n", PRUptrdiff(GetView())); + fprintf(out, "\n", (void*)GetView()); aIndent++; // XXX add in code to dump out view state too... aIndent--; diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index 001f6e990ba5..6be9bbbbbeeb 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -8,6 +8,7 @@ #ifndef nsFrame_h___ #define nsFrame_h___ +#include "mozilla/Attributes.h" #include "nsBox.h" #include "nsRect.h" #include "nsString.h" @@ -379,13 +380,13 @@ public: // Box layout methods virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState); virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState); - virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState); + virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState); - virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState); + virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; // We compute and store the HTML content's overflow area. So don't // try to compute it in the box code. - virtual bool ComputesOwnOverflowArea() { return true; } + virtual bool ComputesOwnOverflowArea() MOZ_OVERRIDE { return true; } //-------------------------------------------------- // Additional methods @@ -636,10 +637,10 @@ protected: // Fills aCursor with the appropriate information from ui static void FillCursorInformationFromStyle(const nsStyleUserInterface* ui, nsIFrame::Cursor& aCursor); - NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState); + NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; #ifdef DEBUG_LAYOUT - virtual void GetBoxName(nsAutoString& aName); + virtual void GetBoxName(nsAutoString& aName) MOZ_OVERRIDE; #endif void InitBoxMetrics(bool aClear); diff --git a/layout/generic/nsFrameSetFrame.h b/layout/generic/nsFrameSetFrame.h index f791f7f6ddef..5b5ebb369396 100644 --- a/layout/generic/nsFrameSetFrame.h +++ b/layout/generic/nsFrameSetFrame.h @@ -8,6 +8,7 @@ #ifndef nsHTMLFrameset_h___ #define nsHTMLFrameset_h___ +#include "mozilla/Attributes.h" #include "nsGkAtoms.h" #include "nsContainerFrame.h" #include "nsColor.h" @@ -79,7 +80,7 @@ public: NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* aPrevInFlow); + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; NS_IMETHOD SetInitialChildList(ChildListID aListID, nsFrameList& aChildList); @@ -96,26 +97,26 @@ public: NS_IMETHOD HandleEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; NS_IMETHOD GetCursor(const nsPoint& aPoint, - nsIFrame::Cursor& aCursor); + nsIFrame::Cursor& aCursor) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif - virtual bool IsLeaf() const; + virtual bool IsLeaf() const MOZ_OVERRIDE; void StartMouseDrag(nsPresContext* aPresContext, nsHTMLFramesetBorderFrame* aBorder, diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index 27de7a3d1dcf..7cd1fa854d37 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -8,6 +8,7 @@ #ifndef nsGfxScrollFrame_h___ #define nsGfxScrollFrame_h___ +#include "mozilla/Attributes.h" #include "nsContainerFrame.h" #include "nsIAnonymousContentCreator.h" #include "nsBoxFrame.h" @@ -79,8 +80,8 @@ public: bool GetBorderRadii(nscoord aRadii[8]) const; // nsIReflowCallback - virtual bool ReflowFinished(); - virtual void ReflowCallbackCanceled(); + virtual bool ReflowFinished() MOZ_OVERRIDE; + virtual void ReflowCallbackCanceled() MOZ_OVERRIDE; // This gets called when the 'curpos' attribute on one of the scrollbars changes void CurPosAttributeChanged(nsIContent* aChild); @@ -357,7 +358,7 @@ public: // Called to set the child frames. We typically have three: the scroll area, // the vertical scrollbar, and the horizontal scrollbar. NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, @@ -398,16 +399,16 @@ public: // Because there can be only one child frame, these two function return // NS_ERROR_FAILURE NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; virtual nsIScrollableFrame* GetScrollTargetFrame() { return this; @@ -431,9 +432,9 @@ public: } // nsIAnonymousContentCreator - virtual nsresult CreateAnonymousContent(nsTArray& aElements); + virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, - uint32_t aFilter); + uint32_t aFilter) MOZ_OVERRIDE; // nsIScrollableFrame virtual nsIFrame* GetScrolledFrame() const { @@ -442,72 +443,72 @@ public: virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const { return mInner.GetScrollbarStylesFromFrame(); } - virtual uint32_t GetScrollbarVisibility() const { + virtual uint32_t GetScrollbarVisibility() const MOZ_OVERRIDE { return mInner.GetScrollbarVisibility(); } - virtual nsMargin GetActualScrollbarSizes() const { + virtual nsMargin GetActualScrollbarSizes() const MOZ_OVERRIDE { return mInner.GetActualScrollbarSizes(); } - virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) { + virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) MOZ_OVERRIDE { return mInner.GetDesiredScrollbarSizes(aState); } virtual nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext, - nsRenderingContext* aRC) { + nsRenderingContext* aRC) MOZ_OVERRIDE { nsBoxLayoutState bls(aPresContext, aRC, 0); return GetDesiredScrollbarSizes(&bls); } - virtual nsRect GetScrollPortRect() const { + virtual nsRect GetScrollPortRect() const MOZ_OVERRIDE { return mInner.GetScrollPortRect(); } - virtual nsPoint GetScrollPosition() const { + virtual nsPoint GetScrollPosition() const MOZ_OVERRIDE { return mInner.GetScrollPosition(); } - virtual nsRect GetScrollRange() const { + virtual nsRect GetScrollRange() const MOZ_OVERRIDE { return mInner.GetScrollRange(); } - virtual nsSize GetScrollPositionClampingScrollPortSize() const { + virtual nsSize GetScrollPositionClampingScrollPortSize() const MOZ_OVERRIDE { return mInner.GetScrollPositionClampingScrollPortSize(); } - virtual nsSize GetLineScrollAmount() const { + virtual nsSize GetLineScrollAmount() const MOZ_OVERRIDE { return mInner.GetLineScrollAmount(); } - virtual nsSize GetPageScrollAmount() const { + virtual nsSize GetPageScrollAmount() const MOZ_OVERRIDE { return mInner.GetPageScrollAmount(); } virtual void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode, - const nsRect* aRange = nullptr) { + const nsRect* aRange = nullptr) MOZ_OVERRIDE { mInner.ScrollTo(aScrollPosition, aMode, aRange); } - virtual void ScrollToCSSPixels(nsIntPoint aScrollPosition) { + virtual void ScrollToCSSPixels(nsIntPoint aScrollPosition) MOZ_OVERRIDE { mInner.ScrollToCSSPixels(aScrollPosition); } - virtual nsIntPoint GetScrollPositionCSSPixels() { + virtual nsIntPoint GetScrollPositionCSSPixels() MOZ_OVERRIDE { return mInner.GetScrollPositionCSSPixels(); } virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode, - nsIntPoint* aOverflow, nsIAtom *aOrigin = nullptr) { + nsIntPoint* aOverflow, nsIAtom *aOrigin = nullptr) MOZ_OVERRIDE { mInner.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin); } - virtual void ScrollToRestoredPosition() { + virtual void ScrollToRestoredPosition() MOZ_OVERRIDE { mInner.ScrollToRestoredPosition(); } - virtual void AddScrollPositionListener(nsIScrollPositionListener* aListener) { + virtual void AddScrollPositionListener(nsIScrollPositionListener* aListener) MOZ_OVERRIDE { mInner.AddScrollPositionListener(aListener); } - virtual void RemoveScrollPositionListener(nsIScrollPositionListener* aListener) { + virtual void RemoveScrollPositionListener(nsIScrollPositionListener* aListener) MOZ_OVERRIDE { mInner.RemoveScrollPositionListener(aListener); } - virtual nsIFrame* GetScrollbarBox(bool aVertical) { + virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE { return mInner.GetScrollbarBox(aVertical); } - virtual void CurPosAttributeChanged(nsIContent* aChild) { + virtual void CurPosAttributeChanged(nsIContent* aChild) MOZ_OVERRIDE { mInner.CurPosAttributeChanged(aChild); } - NS_IMETHOD PostScrolledAreaEventForCurrentArea() { + NS_IMETHOD PostScrolledAreaEventForCurrentArea() MOZ_OVERRIDE { mInner.PostScrolledAreaEvent(); return NS_OK; } - virtual bool IsScrollingActive() { + virtual bool IsScrollingActive() MOZ_OVERRIDE { return mInner.IsScrollingActive(); } virtual bool UpdateOverflow() { @@ -515,12 +516,12 @@ public: } // nsIStatefulFrame - NS_IMETHOD SaveState(SpecialStateID aStateID, nsPresState** aState) { + NS_IMETHOD SaveState(SpecialStateID aStateID, nsPresState** aState) MOZ_OVERRIDE { NS_ENSURE_ARG_POINTER(aState); *aState = mInner.SaveState(aStateID); return NS_OK; } - NS_IMETHOD RestoreState(nsPresState* aState) { + NS_IMETHOD RestoreState(nsPresState* aState) MOZ_OVERRIDE { NS_ENSURE_ARG_POINTER(aState); mInner.RestoreState(aState); return NS_OK; @@ -599,33 +600,33 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) { + const nsDisplayListSet& aLists) MOZ_OVERRIDE { return mInner.BuildDisplayList(aBuilder, aDirtyRect, aLists); } // XXXldb Is this actually used? #if 0 - virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); + virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; #endif // Because there can be only one child frame, these two function return // NS_ERROR_FAILURE NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; virtual nsIScrollableFrame* GetScrollTargetFrame() { return this; } - virtual nsIFrame* GetContentInsertionFrame() { + virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE { return mInner.GetScrolledFrame()->GetContentInsertionFrame(); } @@ -644,9 +645,9 @@ public: } // nsIAnonymousContentCreator - virtual nsresult CreateAnonymousContent(nsTArray& aElements); + virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, - uint32_t aFilter); + uint32_t aFilter) MOZ_OVERRIDE; virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState); virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState); @@ -690,72 +691,72 @@ public: virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const { return mInner.GetScrollbarStylesFromFrame(); } - virtual uint32_t GetScrollbarVisibility() const { + virtual uint32_t GetScrollbarVisibility() const MOZ_OVERRIDE { return mInner.GetScrollbarVisibility(); } - virtual nsMargin GetActualScrollbarSizes() const { + virtual nsMargin GetActualScrollbarSizes() const MOZ_OVERRIDE { return mInner.GetActualScrollbarSizes(); } - virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) { + virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) MOZ_OVERRIDE { return mInner.GetDesiredScrollbarSizes(aState); } virtual nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext, - nsRenderingContext* aRC) { + nsRenderingContext* aRC) MOZ_OVERRIDE { nsBoxLayoutState bls(aPresContext, aRC, 0); return GetDesiredScrollbarSizes(&bls); } - virtual nsRect GetScrollPortRect() const { + virtual nsRect GetScrollPortRect() const MOZ_OVERRIDE { return mInner.GetScrollPortRect(); } - virtual nsPoint GetScrollPosition() const { + virtual nsPoint GetScrollPosition() const MOZ_OVERRIDE { return mInner.GetScrollPosition(); } - virtual nsRect GetScrollRange() const { + virtual nsRect GetScrollRange() const MOZ_OVERRIDE { return mInner.GetScrollRange(); } - virtual nsSize GetScrollPositionClampingScrollPortSize() const { + virtual nsSize GetScrollPositionClampingScrollPortSize() const MOZ_OVERRIDE { return mInner.GetScrollPositionClampingScrollPortSize(); } - virtual nsSize GetLineScrollAmount() const { + virtual nsSize GetLineScrollAmount() const MOZ_OVERRIDE { return mInner.GetLineScrollAmount(); } - virtual nsSize GetPageScrollAmount() const { + virtual nsSize GetPageScrollAmount() const MOZ_OVERRIDE { return mInner.GetPageScrollAmount(); } virtual void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode, - const nsRect* aRange = nullptr) { + const nsRect* aRange = nullptr) MOZ_OVERRIDE { mInner.ScrollTo(aScrollPosition, aMode, aRange); } - virtual void ScrollToCSSPixels(nsIntPoint aScrollPosition) { + virtual void ScrollToCSSPixels(nsIntPoint aScrollPosition) MOZ_OVERRIDE { mInner.ScrollToCSSPixels(aScrollPosition); } - virtual nsIntPoint GetScrollPositionCSSPixels() { + virtual nsIntPoint GetScrollPositionCSSPixels() MOZ_OVERRIDE { return mInner.GetScrollPositionCSSPixels(); } virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode, - nsIntPoint* aOverflow, nsIAtom *aOrigin = nullptr) { + nsIntPoint* aOverflow, nsIAtom *aOrigin = nullptr) MOZ_OVERRIDE { mInner.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin); } - virtual void ScrollToRestoredPosition() { + virtual void ScrollToRestoredPosition() MOZ_OVERRIDE { mInner.ScrollToRestoredPosition(); } - virtual void AddScrollPositionListener(nsIScrollPositionListener* aListener) { + virtual void AddScrollPositionListener(nsIScrollPositionListener* aListener) MOZ_OVERRIDE { mInner.AddScrollPositionListener(aListener); } - virtual void RemoveScrollPositionListener(nsIScrollPositionListener* aListener) { + virtual void RemoveScrollPositionListener(nsIScrollPositionListener* aListener) MOZ_OVERRIDE { mInner.RemoveScrollPositionListener(aListener); } - virtual nsIFrame* GetScrollbarBox(bool aVertical) { + virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE { return mInner.GetScrollbarBox(aVertical); } - virtual void CurPosAttributeChanged(nsIContent* aChild) { + virtual void CurPosAttributeChanged(nsIContent* aChild) MOZ_OVERRIDE { mInner.CurPosAttributeChanged(aChild); } - NS_IMETHOD PostScrolledAreaEventForCurrentArea() { + NS_IMETHOD PostScrolledAreaEventForCurrentArea() MOZ_OVERRIDE { mInner.PostScrolledAreaEvent(); return NS_OK; } - virtual bool IsScrollingActive() { + virtual bool IsScrollingActive() MOZ_OVERRIDE { return mInner.IsScrollingActive(); } virtual bool UpdateOverflow() { @@ -763,12 +764,12 @@ public: } // nsIStatefulFrame - NS_IMETHOD SaveState(SpecialStateID aStateID, nsPresState** aState) { + NS_IMETHOD SaveState(SpecialStateID aStateID, nsPresState** aState) MOZ_OVERRIDE { NS_ENSURE_ARG_POINTER(aState); *aState = mInner.SaveState(aStateID); return NS_OK; } - NS_IMETHOD RestoreState(nsPresState* aState) { + NS_IMETHOD RestoreState(nsPresState* aState) MOZ_OVERRIDE { NS_ENSURE_ARG_POINTER(aState); mInner.RestoreState(aState); return NS_OK; @@ -779,9 +780,9 @@ public: * * @see nsGkAtoms::scrollFrame */ - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; - virtual bool IsFrameOfType(uint32_t aFlags) const + virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE { // Override bogus IsFrameOfType in nsBoxFrame. if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced)) @@ -790,7 +791,7 @@ public: } #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif protected: diff --git a/layout/generic/nsHTMLCanvasFrame.h b/layout/generic/nsHTMLCanvasFrame.h index 3b401dc6526f..862aa05e60ac 100644 --- a/layout/generic/nsHTMLCanvasFrame.h +++ b/layout/generic/nsHTMLCanvasFrame.h @@ -8,6 +8,7 @@ #ifndef nsHTMLCanvasFrame_h___ #define nsHTMLCanvasFrame_h___ +#include "mozilla/Attributes.h" #include "nsContainerFrame.h" #include "nsString.h" #include "nsAString.h" @@ -37,11 +38,11 @@ public: NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* aPrevInFlow); + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; already_AddRefed BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, @@ -50,9 +51,9 @@ public: /* get the size of the canvas's image */ nsIntSize GetCanvasSize(); - virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); - virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext); - virtual nsSize GetIntrinsicRatio(); + virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; + virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; + virtual nsSize GetIntrinsicRatio() MOZ_OVERRIDE; virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext, nsSize aCBSize, nscoord aAvailableWidth, @@ -62,15 +63,15 @@ public: NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; nsRect GetInnerArea() const; #ifdef ACCESSIBILITY - virtual already_AddRefed CreateAccessible(); + virtual already_AddRefed CreateAccessible() MOZ_OVERRIDE; #endif - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; virtual bool IsFrameOfType(uint32_t aFlags) const { @@ -78,7 +79,7 @@ public: } #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif // Inserted child content gets its frames parented by our child block diff --git a/layout/generic/nsImageFrame.h b/layout/generic/nsImageFrame.h index 835bd39c9d27..7e56cc8a723f 100644 --- a/layout/generic/nsImageFrame.h +++ b/layout/generic/nsImageFrame.h @@ -377,7 +377,7 @@ public: MOZ_COUNT_DTOR(nsDisplayImage); } virtual void Paint(nsDisplayListBuilder* aBuilder, - nsRenderingContext* aCtx); + nsRenderingContext* aCtx) MOZ_OVERRIDE; /** * Returns an ImageContainer for this image if the image type @@ -389,11 +389,11 @@ public: virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aParameters); + const ContainerParameters& aParameters) MOZ_OVERRIDE; virtual already_AddRefed BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aContainerParameters); + const ContainerParameters& aContainerParameters) MOZ_OVERRIDE; /** * Configure an ImageLayer for this display item. diff --git a/layout/generic/nsInlineFrame.h b/layout/generic/nsInlineFrame.h index 24bdf8650758..62133a96feb8 100644 --- a/layout/generic/nsInlineFrame.h +++ b/layout/generic/nsInlineFrame.h @@ -8,6 +8,7 @@ #ifndef nsInlineFrame_h___ #define nsInlineFrame_h___ +#include "mozilla/Attributes.h" #include "nsContainerFrame.h" #include "nsLineLayout.h" @@ -47,14 +48,14 @@ public: // nsIFrame overrides NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; #ifdef ACCESSIBILITY - virtual already_AddRefed CreateAccessible(); + virtual already_AddRefed CreateAccessible() MOZ_OVERRIDE; #endif #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif virtual nsIAtom* GetType() const; @@ -64,19 +65,19 @@ public: ~(nsIFrame::eBidiInlineContainer | nsIFrame::eLineParticipant)); } - virtual bool IsEmpty(); - virtual bool IsSelfEmpty(); + virtual bool IsEmpty() MOZ_OVERRIDE; + virtual bool IsSelfEmpty() MOZ_OVERRIDE; - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; virtual bool PeekOffsetCharacter(bool aForward, int32_t* aOffset, - bool aRespectClusters = true); + bool aRespectClusters = true) MOZ_OVERRIDE; // nsIHTMLReflow overrides virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext, - InlineMinWidthData *aData); + InlineMinWidthData *aData) MOZ_OVERRIDE; virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext, - InlinePrefWidthData *aData); + InlinePrefWidthData *aData) MOZ_OVERRIDE; virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext, nsSize aCBSize, nscoord aAvailableWidth, nsSize aMargin, nsSize aBorder, nsSize aPadding, @@ -85,9 +86,9 @@ public: NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; - virtual bool CanContinueTextRun() const; + virtual bool CanContinueTextRun() const MOZ_OVERRIDE; virtual void PullOverflowsFromPrevInFlow(); virtual nscoord GetBaseline() const; @@ -185,20 +186,20 @@ public: #ifdef DEBUG NS_IMETHOD GetFrameName(nsAString& aResult) const; #endif - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; - virtual void PullOverflowsFromPrevInFlow(); + virtual void PullOverflowsFromPrevInFlow() MOZ_OVERRIDE; protected: nsFirstLineFrame(nsStyleContext* aContext) : nsInlineFrame(aContext) {} virtual nsIFrame* PullOneFrame(nsPresContext* aPresContext, InlineReflowState& rs, - bool* aIsComplete); + bool* aIsComplete) MOZ_OVERRIDE; }; #endif /* nsInlineFrame_h___ */ diff --git a/layout/generic/nsLeafFrame.h b/layout/generic/nsLeafFrame.h index c1f31273dafc..c1cf5d5786bb 100644 --- a/layout/generic/nsLeafFrame.h +++ b/layout/generic/nsLeafFrame.h @@ -8,6 +8,7 @@ #ifndef nsLeafFrame_h___ #define nsLeafFrame_h___ +#include "mozilla/Attributes.h" #include "nsFrame.h" #include "nsDisplayList.h" @@ -53,7 +54,7 @@ public: NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; /** * This method does most of the work that Reflow() above need done. diff --git a/layout/generic/nsObjectFrame.h b/layout/generic/nsObjectFrame.h index f0cdd4917b92..68f6280d6361 100644 --- a/layout/generic/nsObjectFrame.h +++ b/layout/generic/nsObjectFrame.h @@ -8,6 +8,7 @@ #ifndef nsObjectFrame_h___ #define nsObjectFrame_h___ +#include "mozilla/Attributes.h" #include "nsPluginInstanceOwner.h" #include "nsIObjectFrame.h" #include "nsFrame.h" @@ -96,7 +97,7 @@ public: NS_METHOD GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance); - virtual void SetIsDocumentActive(bool aIsActive); + virtual void SetIsDocumentActive(bool aIsActive) MOZ_OVERRIDE; NS_IMETHOD GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor); @@ -130,8 +131,8 @@ public: nsIFrame* aRoot); // nsIReflowCallback - virtual bool ReflowFinished(); - virtual void ReflowCallbackCanceled(); + virtual bool ReflowFinished() MOZ_OVERRIDE; + virtual void ReflowCallbackCanceled() MOZ_OVERRIDE; void UpdateImageLayer(const gfxRect& aRect); @@ -169,7 +170,7 @@ public: bool PaintedByGecko(); - nsIWidget* GetWidget() { return mInnerView ? mWidget : nullptr; } + nsIWidget* GetWidget() MOZ_OVERRIDE { return mInnerView ? mWidget : nullptr; } /** * Adjust the plugin's idea of its size, using aSize as its new size. @@ -289,14 +290,14 @@ public: } #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aSnap); + bool* aSnap) MOZ_OVERRIDE; virtual void Paint(nsDisplayListBuilder* aBuilder, - nsRenderingContext* aCtx); + nsRenderingContext* aCtx) MOZ_OVERRIDE; virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion); + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; NS_DISPLAY_DECL_NAME("Plugin", TYPE_PLUGIN) @@ -312,7 +313,7 @@ public: virtual already_AddRefed BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aContainerParameters) + const ContainerParameters& aContainerParameters) MOZ_OVERRIDE { return static_cast(mFrame)->BuildLayer(aBuilder, aManager, @@ -321,7 +322,7 @@ public: virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerParameters& aParameters) + const ContainerParameters& aParameters) MOZ_OVERRIDE { return static_cast(mFrame)->GetLayerState(aBuilder, aManager); diff --git a/layout/generic/nsPageContentFrame.h b/layout/generic/nsPageContentFrame.h index 9850f701c59f..e49eba279ade 100644 --- a/layout/generic/nsPageContentFrame.h +++ b/layout/generic/nsPageContentFrame.h @@ -5,6 +5,7 @@ #ifndef nsPageContentFrame_h___ #define nsPageContentFrame_h___ +#include "mozilla/Attributes.h" #include "nsViewportFrame.h" class nsPageFrame; class nsSharedPageData; @@ -22,7 +23,7 @@ public: NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aMaxSize, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; virtual bool IsFrameOfType(uint32_t aFlags) const { @@ -46,11 +47,11 @@ public: * * @see nsGkAtoms::pageContentFrame */ - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; #ifdef DEBUG // Debugging - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif protected: diff --git a/layout/generic/nsPageFrame.h b/layout/generic/nsPageFrame.h index 80f92ff59f3b..093b051dc5ca 100644 --- a/layout/generic/nsPageFrame.h +++ b/layout/generic/nsPageFrame.h @@ -5,6 +5,7 @@ #ifndef nsPageFrame_h___ #define nsPageFrame_h___ +#include "mozilla/Attributes.h" #include "nsContainerFrame.h" #include "nsLeafFrame.h" @@ -25,17 +26,17 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; /** * Get the "type" of the frame * * @see nsGkAtoms::pageFrame */ - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif ////////////////// @@ -108,18 +109,18 @@ class nsPageBreakFrame : public nsLeafFrame NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif protected: - virtual nscoord GetIntrinsicWidth(); - virtual nscoord GetIntrinsicHeight(); + virtual nscoord GetIntrinsicWidth() MOZ_OVERRIDE; + virtual nscoord GetIntrinsicHeight() MOZ_OVERRIDE; bool mHaveReflowed; diff --git a/layout/generic/nsPlaceholderFrame.h b/layout/generic/nsPlaceholderFrame.h index de9df790006c..385f1ebd0ff9 100644 --- a/layout/generic/nsPlaceholderFrame.h +++ b/layout/generic/nsPlaceholderFrame.h @@ -34,6 +34,7 @@ #ifndef nsPlaceholderFrame_h___ #define nsPlaceholderFrame_h___ +#include "mozilla/Attributes.h" #include "nsFrame.h" #include "nsGkAtoms.h" @@ -90,19 +91,19 @@ public: // nsIHTMLReflow overrides // We need to override GetMinWidth and GetPrefWidth because XUL uses // placeholders not within lines. - virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); - virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext); + virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; + virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext, - InlineMinWidthData *aData); + InlineMinWidthData *aData) MOZ_OVERRIDE; virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext, - InlinePrefWidthData *aData); - virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState); - virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState); - virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState); + InlinePrefWidthData *aData) MOZ_OVERRIDE; + virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; virtual void DestroyFrom(nsIFrame* aDestructRoot); @@ -114,7 +115,7 @@ public: #endif // DEBUG || (MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF) #ifdef DEBUG - NS_IMETHOD List(FILE* out, int32_t aIndent) const; + NS_IMETHOD List(FILE* out, int32_t aIndent) const MOZ_OVERRIDE; #endif // DEBUG /** @@ -122,19 +123,19 @@ public: * * @see nsGkAtoms::placeholderFrame */ - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif - virtual bool IsEmpty() { return true; } - virtual bool IsSelfEmpty() { return true; } + virtual bool IsEmpty() MOZ_OVERRIDE { return true; } + virtual bool IsSelfEmpty() MOZ_OVERRIDE { return true; } - virtual bool CanContinueTextRun() const; + virtual bool CanContinueTextRun() const MOZ_OVERRIDE; #ifdef ACCESSIBILITY - virtual already_AddRefed CreateAccessible() + virtual already_AddRefed CreateAccessible() MOZ_OVERRIDE { nsIFrame* realFrame = GetRealFrameForPlaceholder(this); return realFrame ? realFrame->CreateAccessible() : @@ -142,7 +143,7 @@ public: } #endif - virtual nsIFrame* GetParentStyleContextFrame() const; + virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE; /** * @return the out-of-flow for aFrame if aFrame is a placeholder; otherwise diff --git a/layout/generic/nsSimplePageSequence.h b/layout/generic/nsSimplePageSequence.h index 7cdad3b44ee9..e5a8ff73ec57 100644 --- a/layout/generic/nsSimplePageSequence.h +++ b/layout/generic/nsSimplePageSequence.h @@ -5,6 +5,7 @@ #ifndef nsSimplePageSequence_h___ #define nsSimplePageSequence_h___ +#include "mozilla/Attributes.h" #include "nsIPageSequenceFrame.h" #include "nsContainerFrame.h" #include "nsIPrintSettings.h" @@ -66,25 +67,25 @@ public: // nsIPageSequenceFrame NS_IMETHOD SetPageNo(int32_t aPageNo) { return NS_OK;} - NS_IMETHOD SetSelectionHeight(nscoord aYOffset, nscoord aHeight) { mYSelOffset = aYOffset; mSelectionHeight = aHeight; return NS_OK; } - NS_IMETHOD SetTotalNumPages(int32_t aTotal) { mTotalPages = aTotal; return NS_OK; } + NS_IMETHOD SetSelectionHeight(nscoord aYOffset, nscoord aHeight) MOZ_OVERRIDE { mYSelOffset = aYOffset; mSelectionHeight = aHeight; return NS_OK; } + NS_IMETHOD SetTotalNumPages(int32_t aTotal) MOZ_OVERRIDE { mTotalPages = aTotal; return NS_OK; } // For Shrink To Fit - NS_IMETHOD GetSTFPercent(float& aSTFPercent); + NS_IMETHOD GetSTFPercent(float& aSTFPercent) MOZ_OVERRIDE; // Async Printing NS_IMETHOD StartPrint(nsPresContext* aPresContext, nsIPrintSettings* aPrintSettings, PRUnichar* aDocTitle, PRUnichar* aDocURL); - NS_IMETHOD PrePrintNextPage(nsITimerCallback* aCallback, bool* aDone); - NS_IMETHOD PrintNextPage(); - NS_IMETHOD ResetPrintCanvasList(); - NS_IMETHOD GetCurrentPageNum(int32_t* aPageNum); - NS_IMETHOD GetNumPages(int32_t* aNumPages); - NS_IMETHOD IsDoingPrintRange(bool* aDoing); - NS_IMETHOD GetPrintRange(int32_t* aFromPage, int32_t* aToPage); - NS_IMETHOD DoPageEnd(); + NS_IMETHOD PrePrintNextPage(nsITimerCallback* aCallback, bool* aDone) MOZ_OVERRIDE; + NS_IMETHOD PrintNextPage() MOZ_OVERRIDE; + NS_IMETHOD ResetPrintCanvasList() MOZ_OVERRIDE; + NS_IMETHOD GetCurrentPageNum(int32_t* aPageNum) MOZ_OVERRIDE; + NS_IMETHOD GetNumPages(int32_t* aNumPages) MOZ_OVERRIDE; + NS_IMETHOD IsDoingPrintRange(bool* aDoing) MOZ_OVERRIDE; + NS_IMETHOD GetPrintRange(int32_t* aFromPage, int32_t* aToPage) MOZ_OVERRIDE; + NS_IMETHOD DoPageEnd() MOZ_OVERRIDE; // We must allow Print Preview UI to have a background, no matter what the // user's settings diff --git a/layout/generic/nsSplittableFrame.cpp b/layout/generic/nsSplittableFrame.cpp index 68236ac8fbe0..fecf0d972a24 100644 --- a/layout/generic/nsSplittableFrame.cpp +++ b/layout/generic/nsSplittableFrame.cpp @@ -212,11 +212,11 @@ nsSplittableFrame::DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out nsFrame::DumpBaseRegressionData(aPresContext, out, aIndent); if (nullptr != mNextContinuation) { IndentBy(out, aIndent); - fprintf(out, "\n", PRUptrdiff(mNextContinuation)); + fprintf(out, "\n", (void*)mNextContinuation); } if (nullptr != mPrevContinuation) { IndentBy(out, aIndent); - fprintf(out, "\n", PRUptrdiff(mPrevContinuation)); + fprintf(out, "\n", (void*)mPrevContinuation); } } diff --git a/layout/generic/nsSplittableFrame.h b/layout/generic/nsSplittableFrame.h index adc6f925cffb..0884ff185987 100644 --- a/layout/generic/nsSplittableFrame.h +++ b/layout/generic/nsSplittableFrame.h @@ -11,6 +11,7 @@ #ifndef nsSplittableFrame_h___ #define nsSplittableFrame_h___ +#include "mozilla/Attributes.h" #include "nsFrame.h" // Derived class that allows splitting @@ -21,7 +22,7 @@ public: NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* aPrevInFlow); + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; virtual nsSplittableType GetSplittableType() const; @@ -36,12 +37,12 @@ public: */ // Get the previous/next continuation, regardless of its type (fluid or non-fluid). - virtual nsIFrame* GetPrevContinuation() const; - virtual nsIFrame* GetNextContinuation() const; + virtual nsIFrame* GetPrevContinuation() const MOZ_OVERRIDE; + virtual nsIFrame* GetNextContinuation() const MOZ_OVERRIDE; // Set a previous/next non-fluid continuation. - NS_IMETHOD SetPrevContinuation(nsIFrame*); - NS_IMETHOD SetNextContinuation(nsIFrame*); + NS_IMETHOD SetPrevContinuation(nsIFrame*) MOZ_OVERRIDE; + NS_IMETHOD SetNextContinuation(nsIFrame*) MOZ_OVERRIDE; // Get the first/last continuation for this frame. virtual nsIFrame* GetFirstContinuation() const; @@ -57,12 +58,12 @@ public: nsIFrame* GetPrevInFlow() const; nsIFrame* GetNextInFlow() const; - virtual nsIFrame* GetPrevInFlowVirtual() const { return GetPrevInFlow(); } - virtual nsIFrame* GetNextInFlowVirtual() const { return GetNextInFlow(); } + virtual nsIFrame* GetPrevInFlowVirtual() const MOZ_OVERRIDE { return GetPrevInFlow(); } + virtual nsIFrame* GetNextInFlowVirtual() const MOZ_OVERRIDE { return GetNextInFlow(); } // Set a previous/next fluid continuation. - NS_IMETHOD SetPrevInFlow(nsIFrame*); - NS_IMETHOD SetNextInFlow(nsIFrame*); + NS_IMETHOD SetPrevInFlow(nsIFrame*) MOZ_OVERRIDE; + NS_IMETHOD SetNextInFlow(nsIFrame*) MOZ_OVERRIDE; // Get the first/last frame in the current flow. virtual nsIFrame* GetFirstInFlow() const; @@ -76,7 +77,7 @@ protected: nsSplittableFrame(nsStyleContext* aContext) : nsFrame(aContext) {} #ifdef DEBUG - virtual void DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent); + virtual void DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent) MOZ_OVERRIDE; #endif nsIFrame* mPrevContinuation; diff --git a/layout/generic/nsSubDocumentFrame.h b/layout/generic/nsSubDocumentFrame.h index a80d44dcd142..2586660667d9 100644 --- a/layout/generic/nsSubDocumentFrame.h +++ b/layout/generic/nsSubDocumentFrame.h @@ -6,6 +6,7 @@ #ifndef NSSUBDOCUMENTFRAME_H_ #define NSSUBDOCUMENTFRAME_H_ +#include "mozilla/Attributes.h" #include "nsLeafFrame.h" #include "nsIReflowCallback.h" #include "nsFrameLoader.h" @@ -62,11 +63,11 @@ public: NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, @@ -89,8 +90,8 @@ public: nsIFrame* GetSubdocumentRootFrame(); // nsIReflowCallback - virtual bool ReflowFinished(); - virtual void ReflowCallbackCanceled(); + virtual bool ReflowFinished() MOZ_OVERRIDE; + virtual void ReflowCallbackCanceled() MOZ_OVERRIDE; bool ShouldClipSubdocument() { @@ -114,8 +115,8 @@ protected: bool IsInline() { return mIsInline; } - virtual nscoord GetIntrinsicWidth(); - virtual nscoord GetIntrinsicHeight(); + virtual nscoord GetIntrinsicWidth() MOZ_OVERRIDE; + virtual nscoord GetIntrinsicHeight() MOZ_OVERRIDE; virtual int GetSkipSides() const; diff --git a/layout/generic/nsTextRunTransformations.h b/layout/generic/nsTextRunTransformations.h index 4b9ea0e7c983..5ee9c69854e3 100644 --- a/layout/generic/nsTextRunTransformations.h +++ b/layout/generic/nsTextRunTransformations.h @@ -6,6 +6,7 @@ #ifndef NSTEXTRUNTRANSFORMATIONS_H_ #define NSTEXTRUNTRANSFORMATIONS_H_ +#include "mozilla/Attributes.h" #include "gfxFont.h" class nsTransformedTextRun; @@ -34,7 +35,7 @@ public: */ class nsFontVariantTextRunFactory : public nsTransformingTextRunFactory { public: - virtual void RebuildTextRun(nsTransformedTextRun* aTextRun, gfxContext* aRefContext); + virtual void RebuildTextRun(nsTransformedTextRun* aTextRun, gfxContext* aRefContext) MOZ_OVERRIDE; }; /** @@ -55,7 +56,7 @@ public: : mInnerTransformingTextRunFactory(aInnerTransformingTextRunFactory), mAllUppercase(aAllUppercase) {} - virtual void RebuildTextRun(nsTransformedTextRun* aTextRun, gfxContext* aRefContext); + virtual void RebuildTextRun(nsTransformedTextRun* aTextRun, gfxContext* aRefContext) MOZ_OVERRIDE; protected: nsAutoPtr mInnerTransformingTextRunFactory; diff --git a/layout/generic/nsVideoFrame.h b/layout/generic/nsVideoFrame.h index ffbfd2c4f202..eeb66a85086e 100644 --- a/layout/generic/nsVideoFrame.h +++ b/layout/generic/nsVideoFrame.h @@ -9,6 +9,7 @@ #ifndef nsVideoFrame_h___ #define nsVideoFrame_h___ +#include "mozilla/Attributes.h" #include "nsContainerFrame.h" #include "nsString.h" #include "nsAString.h" @@ -42,7 +43,7 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, @@ -57,8 +58,8 @@ public: uint32_t aFlags) MOZ_OVERRIDE; virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext); - virtual void DestroyFrom(nsIFrame* aDestructRoot); - virtual bool IsLeaf() const; + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + virtual bool IsLeaf() const MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, @@ -76,9 +77,9 @@ public: return nsSplittableFrame::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced)); } - virtual nsresult CreateAnonymousContent(nsTArray& aElements); + virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, - uint32_t aFilters); + uint32_t aFilters) MOZ_OVERRIDE; nsIContent* GetPosterImage() { return mPosterImage; } diff --git a/layout/generic/nsViewportFrame.h b/layout/generic/nsViewportFrame.h index 8086eb3108fd..51da05851094 100644 --- a/layout/generic/nsViewportFrame.h +++ b/layout/generic/nsViewportFrame.h @@ -11,6 +11,7 @@ #ifndef nsViewportFrame_h___ #define nsViewportFrame_h___ +#include "mozilla/Attributes.h" #include "nsContainerFrame.h" #include "nsGkAtoms.h" @@ -32,49 +33,49 @@ public: {} virtual ~ViewportFrame() { } // useful for debugging - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* asPrevInFlow); + nsIFrame* asPrevInFlow) MOZ_OVERRIDE; NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; - virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); - virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext); + virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; + virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; /** * Get the "type" of the frame * * @see nsGkAtoms::viewportFrame */ - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; virtual void InvalidateInternal(const nsRect& aDamageRect, nscoord aX, nscoord aY, nsIFrame* aForChild, uint32_t aFlags); #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif private: diff --git a/layout/ipc/RenderFrameParent.h b/layout/ipc/RenderFrameParent.h index 5adbf371e2ff..eaa13450b268 100644 --- a/layout/ipc/RenderFrameParent.h +++ b/layout/ipc/RenderFrameParent.h @@ -8,6 +8,7 @@ #ifndef mozilla_layout_RenderFrameParent_h #define mozilla_layout_RenderFrameParent_h +#include "mozilla/Attributes.h" #include #include "mozilla/layout/PRenderFrameParent.h" @@ -215,7 +216,7 @@ public: return mRect; } - virtual uint32_t GetPerFrameKey() + virtual uint32_t GetPerFrameKey() MOZ_OVERRIDE { NS_ABORT(); return 0; diff --git a/layout/mathml/nsMathMLContainerFrame.h b/layout/mathml/nsMathMLContainerFrame.h index 215286b14ffb..1b1428d297c4 100644 --- a/layout/mathml/nsMathMLContainerFrame.h +++ b/layout/mathml/nsMathMLContainerFrame.h @@ -6,6 +6,7 @@ #ifndef nsMathMLContainerFrame_h___ #define nsMathMLContainerFrame_h___ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsContainerFrame.h" #include "nsBlockFrame.h" @@ -89,11 +90,11 @@ public: NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; /** * Both GetMinWidth and GetPrefWidth return whatever @@ -132,7 +133,7 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; virtual bool UpdateOverflow(); @@ -404,7 +405,7 @@ public: NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList) + nsFrameList& aFrameList) MOZ_OVERRIDE { NS_ASSERTION(aListID == kPrincipalList || aListID == kNoReflowPrincipalList, "unexpected frame list"); @@ -416,7 +417,7 @@ public: NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame) + nsIFrame* aOldFrame) MOZ_OVERRIDE { NS_ASSERTION(aListID == kPrincipalList || aListID == kNoReflowPrincipalList, "unexpected frame list"); @@ -426,7 +427,7 @@ public: return rv; } - virtual bool IsFrameOfType(uint32_t aFlags) const { + virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE { return nsBlockFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML | nsIFrame::eExcludesIgnorableWhitespace)); } @@ -461,7 +462,7 @@ public: NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList) + nsFrameList& aFrameList) MOZ_OVERRIDE { NS_ASSERTION(aListID == kPrincipalList || aListID == kNoReflowPrincipalList, "unexpected frame list"); @@ -474,7 +475,7 @@ public: NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList) + nsFrameList& aFrameList) MOZ_OVERRIDE { NS_ASSERTION(aListID == kPrincipalList || aListID == kNoReflowPrincipalList, "unexpected frame list"); @@ -486,7 +487,7 @@ public: NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame) + nsIFrame* aOldFrame) MOZ_OVERRIDE { NS_ASSERTION(aListID == kPrincipalList || aListID == kNoReflowPrincipalList, "unexpected frame list"); diff --git a/layout/mathml/nsMathMLFrame.h b/layout/mathml/nsMathMLFrame.h index 76a62f4a283a..25d6241600c1 100644 --- a/layout/mathml/nsMathMLFrame.h +++ b/layout/mathml/nsMathMLFrame.h @@ -6,6 +6,7 @@ #ifndef nsMathMLFrame_h___ #define nsMathMLFrame_h___ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsPresContext.h" #include "nsFontMetrics.h" @@ -32,64 +33,64 @@ public: } NS_IMETHOD - GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) { + GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) MOZ_OVERRIDE { aBoundingMetrics = mBoundingMetrics; return NS_OK; } NS_IMETHOD - SetBoundingMetrics(const nsBoundingMetrics& aBoundingMetrics) { + SetBoundingMetrics(const nsBoundingMetrics& aBoundingMetrics) MOZ_OVERRIDE { mBoundingMetrics = aBoundingMetrics; return NS_OK; } NS_IMETHOD - SetReference(const nsPoint& aReference) { + SetReference(const nsPoint& aReference) MOZ_OVERRIDE { mReference = aReference; return NS_OK; } - virtual eMathMLFrameType GetMathMLFrameType(); + virtual eMathMLFrameType GetMathMLFrameType() MOZ_OVERRIDE; NS_IMETHOD Stretch(nsRenderingContext& aRenderingContext, nsStretchDirection aStretchDirection, nsBoundingMetrics& aContainerSize, - nsHTMLReflowMetrics& aDesiredStretchSize) + nsHTMLReflowMetrics& aDesiredStretchSize) MOZ_OVERRIDE { return NS_OK; } NS_IMETHOD - GetEmbellishData(nsEmbellishData& aEmbellishData) { + GetEmbellishData(nsEmbellishData& aEmbellishData) MOZ_OVERRIDE { aEmbellishData = mEmbellishData; return NS_OK; } NS_IMETHOD - GetPresentationData(nsPresentationData& aPresentationData) { + GetPresentationData(nsPresentationData& aPresentationData) MOZ_OVERRIDE { aPresentationData = mPresentationData; return NS_OK; } NS_IMETHOD - InheritAutomaticData(nsIFrame* aParent); + InheritAutomaticData(nsIFrame* aParent) MOZ_OVERRIDE; NS_IMETHOD - TransmitAutomaticData() + TransmitAutomaticData() MOZ_OVERRIDE { return NS_OK; } NS_IMETHOD UpdatePresentationData(uint32_t aFlagsValues, - uint32_t aFlagsToUpdate); + uint32_t aFlagsToUpdate) MOZ_OVERRIDE; NS_IMETHOD UpdatePresentationDataFromChildAt(int32_t aFirstIndex, int32_t aLastIndex, uint32_t aFlagsValues, - uint32_t aFlagsToUpdate) + uint32_t aFlagsToUpdate) MOZ_OVERRIDE { return NS_OK; } diff --git a/layout/mathml/nsMathMLTokenFrame.h b/layout/mathml/nsMathMLTokenFrame.h index a4fae6d72dc3..ead830bb8b73 100644 --- a/layout/mathml/nsMathMLTokenFrame.h +++ b/layout/mathml/nsMathMLTokenFrame.h @@ -6,6 +6,7 @@ #ifndef nsMathMLTokenFrame_h___ #define nsMathMLTokenFrame_h___ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsMathMLContainerFrame.h" @@ -36,32 +37,32 @@ public: NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; virtual nsresult Place(nsRenderingContext& aRenderingContext, bool aPlaceOrigin, - nsHTMLReflowMetrics& aDesiredSize); + nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE; virtual void MarkIntrinsicWidthsDirty(); virtual nsresult - ChildListChanged(int32_t aModType) + ChildListChanged(int32_t aModType) MOZ_OVERRIDE { ProcessTextData(); return nsMathMLContainerFrame::ChildListChanged(aModType); diff --git a/layout/mathml/nsMathMLmactionFrame.h b/layout/mathml/nsMathMLmactionFrame.h index 8ccefbf0a65e..170bdeaacba8 100644 --- a/layout/mathml/nsMathMLmactionFrame.h +++ b/layout/mathml/nsMathMLmactionFrame.h @@ -31,30 +31,30 @@ public: NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; virtual nsresult - ChildListChanged(int32_t aModType); + ChildListChanged(int32_t aModType) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; virtual nsresult Place(nsRenderingContext& aRenderingContext, bool aPlaceOrigin, - nsHTMLReflowMetrics& aDesiredSize); + nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; private: void MouseClick(); diff --git a/layout/mathml/nsMathMLmencloseFrame.h b/layout/mathml/nsMathMLmencloseFrame.h index e015839690db..a418604dfa9e 100644 --- a/layout/mathml/nsMathMLmencloseFrame.h +++ b/layout/mathml/nsMathMLmencloseFrame.h @@ -7,6 +7,7 @@ #ifndef nsMathMLmencloseFrame_h___ #define nsMathMLmencloseFrame_h___ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsMathMLContainerFrame.h" @@ -54,12 +55,12 @@ public: virtual nsresult MeasureForWidth(nsRenderingContext& aRenderingContext, - nsHTMLReflowMetrics& aDesiredSize); + nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; virtual void SetAdditionalStyleContext(int32_t aIndex, @@ -69,16 +70,16 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; NS_IMETHOD - InheritAutomaticData(nsIFrame* aParent); + InheritAutomaticData(nsIFrame* aParent) MOZ_OVERRIDE; NS_IMETHOD - TransmitAutomaticData(); + TransmitAutomaticData() MOZ_OVERRIDE; virtual nscoord - FixInterFrameSpacing(nsHTMLReflowMetrics& aDesiredSize); + FixInterFrameSpacing(nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE; protected: nsMathMLmencloseFrame(nsStyleContext* aContext); diff --git a/layout/mathml/nsMathMLmfencedFrame.h b/layout/mathml/nsMathMLmfencedFrame.h index d20aa327f4f3..5a31430d78a7 100644 --- a/layout/mathml/nsMathMLmfencedFrame.h +++ b/layout/mathml/nsMathMLmfencedFrame.h @@ -6,6 +6,7 @@ #ifndef nsMathMLmfencedFrame_h #define nsMathMLmfencedFrame_h +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsMathMLContainerFrame.h" @@ -26,37 +27,37 @@ public: GetAdditionalStyleContext(int32_t aIndex) const; NS_IMETHOD - InheritAutomaticData(nsIFrame* aParent); + InheritAutomaticData(nsIFrame* aParent) MOZ_OVERRIDE; NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; virtual nscoord - GetIntrinsicWidth(nsRenderingContext* aRenderingContext); + GetIntrinsicWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; // override the base method because we must keep separators in sync virtual nsresult - ChildListChanged(int32_t aModType); + ChildListChanged(int32_t aModType) MOZ_OVERRIDE; // override the base method so that we can deal with fences and separators virtual nscoord - FixInterFrameSpacing(nsHTMLReflowMetrics& aDesiredSize); + FixInterFrameSpacing(nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE; // helper routines to format the MathMLChars involved here static nsresult diff --git a/layout/mathml/nsMathMLmfracFrame.h b/layout/mathml/nsMathMLmfracFrame.h index a25c1913160c..e8a5553db04b 100644 --- a/layout/mathml/nsMathMLmfracFrame.h +++ b/layout/mathml/nsMathMLmfracFrame.h @@ -6,6 +6,7 @@ #ifndef nsMathMLmfracFrame_h___ #define nsMathMLmfracFrame_h___ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsMathMLContainerFrame.h" @@ -64,24 +65,24 @@ public: virtual nsresult Place(nsRenderingContext& aRenderingContext, bool aPlaceOrigin, - nsHTMLReflowMetrics& aDesiredSize); + nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; NS_IMETHOD - TransmitAutomaticData(); + TransmitAutomaticData() MOZ_OVERRIDE; NS_IMETHOD UpdatePresentationDataFromChildAt(int32_t aFirstIndex, int32_t aLastIndex, uint32_t aFlagsValues, - uint32_t aFlagsToUpdate); + uint32_t aFlagsToUpdate) MOZ_OVERRIDE; // override the base method so that we can deal with the fraction line virtual nscoord - FixInterFrameSpacing(nsHTMLReflowMetrics& aDesiredSize); + FixInterFrameSpacing(nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE; // helper to translate the thickness attribute into a usable form static nscoord diff --git a/layout/mathml/nsMathMLmoFrame.h b/layout/mathml/nsMathMLmoFrame.h index 43b387fe8439..2ba2ae81dd52 100644 --- a/layout/mathml/nsMathMLmoFrame.h +++ b/layout/mathml/nsMathMLmoFrame.h @@ -6,6 +6,7 @@ #ifndef nsMathMLmoFrame_h___ #define nsMathMLmoFrame_h___ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsMathMLTokenFrame.h" @@ -32,26 +33,26 @@ public: const nsDisplayListSet& aLists); NS_IMETHOD - InheritAutomaticData(nsIFrame* aParent); + InheritAutomaticData(nsIFrame* aParent) MOZ_OVERRIDE; NS_IMETHOD - TransmitAutomaticData(); + TransmitAutomaticData() MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; - virtual void MarkIntrinsicWidthsDirty(); + virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE; virtual nscoord - GetIntrinsicWidth(nsRenderingContext *aRenderingContext); + GetIntrinsicWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; // This method is called by the parent frame to ask // to stretch itself. @@ -59,13 +60,13 @@ public: Stretch(nsRenderingContext& aRenderingContext, nsStretchDirection aStretchDirection, nsBoundingMetrics& aContainerSize, - nsHTMLReflowMetrics& aDesiredStretchSize); + nsHTMLReflowMetrics& aDesiredStretchSize) MOZ_OVERRIDE; protected: nsMathMLmoFrame(nsStyleContext* aContext) : nsMathMLTokenFrame(aContext) {} virtual ~nsMathMLmoFrame(); - virtual int GetSkipSides() const { return 0; } + virtual int GetSkipSides() const MOZ_OVERRIDE { return 0; } nsMathMLChar mMathMLChar; // Here is the MathMLChar that will deal with the operator. nsOperatorFlags mFlags; @@ -75,7 +76,7 @@ protected: bool UseMathMLChar(); // overload the base method so that we can setup our nsMathMLChar - virtual void ProcessTextData(); + virtual void ProcessTextData() MOZ_OVERRIDE; // helper to get our 'form' and lookup in the Operator Dictionary to fetch // our default data that may come from there, and to complete the setup diff --git a/layout/mathml/nsMathMLmpaddedFrame.h b/layout/mathml/nsMathMLmpaddedFrame.h index 9db699dd157f..8c9e0f08eb33 100644 --- a/layout/mathml/nsMathMLmpaddedFrame.h +++ b/layout/mathml/nsMathMLmpaddedFrame.h @@ -6,6 +6,7 @@ #ifndef nsMathMLmpaddedFrame_h___ #define nsMathMLmpaddedFrame_h___ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsMathMLContainerFrame.h" @@ -31,12 +32,12 @@ public: Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; virtual nsresult Place(nsRenderingContext& aRenderingContext, bool aPlaceOrigin, - nsHTMLReflowMetrics& aDesiredSize); + nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE; protected: nsMathMLmpaddedFrame(nsStyleContext* aContext) : nsMathMLContainerFrame(aContext) {} diff --git a/layout/mathml/nsMathMLmphantomFrame.h b/layout/mathml/nsMathMLmphantomFrame.h index b6aa85f2e3dd..840050d3d7ac 100644 --- a/layout/mathml/nsMathMLmphantomFrame.h +++ b/layout/mathml/nsMathMLmphantomFrame.h @@ -6,6 +6,7 @@ #ifndef nsMathMLmphantomFrame_h___ #define nsMathMLmphantomFrame_h___ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsMathMLContainerFrame.h" @@ -29,7 +30,7 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) { return NS_OK; } + const nsDisplayListSet& aLists) MOZ_OVERRIDE { return NS_OK; } protected: nsMathMLmphantomFrame(nsStyleContext* aContext) diff --git a/layout/mathml/nsMathMLmrootFrame.h b/layout/mathml/nsMathMLmrootFrame.h index cce7d4153c4b..f890015d4376 100644 --- a/layout/mathml/nsMathMLmrootFrame.h +++ b/layout/mathml/nsMathMLmrootFrame.h @@ -6,6 +6,7 @@ #ifndef nsMathMLmrootFrame_h___ #define nsMathMLmrootFrame_h___ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsMathMLContainerFrame.h" @@ -31,20 +32,20 @@ public: nsIFrame* aPrevInFlow); NS_IMETHOD - TransmitAutomaticData(); + TransmitAutomaticData() MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; virtual nscoord - GetIntrinsicWidth(nsRenderingContext* aRenderingContext); + GetIntrinsicWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; protected: nsMathMLmrootFrame(nsStyleContext* aContext); diff --git a/layout/mathml/nsMathMLmrowFrame.h b/layout/mathml/nsMathMLmrowFrame.h index 8541e2e99f68..4d335a5f04e5 100644 --- a/layout/mathml/nsMathMLmrowFrame.h +++ b/layout/mathml/nsMathMLmrowFrame.h @@ -6,6 +6,7 @@ #ifndef nsMathMLmrowFrame_h___ #define nsMathMLmrowFrame_h___ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsMathMLContainerFrame.h" @@ -28,7 +29,7 @@ public: InheritAutomaticData(nsIFrame* aParent); NS_IMETHOD - TransmitAutomaticData() { + TransmitAutomaticData() MOZ_OVERRIDE { return TransmitAutomaticDataForMrowLikeElement(); } diff --git a/layout/mathml/nsMathMLmspaceFrame.h b/layout/mathml/nsMathMLmspaceFrame.h index 2fb6ca92e807..c92d4a7f5261 100644 --- a/layout/mathml/nsMathMLmspaceFrame.h +++ b/layout/mathml/nsMathMLmspaceFrame.h @@ -6,6 +6,7 @@ #ifndef nsMathMLmspaceFrame_h___ #define nsMathMLmspaceFrame_h___ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsMathMLContainerFrame.h" @@ -33,7 +34,7 @@ public: Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; protected: nsMathMLmspaceFrame(nsStyleContext* aContext) : nsMathMLContainerFrame(aContext) {} diff --git a/layout/mathml/nsMathMLmsqrtFrame.h b/layout/mathml/nsMathMLmsqrtFrame.h index 2c6a52a3924c..dbc144259318 100644 --- a/layout/mathml/nsMathMLmsqrtFrame.h +++ b/layout/mathml/nsMathMLmsqrtFrame.h @@ -6,6 +6,7 @@ #ifndef nsMathMLmsqrtFrame_h___ #define nsMathMLmsqrtFrame_h___ +#include "mozilla/Attributes.h" #include "nsMathMLmencloseFrame.h" // @@ -44,12 +45,12 @@ public: nsIFrame* aPrevInFlow); NS_IMETHOD - InheritAutomaticData(nsIFrame* aParent); + InheritAutomaticData(nsIFrame* aParent) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; protected: nsMathMLmsqrtFrame(nsStyleContext* aContext); diff --git a/layout/mathml/nsMathMLmstyleFrame.h b/layout/mathml/nsMathMLmstyleFrame.h index e5a782363afe..9e7e3d9ba887 100644 --- a/layout/mathml/nsMathMLmstyleFrame.h +++ b/layout/mathml/nsMathMLmstyleFrame.h @@ -6,6 +6,7 @@ #ifndef nsMathMLmstyleFrame_h___ #define nsMathMLmstyleFrame_h___ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsMathMLContainerFrame.h" @@ -28,17 +29,17 @@ public: InheritAutomaticData(nsIFrame* aParent); NS_IMETHOD - TransmitAutomaticData(); + TransmitAutomaticData() MOZ_OVERRIDE; NS_IMETHOD UpdatePresentationData(uint32_t aFlagsValues, - uint32_t aFlagsToUpdate); + uint32_t aFlagsToUpdate) MOZ_OVERRIDE; NS_IMETHOD UpdatePresentationDataFromChildAt(int32_t aFirstIndex, int32_t aLastIndex, uint32_t aFlagsValues, - uint32_t aFlagsToUpdate); + uint32_t aFlagsToUpdate) MOZ_OVERRIDE; protected: nsMathMLmstyleFrame(nsStyleContext* aContext) : nsMathMLContainerFrame(aContext) {} diff --git a/layout/mathml/nsMathMLmtableFrame.h b/layout/mathml/nsMathMLmtableFrame.h index 319f4d4c0822..11d6ff534a1f 100644 --- a/layout/mathml/nsMathMLmtableFrame.h +++ b/layout/mathml/nsMathMLmtableFrame.h @@ -6,6 +6,7 @@ #ifndef nsMathMLmtableFrame_h___ #define nsMathMLmtableFrame_h___ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsMathMLContainerFrame.h" @@ -25,7 +26,7 @@ public: // Overloaded nsIMathMLFrame methods NS_IMETHOD - InheritAutomaticData(nsIFrame* aParent); + InheritAutomaticData(nsIFrame* aParent) MOZ_OVERRIDE; NS_IMETHOD UpdatePresentationData(uint32_t aFlagsValues, @@ -35,7 +36,7 @@ public: UpdatePresentationDataFromChildAt(int32_t aFirstIndex, int32_t aLastIndex, uint32_t aFlagsValues, - uint32_t aWhichFlags); + uint32_t aWhichFlags) MOZ_OVERRIDE; // overloaded nsTableOuterFrame methods @@ -43,7 +44,7 @@ public: Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, @@ -143,7 +144,7 @@ public: NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList) + nsFrameList& aFrameList) MOZ_OVERRIDE { nsresult rv = nsTableRowFrame::AppendFrames(aListID, aFrameList); RestyleTable(); @@ -153,7 +154,7 @@ public: NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList) + nsFrameList& aFrameList) MOZ_OVERRIDE { nsresult rv = nsTableRowFrame::InsertFrames(aListID, aPrevFrame, aFrameList); RestyleTable(); @@ -162,7 +163,7 @@ public: NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame) + nsIFrame* aOldFrame) MOZ_OVERRIDE { nsresult rv = nsTableRowFrame::RemoveFrame(aListID, aOldFrame); RestyleTable(); @@ -205,8 +206,8 @@ public: nsIAtom* aAttribute, int32_t aModType); - virtual int32_t GetRowSpan(); - virtual int32_t GetColSpan(); + virtual int32_t GetRowSpan() MOZ_OVERRIDE; + virtual int32_t GetColSpan() MOZ_OVERRIDE; virtual bool IsFrameOfType(uint32_t aFlags) const { return nsTableCellFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML)); @@ -233,7 +234,7 @@ public: UpdatePresentationDataFromChildAt(int32_t aFirstIndex, int32_t aLastIndex, uint32_t aFlagsValues, - uint32_t aFlagsToUpdate) + uint32_t aFlagsToUpdate) MOZ_OVERRIDE { nsMathMLContainerFrame::PropagatePresentationDataFromChildAt(this, aFirstIndex, aLastIndex, aFlagsValues, aFlagsToUpdate); @@ -256,7 +257,7 @@ protected: nsMathMLmtdInnerFrame(nsStyleContext* aContext) : nsBlockFrame(aContext) {} virtual ~nsMathMLmtdInnerFrame(); - virtual int GetSkipSides() const { return 0; } + virtual int GetSkipSides() const MOZ_OVERRIDE { return 0; } }; // class nsMathMLmtdInnerFrame #endif /* nsMathMLmtableFrame_h___ */ diff --git a/layout/mathml/nsMathMLmunderoverFrame.h b/layout/mathml/nsMathMLmunderoverFrame.h index 0c78382f19d7..c83db7b19299 100644 --- a/layout/mathml/nsMathMLmunderoverFrame.h +++ b/layout/mathml/nsMathMLmunderoverFrame.h @@ -6,6 +6,7 @@ #ifndef nsMathMLmunderoverFrame_h___ #define nsMathMLmunderoverFrame_h___ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsMathMLContainerFrame.h" @@ -28,22 +29,22 @@ public: InheritAutomaticData(nsIFrame* aParent); NS_IMETHOD - TransmitAutomaticData(); + TransmitAutomaticData() MOZ_OVERRIDE; NS_IMETHOD UpdatePresentationData(uint32_t aFlagsValues, - uint32_t aFlagsToUpdate); + uint32_t aFlagsToUpdate) MOZ_OVERRIDE; NS_IMETHOD UpdatePresentationDataFromChildAt(int32_t aFirstIndex, int32_t aLastIndex, uint32_t aFlagsValues, - uint32_t aFlagsToUpdate); + uint32_t aFlagsToUpdate) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; protected: nsMathMLmunderoverFrame(nsStyleContext* aContext) : nsMathMLContainerFrame(aContext) {} diff --git a/layout/style/AnimationCommon.h b/layout/style/AnimationCommon.h index e9a1e4adabc5..f75271fef08a 100644 --- a/layout/style/AnimationCommon.h +++ b/layout/style/AnimationCommon.h @@ -38,10 +38,10 @@ public: // nsIStyleRuleProcessor (parts) virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData); - virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData); + virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE; virtual nsRestyleHint - HasAttributeDependentStyle(AttributeRuleProcessorData* aData); - virtual bool MediumFeaturesChanged(nsPresContext* aPresContext); + HasAttributeDependentStyle(AttributeRuleProcessorData* aData) MOZ_OVERRIDE; + virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) MOZ_OVERRIDE; virtual NS_MUST_OVERRIDE size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const MOZ_OVERRIDE; virtual NS_MUST_OVERRIDE size_t @@ -79,7 +79,7 @@ public: // nsIStyleRule implementation virtual void MapRuleInfoInto(nsRuleData* aRuleData); #ifdef DEBUG - virtual void List(FILE* out = stdout, int32_t aIndent = 0) const; + virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE; #endif void AddValue(nsCSSProperty aProperty, nsStyleAnimation::Value &aStartValue) diff --git a/layout/style/StyleRule.h b/layout/style/StyleRule.h index ae120824e7b9..040a476781e0 100644 --- a/layout/style/StyleRule.h +++ b/layout/style/StyleRule.h @@ -277,7 +277,7 @@ public: // nsIStyleRule interface virtual void MapRuleInfoInto(nsRuleData* aRuleData); #ifdef DEBUG - virtual void List(FILE* out = stdout, int32_t aIndent = 0) const; + virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE; #endif protected: diff --git a/layout/style/nsAnimationManager.h b/layout/style/nsAnimationManager.h index 78e9e8f0e127..88da7215e770 100644 --- a/layout/style/nsAnimationManager.h +++ b/layout/style/nsAnimationManager.h @@ -5,6 +5,7 @@ #ifndef nsAnimationManager_h_ #define nsAnimationManager_h_ +#include "mozilla/Attributes.h" #include "AnimationCommon.h" #include "nsCSSPseudoElements.h" #include "nsStyleContext.h" @@ -187,11 +188,11 @@ public: } // nsIStyleRuleProcessor (parts) - virtual void RulesMatching(ElementRuleProcessorData* aData); - virtual void RulesMatching(PseudoElementRuleProcessorData* aData); - virtual void RulesMatching(AnonBoxRuleProcessorData* aData); + virtual void RulesMatching(ElementRuleProcessorData* aData) MOZ_OVERRIDE; + virtual void RulesMatching(PseudoElementRuleProcessorData* aData) MOZ_OVERRIDE; + virtual void RulesMatching(AnonBoxRuleProcessorData* aData) MOZ_OVERRIDE; #ifdef MOZ_XUL - virtual void RulesMatching(XULTreeRuleProcessorData* aData); + virtual void RulesMatching(XULTreeRuleProcessorData* aData) MOZ_OVERRIDE; #endif virtual NS_MUST_OVERRIDE size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const MOZ_OVERRIDE; @@ -199,7 +200,7 @@ public: SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const MOZ_OVERRIDE; // nsARefreshObserver - virtual void WillRefresh(mozilla::TimeStamp aTime); + virtual void WillRefresh(mozilla::TimeStamp aTime) MOZ_OVERRIDE; /** * Return the style rule that RulesMatching should add for diff --git a/layout/style/nsCSSRuleProcessor.h b/layout/style/nsCSSRuleProcessor.h index 6b989ec8902a..07bf5f2b8c34 100644 --- a/layout/style/nsCSSRuleProcessor.h +++ b/layout/style/nsCSSRuleProcessor.h @@ -12,6 +12,7 @@ #ifndef nsCSSRuleProcessor_h_ #define nsCSSRuleProcessor_h_ +#include "mozilla/Attributes.h" #include "nsIStyleRuleProcessor.h" #include "nsCSSStyleSheet.h" #include "nsTArray.h" @@ -88,24 +89,24 @@ public: static bool IsLink(mozilla::dom::Element* aElement); // nsIStyleRuleProcessor - virtual void RulesMatching(ElementRuleProcessorData* aData); + virtual void RulesMatching(ElementRuleProcessorData* aData) MOZ_OVERRIDE; - virtual void RulesMatching(PseudoElementRuleProcessorData* aData); + virtual void RulesMatching(PseudoElementRuleProcessorData* aData) MOZ_OVERRIDE; - virtual void RulesMatching(AnonBoxRuleProcessorData* aData); + virtual void RulesMatching(AnonBoxRuleProcessorData* aData) MOZ_OVERRIDE; #ifdef MOZ_XUL - virtual void RulesMatching(XULTreeRuleProcessorData* aData); + virtual void RulesMatching(XULTreeRuleProcessorData* aData) MOZ_OVERRIDE; #endif - virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData); + virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE; - virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData); + virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE; virtual nsRestyleHint - HasAttributeDependentStyle(AttributeRuleProcessorData* aData); + HasAttributeDependentStyle(AttributeRuleProcessorData* aData) MOZ_OVERRIDE; - virtual bool MediumFeaturesChanged(nsPresContext* aPresContext); + virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) MOZ_OVERRIDE; virtual NS_MUST_OVERRIDE size_t SizeOfExcludingThis(nsMallocSizeOfFun mallocSizeOf) const MOZ_OVERRIDE; diff --git a/layout/style/nsCSSRules.h b/layout/style/nsCSSRules.h index 6df6e698cd91..35b894a9e649 100644 --- a/layout/style/nsCSSRules.h +++ b/layout/style/nsCSSRules.h @@ -169,8 +169,8 @@ public: SetIsDOMBinding(); } - virtual nsINode *GetParentObject(); - virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName); + virtual nsINode *GetParentObject() MOZ_OVERRIDE; + virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName) MOZ_OVERRIDE; nsresult GetPropertyValue(nsCSSFontDesc aFontDescID, nsAString & aResult) const; @@ -229,7 +229,7 @@ public: void SetDesc(nsCSSFontDesc aDescID, nsCSSValue const & aValue); void GetDesc(nsCSSFontDesc aDescID, nsCSSValue & aValue); - virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const; + virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const MOZ_OVERRIDE; protected: friend class nsCSSFontFaceStyleDecl; @@ -308,12 +308,12 @@ public: nsCSSKeyframeStyleDeclaration(nsCSSKeyframeRule *aRule); virtual ~nsCSSKeyframeStyleDeclaration(); - NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent); + NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent) MOZ_OVERRIDE; void DropReference() { mRule = nullptr; } - virtual mozilla::css::Declaration* GetCSSDeclaration(bool aAllocate); - virtual nsresult SetCSSDeclaration(mozilla::css::Declaration* aDecl); - virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv); - virtual nsIDocument* DocToUpdate(); + virtual mozilla::css::Declaration* GetCSSDeclaration(bool aAllocate) MOZ_OVERRIDE; + virtual nsresult SetCSSDeclaration(mozilla::css::Declaration* aDecl) MOZ_OVERRIDE; + virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) MOZ_OVERRIDE; + virtual nsIDocument* DocToUpdate() MOZ_OVERRIDE; NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCSSKeyframeStyleDeclaration, @@ -365,7 +365,7 @@ public: void ChangeDeclaration(mozilla::css::Declaration* aDeclaration); - virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const; + virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const MOZ_OVERRIDE; private: nsAutoTArray mKeys; @@ -413,7 +413,7 @@ public: const nsString& GetName() { return mName; } - virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const; + virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const MOZ_OVERRIDE; private: uint32_t FindRuleIndexForKey(const nsAString& aKey); diff --git a/layout/style/nsCSSStyleSheet.h b/layout/style/nsCSSStyleSheet.h index 0aaf808e6415..db1a889b13c7 100644 --- a/layout/style/nsCSSStyleSheet.h +++ b/layout/style/nsCSSStyleSheet.h @@ -116,22 +116,22 @@ public: // nsIStyleSheet interface virtual nsIURI* GetSheetURI() const; - virtual nsIURI* GetBaseURI() const; - virtual void GetTitle(nsString& aTitle) const; - virtual void GetType(nsString& aType) const; - virtual bool HasRules() const; - virtual bool IsApplicable() const; - virtual void SetEnabled(bool aEnabled); - virtual bool IsComplete() const; - virtual void SetComplete(); - virtual nsIStyleSheet* GetParentSheet() const; // may be null - virtual nsIDocument* GetOwningDocument() const; // may be null - virtual void SetOwningDocument(nsIDocument* aDocument); + virtual nsIURI* GetBaseURI() const MOZ_OVERRIDE; + virtual void GetTitle(nsString& aTitle) const MOZ_OVERRIDE; + virtual void GetType(nsString& aType) const MOZ_OVERRIDE; + virtual bool HasRules() const MOZ_OVERRIDE; + virtual bool IsApplicable() const MOZ_OVERRIDE; + virtual void SetEnabled(bool aEnabled) MOZ_OVERRIDE; + virtual bool IsComplete() const MOZ_OVERRIDE; + virtual void SetComplete() MOZ_OVERRIDE; + virtual nsIStyleSheet* GetParentSheet() const MOZ_OVERRIDE; // may be null + virtual nsIDocument* GetOwningDocument() const MOZ_OVERRIDE; // may be null + virtual void SetOwningDocument(nsIDocument* aDocument) MOZ_OVERRIDE; // Find the ID of the owner inner window. uint64_t FindOwningWindowInnerID() const; #ifdef DEBUG - virtual void List(FILE* out = stdout, int32_t aIndent = 0) const; + virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE; #endif void AppendStyleSheet(nsCSSStyleSheet* aSheet); @@ -240,7 +240,7 @@ public: // list after we clone a unique inner for ourselves. static bool RebuildChildList(mozilla::css::Rule* aRule, void* aBuilder); - size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const; + size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const MOZ_OVERRIDE; // Get this style sheet's CORS mode mozilla::CORSMode GetCORSMode() const { return mInner->mCORSMode; } diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index 60b8ba4b3bed..c443608a8378 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -8,6 +8,7 @@ #ifndef nsComputedDOMStyle_h__ #define nsComputedDOMStyle_h__ +#include "mozilla/Attributes.h" #include "nsDOMCSSDeclaration.h" #include "nsROCSSPrimitiveValue.h" @@ -44,7 +45,7 @@ public: static void Shutdown(); - virtual nsINode *GetParentObject() + virtual nsINode *GetParentObject() MOZ_OVERRIDE { return mContent; } @@ -70,10 +71,10 @@ public: // nsDOMCSSDeclaration abstract methods which should never be called // on a nsComputedDOMStyle object, but must be defined to avoid // compile errors. - virtual mozilla::css::Declaration* GetCSSDeclaration(bool); - virtual nsresult SetCSSDeclaration(mozilla::css::Declaration*); - virtual nsIDocument* DocToUpdate(); - virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv); + virtual mozilla::css::Declaration* GetCSSDeclaration(bool) MOZ_OVERRIDE; + virtual nsresult SetCSSDeclaration(mozilla::css::Declaration*) MOZ_OVERRIDE; + virtual nsIDocument* DocToUpdate() MOZ_OVERRIDE; + virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) MOZ_OVERRIDE; private: void AssertFlushedPendingReflows() { diff --git a/layout/style/nsDOMCSSAttrDeclaration.h b/layout/style/nsDOMCSSAttrDeclaration.h index 56a42bdaefa1..7b4e47a57d15 100644 --- a/layout/style/nsDOMCSSAttrDeclaration.h +++ b/layout/style/nsDOMCSSAttrDeclaration.h @@ -8,6 +8,7 @@ #ifndef nsDOMCSSAttributeDeclaration_h #define nsDOMCSSAttributeDeclaration_h +#include "mozilla/Attributes.h" #include "nsDOMCSSDeclaration.h" #include "nsAutoPtr.h" @@ -37,14 +38,14 @@ public: // If GetCSSDeclaration returns non-null, then the decl it returns // is owned by our current style rule. virtual mozilla::css::Declaration* GetCSSDeclaration(bool aAllocate); - virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv); - NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent); + virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) MOZ_OVERRIDE; + NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent) MOZ_OVERRIDE; - virtual nsINode* GetParentObject(); + virtual nsINode* GetParentObject() MOZ_OVERRIDE; protected: - virtual nsresult SetCSSDeclaration(mozilla::css::Declaration* aDecl); - virtual nsIDocument* DocToUpdate(); + virtual nsresult SetCSSDeclaration(mozilla::css::Declaration* aDecl) MOZ_OVERRIDE; + virtual nsIDocument* DocToUpdate() MOZ_OVERRIDE; nsRefPtr mElement; diff --git a/layout/style/nsDOMCSSDeclaration.h b/layout/style/nsDOMCSSDeclaration.h index ed2bdfac4c9c..9013ca5fdfcf 100644 --- a/layout/style/nsDOMCSSDeclaration.h +++ b/layout/style/nsDOMCSSDeclaration.h @@ -8,6 +8,7 @@ #ifndef nsDOMCSSDeclaration_h___ #define nsDOMCSSDeclaration_h___ +#include "mozilla/Attributes.h" #include "nsICSSDeclaration.h" #include "nsIDOMCSS2Properties.h" #include "nsCOMPtr.h" @@ -46,19 +47,19 @@ public: // Require subclasses to implement |GetParentRule|. //NS_DECL_NSIDOMCSSSTYLEDECLARATION NS_IMETHOD GetCssText(nsAString & aCssText); - NS_IMETHOD SetCssText(const nsAString & aCssText); + NS_IMETHOD SetCssText(const nsAString & aCssText) MOZ_OVERRIDE; NS_IMETHOD GetPropertyValue(const nsAString & propertyName, - nsAString & _retval); + nsAString & _retval) MOZ_OVERRIDE; NS_IMETHOD GetPropertyCSSValue(const nsAString & propertyName, - nsIDOMCSSValue **_retval); + nsIDOMCSSValue **_retval) MOZ_OVERRIDE; NS_IMETHOD RemoveProperty(const nsAString & propertyName, nsAString & _retval); NS_IMETHOD GetPropertyPriority(const nsAString & propertyName, - nsAString & _retval); + nsAString & _retval) MOZ_OVERRIDE; NS_IMETHOD SetProperty(const nsAString & propertyName, - const nsAString & value, const nsAString & priority); - NS_IMETHOD GetLength(uint32_t *aLength); - NS_IMETHOD GetParentRule(nsIDOMCSSRule * *aParentRule) = 0; + const nsAString & value, const nsAString & priority) MOZ_OVERRIDE; + NS_IMETHOD GetLength(uint32_t *aLength) MOZ_OVERRIDE; + NS_IMETHOD GetParentRule(nsIDOMCSSRule * *aParentRule) MOZ_OVERRIDE = 0; // We implement this as a shim which forwards to GetPropertyValue // and SetPropertyValue; subclasses need not. diff --git a/layout/style/nsHTMLCSSStyleSheet.h b/layout/style/nsHTMLCSSStyleSheet.h index fe3bb996e770..9260eec6df17 100644 --- a/layout/style/nsHTMLCSSStyleSheet.h +++ b/layout/style/nsHTMLCSSStyleSheet.h @@ -27,33 +27,33 @@ public: // nsIStyleSheet virtual nsIURI* GetSheetURI() const; - virtual nsIURI* GetBaseURI() const; - virtual void GetTitle(nsString& aTitle) const; - virtual void GetType(nsString& aType) const; - virtual bool HasRules() const; - virtual bool IsApplicable() const; - virtual void SetEnabled(bool aEnabled); - virtual bool IsComplete() const; - virtual void SetComplete(); - virtual nsIStyleSheet* GetParentSheet() const; // will be null - virtual nsIDocument* GetOwningDocument() const; - virtual void SetOwningDocument(nsIDocument* aDocument); + virtual nsIURI* GetBaseURI() const MOZ_OVERRIDE; + virtual void GetTitle(nsString& aTitle) const MOZ_OVERRIDE; + virtual void GetType(nsString& aType) const MOZ_OVERRIDE; + virtual bool HasRules() const MOZ_OVERRIDE; + virtual bool IsApplicable() const MOZ_OVERRIDE; + virtual void SetEnabled(bool aEnabled) MOZ_OVERRIDE; + virtual bool IsComplete() const MOZ_OVERRIDE; + virtual void SetComplete() MOZ_OVERRIDE; + virtual nsIStyleSheet* GetParentSheet() const MOZ_OVERRIDE; // will be null + virtual nsIDocument* GetOwningDocument() const MOZ_OVERRIDE; + virtual void SetOwningDocument(nsIDocument* aDocument) MOZ_OVERRIDE; #ifdef DEBUG - virtual void List(FILE* out = stdout, int32_t aIndent = 0) const; + virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE; #endif // nsIStyleRuleProcessor - virtual void RulesMatching(ElementRuleProcessorData* aData); - virtual void RulesMatching(PseudoElementRuleProcessorData* aData); - virtual void RulesMatching(AnonBoxRuleProcessorData* aData); + virtual void RulesMatching(ElementRuleProcessorData* aData) MOZ_OVERRIDE; + virtual void RulesMatching(PseudoElementRuleProcessorData* aData) MOZ_OVERRIDE; + virtual void RulesMatching(AnonBoxRuleProcessorData* aData) MOZ_OVERRIDE; #ifdef MOZ_XUL - virtual void RulesMatching(XULTreeRuleProcessorData* aData); + virtual void RulesMatching(XULTreeRuleProcessorData* aData) MOZ_OVERRIDE; #endif - virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData); - virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData); + virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE; + virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE; virtual nsRestyleHint - HasAttributeDependentStyle(AttributeRuleProcessorData* aData); - virtual bool MediumFeaturesChanged(nsPresContext* aPresContext); + HasAttributeDependentStyle(AttributeRuleProcessorData* aData) MOZ_OVERRIDE; + virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) MOZ_OVERRIDE; virtual NS_MUST_OVERRIDE size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const MOZ_OVERRIDE; virtual NS_MUST_OVERRIDE size_t diff --git a/layout/style/nsHTMLStyleSheet.h b/layout/style/nsHTMLStyleSheet.h index f7249662ec26..036b96fc4de4 100644 --- a/layout/style/nsHTMLStyleSheet.h +++ b/layout/style/nsHTMLStyleSheet.h @@ -34,33 +34,33 @@ public: // nsIStyleSheet api virtual nsIURI* GetSheetURI() const; - virtual nsIURI* GetBaseURI() const; - virtual void GetTitle(nsString& aTitle) const; - virtual void GetType(nsString& aType) const; - virtual bool HasRules() const; - virtual bool IsApplicable() const; - virtual void SetEnabled(bool aEnabled); - virtual bool IsComplete() const; - virtual void SetComplete(); - virtual nsIStyleSheet* GetParentSheet() const; // will be null - virtual nsIDocument* GetOwningDocument() const; - virtual void SetOwningDocument(nsIDocument* aDocumemt); + virtual nsIURI* GetBaseURI() const MOZ_OVERRIDE; + virtual void GetTitle(nsString& aTitle) const MOZ_OVERRIDE; + virtual void GetType(nsString& aType) const MOZ_OVERRIDE; + virtual bool HasRules() const MOZ_OVERRIDE; + virtual bool IsApplicable() const MOZ_OVERRIDE; + virtual void SetEnabled(bool aEnabled) MOZ_OVERRIDE; + virtual bool IsComplete() const MOZ_OVERRIDE; + virtual void SetComplete() MOZ_OVERRIDE; + virtual nsIStyleSheet* GetParentSheet() const MOZ_OVERRIDE; // will be null + virtual nsIDocument* GetOwningDocument() const MOZ_OVERRIDE; + virtual void SetOwningDocument(nsIDocument* aDocumemt) MOZ_OVERRIDE; #ifdef DEBUG - virtual void List(FILE* out = stdout, int32_t aIndent = 0) const; + virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE; #endif // nsIStyleRuleProcessor API - virtual void RulesMatching(ElementRuleProcessorData* aData); - virtual void RulesMatching(PseudoElementRuleProcessorData* aData); - virtual void RulesMatching(AnonBoxRuleProcessorData* aData); + virtual void RulesMatching(ElementRuleProcessorData* aData) MOZ_OVERRIDE; + virtual void RulesMatching(PseudoElementRuleProcessorData* aData) MOZ_OVERRIDE; + virtual void RulesMatching(AnonBoxRuleProcessorData* aData) MOZ_OVERRIDE; #ifdef MOZ_XUL - virtual void RulesMatching(XULTreeRuleProcessorData* aData); + virtual void RulesMatching(XULTreeRuleProcessorData* aData) MOZ_OVERRIDE; #endif - virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData); - virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData); + virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE; + virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE; virtual nsRestyleHint - HasAttributeDependentStyle(AttributeRuleProcessorData* aData); - virtual bool MediumFeaturesChanged(nsPresContext* aPresContext); + HasAttributeDependentStyle(AttributeRuleProcessorData* aData) MOZ_OVERRIDE; + virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) MOZ_OVERRIDE; virtual NS_MUST_OVERRIDE size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const MOZ_OVERRIDE; virtual NS_MUST_OVERRIDE size_t @@ -94,7 +94,7 @@ private: // nsIStyleRule interface virtual void MapRuleInfoInto(nsRuleData* aRuleData); #ifdef DEBUG - virtual void List(FILE* out = stdout, int32_t aIndent = 0) const; + virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE; #endif nscolor mColor; @@ -115,7 +115,7 @@ private: // nsIStyleRule interface virtual void MapRuleInfoInto(nsRuleData* aRuleData) = 0; #ifdef DEBUG - virtual void List(FILE* out = stdout, int32_t aIndent = 0) const; + virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE; #endif }; diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index cb03b185b133..de4433dfb69c 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -19,6 +19,7 @@ #include "prlog.h" #include "nsStyleAnimation.h" #include "mozilla/Util.h" +#include "sampler.h" #ifdef DEBUG // #define NOISY_DEBUG @@ -368,6 +369,8 @@ nsChangeHint nsStyleContext::CalcStyleDifference(nsStyleContext* aOther, nsChangeHint aParentHintsNotHandledForDescendants) { + SAMPLE_LABEL("nsStyleContext", "CalcStyleDifference"); + NS_ABORT_IF_FALSE(NS_IsHintSubset(aParentHintsNotHandledForDescendants, nsChangeHint_Hints_NotHandledForDescendants), "caller is passing inherited hints, but shouldn't be"); diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index 9828fe715179..41a616f332bd 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -28,6 +28,7 @@ #include "nsAnimationManager.h" #include "nsEventStates.h" #include "mozilla/dom/Element.h" +#include "sampler.h" using namespace mozilla; using namespace mozilla::dom; @@ -714,6 +715,8 @@ nsStyleSet::FileRules(nsIStyleRuleProcessor::EnumFunc aCollectorFunc, void* aData, nsIContent* aContent, nsRuleWalker* aRuleWalker) { + SAMPLE_LABEL("nsStyleSet", "FileRules"); + // Cascading order: // [least important] // - UA normal rules = Agent normal diff --git a/layout/style/nsStyleSet.h b/layout/style/nsStyleSet.h index 8ba8ed7eedbb..d698a4bc556a 100644 --- a/layout/style/nsStyleSet.h +++ b/layout/style/nsStyleSet.h @@ -38,7 +38,7 @@ class nsEmptyStyleRule MOZ_FINAL : public nsIStyleRule NS_DECL_ISUPPORTS virtual void MapRuleInfoInto(nsRuleData* aRuleData); #ifdef DEBUG - virtual void List(FILE* out = stdout, int32_t aIndent = 0) const; + virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE; #endif }; @@ -47,7 +47,7 @@ class nsInitialStyleRule MOZ_FINAL : public nsIStyleRule NS_DECL_ISUPPORTS virtual void MapRuleInfoInto(nsRuleData* aRuleData); #ifdef DEBUG - virtual void List(FILE* out = stdout, int32_t aIndent = 0) const; + virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE; #endif }; diff --git a/layout/style/nsTransitionManager.h b/layout/style/nsTransitionManager.h index d373a4dbeb2a..91700ad2e61b 100644 --- a/layout/style/nsTransitionManager.h +++ b/layout/style/nsTransitionManager.h @@ -8,6 +8,7 @@ #ifndef nsTransitionManager_h_ #define nsTransitionManager_h_ +#include "mozilla/Attributes.h" #include "AnimationCommon.h" #include "nsCSSPseudoElements.h" @@ -135,11 +136,11 @@ public: nsStyleContext *aNewStyleContext); // nsIStyleRuleProcessor (parts) - virtual void RulesMatching(ElementRuleProcessorData* aData); - virtual void RulesMatching(PseudoElementRuleProcessorData* aData); - virtual void RulesMatching(AnonBoxRuleProcessorData* aData); + virtual void RulesMatching(ElementRuleProcessorData* aData) MOZ_OVERRIDE; + virtual void RulesMatching(PseudoElementRuleProcessorData* aData) MOZ_OVERRIDE; + virtual void RulesMatching(AnonBoxRuleProcessorData* aData) MOZ_OVERRIDE; #ifdef MOZ_XUL - virtual void RulesMatching(XULTreeRuleProcessorData* aData); + virtual void RulesMatching(XULTreeRuleProcessorData* aData) MOZ_OVERRIDE; #endif virtual NS_MUST_OVERRIDE size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const MOZ_OVERRIDE; @@ -147,7 +148,7 @@ public: SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const MOZ_OVERRIDE; // nsARefreshObserver - virtual void WillRefresh(mozilla::TimeStamp aTime); + virtual void WillRefresh(mozilla::TimeStamp aTime) MOZ_OVERRIDE; private: void ConsiderStartingTransition(nsCSSProperty aProperty, diff --git a/layout/svg/base/src/nsSVGContainerFrame.h b/layout/svg/base/src/nsSVGContainerFrame.h index 5a275e3fa011..7b630da7f4d4 100644 --- a/layout/svg/base/src/nsSVGContainerFrame.h +++ b/layout/svg/base/src/nsSVGContainerFrame.h @@ -6,6 +6,7 @@ #ifndef NS_SVGCONTAINERFRAME_H #define NS_SVGCONTAINERFRAME_H +#include "mozilla/Attributes.h" #include "gfxMatrix.h" #include "gfxRect.h" #include "nsContainerFrame.h" @@ -111,16 +112,16 @@ public: // nsIFrame: NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, nsIFrame* aPrevInFlow); NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; virtual bool IsSVGTransformed(gfxMatrix *aOwnTransform = nullptr, gfxMatrix *aFromParentTransform = nullptr) const; @@ -128,13 +129,13 @@ public: // nsISVGChildFrame interface: NS_IMETHOD PaintSVG(nsRenderingContext* aContext, const nsIntRect *aDirtyRect); - NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint); - NS_IMETHOD_(nsRect) GetCoveredRegion(); - virtual void ReflowSVG(); - virtual void NotifySVGChanged(uint32_t aFlags); + NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint) MOZ_OVERRIDE; + NS_IMETHOD_(nsRect) GetCoveredRegion() MOZ_OVERRIDE; + virtual void ReflowSVG() MOZ_OVERRIDE; + virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE; virtual SVGBBox GetBBoxContribution(const gfxMatrix &aToBBoxUserspace, - uint32_t aFlags); - NS_IMETHOD_(bool) IsDisplayContainer() { return true; } + uint32_t aFlags) MOZ_OVERRIDE; + NS_IMETHOD_(bool) IsDisplayContainer() MOZ_OVERRIDE { return true; } }; #endif diff --git a/layout/svg/base/src/nsSVGEffects.h b/layout/svg/base/src/nsSVGEffects.h index 428a03112913..3c4ab9d3838b 100644 --- a/layout/svg/base/src/nsSVGEffects.h +++ b/layout/svg/base/src/nsSVGEffects.h @@ -6,6 +6,7 @@ #ifndef NSSVGEFFECTS_H_ #define NSSVGEFFECTS_H_ +#include "mozilla/Attributes.h" #include "FramePropertyTable.h" #include "mozilla/dom/Element.h" #include "nsHashKeys.h" @@ -112,10 +113,10 @@ public: virtual ~nsSVGIDRenderingObserver(); protected: - Element* GetTarget() { return mElement.get(); } + Element* GetTarget() MOZ_OVERRIDE { return mElement.get(); } // This is called when the referenced resource changes. - virtual void DoUpdate(); + virtual void DoUpdate() MOZ_OVERRIDE; class SourceReference : public nsReferencedElement { public: @@ -167,7 +168,7 @@ public: private: // nsSVGRenderingObserver - virtual void DoUpdate(); + virtual void DoUpdate() MOZ_OVERRIDE; }; class nsSVGMarkerProperty : public nsSVGIDRenderingObserver { @@ -176,7 +177,7 @@ public: : nsSVGIDRenderingObserver(aURI, aFrame, aReferenceImage) {} protected: - virtual void DoUpdate(); + virtual void DoUpdate() MOZ_OVERRIDE; }; class nsSVGTextPathProperty : public nsSVGIDRenderingObserver { @@ -185,7 +186,7 @@ public: : nsSVGIDRenderingObserver(aURI, aFrame, aReferenceImage) {} protected: - virtual void DoUpdate(); + virtual void DoUpdate() MOZ_OVERRIDE; }; class nsSVGPaintingProperty : public nsSVGIDRenderingObserver { @@ -194,7 +195,7 @@ public: : nsSVGIDRenderingObserver(aURI, aFrame, aReferenceImage) {} protected: - virtual void DoUpdate(); + virtual void DoUpdate() MOZ_OVERRIDE; }; /** diff --git a/layout/svg/base/src/nsSVGForeignObjectFrame.h b/layout/svg/base/src/nsSVGForeignObjectFrame.h index e10ce5e3d957..78806107e2e4 100644 --- a/layout/svg/base/src/nsSVGForeignObjectFrame.h +++ b/layout/svg/base/src/nsSVGForeignObjectFrame.h @@ -6,6 +6,7 @@ #ifndef NSSVGFOREIGNOBJECTFRAME_H__ #define NSSVGFOREIGNOBJECTFRAME_H__ +#include "mozilla/Attributes.h" #include "nsContainerFrame.h" #include "nsIPresShell.h" #include "nsISVGChildFrame.h" @@ -83,13 +84,13 @@ public: // nsISVGChildFrame interface: NS_IMETHOD PaintSVG(nsRenderingContext *aContext, const nsIntRect *aDirtyRect); - NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint); - NS_IMETHOD_(nsRect) GetCoveredRegion(); - virtual void ReflowSVG(); - virtual void NotifySVGChanged(uint32_t aFlags); + NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint) MOZ_OVERRIDE; + NS_IMETHOD_(nsRect) GetCoveredRegion() MOZ_OVERRIDE; + virtual void ReflowSVG() MOZ_OVERRIDE; + virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE; virtual SVGBBox GetBBoxContribution(const gfxMatrix &aToBBoxUserspace, - uint32_t aFlags); - NS_IMETHOD_(bool) IsDisplayContainer() { return true; } + uint32_t aFlags) MOZ_OVERRIDE; + NS_IMETHOD_(bool) IsDisplayContainer() MOZ_OVERRIDE { return true; } gfxMatrix GetCanvasTM(uint32_t aFor); diff --git a/layout/svg/base/src/nsSVGGlyphFrame.h b/layout/svg/base/src/nsSVGGlyphFrame.h index 80667854fced..c7e43d7653dc 100644 --- a/layout/svg/base/src/nsSVGGlyphFrame.h +++ b/layout/svg/base/src/nsSVGGlyphFrame.h @@ -6,6 +6,7 @@ #ifndef __NS_SVGGLYPHFRAME_H__ #define __NS_SVGGLYPHFRAME_H__ +#include "mozilla/Attributes.h" #include "gfxFont.h" #include "nsISVGGlyphFragmentNode.h" #include "nsISVGChildFrame.h" @@ -155,14 +156,14 @@ public: // These four always use the global transform, even if NS_STATE_NONDISPLAY_CHILD NS_IMETHOD PaintSVG(nsRenderingContext *aContext, const nsIntRect *aDirtyRect); - NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint); + NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint) MOZ_OVERRIDE; virtual SVGBBox GetBBoxContribution(const gfxMatrix &aToBBoxUserspace, - uint32_t aFlags); + uint32_t aFlags) MOZ_OVERRIDE; - NS_IMETHOD_(nsRect) GetCoveredRegion(); - virtual void ReflowSVG(); - virtual void NotifySVGChanged(uint32_t aFlags); - NS_IMETHOD_(bool) IsDisplayContainer() { return false; } + NS_IMETHOD_(nsRect) GetCoveredRegion() MOZ_OVERRIDE; + virtual void ReflowSVG() MOZ_OVERRIDE; + virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE; + NS_IMETHOD_(bool) IsDisplayContainer() MOZ_OVERRIDE { return false; } // nsSVGGeometryFrame methods gfxMatrix GetCanvasTM(uint32_t aFor); @@ -170,12 +171,12 @@ public: // nsISVGGlyphFragmentNode interface: // These do not use the global transform if NS_STATE_NONDISPLAY_CHILD virtual uint32_t GetNumberOfChars(); - virtual float GetComputedTextLength(); - virtual float GetSubStringLength(uint32_t charnum, uint32_t fragmentChars); - virtual int32_t GetCharNumAtPosition(nsIDOMSVGPoint *point); - NS_IMETHOD_(nsSVGGlyphFrame *) GetFirstGlyphFrame(); - NS_IMETHOD_(nsSVGGlyphFrame *) GetNextGlyphFrame(); - NS_IMETHOD_(void) SetWhitespaceCompression(bool aCompressWhitespace) { + virtual float GetComputedTextLength() MOZ_OVERRIDE; + virtual float GetSubStringLength(uint32_t charnum, uint32_t fragmentChars) MOZ_OVERRIDE; + virtual int32_t GetCharNumAtPosition(nsIDOMSVGPoint *point) MOZ_OVERRIDE; + NS_IMETHOD_(nsSVGGlyphFrame *) GetFirstGlyphFrame() MOZ_OVERRIDE; + NS_IMETHOD_(nsSVGGlyphFrame *) GetNextGlyphFrame() MOZ_OVERRIDE; + NS_IMETHOD_(void) SetWhitespaceCompression(bool aCompressWhitespace) MOZ_OVERRIDE { if (mCompressWhitespace != aCompressWhitespace) { mCompressWhitespace = aCompressWhitespace; ClearTextRun(); diff --git a/layout/svg/base/src/nsSVGPathGeometryFrame.h b/layout/svg/base/src/nsSVGPathGeometryFrame.h index e6ba7c58295e..c3338b13ac7f 100644 --- a/layout/svg/base/src/nsSVGPathGeometryFrame.h +++ b/layout/svg/base/src/nsSVGPathGeometryFrame.h @@ -6,6 +6,7 @@ #ifndef __NS_SVGPATHGEOMETRYFRAME_H__ #define __NS_SVGPATHGEOMETRYFRAME_H__ +#include "mozilla/Attributes.h" #include "gfxMatrix.h" #include "gfxRect.h" #include "nsFrame.h" @@ -84,13 +85,13 @@ protected: // nsISVGChildFrame interface: NS_IMETHOD PaintSVG(nsRenderingContext *aContext, const nsIntRect *aDirtyRect); - NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint); - NS_IMETHOD_(nsRect) GetCoveredRegion(); - virtual void ReflowSVG(); - virtual void NotifySVGChanged(uint32_t aFlags); + NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint) MOZ_OVERRIDE; + NS_IMETHOD_(nsRect) GetCoveredRegion() MOZ_OVERRIDE; + virtual void ReflowSVG() MOZ_OVERRIDE; + virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE; virtual SVGBBox GetBBoxContribution(const gfxMatrix &aToBBoxUserspace, - uint32_t aFlags); - NS_IMETHOD_(bool) IsDisplayContainer() { return false; } + uint32_t aFlags) MOZ_OVERRIDE; + NS_IMETHOD_(bool) IsDisplayContainer() MOZ_OVERRIDE { return false; } protected: void GeneratePath(gfxContext *aContext, const gfxMatrix &aTransform); diff --git a/layout/svg/base/src/nsSVGTSpanFrame.h b/layout/svg/base/src/nsSVGTSpanFrame.h index d32b24e4faf0..5c8a9a2e982f 100644 --- a/layout/svg/base/src/nsSVGTSpanFrame.h +++ b/layout/svg/base/src/nsSVGTSpanFrame.h @@ -6,6 +6,7 @@ #ifndef NSSVGTSPANFRAME_H #define NSSVGTSPANFRAME_H +#include "mozilla/Attributes.h" #include "gfxMatrix.h" #include "nsFrame.h" #include "nsISVGGlyphFragmentNode.h" @@ -65,12 +66,12 @@ public: // nsISVGGlyphFragmentNode interface: virtual uint32_t GetNumberOfChars(); - virtual float GetComputedTextLength(); - virtual float GetSubStringLength(uint32_t charnum, uint32_t fragmentChars); - virtual int32_t GetCharNumAtPosition(nsIDOMSVGPoint *point); - NS_IMETHOD_(nsSVGGlyphFrame *) GetFirstGlyphFrame(); - NS_IMETHOD_(nsSVGGlyphFrame *) GetNextGlyphFrame(); - NS_IMETHOD_(void) SetWhitespaceCompression(bool aCompressWhitespace); + virtual float GetComputedTextLength() MOZ_OVERRIDE; + virtual float GetSubStringLength(uint32_t charnum, uint32_t fragmentChars) MOZ_OVERRIDE; + virtual int32_t GetCharNumAtPosition(nsIDOMSVGPoint *point) MOZ_OVERRIDE; + NS_IMETHOD_(nsSVGGlyphFrame *) GetFirstGlyphFrame() MOZ_OVERRIDE; + NS_IMETHOD_(nsSVGGlyphFrame *) GetNextGlyphFrame() MOZ_OVERRIDE; + NS_IMETHOD_(void) SetWhitespaceCompression(bool aCompressWhitespace) MOZ_OVERRIDE; }; #endif diff --git a/layout/svg/base/src/nsSVGTextContainerFrame.h b/layout/svg/base/src/nsSVGTextContainerFrame.h index 1494a0c315e9..ce2f2e68fb5a 100644 --- a/layout/svg/base/src/nsSVGTextContainerFrame.h +++ b/layout/svg/base/src/nsSVGTextContainerFrame.h @@ -6,6 +6,7 @@ #ifndef NS_SVGTEXTCONTAINERFRAME_H #define NS_SVGTEXTCONTAINERFRAME_H +#include "mozilla/Attributes.h" #include "nsFrame.h" #include "nsIFrame.h" #include "nsISVGChildFrame.h" @@ -40,8 +41,8 @@ public: // nsIFrame NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); - NS_IMETHOD RemoveFrame(ChildListID aListID, nsIFrame *aOldFrame); + nsFrameList& aFrameList) MOZ_OVERRIDE; + NS_IMETHOD RemoveFrame(ChildListID aListID, nsIFrame *aOldFrame) MOZ_OVERRIDE; NS_IMETHOD GetStartPositionOfChar(uint32_t charnum, nsIDOMSVGPoint **_retval); NS_IMETHOD GetEndPositionOfChar(uint32_t charnum, nsIDOMSVGPoint **_retval); diff --git a/layout/tables/BasicTableLayoutStrategy.h b/layout/tables/BasicTableLayoutStrategy.h index a77037030a66..132f0dcacf68 100644 --- a/layout/tables/BasicTableLayoutStrategy.h +++ b/layout/tables/BasicTableLayoutStrategy.h @@ -12,6 +12,7 @@ #ifndef BasicTableLayoutStrategy_h_ #define BasicTableLayoutStrategy_h_ +#include "mozilla/Attributes.h" #include "nsITableLayoutStrategy.h" class nsTableFrame; @@ -23,11 +24,11 @@ public: virtual ~BasicTableLayoutStrategy(); // nsITableLayoutStrategy implementation - virtual nscoord GetMinWidth(nsRenderingContext* aRenderingContext); + virtual nscoord GetMinWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE; virtual nscoord GetPrefWidth(nsRenderingContext* aRenderingContext, - bool aComputingSize); - virtual void MarkIntrinsicWidthsDirty(); - virtual void ComputeColumnWidths(const nsHTMLReflowState& aReflowState); + bool aComputingSize) MOZ_OVERRIDE; + virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE; + virtual void ComputeColumnWidths(const nsHTMLReflowState& aReflowState) MOZ_OVERRIDE; private: // NOTE: Using prefix "BTLS" to avoid overlapping names with diff --git a/layout/tables/FixedTableLayoutStrategy.h b/layout/tables/FixedTableLayoutStrategy.h index c6ad72f0d71c..52176f12186d 100644 --- a/layout/tables/FixedTableLayoutStrategy.h +++ b/layout/tables/FixedTableLayoutStrategy.h @@ -12,6 +12,7 @@ #ifndef FixedTableLayoutStrategy_h_ #define FixedTableLayoutStrategy_h_ +#include "mozilla/Attributes.h" #include "nsITableLayoutStrategy.h" class nsTableFrame; @@ -23,11 +24,11 @@ public: virtual ~FixedTableLayoutStrategy(); // nsITableLayoutStrategy implementation - virtual nscoord GetMinWidth(nsRenderingContext* aRenderingContext); + virtual nscoord GetMinWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE; virtual nscoord GetPrefWidth(nsRenderingContext* aRenderingContext, - bool aComputingSize); - virtual void MarkIntrinsicWidthsDirty(); - virtual void ComputeColumnWidths(const nsHTMLReflowState& aReflowState); + bool aComputingSize) MOZ_OVERRIDE; + virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE; + virtual void ComputeColumnWidths(const nsHTMLReflowState& aReflowState) MOZ_OVERRIDE; private: nsTableFrame *mTableFrame; diff --git a/layout/tables/nsTableCellFrame.h b/layout/tables/nsTableCellFrame.h index 99e1c14765c5..da7d3fed0d19 100644 --- a/layout/tables/nsTableCellFrame.h +++ b/layout/tables/nsTableCellFrame.h @@ -5,6 +5,7 @@ #ifndef nsTableCellFrame_h__ #define nsTableCellFrame_h__ +#include "mozilla/Attributes.h" #include "nsITableCellLayout.h" #include "nscore.h" #include "nsContainerFrame.h" @@ -68,12 +69,12 @@ public: // so these functions should never be called. They assert and return // NS_ERROR_NOT_IMPLEMENTED NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; virtual nsIFrame* GetContentInsertionFrame() { return GetFirstPrincipalChild()->GetContentInsertionFrame(); @@ -83,7 +84,7 @@ public: virtual void NotifyPercentHeight(const nsHTMLReflowState& aReflowState); - virtual bool NeedsToObserve(const nsHTMLReflowState& aReflowState); + virtual bool NeedsToObserve(const nsHTMLReflowState& aReflowState) MOZ_OVERRIDE; /** instantiate a new instance of nsTableRowFrame. * @param aPresShell the pres shell for this frame @@ -94,7 +95,7 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; void PaintCellBackground(nsRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsPoint aPt, @@ -164,7 +165,7 @@ public: NS_IMETHOD GetCellIndexes(int32_t &aRowIndex, int32_t &aColIndex); /** return the mapped cell's row index (starting at 0 for the first row) */ - virtual nsresult GetRowIndex(int32_t &aRowIndex) const; + virtual nsresult GetRowIndex(int32_t &aRowIndex) const MOZ_OVERRIDE; /** * return the cell's specified col span. this is what was specified in the @@ -175,7 +176,7 @@ public: virtual int32_t GetColSpan(); /** return the cell's column index (starting at 0 for the first column) */ - virtual nsresult GetColIndex(int32_t &aColIndex) const; + virtual nsresult GetColIndex(int32_t &aColIndex) const MOZ_OVERRIDE; void SetColIndex(int32_t aColIndex); /** return the available width given to this frame during its last reflow */ @@ -286,13 +287,13 @@ public: ~nsBCTableCellFrame(); - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; virtual nsMargin GetUsedBorder() const; virtual bool GetBorderRadii(nscoord aRadii[8]) const; // Get the *inner half of the border only*, in twips. - virtual nsMargin* GetBorderWidth(nsMargin& aBorder) const; + virtual nsMargin* GetBorderWidth(nsMargin& aBorder) const MOZ_OVERRIDE; // Get the *inner half of the border only*, in pixels. BCPixelSize GetBorderWidth(mozilla::css::Side aSide) const; @@ -300,16 +301,16 @@ public: // Set the full (both halves) width of the border void SetBorderWidth(mozilla::css::Side aSide, BCPixelSize aPixelValue); - virtual nsMargin GetBorderOverflow(); + virtual nsMargin GetBorderOverflow() MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif virtual void PaintBackground(nsRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsPoint aPt, - uint32_t aFlags); + uint32_t aFlags) MOZ_OVERRIDE; private: diff --git a/layout/tables/nsTableColFrame.h b/layout/tables/nsTableColFrame.h index 6d2f5d8cca9c..5acfd5953962 100644 --- a/layout/tables/nsTableColFrame.h +++ b/layout/tables/nsTableColFrame.h @@ -5,6 +5,7 @@ #ifndef nsTableColFrame_h__ #define nsTableColFrame_h__ +#include "mozilla/Attributes.h" #include "nscore.h" #include "nsContainerFrame.h" #include "nsTablePainter.h" @@ -39,7 +40,7 @@ public: friend nsTableColFrame* NS_NewTableColFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); /** @see nsIFrame::DidSetStyleContext */ - virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext); + virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; int32_t GetColIndex() const; @@ -50,7 +51,7 @@ public: NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; /** * Table columns never paint anything, nor receive events. @@ -64,13 +65,13 @@ public: * * @see nsGkAtoms::tableColFrame */ - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif - virtual nsSplittableType GetSplittableType() const; + virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE; /** return the number of the columns the col represents. always >= 1 */ int32_t GetSpan(); diff --git a/layout/tables/nsTableColGroupFrame.h b/layout/tables/nsTableColGroupFrame.h index 9822953c4bc3..724a364417e4 100644 --- a/layout/tables/nsTableColGroupFrame.h +++ b/layout/tables/nsTableColGroupFrame.h @@ -5,6 +5,7 @@ #ifndef nsTableColGroupFrame_h__ #define nsTableColGroupFrame_h__ +#include "mozilla/Attributes.h" #include "nscore.h" #include "nsContainerFrame.h" #include "nsTableColFrame.h" @@ -42,7 +43,7 @@ public: * @see nsIFrame::SetInitialChildList */ NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; /** * ColGroups never paint anything, nor receive events. @@ -77,17 +78,17 @@ public: static nsTableColGroupFrame* GetLastRealColGroup(nsTableFrame* aTableFrame); /** @see nsIFrame::DidSetStyleContext */ - virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext); + virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; /** @see nsIFrame::AppendFrames, InsertFrames, RemoveFrame */ NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; /** remove the column aChild from the column group, if requested renumber * the subsequent columns in this column group and all following column @@ -108,14 +109,14 @@ public: NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; /** * Get the "type" of the frame * * @see nsGkAtoms::tableColGroupFrame */ - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; /** Add column frames to the table storages: colframe cache and cellmap * this doesn't change the mFrames of the colgroup frame. @@ -136,7 +137,7 @@ public: const nsFrameList::Slice& aCols); #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; void Dump(int32_t aIndent); #endif diff --git a/layout/tables/nsTableOuterFrame.h b/layout/tables/nsTableOuterFrame.h index 1f04365d8879..f0d2e5240ab4 100644 --- a/layout/tables/nsTableOuterFrame.h +++ b/layout/tables/nsTableOuterFrame.h @@ -5,6 +5,7 @@ #ifndef nsTableOuterFrame_h__ #define nsTableOuterFrame_h__ +#include "mozilla/Attributes.h" #include "nscore.h" #include "nsContainerFrame.h" #include "nsBlockFrame.h" @@ -28,11 +29,11 @@ public: virtual nsIFrame* GetParentStyleContextFrame() const; #ifdef ACCESSIBILITY - virtual already_AddRefed CreateAccessible(); + virtual already_AddRefed CreateAccessible() MOZ_OVERRIDE; #endif #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif protected: @@ -68,32 +69,32 @@ public: virtual void DestroyFrom(nsIFrame* aDestructRoot); NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; virtual const nsFrameList& GetChildList(ChildListID aListID) const; - virtual void GetChildLists(nsTArray* aLists) const; + virtual void GetChildLists(nsTArray* aLists) const MOZ_OVERRIDE; NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; virtual nsIFrame* GetContentInsertionFrame() { return GetFirstPrincipalChild()->GetContentInsertionFrame(); } #ifdef ACCESSIBILITY - virtual already_AddRefed CreateAccessible(); + virtual already_AddRefed CreateAccessible() MOZ_OVERRIDE; #endif NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; nsresult BuildDisplayListForInnerTable(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, @@ -101,12 +102,12 @@ public: virtual nscoord GetBaseline() const; - virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); - virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext); + virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; + virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext, nsSize aCBSize, nscoord aAvailableWidth, nsSize aMargin, nsSize aBorder, - nsSize aPadding, bool aShrinkWrap); + nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE; /** process a reflow command for the table. * This involves reflowing the caption and the inner table. @@ -114,20 +115,20 @@ public: NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; /** * Get the "type" of the frame * * @see nsGkAtoms::tableOuterFrame */ - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif - virtual nsIFrame* GetParentStyleContextFrame() const; + virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE; /*---------------- nsITableLayout methods ------------------------*/ @@ -140,10 +141,10 @@ public: bool& aIsSelected); /** @see nsITableFrame::GetTableSize */ - NS_IMETHOD GetTableSize(int32_t& aRowCount, int32_t& aColCount); + NS_IMETHOD GetTableSize(int32_t& aRowCount, int32_t& aColCount) MOZ_OVERRIDE; - NS_IMETHOD GetIndexByRowAndColumn(int32_t aRow, int32_t aColumn, int32_t *aIndex); - NS_IMETHOD GetRowAndColumnByIndex(int32_t aIndex, int32_t *aRow, int32_t *aColumn); + NS_IMETHOD GetIndexByRowAndColumn(int32_t aRow, int32_t aColumn, int32_t *aIndex) MOZ_OVERRIDE; + NS_IMETHOD GetRowAndColumnByIndex(int32_t aIndex, int32_t *aRow, int32_t *aColumn) MOZ_OVERRIDE; protected: diff --git a/layout/tables/nsTableRowFrame.h b/layout/tables/nsTableRowFrame.h index 3515c546bea1..a14959f79cfa 100644 --- a/layout/tables/nsTableRowFrame.h +++ b/layout/tables/nsTableRowFrame.h @@ -5,6 +5,7 @@ #ifndef nsTableRowFrame_h__ #define nsTableRowFrame_h__ +#include "mozilla/Attributes.h" #include "nscore.h" #include "nsContainerFrame.h" #include "nsTablePainter.h" @@ -43,17 +44,17 @@ public: NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* aPrevInFlow); + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; /** @see nsIFrame::DidSetStyleContext */ virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext); NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; /** instantiate a new instance of nsTableRowFrame. * @param aPresShell the pres shell for this frame @@ -68,7 +69,7 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; nsTableCellFrame* GetFirstCell() ; @@ -88,7 +89,7 @@ public: NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; void DidResize(); @@ -97,10 +98,10 @@ public: * * @see nsGkAtoms::tableRowFrame */ - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif void UpdateHeight(nscoord aHeight, @@ -224,7 +225,7 @@ public: BCPixelSize aPixelValue); #ifdef ACCESSIBILITY - virtual already_AddRefed CreateAccessible(); + virtual already_AddRefed CreateAccessible() MOZ_OVERRIDE; #endif protected: diff --git a/layout/tables/nsTableRowGroupFrame.h b/layout/tables/nsTableRowGroupFrame.h index 4317a8734491..f011fd9763f1 100644 --- a/layout/tables/nsTableRowGroupFrame.h +++ b/layout/tables/nsTableRowGroupFrame.h @@ -5,6 +5,7 @@ #ifndef nsTableRowGroupFrame_h__ #define nsTableRowGroupFrame_h__ +#include "mozilla/Attributes.h" #include "nscore.h" #include "nsContainerFrame.h" #include "nsIAtom.h" @@ -79,14 +80,14 @@ public: virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext); NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; virtual nsMargin GetUsedMargin() const; virtual nsMargin GetUsedBorder() const; @@ -94,7 +95,7 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; /** calls Reflow for all of its child rows. * Rows are all set to the same width and stacked vertically. @@ -185,7 +186,7 @@ public: // nsILineIterator methods public: - virtual void DisposeLineIterator() { } + virtual void DisposeLineIterator() MOZ_OVERRIDE { } // The table row is the equivalent to a line in block layout. // The nsILineIterator assumes that a line resides in a block, this role is @@ -197,12 +198,12 @@ public: /** Get the number of rows in a row group * @return the number of lines in a row group */ - virtual int32_t GetNumLines(); + virtual int32_t GetNumLines() MOZ_OVERRIDE; /** @see nsILineIterator.h GetDirection * @return true if the table is rtl */ - virtual bool GetDirection(); + virtual bool GetDirection() MOZ_OVERRIDE; /** Return structural information about a line. * @param aLineNumber - the index of the row relative to the row group @@ -220,7 +221,7 @@ public: nsIFrame** aFirstFrameOnLine, int32_t* aNumFramesOnLine, nsRect& aLineBounds, - uint32_t* aLineFlags); + uint32_t* aLineFlags) MOZ_OVERRIDE; /** Given a frame that's a child of the rowgroup, find which line its on. * @param aFrame - frame, should be a row @@ -229,7 +230,7 @@ public: * frame and the index is at least aStartLine. * -1 if the frame cannot be found. */ - virtual int32_t FindLineContaining(nsIFrame* aFrame, int32_t aStartLine = 0); + virtual int32_t FindLineContaining(nsIFrame* aFrame, int32_t aStartLine = 0) MOZ_OVERRIDE; /** Find the orginating cell frame on a row that is the nearest to the * coordinate X. @@ -246,7 +247,7 @@ public: nscoord aX, nsIFrame** aFrameFound, bool* aXIsBeforeFirstFrame, - bool* aXIsAfterLastFrame); + bool* aXIsAfterLastFrame) MOZ_OVERRIDE; #ifdef IBMBIDI /** Check whether visual and logical order of cell frames within a line are @@ -260,7 +261,7 @@ public: NS_IMETHOD CheckLineOrder(int32_t aLine, bool *aIsReordered, nsIFrame **aFirstVisual, - nsIFrame **aLastVisual); + nsIFrame **aLastVisual) MOZ_OVERRIDE; #endif /** Find the next originating cell frame that originates in the row. @@ -268,7 +269,7 @@ public: * originating in a row * @param aLineNumber - the index of the row relative to the table */ - NS_IMETHOD GetNextSiblingOnLine(nsIFrame*& aFrame, int32_t aLineNumber); + NS_IMETHOD GetNextSiblingOnLine(nsIFrame*& aFrame, int32_t aLineNumber) MOZ_OVERRIDE; // row cursor methods to speed up searching for the row(s) // containing a point. The basic idea is that we set the cursor diff --git a/layout/tools/reftest/reftest.js b/layout/tools/reftest/reftest.js index b34280162655..0afa0ec578ad 100644 --- a/layout/tools/reftest/reftest.js +++ b/layout/tools/reftest/reftest.js @@ -1484,26 +1484,30 @@ function RecordResult(testRunTime, errorMsg, scriptResults) gURLs[0].prettyPath + " | "; // the URL being tested switch (gURLs[0].type) { case TYPE_REFTEST_NOTEQUAL: - result += "image comparison (!=) "; + result += "image comparison (!=)"; break; case TYPE_REFTEST_EQUAL: - result += "image comparison (==) "; + result += "image comparison (==)"; break; } - gDumpLog(result + "\n"); if (!test_passed && expected == EXPECTED_PASS || !test_passed && expected == EXPECTED_FUZZY || test_passed && expected == EXPECTED_FAIL) { if (!equal) { - gDumpLog("REFTEST IMAGE 1 (TEST): " + gCanvas1.toDataURL() + "\n"); - gDumpLog("REFTEST IMAGE 2 (REFERENCE): " + gCanvas2.toDataURL() + "\n"); - gDumpLog("REFTEST max difference: " + maxDifference.value + " number of differing pixels: " + differences + "\n"); + result += ", max difference: " + maxDifference.value + ", number of differing pixels: " + differences + "\n"; + result += "REFTEST IMAGE 1 (TEST): " + gCanvas1.toDataURL() + "\n"; + result += "REFTEST IMAGE 2 (REFERENCE): " + gCanvas2.toDataURL() + "\n"; } else { + result += "\n"; gDumpLog("REFTEST IMAGE: " + gCanvas1.toDataURL() + "\n"); } + } else { + result += "\n"; } + gDumpLog(result); + if (!test_passed && expected == EXPECTED_PASS) { FlushTestLog(); } diff --git a/layout/xul/base/src/grid/nsGridLayout2.h b/layout/xul/base/src/grid/nsGridLayout2.h index 1d5b37fe25a8..9307fd51c875 100644 --- a/layout/xul/base/src/grid/nsGridLayout2.h +++ b/layout/xul/base/src/grid/nsGridLayout2.h @@ -7,6 +7,7 @@ #ifndef nsGridLayout2_h___ #define nsGridLayout2_h___ +#include "mozilla/Attributes.h" #include "nsStackLayout.h" #include "nsIGridPart.h" #include "nsCoord.h" @@ -31,23 +32,23 @@ public: NS_DECL_ISUPPORTS_INHERITED - NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); + NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; virtual void IntrinsicWidthsDirty(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); virtual nsGridRowGroupLayout* CastToRowGroupLayout() { return nullptr; } - virtual nsGridLayout2* CastToGridLayout() { return this; } - virtual nsGrid* GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor=nullptr); - virtual nsIGridPart* GetParentGridPart(nsIFrame* aBox, nsIFrame** aParentBox) { + virtual nsGridLayout2* CastToGridLayout() MOZ_OVERRIDE { return this; } + virtual nsGrid* GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor=nullptr) MOZ_OVERRIDE; + virtual nsIGridPart* GetParentGridPart(nsIFrame* aBox, nsIFrame** aParentBox) MOZ_OVERRIDE { NS_NOTREACHED("Should not be called"); return nullptr; } - virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); - virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); - virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); - virtual void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount) { aRowCount++; } - virtual void DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) { } - virtual int32_t BuildRows(nsIFrame* aBox, nsGridRow* aRows); - virtual nsMargin GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal); - virtual Type GetType() { return eGrid; } + virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount) MOZ_OVERRIDE { aRowCount++; } + virtual void DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE { } + virtual int32_t BuildRows(nsIFrame* aBox, nsGridRow* aRows) MOZ_OVERRIDE; + virtual nsMargin GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) MOZ_OVERRIDE; + virtual Type GetType() MOZ_OVERRIDE { return eGrid; } virtual void ChildrenInserted(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aPrevBox, const nsFrameList::Slice& aNewChildren); diff --git a/layout/xul/base/src/grid/nsGridRowGroupFrame.h b/layout/xul/base/src/grid/nsGridRowGroupFrame.h index e721a299f721..d1621298b5ff 100644 --- a/layout/xul/base/src/grid/nsGridRowGroupFrame.h +++ b/layout/xul/base/src/grid/nsGridRowGroupFrame.h @@ -14,6 +14,7 @@ #ifndef nsGridRowGroupFrame_h___ #define nsGridRowGroupFrame_h___ +#include "mozilla/Attributes.h" #include "nsBoxFrame.h" /** @@ -28,7 +29,7 @@ public: NS_DECL_FRAMEARENA_HELPERS #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { return MakeFrameName(NS_LITERAL_STRING("nsGridRowGroup"), aResult); } @@ -39,7 +40,7 @@ public: nsBoxLayout* aLayoutManager): nsBoxFrame(aPresShell, aContext, false, aLayoutManager) {} - virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState); + virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; }; // class nsGridRowGroupFrame diff --git a/layout/xul/base/src/grid/nsGridRowGroupLayout.h b/layout/xul/base/src/grid/nsGridRowGroupLayout.h index 004a87957ffa..106c92ec6117 100644 --- a/layout/xul/base/src/grid/nsGridRowGroupLayout.h +++ b/layout/xul/base/src/grid/nsGridRowGroupLayout.h @@ -13,6 +13,7 @@ #ifndef nsGridRowGroupLayout_h___ #define nsGridRowGroupLayout_h___ +#include "mozilla/Attributes.h" #include "nsGridRowLayout.h" /** @@ -28,18 +29,18 @@ public: virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); - virtual void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount); - virtual void DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState); - virtual int32_t BuildRows(nsIFrame* aBox, nsGridRow* aRows); - virtual nsMargin GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal); - virtual int32_t GetRowCount() { return mRowCount; } - virtual Type GetType() { return eRowGroup; } + virtual void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount) MOZ_OVERRIDE; + virtual void DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE; + virtual int32_t BuildRows(nsIFrame* aBox, nsGridRow* aRows) MOZ_OVERRIDE; + virtual nsMargin GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) MOZ_OVERRIDE; + virtual int32_t GetRowCount() MOZ_OVERRIDE { return mRowCount; } + virtual Type GetType() MOZ_OVERRIDE { return eRowGroup; } protected: nsGridRowGroupLayout(); virtual ~nsGridRowGroupLayout(); - virtual void ChildAddedOrRemoved(nsIFrame* aBox, nsBoxLayoutState& aState); + virtual void ChildAddedOrRemoved(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE; static void AddWidth(nsSize& aSize, nscoord aSize2, bool aIsHorizontal); private: diff --git a/layout/xul/base/src/grid/nsGridRowLayout.h b/layout/xul/base/src/grid/nsGridRowLayout.h index 06ade23b7ab3..94e40d9dab8c 100644 --- a/layout/xul/base/src/grid/nsGridRowLayout.h +++ b/layout/xul/base/src/grid/nsGridRowLayout.h @@ -13,6 +13,7 @@ #ifndef nsGridRowLayout_h___ #define nsGridRowLayout_h___ +#include "mozilla/Attributes.h" #include "nsSprocketLayout.h" #include "nsIGridPart.h" class nsGridRowGroupLayout; @@ -34,9 +35,9 @@ public: NS_DECL_ISUPPORTS_INHERITED virtual nsGridRowGroupLayout* CastToRowGroupLayout() { return nullptr; } - virtual nsGridLayout2* CastToGridLayout() { return nullptr; } - virtual nsGrid* GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor=nullptr); - virtual nsIGridPart* GetParentGridPart(nsIFrame* aBox, nsIFrame** aParentBox); + virtual nsGridLayout2* CastToGridLayout() MOZ_OVERRIDE { return nullptr; } + virtual nsGrid* GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor=nullptr) MOZ_OVERRIDE; + virtual nsIGridPart* GetParentGridPart(nsIFrame* aBox, nsIFrame** aParentBox) MOZ_OVERRIDE; virtual void ChildrenInserted(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aPrevBox, const nsFrameList::Slice& aNewChildren); @@ -44,7 +45,7 @@ public: const nsFrameList::Slice& aNewChildren); virtual void ChildrenRemoved(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList); virtual void ChildrenSet(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList); - virtual nsMargin GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal); + virtual nsMargin GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) MOZ_OVERRIDE; virtual nsIGridPart* AsGridPart() { return this; } diff --git a/layout/xul/base/src/grid/nsGridRowLeafFrame.h b/layout/xul/base/src/grid/nsGridRowLeafFrame.h index 58dc348dd7e7..9d1ee798c924 100644 --- a/layout/xul/base/src/grid/nsGridRowLeafFrame.h +++ b/layout/xul/base/src/grid/nsGridRowLeafFrame.h @@ -14,6 +14,7 @@ #ifndef nsGridRowLeafFrame_h___ #define nsGridRowLeafFrame_h___ +#include "mozilla/Attributes.h" #include "nsBoxFrame.h" /** @@ -32,7 +33,7 @@ public: nsStyleContext* aContext); #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { return MakeFrameName(NS_LITERAL_STRING("nsGridRowLeaf"), aResult); } diff --git a/layout/xul/base/src/grid/nsGridRowLeafLayout.h b/layout/xul/base/src/grid/nsGridRowLeafLayout.h index 489965a0fc1f..0b9e4e29f5fc 100644 --- a/layout/xul/base/src/grid/nsGridRowLeafLayout.h +++ b/layout/xul/base/src/grid/nsGridRowLeafLayout.h @@ -13,6 +13,7 @@ #ifndef nsGridRowLeafLayout_h___ #define nsGridRowLeafLayout_h___ +#include "mozilla/Attributes.h" #include "nsGridRowLayout.h" #include "nsCOMPtr.h" @@ -31,22 +32,22 @@ public: virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); virtual void ChildAddedOrRemoved(nsIFrame* aBox, nsBoxLayoutState& aState); - NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); - virtual void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount); - virtual void DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState); - virtual int32_t BuildRows(nsIFrame* aBox, nsGridRow* aRows); - virtual Type GetType() { return eRowLeaf; } + NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount) MOZ_OVERRIDE; + virtual void DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE; + virtual int32_t BuildRows(nsIFrame* aBox, nsGridRow* aRows) MOZ_OVERRIDE; + virtual Type GetType() MOZ_OVERRIDE { return eRowLeaf; } protected: virtual void PopulateBoxSizes(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState, nsBoxSize*& aBoxSizes, nscoord& aMinSize, - nscoord& aMaxSize, int32_t& aFlexes); + nscoord& aMaxSize, int32_t& aFlexes) MOZ_OVERRIDE; virtual void ComputeChildSizes(nsIFrame* aBox, nsBoxLayoutState& aState, nscoord& aGivenSize, nsBoxSize* aBoxSizes, - nsComputedBoxSize*& aComputedBoxSizes); + nsComputedBoxSize*& aComputedBoxSizes) MOZ_OVERRIDE; nsGridRowLeafLayout(); diff --git a/layout/xul/base/src/nsBoxFrame.h b/layout/xul/base/src/nsBoxFrame.h index cd788b33bab2..32ce51f8afad 100644 --- a/layout/xul/base/src/nsBoxFrame.h +++ b/layout/xul/base/src/nsBoxFrame.h @@ -14,6 +14,7 @@ #ifndef nsBoxFrame_h___ #define nsBoxFrame_h___ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsContainerFrame.h" #include "nsBoxLayout.h" @@ -70,13 +71,13 @@ public: virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState); #ifdef DEBUG_LAYOUT NS_IMETHOD SetDebug(nsBoxLayoutState& aBoxLayoutState, bool aDebug); - NS_IMETHOD GetDebug(bool& aDebug); + NS_IMETHOD GetDebug(bool& aDebug) MOZ_OVERRIDE; #endif - virtual Valignment GetVAlign() const { return mValign; } - virtual Halignment GetHAlign() const { return mHalign; } + virtual Valignment GetVAlign() const MOZ_OVERRIDE { return mValign; } + virtual Halignment GetHAlign() const MOZ_OVERRIDE { return mHalign; } NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState); - virtual bool ComputesOwnOverflowArea() { return false; } + virtual bool ComputesOwnOverflowArea() MOZ_OVERRIDE { return false; } // ----- child and sibling operations --- @@ -84,40 +85,40 @@ public: NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* asPrevInFlow); + nsIFrame* asPrevInFlow) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; - virtual void MarkIntrinsicWidthsDirty(); - virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); - virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext); + virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE; + virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; + virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; virtual nsIFrame* GetContentInsertionFrame(); NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; - virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext); + virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; virtual bool IsFrameOfType(uint32_t aFlags) const { @@ -137,12 +138,12 @@ public: } #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif NS_IMETHOD DidReflow(nsPresContext* aPresContext, const nsHTMLReflowState* aReflowState, - nsDidReflowStatus aStatus); + nsDidReflowStatus aStatus) MOZ_OVERRIDE; virtual bool HonorPrintBackgroundSettings(); @@ -158,7 +159,7 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; #ifdef DEBUG_LAYOUT virtual void SetDebugOnChildList(nsBoxLayoutState& aState, nsIFrame* aChild, bool aDebug); @@ -185,7 +186,7 @@ public: protected: #ifdef DEBUG_LAYOUT - virtual void GetBoxName(nsAutoString& aName); + virtual void GetBoxName(nsAutoString& aName) MOZ_OVERRIDE; void PaintXULDebugBackground(nsRenderingContext& aRenderingContext, nsPoint aPt); void PaintXULDebugOverlay(nsRenderingContext& aRenderingContext, @@ -199,7 +200,7 @@ protected: virtual bool GetInitialVAlignment(Valignment& aValign); virtual bool GetInitialAutoStretch(bool& aStretch); - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; nsSize mPrefSize; nsSize mMinSize; diff --git a/layout/xul/base/src/nsBoxObject.h b/layout/xul/base/src/nsBoxObject.h index 9355dde7bd15..cd2fff175951 100644 --- a/layout/xul/base/src/nsBoxObject.h +++ b/layout/xul/base/src/nsBoxObject.h @@ -5,6 +5,7 @@ #ifndef nsBoxObject_h_ #define nsBoxObject_h_ +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsIBoxObject.h" #include "nsPIBoxObject.h" @@ -31,8 +32,8 @@ public: // nsPIBoxObject virtual nsresult Init(nsIContent* aContent); - virtual void Clear(); - virtual void ClearCachedValues(); + virtual void Clear() MOZ_OVERRIDE; + virtual void ClearCachedValues() MOZ_OVERRIDE; nsIFrame* GetFrame(bool aFlushLayout); nsIPresShell* GetPresShell(bool aFlushLayout); diff --git a/layout/xul/base/src/nsButtonBoxFrame.h b/layout/xul/base/src/nsButtonBoxFrame.h index af931c4788be..981636a7b21e 100644 --- a/layout/xul/base/src/nsButtonBoxFrame.h +++ b/layout/xul/base/src/nsButtonBoxFrame.h @@ -5,6 +5,7 @@ #ifndef nsButtonBoxFrame_h___ #define nsButtonBoxFrame_h___ +#include "mozilla/Attributes.h" #include "nsBoxFrame.h" class nsButtonBoxFrame : public nsBoxFrame @@ -21,17 +22,17 @@ public: NS_IMETHOD BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; NS_IMETHOD HandleEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; virtual void MouseClicked (nsPresContext* aPresContext, nsGUIEvent* aEvent) { DoMouseClick(aEvent, false); } #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const { + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { return MakeFrameName(NS_LITERAL_STRING("ButtonBoxFrame"), aResult); } #endif @@ -41,7 +42,7 @@ public: * @param aTrustEvent if true and aEvent as null, then assume the event was trusted */ void DoMouseClick(nsGUIEvent* aEvent, bool aTrustEvent); - void UpdateMouseThrough() { AddStateBits(NS_FRAME_MOUSE_THROUGH_NEVER); } + void UpdateMouseThrough() MOZ_OVERRIDE { AddStateBits(NS_FRAME_MOUSE_THROUGH_NEVER); } }; // class nsButtonBoxFrame #endif /* nsButtonBoxFrame_h___ */ diff --git a/layout/xul/base/src/nsDeckFrame.h b/layout/xul/base/src/nsDeckFrame.h index d344d2fb17d0..7c729cfa326e 100644 --- a/layout/xul/base/src/nsDeckFrame.h +++ b/layout/xul/base/src/nsDeckFrame.h @@ -14,6 +14,7 @@ #ifndef nsDeckFrame_h___ #define nsDeckFrame_h___ +#include "mozilla/Attributes.h" #include "nsBoxFrame.h" class nsDeckFrame : public nsBoxFrame @@ -28,26 +29,26 @@ public: NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; - NS_IMETHOD DoLayout(nsBoxLayoutState& aState); + NS_IMETHOD DoLayout(nsBoxLayoutState& aState) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* aPrevInFlow); + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { return MakeFrameName(NS_LITERAL_STRING("Deck"), aResult); } diff --git a/layout/xul/base/src/nsImageBoxFrame.h b/layout/xul/base/src/nsImageBoxFrame.h index 187bc250429a..b8c6b90f88fc 100644 --- a/layout/xul/base/src/nsImageBoxFrame.h +++ b/layout/xul/base/src/nsImageBoxFrame.h @@ -5,6 +5,7 @@ #ifndef nsImageBoxFrame_h___ #define nsImageBoxFrame_h___ +#include "mozilla/Attributes.h" #include "nsLeafBoxFrame.h" #include "imgILoader.h" @@ -46,26 +47,26 @@ public: virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState); virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState); - virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState); - virtual void MarkIntrinsicWidthsDirty(); + virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE; friend nsIFrame* NS_NewImageBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* asPrevInFlow); + nsIFrame* asPrevInFlow) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; - virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext); + virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; virtual void DestroyFrom(nsIFrame* aDestructRoot); - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif /** @@ -83,7 +84,7 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; NS_IMETHOD OnStartContainer(imgIRequest *request, imgIContainer *image); NS_IMETHOD OnStopContainer(imgIRequest *request, imgIContainer *image); diff --git a/layout/xul/base/src/nsLeafBoxFrame.h b/layout/xul/base/src/nsLeafBoxFrame.h index 2cd1ffc1d1fd..050e09327000 100644 --- a/layout/xul/base/src/nsLeafBoxFrame.h +++ b/layout/xul/base/src/nsLeafBoxFrame.h @@ -5,6 +5,7 @@ #ifndef nsLeafBoxFrame_h___ #define nsLeafBoxFrame_h___ +#include "mozilla/Attributes.h" #include "nsLeafFrame.h" #include "nsBox.h" @@ -19,12 +20,12 @@ public: virtual nsSize GetPrefSize(nsBoxLayoutState& aState); virtual nsSize GetMinSize(nsBoxLayoutState& aState); - virtual nsSize GetMaxSize(nsBoxLayoutState& aState); - virtual nscoord GetFlex(nsBoxLayoutState& aState); - virtual nscoord GetBoxAscent(nsBoxLayoutState& aState); + virtual nsSize GetMaxSize(nsBoxLayoutState& aState) MOZ_OVERRIDE; + virtual nscoord GetFlex(nsBoxLayoutState& aState) MOZ_OVERRIDE; + virtual nscoord GetBoxAscent(nsBoxLayoutState& aState) MOZ_OVERRIDE; - virtual nsIAtom* GetType() const; - virtual bool IsFrameOfType(uint32_t aFlags) const + virtual nsIAtom* GetType() const MOZ_OVERRIDE; + virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE { // This is bogus, but it's what we've always done. // Note that nsLeafFrame is also eReplacedContainsBlock. @@ -33,52 +34,52 @@ public: } #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif // nsIHTMLReflow overrides - virtual void MarkIntrinsicWidthsDirty(); - virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); - virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext); + virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE; + virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; + virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; // Our auto size is that provided by nsFrame, not nsLeafFrame virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext, nsSize aCBSize, nscoord aAvailableWidth, nsSize aMargin, nsSize aBorder, - nsSize aPadding, bool aShrinkWrap); + nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; - NS_IMETHOD CharacterDataChanged(CharacterDataChangeInfo* aInfo); + NS_IMETHOD CharacterDataChanged(CharacterDataChangeInfo* aInfo) MOZ_OVERRIDE; NS_IMETHOD Init( nsIContent* aContent, nsIFrame* aParent, - nsIFrame* asPrevInFlow); + nsIFrame* asPrevInFlow) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; - virtual bool ComputesOwnOverflowArea() { return false; } + virtual bool ComputesOwnOverflowArea() MOZ_OVERRIDE { return false; } protected: - NS_IMETHOD DoLayout(nsBoxLayoutState& aState); + NS_IMETHOD DoLayout(nsBoxLayoutState& aState) MOZ_OVERRIDE; #ifdef DEBUG_LAYOUT - virtual void GetBoxName(nsAutoString& aName); + virtual void GetBoxName(nsAutoString& aName) MOZ_OVERRIDE; #endif - virtual nscoord GetIntrinsicWidth(); + virtual nscoord GetIntrinsicWidth() MOZ_OVERRIDE; nsLeafBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext); diff --git a/layout/xul/base/src/nsListBoxBodyFrame.h b/layout/xul/base/src/nsListBoxBodyFrame.h index 87907abf0e74..a252ba41b0f1 100644 --- a/layout/xul/base/src/nsListBoxBodyFrame.h +++ b/layout/xul/base/src/nsListBoxBodyFrame.h @@ -6,6 +6,7 @@ #ifndef nsListBoxBodyFrame_h #define nsListBoxBodyFrame_h +#include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsBoxFrame.h" #include "nsIListBoxObject.h" @@ -49,22 +50,22 @@ public: // nsIFrame NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* aPrevInFlow); - virtual void DestroyFrom(nsIFrame* aDestructRoot); + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; - NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType); + NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) MOZ_OVERRIDE; // nsIScrollbarMediator NS_IMETHOD PositionChanged(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t& aNewIndex); - NS_IMETHOD ScrollbarButtonPressed(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t aNewIndex); - NS_IMETHOD VisibilityChanged(bool aVisible); + NS_IMETHOD ScrollbarButtonPressed(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t aNewIndex) MOZ_OVERRIDE; + NS_IMETHOD VisibilityChanged(bool aVisible) MOZ_OVERRIDE; // nsIReflowCallback - virtual bool ReflowFinished(); - virtual void ReflowCallbackCanceled(); + virtual bool ReflowFinished() MOZ_OVERRIDE; + virtual void ReflowCallbackCanceled() MOZ_OVERRIDE; NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState); - virtual void MarkIntrinsicWidthsDirty(); + virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE; virtual nsSize GetMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState); virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState); @@ -118,9 +119,9 @@ public: return true; } - virtual bool SupportsOrdinalsInChildren(); + virtual bool SupportsOrdinalsInChildren() MOZ_OVERRIDE; - virtual bool ComputesOwnOverflowArea() { return true; } + virtual bool ComputesOwnOverflowArea() MOZ_OVERRIDE { return true; } protected: class nsPositionChangedEvent; diff --git a/layout/xul/base/src/nsListBoxLayout.h b/layout/xul/base/src/nsListBoxLayout.h index dcef3d958638..3b548c77922c 100644 --- a/layout/xul/base/src/nsListBoxLayout.h +++ b/layout/xul/base/src/nsListBoxLayout.h @@ -6,6 +6,7 @@ #ifndef nsListBoxLayout_h___ #define nsListBoxLayout_h___ +#include "mozilla/Attributes.h" #include "nsGridRowGroupLayout.h" class nsIFrame; @@ -18,10 +19,10 @@ public: nsListBoxLayout(); // nsBoxLayout - NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aState); - virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); + NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE; + virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); - virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); + virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; protected: NS_IMETHOD LayoutInternal(nsIFrame* aBox, nsBoxLayoutState& aState); diff --git a/layout/xul/base/src/nsListItemFrame.h b/layout/xul/base/src/nsListItemFrame.h index 8fce5756f06c..891c55982a43 100644 --- a/layout/xul/base/src/nsListItemFrame.h +++ b/layout/xul/base/src/nsListItemFrame.h @@ -3,6 +3,7 @@ * 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/Attributes.h" #include "nsGridRowLeafFrame.h" nsIFrame* NS_NewListItemFrame(nsIPresShell* aPresShell, @@ -22,7 +23,7 @@ public: const nsRect& aDirtyRect, const nsDisplayListSet& aLists); - virtual nsSize GetPrefSize(nsBoxLayoutState& aState); + virtual nsSize GetPrefSize(nsBoxLayoutState& aState) MOZ_OVERRIDE; protected: nsListItemFrame(nsIPresShell* aPresShell, diff --git a/layout/xul/base/src/nsMenuBarFrame.h b/layout/xul/base/src/nsMenuBarFrame.h index a8330893b9d0..d258aa36d82e 100644 --- a/layout/xul/base/src/nsMenuBarFrame.h +++ b/layout/xul/base/src/nsMenuBarFrame.h @@ -10,6 +10,7 @@ #ifndef nsMenuBarFrame_h__ #define nsMenuBarFrame_h__ +#include "mozilla/Attributes.h" #include "prtypes.h" #include "nsIAtom.h" #include "nsCOMPtr.h" @@ -32,18 +33,18 @@ public: nsMenuBarFrame(nsIPresShell* aShell, nsStyleContext* aContext); // nsMenuParent interface - virtual nsMenuFrame* GetCurrentMenuItem(); - NS_IMETHOD SetCurrentMenuItem(nsMenuFrame* aMenuItem); - virtual void CurrentMenuIsBeingDestroyed(); - NS_IMETHOD ChangeMenuItem(nsMenuFrame* aMenuItem, bool aSelectFirstItem); + virtual nsMenuFrame* GetCurrentMenuItem() MOZ_OVERRIDE; + NS_IMETHOD SetCurrentMenuItem(nsMenuFrame* aMenuItem) MOZ_OVERRIDE; + virtual void CurrentMenuIsBeingDestroyed() MOZ_OVERRIDE; + NS_IMETHOD ChangeMenuItem(nsMenuFrame* aMenuItem, bool aSelectFirstItem) MOZ_OVERRIDE; - NS_IMETHOD SetActive(bool aActiveFlag); + NS_IMETHOD SetActive(bool aActiveFlag) MOZ_OVERRIDE; - virtual bool IsMenuBar() { return true; } + virtual bool IsMenuBar() MOZ_OVERRIDE { return true; } virtual bool IsContextMenu() { return false; } - virtual bool IsActive() { return mIsActive; } + virtual bool IsActive() MOZ_OVERRIDE { return mIsActive; } virtual bool IsMenu() { return false; } - virtual bool IsOpen() { return true; } // menubars are considered always open + virtual bool IsOpen() MOZ_OVERRIDE { return true; } // menubars are considered always open bool IsMenuOpen() { return mCurrentMenu && mCurrentMenu->IsOpen(); } @@ -52,12 +53,12 @@ public: NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* aPrevInFlow); + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; - virtual void LockMenuUntilClosed(bool aLock) {} - virtual bool IsMenuLocked() { return false; } + virtual void LockMenuUntilClosed(bool aLock) MOZ_OVERRIDE {} + virtual bool IsMenuLocked() MOZ_OVERRIDE { return false; } // Non-interface helpers @@ -73,7 +74,7 @@ public: // indicate that a menu on the menubar was closed. Returns true if the caller // may deselect the menuitem. - virtual bool MenuClosed(); + virtual bool MenuClosed() MOZ_OVERRIDE; // Called when Enter is pressed while the menubar is focused. If the current // menu is open, let the child handle the key. @@ -82,7 +83,7 @@ public: // Used to handle ALT+key combos nsMenuFrame* FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent); - virtual bool IsFrameOfType(uint32_t aFlags) const + virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE { // Override bogus IsFrameOfType in nsBoxFrame. if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced)) @@ -91,7 +92,7 @@ public: } #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { return MakeFrameName(NS_LITERAL_STRING("MenuBar"), aResult); } diff --git a/layout/xul/base/src/nsMenuFrame.h b/layout/xul/base/src/nsMenuFrame.h index 34835cb4fa1e..855f84c83ff3 100644 --- a/layout/xul/base/src/nsMenuFrame.h +++ b/layout/xul/base/src/nsMenuFrame.h @@ -82,23 +82,23 @@ public: NS_DECL_QUERYFRAME NS_DECL_FRAMEARENA_HELPERS - NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState); - virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState); - virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState); + NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* aPrevInFlow); + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; #ifdef DEBUG_LAYOUT - NS_IMETHOD SetDebug(nsBoxLayoutState& aState, bool aDebug); + NS_IMETHOD SetDebug(nsBoxLayoutState& aState, bool aDebug) MOZ_OVERRIDE; #endif // The following methods are all overridden so that the menupopup // can be stored in a separate list, so that it doesn't impact reflow of the // actual menu item at all. - virtual const nsFrameList& GetChildList(ChildListID aList) const; - virtual void GetChildLists(nsTArray* aLists) const; + virtual const nsFrameList& GetChildList(ChildListID aList) const MOZ_OVERRIDE; + virtual void GetChildLists(nsTArray* aLists) const MOZ_OVERRIDE; NS_IMETHOD SetInitialChildList(ChildListID aListID, nsFrameList& aChildList); virtual void DestroyFrom(nsIFrame* aDestructRoot); @@ -106,24 +106,24 @@ public: // Overridden to prevent events from going to children of the menu. NS_IMETHOD BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; // this method can destroy the frame NS_IMETHOD HandleEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; - virtual nsIAtom* GetType() const { return nsGkAtoms::menuFrame; } + virtual nsIAtom* GetType() const MOZ_OVERRIDE { return nsGkAtoms::menuFrame; } NS_IMETHOD SelectMenu(bool aActivateFlag); @@ -189,7 +189,7 @@ public: void SetIsMenu(bool aIsMenu) { mIsMenu = aIsMenu; } #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { return MakeFrameName(NS_LITERAL_STRING("Menu"), aResult); } @@ -240,7 +240,7 @@ protected: // This method can destroy the frame NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; virtual ~nsMenuFrame() { }; bool SizeToPopup(nsBoxLayoutState& aState, nsSize& aSize); diff --git a/layout/xul/base/src/nsMenuPopupFrame.cpp b/layout/xul/base/src/nsMenuPopupFrame.cpp index 6aa2335372e3..9f60549e7b9b 100644 --- a/layout/xul/base/src/nsMenuPopupFrame.cpp +++ b/layout/xul/base/src/nsMenuPopupFrame.cpp @@ -1201,7 +1201,7 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove) // context menu close up again. if (mAdjustOffsetForContextMenu) { int32_t offsetForContextMenuDev = - nsPresContext::CSSPixelsToAppUnits(2) / factor; + nsPresContext::CSSPixelsToAppUnits(CONTEXT_MENU_OFFSET_PIXELS) / factor; offsetForContextMenu = presContext->DevPixelsToAppUnits(offsetForContextMenuDev); } @@ -1846,6 +1846,15 @@ nsMenuPopupFrame::MoveTo(int32_t aLeft, int32_t aTop, bool aUpdateAttrs) // added to the position when SetPopupPosition is called. nsMargin margin(0, 0, 0, 0); GetStyleMargin()->GetMargin(margin); + + // Workaround for bug 788189. See also bug 708278 comment #25 and following. + if (mAdjustOffsetForContextMenu) { + nscoord offsetForContextMenu = + nsPresContext::CSSPixelsToAppUnits(CONTEXT_MENU_OFFSET_PIXELS); + margin.left += offsetForContextMenu; + margin.top += offsetForContextMenu; + } + nsPresContext* presContext = PresContext(); mScreenXPos = aLeft - presContext->AppUnitsToIntCSSPixels(margin.left); mScreenYPos = aTop - presContext->AppUnitsToIntCSSPixels(margin.top); diff --git a/layout/xul/base/src/nsMenuPopupFrame.h b/layout/xul/base/src/nsMenuPopupFrame.h index c6c09ce9ecb6..cbc2e130d3fe 100644 --- a/layout/xul/base/src/nsMenuPopupFrame.h +++ b/layout/xul/base/src/nsMenuPopupFrame.h @@ -10,6 +10,7 @@ #ifndef nsMenuPopupFrame_h__ #define nsMenuPopupFrame_h__ +#include "mozilla/Attributes.h" #include "prtypes.h" #include "nsIAtom.h" #include "nsGkAtoms.h" @@ -86,6 +87,8 @@ enum FlipStyle { // need to find a good place to put them together. // if someone changes one, please also change the other. +#define CONTEXT_MENU_OFFSET_PIXELS 2 + nsIFrame* NS_NewMenuPopupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); class nsIViewManager; @@ -103,9 +106,9 @@ public: // nsMenuParent interface virtual nsMenuFrame* GetCurrentMenuItem(); - NS_IMETHOD SetCurrentMenuItem(nsMenuFrame* aMenuItem); - virtual void CurrentMenuIsBeingDestroyed(); - NS_IMETHOD ChangeMenuItem(nsMenuFrame* aMenuItem, bool aSelectFirstItem); + NS_IMETHOD SetCurrentMenuItem(nsMenuFrame* aMenuItem) MOZ_OVERRIDE; + virtual void CurrentMenuIsBeingDestroyed() MOZ_OVERRIDE; + NS_IMETHOD ChangeMenuItem(nsMenuFrame* aMenuItem, bool aSelectFirstItem) MOZ_OVERRIDE; // as popups are opened asynchronously, the popup pending state is used to // prevent multiple requests from attempting to open the same popup twice @@ -113,8 +116,8 @@ public: void SetPopupState(nsPopupState aPopupState) { mPopupState = aPopupState; } NS_IMETHOD SetActive(bool aActiveFlag) { return NS_OK; } // We don't care. - virtual bool IsActive() { return false; } - virtual bool IsMenuBar() { return false; } + virtual bool IsActive() MOZ_OVERRIDE { return false; } + virtual bool IsMenuBar() MOZ_OVERRIDE { return false; } /* * When this popup is open, should clicks outside of it be consumed? @@ -134,12 +137,12 @@ public: */ bool ConsumeOutsideClicks(); - virtual bool IsContextMenu() { return mIsContextMenu; } + virtual bool IsContextMenu() MOZ_OVERRIDE { return mIsContextMenu; } - virtual bool MenuClosed() { return true; } + virtual bool MenuClosed() MOZ_OVERRIDE { return true; } - virtual void LockMenuUntilClosed(bool aLock); - virtual bool IsMenuLocked() { return mIsMenuLocked; } + virtual void LockMenuUntilClosed(bool aLock) MOZ_OVERRIDE; + virtual bool IsMenuLocked() MOZ_OVERRIDE { return mIsMenuLocked; } nsIWidget* GetWidget(); @@ -149,13 +152,13 @@ public: // Overridden methods NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* aPrevInFlow); + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; virtual void InvalidateInternal(const nsRect& aDamageRect, nscoord aX, nscoord aY, nsIFrame* aForChild, @@ -176,7 +179,7 @@ public: uint8_t GetShadowStyle(); NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; virtual bool IsLeaf() const; @@ -205,7 +208,7 @@ public: nsPopupType PopupType() const { return mPopupType; } bool IsMenu() { return mPopupType == ePopupTypeMenu; } - bool IsOpen() { return mPopupState == ePopupOpen || mPopupState == ePopupOpenAndVisible; } + bool IsOpen() MOZ_OVERRIDE { return mPopupState == ePopupOpen || mPopupState == ePopupOpenAndVisible; } bool IsDragPopup() { return mIsDragPopup; } @@ -254,10 +257,10 @@ public: void ClearIncrementalString() { mIncrementalString.Truncate(); } - virtual nsIAtom* GetType() const { return nsGkAtoms::menuPopupFrame; } + virtual nsIAtom* GetType() const MOZ_OVERRIDE { return nsGkAtoms::menuPopupFrame; } #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { return MakeFrameName(NS_LITERAL_STRING("MenuPopup"), aResult); } @@ -307,7 +310,7 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; nsIntPoint GetLastClientOffset() const { return mLastClientOffset; } diff --git a/layout/xul/base/src/nsPopupSetFrame.h b/layout/xul/base/src/nsPopupSetFrame.h index 8af76109fae9..2fbdf08382e7 100644 --- a/layout/xul/base/src/nsPopupSetFrame.h +++ b/layout/xul/base/src/nsPopupSetFrame.h @@ -7,6 +7,7 @@ #ifndef nsPopupSetFrame_h__ #define nsPopupSetFrame_h__ +#include "mozilla/Attributes.h" #include "nsIAtom.h" #include "nsBoxFrame.h" @@ -24,27 +25,27 @@ public: NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* aPrevInFlow); + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; - NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState); + NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; // Used to destroy our popup frames. - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD List(FILE* out, int32_t aIndent) const; - NS_IMETHOD GetFrameName(nsAString& aResult) const + NS_IMETHOD List(FILE* out, int32_t aIndent) const MOZ_OVERRIDE; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { return MakeFrameName(NS_LITERAL_STRING("PopupSet"), aResult); } diff --git a/layout/xul/base/src/nsProgressMeterFrame.h b/layout/xul/base/src/nsProgressMeterFrame.h index 0862a739a049..af18795cbdc1 100644 --- a/layout/xul/base/src/nsProgressMeterFrame.h +++ b/layout/xul/base/src/nsProgressMeterFrame.h @@ -17,6 +17,7 @@ **/ +#include "mozilla/Attributes.h" #include "nsBoxFrame.h" class nsProgressMeterFrame : public nsBoxFrame @@ -30,10 +31,10 @@ public: NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif protected: diff --git a/layout/xul/base/src/nsResizerFrame.h b/layout/xul/base/src/nsResizerFrame.h index d08c45ec395b..4efbbc01c643 100644 --- a/layout/xul/base/src/nsResizerFrame.h +++ b/layout/xul/base/src/nsResizerFrame.h @@ -5,6 +5,7 @@ #ifndef nsResizerFrame_h___ #define nsResizerFrame_h___ +#include "mozilla/Attributes.h" #include "nsTitleBarFrame.h" class nsIBaseWindow; @@ -27,9 +28,9 @@ public: NS_IMETHOD HandleEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; - virtual void MouseClicked(nsPresContext* aPresContext, nsGUIEvent *aEvent); + virtual void MouseClicked(nsPresContext* aPresContext, nsGUIEvent *aEvent) MOZ_OVERRIDE; protected: nsIContent* GetContentToResize(nsIPresShell* aPresShell, nsIBaseWindow** aWindow); diff --git a/layout/xul/base/src/nsScrollbarButtonFrame.h b/layout/xul/base/src/nsScrollbarButtonFrame.h index ad1303c01d21..6f73bb62811c 100644 --- a/layout/xul/base/src/nsScrollbarButtonFrame.h +++ b/layout/xul/base/src/nsScrollbarButtonFrame.h @@ -13,6 +13,7 @@ #ifndef nsScrollbarButtonFrame_h___ #define nsScrollbarButtonFrame_h___ +#include "mozilla/Attributes.h" #include "nsButtonBoxFrame.h" #include "nsITimer.h" #include "nsRepeatService.h" @@ -28,13 +29,13 @@ public: nsButtonBoxFrame(aPresShell, aContext), mCursorOnThis(false) {} // Overrides - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; friend nsIFrame* NS_NewScrollbarButtonFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); NS_IMETHOD HandleEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; static nsresult GetChildWithTag(nsPresContext* aPresContext, nsIAtom* atom, nsIFrame* start, nsIFrame*& result); @@ -47,18 +48,18 @@ public: NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext, nsGUIEvent * aEvent, nsEventStatus* aEventStatus, - bool aControlHeld) { return NS_OK; } + bool aControlHeld) MOZ_OVERRIDE { return NS_OK; } NS_IMETHOD HandleDrag(nsPresContext* aPresContext, nsGUIEvent * aEvent, - nsEventStatus* aEventStatus) { return NS_OK; } + nsEventStatus* aEventStatus) MOZ_OVERRIDE { return NS_OK; } NS_IMETHOD HandleRelease(nsPresContext* aPresContext, nsGUIEvent * aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; protected: - virtual void MouseClicked(nsPresContext* aPresContext, nsGUIEvent* aEvent); + virtual void MouseClicked(nsPresContext* aPresContext, nsGUIEvent* aEvent) MOZ_OVERRIDE; void DoButtonAction(bool aSmoothScroll); void StartRepeat() { diff --git a/layout/xul/base/src/nsScrollbarFrame.h b/layout/xul/base/src/nsScrollbarFrame.h index 95fdbb90fa4b..637d6c269037 100644 --- a/layout/xul/base/src/nsScrollbarFrame.h +++ b/layout/xul/base/src/nsScrollbarFrame.h @@ -10,6 +10,7 @@ #ifndef nsScrollbarFrame_h__ #define nsScrollbarFrame_h__ +#include "mozilla/Attributes.h" #include "nsBoxFrame.h" class nsIScrollbarMediator; @@ -33,38 +34,38 @@ public: // nsIFrame overrides NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; NS_DECL_QUERYFRAME NS_DECL_FRAMEARENA_HELPERS NS_IMETHOD HandlePress(nsPresContext* aPresContext, nsGUIEvent * aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext, nsGUIEvent * aEvent, nsEventStatus* aEventStatus, - bool aControlHeld); + bool aControlHeld) MOZ_OVERRIDE; NS_IMETHOD HandleDrag(nsPresContext* aPresContext, nsGUIEvent * aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; NS_IMETHOD HandleRelease(nsPresContext* aPresContext, nsGUIEvent * aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* aPrevInFlow); + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus) MOZ_OVERRIDE; - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; void SetScrollbarMediatorContent(nsIContent* aMediator); nsIScrollbarMediator* GetScrollbarMediator(); @@ -78,7 +79,7 @@ public: * scrollframe by setting its height or width to zero, that will * hide the children too. */ - virtual bool DoesClipChildren() { return true; } + virtual bool DoesClipChildren() MOZ_OVERRIDE { return true; } private: nsCOMPtr mScrollbarMediator; diff --git a/layout/xul/base/src/nsSliderFrame.h b/layout/xul/base/src/nsSliderFrame.h index 3f918eacab3c..36ce228c5ae5 100644 --- a/layout/xul/base/src/nsSliderFrame.h +++ b/layout/xul/base/src/nsSliderFrame.h @@ -6,6 +6,7 @@ #ifndef nsSliderFrame_h__ #define nsSliderFrame_h__ +#include "mozilla/Attributes.h" #include "nsRepeatService.h" #include "nsBoxFrame.h" #include "prtypes.h" @@ -47,54 +48,54 @@ public: virtual ~nsSliderFrame(); #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const { + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { return MakeFrameName(NS_LITERAL_STRING("SliderFrame"), aResult); } #endif - virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState); - virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState); - virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState); - NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState); + virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; // nsIFrame overrides NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - nsFrameList& aFrameList); + nsFrameList& aFrameList) MOZ_OVERRIDE; NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); + nsIFrame* aOldFrame) MOZ_OVERRIDE; - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* asPrevInFlow); + nsIFrame* asPrevInFlow) MOZ_OVERRIDE; NS_IMETHOD HandleEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList); + nsFrameList& aChildList) MOZ_OVERRIDE; - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; nsresult StartDrag(nsIDOMEvent* aEvent); @@ -108,20 +109,20 @@ public: NS_IMETHOD HandlePress(nsPresContext* aPresContext, nsGUIEvent * aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext, nsGUIEvent * aEvent, nsEventStatus* aEventStatus, - bool aControlHeld) { return NS_OK; } + bool aControlHeld) MOZ_OVERRIDE { return NS_OK; } NS_IMETHOD HandleDrag(nsPresContext* aPresContext, nsGUIEvent * aEvent, - nsEventStatus* aEventStatus) { return NS_OK; } + nsEventStatus* aEventStatus) MOZ_OVERRIDE { return NS_OK; } NS_IMETHOD HandleRelease(nsPresContext* aPresContext, nsGUIEvent * aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; private: diff --git a/layout/xul/base/src/nsSplitterFrame.h b/layout/xul/base/src/nsSplitterFrame.h index 369459745357..e8523eb8e54c 100644 --- a/layout/xul/base/src/nsSplitterFrame.h +++ b/layout/xul/base/src/nsSplitterFrame.h @@ -11,6 +11,7 @@ #define nsSplitterFrame_h__ +#include "mozilla/Attributes.h" #include "nsBoxFrame.h" class nsSplitterFrameInner; @@ -23,10 +24,10 @@ public: NS_DECL_FRAMEARENA_HELPERS nsSplitterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const { + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { return MakeFrameName(NS_LITERAL_STRING("SplitterFrame"), aResult); } #endif @@ -34,43 +35,43 @@ public: // nsIFrame overrides NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* aPrevInFlow); + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; NS_IMETHOD GetCursor(const nsPoint& aPoint, - nsIFrame::Cursor& aCursor); + nsIFrame::Cursor& aCursor) MOZ_OVERRIDE; - NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState); + NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; NS_IMETHOD HandlePress(nsPresContext* aPresContext, nsGUIEvent * aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext, nsGUIEvent * aEvent, nsEventStatus* aEventStatus, - bool aControlHeld); + bool aControlHeld) MOZ_OVERRIDE; NS_IMETHOD HandleDrag(nsPresContext* aPresContext, nsGUIEvent * aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; NS_IMETHOD HandleRelease(nsPresContext* aPresContext, nsGUIEvent * aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; NS_IMETHOD HandleEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; - virtual void GetInitialOrientation(bool& aIsHorizontal); + virtual void GetInitialOrientation(bool& aIsHorizontal) MOZ_OVERRIDE; private: diff --git a/layout/xul/base/src/nsSprocketLayout.h b/layout/xul/base/src/nsSprocketLayout.h index 67a70e08e940..21addaa12610 100644 --- a/layout/xul/base/src/nsSprocketLayout.h +++ b/layout/xul/base/src/nsSprocketLayout.h @@ -6,6 +6,7 @@ #ifndef nsSprocketLayout_h___ #define nsSprocketLayout_h___ +#include "mozilla/Attributes.h" #include "nsBoxLayout.h" #include "nsCOMPtr.h" #include "nsIFrame.h" @@ -69,7 +70,7 @@ public: NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aState); - virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); + virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); virtual nscoord GetAscent(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); diff --git a/layout/xul/base/src/nsStackFrame.h b/layout/xul/base/src/nsStackFrame.h index d0be77b46d23..6ea0a56a65d8 100644 --- a/layout/xul/base/src/nsStackFrame.h +++ b/layout/xul/base/src/nsStackFrame.h @@ -14,6 +14,7 @@ #ifndef nsStackFrame_h___ #define nsStackFrame_h___ +#include "mozilla/Attributes.h" #include "nsBoxFrame.h" class nsStackFrame : public nsBoxFrame @@ -25,7 +26,7 @@ public: nsStyleContext* aContext); #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { return MakeFrameName(NS_LITERAL_STRING("Stack"), aResult); } @@ -33,7 +34,7 @@ public: NS_IMETHOD BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; protected: nsStackFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); diff --git a/layout/xul/base/src/nsStackLayout.h b/layout/xul/base/src/nsStackLayout.h index d6fe73e3dd1f..b73239d19947 100644 --- a/layout/xul/base/src/nsStackLayout.h +++ b/layout/xul/base/src/nsStackLayout.h @@ -14,6 +14,7 @@ #ifndef nsStackLayout_h___ #define nsStackLayout_h___ +#include "mozilla/Attributes.h" #include "nsBoxLayout.h" #include "nsCOMPtr.h" #include "nsCoord.h" @@ -33,10 +34,10 @@ public: NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aState); - virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); - virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); - virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); - virtual nscoord GetAscent(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); + virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nscoord GetAscent(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; // get the child offsets for aChild and set them in aMargin. Returns a // bitfield mask of the SPECIFIED_LEFT, SPECIFIED_RIGHT, SPECIFIED_TOP and diff --git a/layout/xul/base/src/nsTitleBarFrame.h b/layout/xul/base/src/nsTitleBarFrame.h index c09a5c17f9e2..52b9bdb359f2 100644 --- a/layout/xul/base/src/nsTitleBarFrame.h +++ b/layout/xul/base/src/nsTitleBarFrame.h @@ -5,6 +5,7 @@ #ifndef nsTitleBarFrame_h___ #define nsTitleBarFrame_h___ +#include "mozilla/Attributes.h" #include "nsBoxFrame.h" class nsTitleBarFrame : public nsBoxFrame @@ -18,15 +19,15 @@ public: NS_IMETHOD BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; NS_IMETHOD HandleEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent, - nsEventStatus* aEventStatus); + nsEventStatus* aEventStatus) MOZ_OVERRIDE; virtual void MouseClicked(nsPresContext* aPresContext, nsGUIEvent* aEvent); - void UpdateMouseThrough() { AddStateBits(NS_FRAME_MOUSE_THROUGH_NEVER); } + void UpdateMouseThrough() MOZ_OVERRIDE { AddStateBits(NS_FRAME_MOUSE_THROUGH_NEVER); } protected: bool mTrackingMouseMove; diff --git a/layout/xul/base/src/nsXULLabelFrame.h b/layout/xul/base/src/nsXULLabelFrame.h index fe86121d0d18..f22ee00ce4c2 100644 --- a/layout/xul/base/src/nsXULLabelFrame.h +++ b/layout/xul/base/src/nsXULLabelFrame.h @@ -8,6 +8,7 @@ #ifndef nsXULLabelFrame_h_ #define nsXULLabelFrame_h_ +#include "mozilla/Attributes.h" #include "nsBlockFrame.h" #ifndef MOZ_XUL @@ -27,21 +28,21 @@ public: nsIFrame* aParent, nsIFrame* aPrevInFlow); - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; /** * Get the "type" of the frame * * @see nsGkAtoms::XULLabelFrame */ - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif protected: diff --git a/layout/xul/base/src/tree/src/nsTreeBodyFrame.h b/layout/xul/base/src/tree/src/nsTreeBodyFrame.h index 2b0c0c89227e..2446394fa630 100644 --- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.h +++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.h @@ -106,21 +106,21 @@ public: bool aRemoveOverflowArea = false); // nsIReflowCallback - virtual bool ReflowFinished(); - virtual void ReflowCallbackCanceled(); + virtual bool ReflowFinished() MOZ_OVERRIDE; + virtual void ReflowCallbackCanceled() MOZ_OVERRIDE; // nsICSSPseudoComparator - virtual bool PseudoMatches(nsCSSSelector* aSelector); + virtual bool PseudoMatches(nsCSSSelector* aSelector) MOZ_OVERRIDE; // nsIScrollbarMediator NS_IMETHOD PositionChanged(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t& aNewIndex); - NS_IMETHOD ScrollbarButtonPressed(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t aNewIndex); - NS_IMETHOD VisibilityChanged(bool aVisible) { Invalidate(); return NS_OK; } + NS_IMETHOD ScrollbarButtonPressed(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t aNewIndex) MOZ_OVERRIDE; + NS_IMETHOD VisibilityChanged(bool aVisible) MOZ_OVERRIDE { Invalidate(); return NS_OK; } // Overridden from nsIFrame to cache our pres context. NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* aPrevInFlow); + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; virtual void DestroyFrom(nsIFrame* aDestructRoot); NS_IMETHOD GetCursor(const nsPoint& aPoint, @@ -132,7 +132,7 @@ public: NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext); diff --git a/layout/xul/base/src/tree/src/nsTreeBoxObject.h b/layout/xul/base/src/tree/src/nsTreeBoxObject.h index 1dd2fdd42d7f..897b22684158 100644 --- a/layout/xul/base/src/tree/src/nsTreeBoxObject.h +++ b/layout/xul/base/src/tree/src/nsTreeBoxObject.h @@ -6,6 +6,7 @@ #ifndef nsTreeBoxObject_h___ #define nsTreeBoxObject_h___ +#include "mozilla/Attributes.h" #include "nsBoxObject.h" #include "nsITreeView.h" #include "nsITreeBoxObject.h" @@ -26,8 +27,8 @@ public: nsTreeBodyFrame* GetCachedTreeBody() { return mTreeBody; } //NS_PIBOXOBJECT interfaces - virtual void Clear(); - virtual void ClearCachedValues(); + virtual void Clear() MOZ_OVERRIDE; + virtual void ClearCachedValues() MOZ_OVERRIDE; protected: nsTreeBodyFrame* mTreeBody; diff --git a/layout/xul/base/src/tree/src/nsTreeColFrame.h b/layout/xul/base/src/tree/src/nsTreeColFrame.h index 7b716341fccb..714c4b1118f1 100644 --- a/layout/xul/base/src/tree/src/nsTreeColFrame.h +++ b/layout/xul/base/src/tree/src/nsTreeColFrame.h @@ -3,6 +3,7 @@ * 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/Attributes.h" #include "nsBoxFrame.h" class nsITreeBoxObject; @@ -21,20 +22,20 @@ public: NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, - nsIFrame* aPrevInFlow); + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; NS_IMETHOD BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); + const nsDisplayListSet& aLists) MOZ_OVERRIDE; NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType) MOZ_OVERRIDE; virtual void SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect, - bool aRemoveOverflowArea = false); + bool aRemoveOverflowArea = false) MOZ_OVERRIDE; friend nsIFrame* NS_NewTreeColFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index 07d82b5483d2..2599e9ba18fb 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -60,7 +60,6 @@ pref("image.cache.size", 1048576); // bytes pref("browser.offline-apps.notify", true); pref("browser.cache.offline.enable", true); pref("browser.cache.offline.capacity", 5120); // kilobytes -pref("offline-apps.quota.max", 2048); // kilobytes pref("offline-apps.quota.warn", 1024); // kilobytes // cache compression turned off for now - see bug #715198 diff --git a/mobile/android/base/GeckoActivity.java.in b/mobile/android/base/GeckoActivity.java.in index 40b1744b7e86..76bb5d2293a4 100644 --- a/mobile/android/base/GeckoActivity.java.in +++ b/mobile/android/base/GeckoActivity.java.in @@ -2,68 +2,29 @@ * 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/. */ -#filter substitution package org.mozilla.gecko; import android.app.Activity; -import android.content.ComponentName; -import android.content.Intent; public class GeckoActivity extends Activity { - private boolean hasStarted = false; - private boolean mGeckoActivityOpened = false; - @Override public void onPause() { super.onPause(); - // Avoid pause notifications in destroy path. - if (!isFinishing() && (getApplication() instanceof GeckoApplication)) + if (getApplication() instanceof GeckoApplication) { ((GeckoApplication) getApplication()).onActivityPause(this); + } } @Override public void onResume() { super.onResume(); - // Avoid resume notifications in startup path. - if (hasStarted && (getApplication() instanceof GeckoApplication)) { + if (getApplication() instanceof GeckoApplication) { ((GeckoApplication) getApplication()).onActivityResume(this); - mGeckoActivityOpened = false; - } else { - hasStarted = true; } } - @Override - public void startActivity(Intent intent) { - checkIfGeckoActivity(intent); - super.startActivity(intent); - } - - @Override - public void startActivityForResult(Intent intent, int request) { - checkIfGeckoActivity(intent); - super.startActivityForResult(intent, request); - } - - private void checkIfGeckoActivity(Intent intent) { - // Whenever we call our own activity, the component and it's package name is set. - // If we call an activity from another package, or an open intent (leaving android to resolve) - // component has a different package name or it is null. - ComponentName component = intent.getComponent(); - mGeckoActivityOpened = false; - if (component != null && - component.getPackageName() != null && - component.getPackageName().equals("@ANDROID_PACKAGE_NAME@")) { - mGeckoActivityOpened = true; - } - } - - public boolean isGeckoActivityOpened() { - return mGeckoActivityOpened; - } - public boolean isApplicationInBackground() { return ((GeckoApplication) getApplication()).isApplicationInBackground(); } diff --git a/mobile/android/base/GeckoApp.java b/mobile/android/base/GeckoApp.java index 253a7a07d7fe..0fbd1cdad94b 100644 --- a/mobile/android/base/GeckoApp.java +++ b/mobile/android/base/GeckoApp.java @@ -111,7 +111,6 @@ import java.util.regex.Pattern; abstract public class GeckoApp extends GeckoActivity implements GeckoEventListener, SensorEventListener, LocationListener, - GeckoApplication.ApplicationLifecycleCallbacks, Tabs.OnTabsChangedListener, GeckoEventResponder { private static final String LOGTAG = "GeckoApp"; @@ -154,8 +153,6 @@ abstract public class GeckoApp private boolean mIsRestoringActivity; private String mCurrentResponse = ""; - private GeckoConnectivityReceiver mConnectivityReceiver; - private GeckoBatteryManager mBatteryReceiver; private PromptService mPromptService; private Favicons mFavicons; private TextSelection mTextSelection; @@ -1443,8 +1440,6 @@ abstract public class GeckoApp editor.commit(); } }); - - ((GeckoApplication)getApplication()).addApplicationLifecycleCallbacks(this); } void initializeChrome(String uri, Boolean isExternalURL) { @@ -1604,25 +1599,14 @@ abstract public class GeckoApp SmsManager.getInstance().start(); } - mBatteryReceiver = new GeckoBatteryManager(); - mBatteryReceiver.registerFor(mAppContext); - - mConnectivityReceiver = new GeckoConnectivityReceiver(); - mConnectivityReceiver.registerFor(mAppContext); - mPromptService = new PromptService(); mTextSelection = new TextSelection((TextSelectionHandle) findViewById(R.id.start_handle), (TextSelectionHandle) findViewById(R.id.end_handle), GeckoAppShell.getEventDispatcher()); - GeckoNetworkManager.getInstance().init(); - GeckoNetworkManager.getInstance().start(); - UpdateServiceHelper.registerForUpdates(this); - GeckoScreenOrientationListener.getInstance().start(); - final GeckoApp self = this; GeckoAppShell.getHandler().postDelayed(new Runnable() { @@ -1901,6 +1885,8 @@ abstract public class GeckoApp refreshChrome(); } + GeckoScreenOrientationListener.getInstance().start(); + // User may have enabled/disabled accessibility. GeckoAccessibility.updateAccessibilitySettings(); @@ -1960,6 +1946,8 @@ abstract public class GeckoApp } }); + GeckoScreenOrientationListener.getInstance().stop(); + super.onPause(); } @@ -2068,12 +2056,7 @@ abstract public class GeckoApp super.onDestroy(); - if (mBatteryReceiver != null) - mBatteryReceiver.unregisterFor(mAppContext); - Tabs.unregisterOnTabsChangedListener(this); - - ((GeckoApplication) getApplication()).removeApplicationLifecycleCallbacks(this); } protected void registerEventListener(String event) { @@ -2135,29 +2118,6 @@ abstract public class GeckoApp GeckoAppShell.geckoEventSync(); } - @Override - public void onApplicationPause() { - Log.i(LOGTAG, "application paused"); - GeckoAppShell.sendEventToGecko(GeckoEvent.createPauseEvent(true)); - - if (mConnectivityReceiver != null) - mConnectivityReceiver.unregisterFor(mAppContext); - GeckoNetworkManager.getInstance().stop(); - GeckoScreenOrientationListener.getInstance().stop(); - } - - @Override - public void onApplicationResume() { - Log.i(LOGTAG, "application resumed"); - if (checkLaunchState(LaunchState.GeckoRunning)) - GeckoAppShell.sendEventToGecko(GeckoEvent.createResumeEvent(true)); - - if (mConnectivityReceiver != null) - mConnectivityReceiver.registerFor(mAppContext); - GeckoNetworkManager.getInstance().start(); - GeckoScreenOrientationListener.getInstance().start(); - } - @Override public Object onRetainNonConfigurationInstance() { // Send a non-null value so that we can restart the application, diff --git a/mobile/android/base/GeckoApplication.java b/mobile/android/base/GeckoApplication.java index 21f79f3caae9..99f535caf975 100644 --- a/mobile/android/base/GeckoApplication.java +++ b/mobile/android/base/GeckoApplication.java @@ -10,8 +10,7 @@ import java.util.ArrayList; public class GeckoApplication extends Application { - private boolean mInBackground = false; - private ArrayList mListeners; + private boolean mInBackground; @Override public void onCreate() { @@ -21,50 +20,26 @@ public class GeckoApplication extends Application { } catch (ClassNotFoundException e) {} super.onCreate(); + + GeckoConnectivityReceiver.getInstance().init(getApplicationContext()); + GeckoBatteryManager.getInstance().init(getApplicationContext()); + GeckoBatteryManager.getInstance().start(); + GeckoNetworkManager.getInstance().init(getApplicationContext()); } - public interface ApplicationLifecycleCallbacks { - public void onApplicationPause(); - public void onApplicationResume(); - } - - public void addApplicationLifecycleCallbacks(ApplicationLifecycleCallbacks callback) { - if (mListeners == null) - mListeners = new ArrayList(); - - mListeners.add(callback); - } - - public void removeApplicationLifecycleCallbacks(ApplicationLifecycleCallbacks callback) { - if (mListeners == null) - return; - - mListeners.remove(callback); - } - - public void onActivityPause(GeckoActivity activity) { - if (activity.isGeckoActivityOpened()) - return; - - if (mListeners == null) - return; - + protected void onActivityPause(GeckoActivity activity) { mInBackground = true; - for (ApplicationLifecycleCallbacks listener: mListeners) - listener.onApplicationPause(); + GeckoAppShell.sendEventToGecko(GeckoEvent.createPauseEvent(true)); + GeckoConnectivityReceiver.getInstance().stop(); + GeckoNetworkManager.getInstance().stop(); } - public void onActivityResume(GeckoActivity activity) { - // This is a misnomer. Should have been "wasGeckoActivityOpened". - if (activity.isGeckoActivityOpened()) - return; - - if (mListeners == null) - return; - - for (ApplicationLifecycleCallbacks listener: mListeners) - listener.onApplicationResume(); + protected void onActivityResume(GeckoActivity activity) { + if (GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning)) + GeckoAppShell.sendEventToGecko(GeckoEvent.createResumeEvent(true)); + GeckoConnectivityReceiver.getInstance().start(); + GeckoNetworkManager.getInstance().start(); mInBackground = false; } diff --git a/mobile/android/base/GeckoBatteryManager.java b/mobile/android/base/GeckoBatteryManager.java index 9255a4cd0e76..b8dc56726a79 100644 --- a/mobile/android/base/GeckoBatteryManager.java +++ b/mobile/android/base/GeckoBatteryManager.java @@ -5,7 +5,6 @@ package org.mozilla.gecko; -import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -15,170 +14,180 @@ import android.os.Build; import android.os.SystemClock; import android.util.Log; -public class GeckoBatteryManager - extends BroadcastReceiver -{ - private static final String LOGTAG = "GeckoBatteryManager"; +public class GeckoBatteryManager extends BroadcastReceiver { + private static final String LOGTAG = "GeckoBatteryManager"; - // Those constants should be keep in sync with the ones in: - // dom/battery/Constants.h - private final static double kDefaultLevel = 1.0; - private final static boolean kDefaultCharging = true; - private final static double kDefaultRemainingTime = -1.0; - private final static double kUnknownRemainingTime = -1.0; + // Those constants should be keep in sync with the ones in: + // dom/battery/Constants.h + private final static double kDefaultLevel = 1.0; + private final static boolean kDefaultCharging = true; + private final static double kDefaultRemainingTime = -1.0; + private final static double kUnknownRemainingTime = -1.0; - private static long sLastLevelChange = 0; - private static boolean sNotificationsEnabled = false; - private static double sLevel = kDefaultLevel; - private static boolean sCharging = kDefaultCharging; - private static double sRemainingTime = kDefaultRemainingTime;; + private static long sLastLevelChange = 0; + private static boolean sNotificationsEnabled = false; + private static double sLevel = kDefaultLevel; + private static boolean sCharging = kDefaultCharging; + private static double sRemainingTime = kDefaultRemainingTime;; - private static boolean isRegistered = false; + private static GeckoBatteryManager sInstance = new GeckoBatteryManager(); - public void registerFor(Activity activity) { - if (!isRegistered) { - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_BATTERY_CHANGED); + private IntentFilter mFilter; + private Context mApplicationContext; + private boolean mIsEnabled; - // registerReceiver can return null if registering fails - isRegistered = activity.registerReceiver(this, filter) != null; - if (!isRegistered) - Log.e(LOGTAG, "Registering receiver failed"); - } - } - - public void unregisterFor(Activity activity) { - if (isRegistered) { - try { - activity.unregisterReceiver(this); - } catch (IllegalArgumentException iae) { - Log.e(LOGTAG, "Unregistering receiver failed", iae); - } - isRegistered = false; - } - } - - @Override - public void onReceive(Context context, Intent intent) { - if (!intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) { - Log.e(LOGTAG, "Got an unexpected intent!"); - return; + public static GeckoBatteryManager getInstance() { + return sInstance; } - boolean previousCharging = isCharging(); - double previousLevel = getLevel(); + private GeckoBatteryManager() { + mFilter = new IntentFilter(); + mFilter.addAction(Intent.ACTION_BATTERY_CHANGED); + } - // NOTE: it might not be common (in 2012) but technically, Android can run - // on a device that has no battery so we want to make sure it's not the case - // before bothering checking for battery state. - // However, the Galaxy Nexus phone advertizes itself as battery-less which - // force us to special-case the logic. - // See the Google bug: https://code.google.com/p/android/issues/detail?id=22035 - if (intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false) || - Build.MODEL.equals("Galaxy Nexus")) { - int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); - if (plugged == -1) { - sCharging = kDefaultCharging; - Log.e(LOGTAG, "Failed to get the plugged status!"); - } else { - // Likely, if plugged > 0, it's likely plugged and charging but the doc - // isn't clear about that. - sCharging = plugged != 0; - } + public void init(Context context) { + mApplicationContext = context.getApplicationContext(); + } - if (sCharging != previousCharging) { - sRemainingTime = kUnknownRemainingTime; - // The new remaining time is going to take some time to show up but - // it's the best way to show a not too wrong value. - sLastLevelChange = 0; - } - - // We need two doubles because sLevel is a double. - double current = (double)intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); - double max = (double)intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); - if (current == -1 || max == -1) { - Log.e(LOGTAG, "Failed to get battery level!"); - sLevel = kDefaultLevel; - } else { - sLevel = current / max; - } - - if (sLevel == 1.0 && sCharging) { - sRemainingTime = 0.0; - } else if (sLevel != previousLevel) { - // Estimate remaining time. - if (sLastLevelChange != 0) { - // Use elapsedRealtime() because we want to track time across device sleeps. - long currentTime = SystemClock.elapsedRealtime(); - long dt = (currentTime - sLastLevelChange) / 1000; - double dLevel = sLevel - previousLevel; - - if (sCharging) { - if (dLevel < 0) { - Log.w(LOGTAG, "When charging, level should increase!"); - sRemainingTime = kUnknownRemainingTime; + public synchronized void start() { + if (!mIsEnabled) { + // registerReceiver will return null if registering fails + if (mApplicationContext.registerReceiver(this, mFilter) == null) { + Log.e(LOGTAG, "Registering receiver failed"); } else { - sRemainingTime = Math.round(dt / dLevel * (1.0 - sLevel)); + mIsEnabled = true; } - } else { - if (dLevel > 0) { - Log.w(LOGTAG, "When discharging, level should decrease!"); - sRemainingTime = kUnknownRemainingTime; - } else { - sRemainingTime = Math.round(dt / -dLevel * sLevel); - } - } - - sLastLevelChange = currentTime; - } else { - // That's the first time we got an update, we can't do anything. - sLastLevelChange = SystemClock.elapsedRealtime(); } - } - } else { - sLevel = kDefaultLevel; - sCharging = kDefaultCharging; - sRemainingTime = 0; } - /* - * We want to inform listeners if the following conditions are fulfilled: - * - we have at least one observer; - * - the charging state or the level has changed. - * - * Note: no need to check for a remaining time change given that it's only - * updated if there is a level change or a charging change. - * - * The idea is to prevent doing all the way to the DOM code in the child - * process to finally not send an event. - */ - if (sNotificationsEnabled && - (previousCharging != isCharging() || previousLevel != getLevel())) { - GeckoAppShell.notifyBatteryChange(getLevel(), isCharging(), getRemainingTime()); + public synchronized void stop() { + if (mIsEnabled) { + mApplicationContext.unregisterReceiver(this); + mIsEnabled = false; + } } - } - public static boolean isCharging() { - return sCharging; - } + @Override + public void onReceive(Context context, Intent intent) { + if (!intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) { + Log.e(LOGTAG, "Got an unexpected intent!"); + return; + } - public static double getLevel() { - return sLevel; - } + boolean previousCharging = isCharging(); + double previousLevel = getLevel(); - public static double getRemainingTime() { - return sRemainingTime; - } + // NOTE: it might not be common (in 2012) but technically, Android can run + // on a device that has no battery so we want to make sure it's not the case + // before bothering checking for battery state. + // However, the Galaxy Nexus phone advertizes itself as battery-less which + // force us to special-case the logic. + // See the Google bug: https://code.google.com/p/android/issues/detail?id=22035 + if (intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false) || + Build.MODEL.equals("Galaxy Nexus")) { + int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); + if (plugged == -1) { + sCharging = kDefaultCharging; + Log.e(LOGTAG, "Failed to get the plugged status!"); + } else { + // Likely, if plugged > 0, it's likely plugged and charging but the doc + // isn't clear about that. + sCharging = plugged != 0; + } - public static void enableNotifications() { - sNotificationsEnabled = true; - } + if (sCharging != previousCharging) { + sRemainingTime = kUnknownRemainingTime; + // The new remaining time is going to take some time to show up but + // it's the best way to show a not too wrong value. + sLastLevelChange = 0; + } - public static void disableNotifications() { - sNotificationsEnabled = false; - } + // We need two doubles because sLevel is a double. + double current = (double)intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); + double max = (double)intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); + if (current == -1 || max == -1) { + Log.e(LOGTAG, "Failed to get battery level!"); + sLevel = kDefaultLevel; + } else { + sLevel = current / max; + } - public static double[] getCurrentInformation() { - return new double[] { getLevel(), isCharging() ? 1.0 : 0.0, getRemainingTime() }; - } + if (sLevel == 1.0 && sCharging) { + sRemainingTime = 0.0; + } else if (sLevel != previousLevel) { + // Estimate remaining time. + if (sLastLevelChange != 0) { + // Use elapsedRealtime() because we want to track time across device sleeps. + long currentTime = SystemClock.elapsedRealtime(); + long dt = (currentTime - sLastLevelChange) / 1000; + double dLevel = sLevel - previousLevel; + + if (sCharging) { + if (dLevel < 0) { + Log.w(LOGTAG, "When charging, level should increase!"); + sRemainingTime = kUnknownRemainingTime; + } else { + sRemainingTime = Math.round(dt / dLevel * (1.0 - sLevel)); + } + } else { + if (dLevel > 0) { + Log.w(LOGTAG, "When discharging, level should decrease!"); + sRemainingTime = kUnknownRemainingTime; + } else { + sRemainingTime = Math.round(dt / -dLevel * sLevel); + } + } + + sLastLevelChange = currentTime; + } else { + // That's the first time we got an update, we can't do anything. + sLastLevelChange = SystemClock.elapsedRealtime(); + } + } + } else { + sLevel = kDefaultLevel; + sCharging = kDefaultCharging; + sRemainingTime = 0; + } + + /* + * We want to inform listeners if the following conditions are fulfilled: + * - we have at least one observer; + * - the charging state or the level has changed. + * + * Note: no need to check for a remaining time change given that it's only + * updated if there is a level change or a charging change. + * + * The idea is to prevent doing all the way to the DOM code in the child + * process to finally not send an event. + */ + if (sNotificationsEnabled && + (previousCharging != isCharging() || previousLevel != getLevel())) { + GeckoAppShell.notifyBatteryChange(getLevel(), isCharging(), getRemainingTime()); + } + } + + public static boolean isCharging() { + return sCharging; + } + + public static double getLevel() { + return sLevel; + } + + public static double getRemainingTime() { + return sRemainingTime; + } + + public static void enableNotifications() { + sNotificationsEnabled = true; + } + + public static void disableNotifications() { + sNotificationsEnabled = false; + } + + public static double[] getCurrentInformation() { + return new double[] { getLevel(), isCharging() ? 1.0 : 0.0, getRemainingTime() }; + } } diff --git a/mobile/android/base/GeckoConnectivityReceiver.java b/mobile/android/base/GeckoConnectivityReceiver.java index 93c4a0938e64..6c674e0d7767 100644 --- a/mobile/android/base/GeckoConnectivityReceiver.java +++ b/mobile/android/base/GeckoConnectivityReceiver.java @@ -5,7 +5,6 @@ package org.mozilla.gecko; -import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -25,49 +24,59 @@ public class GeckoConnectivityReceiver extends BroadcastReceiver { private static final String LOGTAG = "GeckoConnectivityReceiver"; + private static GeckoConnectivityReceiver sInstance = new GeckoConnectivityReceiver(); + private IntentFilter mFilter; + private Context mApplicationContext; + private boolean mIsEnabled; - private static boolean isRegistered = false; + public static GeckoConnectivityReceiver getInstance() { + return sInstance; + } - public GeckoConnectivityReceiver() { + private GeckoConnectivityReceiver() { mFilter = new IntentFilter(); mFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); } - @Override - public void onReceive(Context context, Intent intent) { - String status; - ConnectivityManager cm = (ConnectivityManager) - context.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo info = cm.getActiveNetworkInfo(); - if (info == null) - status = LINK_DATA_UNKNOWN; - else if (!info.isConnected()) - status = LINK_DATA_DOWN; - else - status = LINK_DATA_UP; - - if (GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning)) - GeckoAppShell.onChangeNetworkLinkStatus(status); + public void init(Context context) { + mApplicationContext = context.getApplicationContext(); } - public void registerFor(Activity activity) { - if (!isRegistered) { - // registerReciever will return null if registering fails - isRegistered = activity.registerReceiver(this, mFilter) != null; - if (!isRegistered) + public synchronized void start() { + if (!mIsEnabled) { + // registerReceiver will return null if registering fails + if (mApplicationContext.registerReceiver(this, mFilter) == null) { Log.e(LOGTAG, "Registering receiver failed"); + } else { + mIsEnabled = true; + } } } - public void unregisterFor(Activity activity) { - if (isRegistered) { - try { - activity.unregisterReceiver(this); - } catch (IllegalArgumentException iae) { - Log.e(LOGTAG, "Unregistering receiver failed", iae); - } - isRegistered = false; + public synchronized void stop() { + if (mIsEnabled) { + mApplicationContext.unregisterReceiver(this); + mIsEnabled = false; + } + } + + @Override + public void onReceive(Context context, Intent intent) { + ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo info = cm.getActiveNetworkInfo(); + + String status; + if (info == null) { + status = LINK_DATA_UNKNOWN; + } else if (!info.isConnected()) { + status = LINK_DATA_DOWN; + } else { + status = LINK_DATA_UP; + } + + if (GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning)) { + GeckoAppShell.onChangeNetworkLinkStatus(status); } } } diff --git a/mobile/android/base/GeckoNetworkManager.java b/mobile/android/base/GeckoNetworkManager.java index 73f79bd4356a..5ec4934636b2 100644 --- a/mobile/android/base/GeckoNetworkManager.java +++ b/mobile/android/base/GeckoNetworkManager.java @@ -57,240 +57,241 @@ import android.util.Log; * int NETWORK_TYPE_LTE Current network is LTE */ -public class GeckoNetworkManager - extends BroadcastReceiver -{ - static private final GeckoNetworkManager sInstance = new GeckoNetworkManager(); +public class GeckoNetworkManager extends BroadcastReceiver { + private static final String LOGTAG = "GeckoNetworkManager"; - static private final double kDefaultBandwidth = -1.0; - static private final boolean kDefaultCanBeMetered = false; + static private final GeckoNetworkManager sInstance = new GeckoNetworkManager(); - static private final double kMaxBandwidth = 20.0; + static private final double kDefaultBandwidth = -1.0; + static private final boolean kDefaultCanBeMetered = false; - static private final double kNetworkSpeedEthernet = 20.0; // 20 Mb/s - static private final double kNetworkSpeedWifi = 20.0; // 20 Mb/s - static private final double kNetworkSpeedWiMax = 40.0; // 40 Mb/s - static private final double kNetworkSpeed_2_G = 15.0 / 1024.0; // 15 kb/s - static private final double kNetworkSpeed_2_5_G = 60.0 / 1024.0; // 60 kb/s - static private final double kNetworkSpeed_2_75_G = 200.0 / 1024.0; // 200 kb/s - static private final double kNetworkSpeed_3_G = 300.0 / 1024.0; // 300 kb/s - static private final double kNetworkSpeed_3_5_G = 7.0; // 7 Mb/s - static private final double kNetworkSpeed_3_75_G = 20.0; // 20 Mb/s - static private final double kNetworkSpeed_3_9_G = 50.0; // 50 Mb/s + static private final double kMaxBandwidth = 20.0; - private enum NetworkType { - NETWORK_NONE, - NETWORK_ETHERNET, - NETWORK_WIFI, - NETWORK_WIMAX, - NETWORK_2_G, // 2G - NETWORK_2_5_G, // 2.5G - NETWORK_2_75_G, // 2.75G - NETWORK_3_G, // 3G - NETWORK_3_5_G, // 3.5G - NETWORK_3_75_G, // 3.75G - NETWORK_3_9_G, // 3.9G - NETWORK_UNKNOWN - } + static private final double kNetworkSpeedEthernet = 20.0; // 20 Mb/s + static private final double kNetworkSpeedWifi = 20.0; // 20 Mb/s + static private final double kNetworkSpeedWiMax = 40.0; // 40 Mb/s + static private final double kNetworkSpeed_2_G = 15.0 / 1024.0; // 15 kb/s + static private final double kNetworkSpeed_2_5_G = 60.0 / 1024.0; // 60 kb/s + static private final double kNetworkSpeed_2_75_G = 200.0 / 1024.0; // 200 kb/s + static private final double kNetworkSpeed_3_G = 300.0 / 1024.0; // 300 kb/s + static private final double kNetworkSpeed_3_5_G = 7.0; // 7 Mb/s + static private final double kNetworkSpeed_3_75_G = 20.0; // 20 Mb/s + static private final double kNetworkSpeed_3_9_G = 50.0; // 50 Mb/s - private NetworkType mNetworkType = NetworkType.NETWORK_NONE; - private IntentFilter mNetworkFilter = new IntentFilter(); - // Whether the manager should be listening to Network Information changes. - private boolean mShouldBeListening = false; - // Whether the manager should notify Gecko that a change in Network - // Information happened. - private boolean mShouldNotify = false; - - public static GeckoNetworkManager getInstance() { - return sInstance; - } - - @Override - public void onReceive(Context aContext, Intent aIntent) { - updateNetworkType(); - } - - public void init() { - mNetworkFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - - mNetworkType = getNetworkType(); - } - - public void start() { - mShouldBeListening = true; - updateNetworkType(); - - if (mShouldNotify) { - startListening(); - } - } - - private void startListening() { - GeckoApp.mAppContext.registerReceiver(sInstance, mNetworkFilter); - } - - public void stop() { - mShouldBeListening = false; - - if (mShouldNotify) { - stopListening(); - } - } - - private void stopListening() { - GeckoApp.mAppContext.unregisterReceiver(sInstance); - } - - private void updateNetworkType() { - NetworkType previousNetworkType = mNetworkType; - mNetworkType = getNetworkType(); - - if (mNetworkType == previousNetworkType || !mShouldNotify) { - return; + private enum NetworkType { + NETWORK_NONE, + NETWORK_ETHERNET, + NETWORK_WIFI, + NETWORK_WIMAX, + NETWORK_2_G, // 2G + NETWORK_2_5_G, // 2.5G + NETWORK_2_75_G, // 2.75G + NETWORK_3_G, // 3G + NETWORK_3_5_G, // 3.5G + NETWORK_3_75_G, // 3.75G + NETWORK_3_9_G, // 3.9G + NETWORK_UNKNOWN } - GeckoAppShell.sendEventToGecko(GeckoEvent.createNetworkEvent( + private Context mApplicationContext; + private NetworkType mNetworkType = NetworkType.NETWORK_NONE; + private IntentFilter mNetworkFilter = new IntentFilter(); + // Whether the manager should be listening to Network Information changes. + private boolean mShouldBeListening = false; + // Whether the manager should notify Gecko that a change in Network + // Information happened. + private boolean mShouldNotify = false; + + public static GeckoNetworkManager getInstance() { + return sInstance; + } + + @Override + public void onReceive(Context aContext, Intent aIntent) { + updateNetworkType(); + } + + public void init(Context context) { + mApplicationContext = context.getApplicationContext(); + mNetworkFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + mNetworkType = getNetworkType(); + } + + public void start() { + mShouldBeListening = true; + updateNetworkType(); + + if (mShouldNotify) { + startListening(); + } + } + + private void startListening() { + mApplicationContext.registerReceiver(sInstance, mNetworkFilter); + } + + public void stop() { + mShouldBeListening = false; + + if (mShouldNotify) { + stopListening(); + } + } + + private void stopListening() { + mApplicationContext.unregisterReceiver(sInstance); + } + + private void updateNetworkType() { + NetworkType previousNetworkType = mNetworkType; + mNetworkType = getNetworkType(); + + if (mNetworkType == previousNetworkType || !mShouldNotify) { + return; + } + + GeckoAppShell.sendEventToGecko(GeckoEvent.createNetworkEvent( getNetworkSpeed(mNetworkType), isNetworkUsuallyMetered(mNetworkType))); - } - - public double[] getCurrentInformation() { - return new double[] { getNetworkSpeed(mNetworkType), - isNetworkUsuallyMetered(mNetworkType) ? 1.0 : 0.0 }; - } - - public void enableNotifications() { - // We set mShouldNotify *after* calling updateNetworkType() to make sure we - // don't notify an eventual change in mNetworkType. - updateNetworkType(); - mShouldNotify = true; - - if (mShouldBeListening) { - startListening(); - } - } - - public void disableNotifications() { - mShouldNotify = false; - - if (mShouldBeListening) { - stopListening(); - } - } - - private static NetworkType getNetworkType() { - ConnectivityManager cm = - (ConnectivityManager)GeckoApp.mAppContext.getSystemService(Context.CONNECTIVITY_SERVICE); - if (cm == null) { - Log.e("GeckoNetworkManager", "Connectivity service does not exist"); - return NetworkType.NETWORK_NONE; } - NetworkInfo ni = cm.getActiveNetworkInfo(); - if (ni == null) { - return NetworkType.NETWORK_NONE; + public double[] getCurrentInformation() { + return new double[] { getNetworkSpeed(mNetworkType), + isNetworkUsuallyMetered(mNetworkType) ? 1.0 : 0.0 }; } - switch (ni.getType()) { - case ConnectivityManager.TYPE_ETHERNET: - return NetworkType.NETWORK_ETHERNET; - case ConnectivityManager.TYPE_WIFI: - return NetworkType.NETWORK_WIFI; - case ConnectivityManager.TYPE_WIMAX: - return NetworkType.NETWORK_WIMAX; - case ConnectivityManager.TYPE_MOBILE: - break; // We will handle sub-types after the switch. - default: - Log.w("GeckoNetworkManager", "Ignoring the current network type."); - return NetworkType.NETWORK_UNKNOWN; + public void enableNotifications() { + // We set mShouldNotify *after* calling updateNetworkType() to make sure we + // don't notify an eventual change in mNetworkType. + updateNetworkType(); + mShouldNotify = true; + + if (mShouldBeListening) { + startListening(); + } } - TelephonyManager tm = - (TelephonyManager)GeckoApp.mAppContext.getSystemService(Context.TELEPHONY_SERVICE); - if (tm == null) { - Log.e("GeckoNetworkManager", "Telephony service does not exist"); - return NetworkType.NETWORK_UNKNOWN; + public void disableNotifications() { + mShouldNotify = false; + + if (mShouldBeListening) { + stopListening(); + } } - switch (tm.getNetworkType()) { - case TelephonyManager.NETWORK_TYPE_IDEN: - case TelephonyManager.NETWORK_TYPE_CDMA: - return NetworkType.NETWORK_2_G; - case TelephonyManager.NETWORK_TYPE_GPRS: - case TelephonyManager.NETWORK_TYPE_1xRTT: - return NetworkType.NETWORK_2_5_G; - case TelephonyManager.NETWORK_TYPE_EDGE: - return NetworkType.NETWORK_2_75_G; - case TelephonyManager.NETWORK_TYPE_UMTS: - case TelephonyManager.NETWORK_TYPE_EVDO_0: - return NetworkType.NETWORK_3_G; - case TelephonyManager.NETWORK_TYPE_HSPA: - case TelephonyManager.NETWORK_TYPE_HSDPA: - case TelephonyManager.NETWORK_TYPE_HSUPA: - case TelephonyManager.NETWORK_TYPE_EVDO_A: - case TelephonyManager.NETWORK_TYPE_EVDO_B: - case TelephonyManager.NETWORK_TYPE_EHRPD: - return NetworkType.NETWORK_3_5_G; - case TelephonyManager.NETWORK_TYPE_HSPAP: - return NetworkType.NETWORK_3_75_G; - case TelephonyManager.NETWORK_TYPE_LTE: - return NetworkType.NETWORK_3_9_G; - case TelephonyManager.NETWORK_TYPE_UNKNOWN: - default: - Log.w("GeckoNetworkManager", "Connected to an unknown mobile network!"); - return NetworkType.NETWORK_UNKNOWN; - } - } + private static NetworkType getNetworkType() { + ConnectivityManager cm = + (ConnectivityManager)sInstance.mApplicationContext.getSystemService(Context.CONNECTIVITY_SERVICE); + if (cm == null) { + Log.e(LOGTAG, "Connectivity service does not exist"); + return NetworkType.NETWORK_NONE; + } - private static double getNetworkSpeed(NetworkType aType) { - switch (aType) { - case NETWORK_NONE: - return 0.0; - case NETWORK_ETHERNET: - return kNetworkSpeedEthernet; - case NETWORK_WIFI: - return kNetworkSpeedWifi; - case NETWORK_WIMAX: - return kNetworkSpeedWiMax; - case NETWORK_2_G: - return kNetworkSpeed_2_G; - case NETWORK_2_5_G: - return kNetworkSpeed_2_5_G; - case NETWORK_2_75_G: - return kNetworkSpeed_2_75_G; - case NETWORK_3_G: - return kNetworkSpeed_3_G; - case NETWORK_3_5_G: - return kNetworkSpeed_3_5_G; - case NETWORK_3_75_G: - return kNetworkSpeed_3_75_G; - case NETWORK_3_9_G: - return kNetworkSpeed_3_9_G; - case NETWORK_UNKNOWN: - default: - return kDefaultBandwidth; - } - } + NetworkInfo ni = cm.getActiveNetworkInfo(); + if (ni == null) { + return NetworkType.NETWORK_NONE; + } - private static boolean isNetworkUsuallyMetered(NetworkType aType) { - switch (aType) { - case NETWORK_NONE: - case NETWORK_UNKNOWN: - case NETWORK_ETHERNET: - case NETWORK_WIFI: - case NETWORK_WIMAX: - return false; - case NETWORK_2_G: - case NETWORK_2_5_G: - case NETWORK_2_75_G: - case NETWORK_3_G: - case NETWORK_3_5_G: - case NETWORK_3_75_G: - case NETWORK_3_9_G: - return true; - default: - Log.e("GeckoNetworkManager", "Got an unexpected network type!"); - return false; + switch (ni.getType()) { + case ConnectivityManager.TYPE_ETHERNET: + return NetworkType.NETWORK_ETHERNET; + case ConnectivityManager.TYPE_WIFI: + return NetworkType.NETWORK_WIFI; + case ConnectivityManager.TYPE_WIMAX: + return NetworkType.NETWORK_WIMAX; + case ConnectivityManager.TYPE_MOBILE: + break; // We will handle sub-types after the switch. + default: + Log.w(LOGTAG, "Ignoring the current network type."); + return NetworkType.NETWORK_UNKNOWN; + } + + TelephonyManager tm = + (TelephonyManager)sInstance.mApplicationContext.getSystemService(Context.TELEPHONY_SERVICE); + if (tm == null) { + Log.e(LOGTAG, "Telephony service does not exist"); + return NetworkType.NETWORK_UNKNOWN; + } + + switch (tm.getNetworkType()) { + case TelephonyManager.NETWORK_TYPE_IDEN: + case TelephonyManager.NETWORK_TYPE_CDMA: + return NetworkType.NETWORK_2_G; + case TelephonyManager.NETWORK_TYPE_GPRS: + case TelephonyManager.NETWORK_TYPE_1xRTT: + return NetworkType.NETWORK_2_5_G; + case TelephonyManager.NETWORK_TYPE_EDGE: + return NetworkType.NETWORK_2_75_G; + case TelephonyManager.NETWORK_TYPE_UMTS: + case TelephonyManager.NETWORK_TYPE_EVDO_0: + return NetworkType.NETWORK_3_G; + case TelephonyManager.NETWORK_TYPE_HSPA: + case TelephonyManager.NETWORK_TYPE_HSDPA: + case TelephonyManager.NETWORK_TYPE_HSUPA: + case TelephonyManager.NETWORK_TYPE_EVDO_A: + case TelephonyManager.NETWORK_TYPE_EVDO_B: + case TelephonyManager.NETWORK_TYPE_EHRPD: + return NetworkType.NETWORK_3_5_G; + case TelephonyManager.NETWORK_TYPE_HSPAP: + return NetworkType.NETWORK_3_75_G; + case TelephonyManager.NETWORK_TYPE_LTE: + return NetworkType.NETWORK_3_9_G; + case TelephonyManager.NETWORK_TYPE_UNKNOWN: + default: + Log.w(LOGTAG, "Connected to an unknown mobile network!"); + return NetworkType.NETWORK_UNKNOWN; + } + } + + private static double getNetworkSpeed(NetworkType aType) { + switch (aType) { + case NETWORK_NONE: + return 0.0; + case NETWORK_ETHERNET: + return kNetworkSpeedEthernet; + case NETWORK_WIFI: + return kNetworkSpeedWifi; + case NETWORK_WIMAX: + return kNetworkSpeedWiMax; + case NETWORK_2_G: + return kNetworkSpeed_2_G; + case NETWORK_2_5_G: + return kNetworkSpeed_2_5_G; + case NETWORK_2_75_G: + return kNetworkSpeed_2_75_G; + case NETWORK_3_G: + return kNetworkSpeed_3_G; + case NETWORK_3_5_G: + return kNetworkSpeed_3_5_G; + case NETWORK_3_75_G: + return kNetworkSpeed_3_75_G; + case NETWORK_3_9_G: + return kNetworkSpeed_3_9_G; + case NETWORK_UNKNOWN: + default: + return kDefaultBandwidth; + } + } + + private static boolean isNetworkUsuallyMetered(NetworkType aType) { + switch (aType) { + case NETWORK_NONE: + case NETWORK_UNKNOWN: + case NETWORK_ETHERNET: + case NETWORK_WIFI: + case NETWORK_WIMAX: + return false; + case NETWORK_2_G: + case NETWORK_2_5_G: + case NETWORK_2_75_G: + case NETWORK_3_G: + case NETWORK_3_5_G: + case NETWORK_3_75_G: + case NETWORK_3_9_G: + return true; + default: + Log.e(LOGTAG, "Got an unexpected network type!"); + return false; + } } - } } diff --git a/mobile/android/base/GeckoScreenOrientationListener.java b/mobile/android/base/GeckoScreenOrientationListener.java index 03a3423e36ea..1bd88c90ff93 100644 --- a/mobile/android/base/GeckoScreenOrientationListener.java +++ b/mobile/android/base/GeckoScreenOrientationListener.java @@ -19,224 +19,221 @@ import org.json.JSONObject; import org.mozilla.gecko.util.GeckoEventListener; -public class GeckoScreenOrientationListener implements GeckoEventListener -{ - private static final String LOGTAG = "GeckoScreenOrientationListener"; +public class GeckoScreenOrientationListener implements GeckoEventListener { + private static final String LOGTAG = "GeckoScreenOrientationListener"; - static class OrientationEventListenerImpl extends OrientationEventListener { - public OrientationEventListenerImpl(Context c) { - super(c); + static class OrientationEventListenerImpl extends OrientationEventListener { + public OrientationEventListenerImpl(Context c) { + super(c); + } + + @Override + public void onOrientationChanged(int aOrientation) { + GeckoScreenOrientationListener.getInstance().updateScreenOrientation(); + } } - @Override - public void onOrientationChanged(int aOrientation) { - GeckoScreenOrientationListener.getInstance().updateScreenOrientation(); - } - } + static private GeckoScreenOrientationListener sInstance = null; - static private GeckoScreenOrientationListener sInstance = null; + // Make sure that any change in dom/base/ScreenOrientation.h happens here too. + static public final short eScreenOrientation_None = 0; + static public final short eScreenOrientation_PortraitPrimary = 1; + static public final short eScreenOrientation_PortraitSecondary = 2; + static public final short eScreenOrientation_Portrait = 3; + static public final short eScreenOrientation_LandscapePrimary = 4; + static public final short eScreenOrientation_LandscapeSecondary = 8; + static public final short eScreenOrientation_Landscape = 12; - // Make sure that any change in dom/base/ScreenOrientation.h happens here too. - static public final short eScreenOrientation_None = 0; - static public final short eScreenOrientation_PortraitPrimary = 1; - static public final short eScreenOrientation_PortraitSecondary = 2; - static public final short eScreenOrientation_Portrait = 3; - static public final short eScreenOrientation_LandscapePrimary = 4; - static public final short eScreenOrientation_LandscapeSecondary = 8; - static public final short eScreenOrientation_Landscape = 12; + static private final short DEFAULT_ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; - static private final short DEFAULT_ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; + private short mOrientation; + private OrientationEventListenerImpl mListener = null; - private short mOrientation; - private OrientationEventListenerImpl mListener = null; + // Whether the listener should be listening to changes. + private boolean mShouldBeListening = false; + // Whether the listener should notify Gecko that a change happened. + private boolean mShouldNotify = false; + // The default orientation to use if nothing is specified + private short mDefaultOrientation; - // Whether the listener should be listening to changes. - private boolean mShouldBeListening = false; - // Whether the listener should notify Gecko that a change happened. - private boolean mShouldNotify = false; - // The default orientation to use if nothing is specified - private short mDefaultOrientation; + private static final String DEFAULT_ORIENTATION_PREF = "app.orientation.default"; - private static final String DEFAULT_ORIENTATION_PREF = "app.orientation.default"; + private GeckoScreenOrientationListener() { + mListener = new OrientationEventListenerImpl(GeckoApp.mAppContext); - private GeckoScreenOrientationListener() { - mListener = new OrientationEventListenerImpl(GeckoApp.mAppContext); + ArrayList prefs = new ArrayList(); + prefs.add(DEFAULT_ORIENTATION_PREF); + JSONArray jsonPrefs = new JSONArray(prefs); + GeckoAppShell.registerEventListener("Preferences:Data", this); + GeckoEvent event = GeckoEvent.createBroadcastEvent("Preferences:Get", jsonPrefs.toString()); + GeckoAppShell.sendEventToGecko(event); - ArrayList prefs = new ArrayList(); - prefs.add(DEFAULT_ORIENTATION_PREF); - JSONArray jsonPrefs = new JSONArray(prefs); - GeckoAppShell.registerEventListener("Preferences:Data", this); - GeckoEvent event = GeckoEvent.createBroadcastEvent("Preferences:Get", jsonPrefs.toString()); - GeckoAppShell.sendEventToGecko(event); - - mDefaultOrientation = DEFAULT_ORIENTATION; - } - - public static GeckoScreenOrientationListener getInstance() { - if (sInstance == null) { - sInstance = new GeckoScreenOrientationListener(); + mDefaultOrientation = DEFAULT_ORIENTATION; } - return sInstance; - } + public static GeckoScreenOrientationListener getInstance() { + if (sInstance == null) { + sInstance = new GeckoScreenOrientationListener(); + } - public void start() { - mShouldBeListening = true; - updateScreenOrientation(); - - if (mShouldNotify) { - startListening(); - } - } - - public void stop() { - mShouldBeListening = false; - - if (mShouldNotify) { - stopListening(); - } - } - - public void enableNotifications() { - updateScreenOrientation(); - mShouldNotify = true; - - if (mShouldBeListening) { - startListening(); - } - } - - public void disableNotifications() { - mShouldNotify = false; - - if (mShouldBeListening) { - stopListening(); - } - } - - private void startListening() { - mListener.enable(); - } - - private void stopListening() { - mListener.disable(); - } - - public void handleMessage(String event, JSONObject message) { - try { - if ("Preferences:Data".equals(event)) { - JSONArray jsonPrefs = message.getJSONArray("preferences"); - final int length = jsonPrefs.length(); - for (int i = 0; i < length; i++) { - JSONObject jPref = jsonPrefs.getJSONObject(i); - final String prefName = jPref.getString("name"); - - if (DEFAULT_ORIENTATION_PREF.equals(prefName)) { - final String value = jPref.getString("value"); - mDefaultOrientation = orientationFromStringArray(value); - unlockScreenOrientation(); - - // this is the only pref we care about. unregister after we receive it - GeckoAppShell.unregisterEventListener("Preferences:Data", this); - } - } - } - } catch (Exception e) { - Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e); - } - } - - private short orientationFromStringArray(String val) { - List orientations = Arrays.asList(val.split(",")); - // if nothing is listed, return unspecified - if (orientations.size() == 0) - return DEFAULT_ORIENTATION; - - // we dont' support multiple orientations yet. To avoid developer confusion, - // just take the first one listed - return orientationFromString(orientations.get(0)); - } - - private short orientationFromString(String val) { - if ("portrait".equals(val)) - return (short)ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; - else if ("landscape".equals(val)) - return (short)ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; - else if ("portrait-primary".equals(val)) - return (short)ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; - else if ("portrait-secondary".equals(val)) - return (short)ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; - else if ("landscape-primary".equals(val)) - return (short)ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; - else if ("landscape-secondary".equals(val)) - return (short)ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; - return DEFAULT_ORIENTATION; - } - - // NOTE: this is public so OrientationEventListenerImpl can access it. - // Unfortunately, Java doesn't know about friendship. - public void updateScreenOrientation() { - int rotation = GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getRotation(); - short previousOrientation = mOrientation; - - if (rotation == Surface.ROTATION_0) { - mOrientation = eScreenOrientation_PortraitPrimary; - } else if (rotation == Surface.ROTATION_180) { - mOrientation = eScreenOrientation_PortraitSecondary; - } else if (rotation == Surface.ROTATION_270) { - mOrientation = eScreenOrientation_LandscapeSecondary; - } else if (rotation == Surface.ROTATION_90) { - mOrientation = eScreenOrientation_LandscapePrimary; - } else { - Log.e(LOGTAG, "Unexpected value received! (" + rotation + ")"); - return; + return sInstance; } - if (mShouldNotify && mOrientation != previousOrientation) { - GeckoAppShell.sendEventToGecko(GeckoEvent.createScreenOrientationEvent(mOrientation)); - } - } + public void start() { + mShouldBeListening = true; + updateScreenOrientation(); - public short getScreenOrientation() { - return mOrientation; - } - - public void lockScreenOrientation(int aOrientation) { - int orientation = 0; - - switch (aOrientation) { - case eScreenOrientation_PortraitPrimary: - orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; - break; - case eScreenOrientation_PortraitSecondary: - orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; - break; - case eScreenOrientation_Portrait: - orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; - break; - case eScreenOrientation_LandscapePrimary: - orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; - break; - case eScreenOrientation_LandscapeSecondary: - orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; - break; - case eScreenOrientation_Landscape: - orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; - break; - default: - Log.e(LOGTAG, "Unexpected value received! (" + aOrientation + ")"); - return; + if (mShouldNotify) { + startListening(); + } } - GeckoApp.mAppContext.setRequestedOrientation(orientation); - updateScreenOrientation(); - } + public void stop() { + mShouldBeListening = false; - public void unlockScreenOrientation() { - if (GeckoApp.mAppContext.getRequestedOrientation() == mDefaultOrientation) - return; + if (mShouldNotify) { + stopListening(); + } + } - GeckoApp.mAppContext.setRequestedOrientation(mDefaultOrientation); - updateScreenOrientation(); - } + public void enableNotifications() { + updateScreenOrientation(); + mShouldNotify = true; + + if (mShouldBeListening) { + startListening(); + } + } + + public void disableNotifications() { + mShouldNotify = false; + + if (mShouldBeListening) { + stopListening(); + } + } + + private void startListening() { + mListener.enable(); + } + + private void stopListening() { + mListener.disable(); + } + + public void handleMessage(String event, JSONObject message) { + try { + if ("Preferences:Data".equals(event)) { + JSONArray jsonPrefs = message.getJSONArray("preferences"); + final int length = jsonPrefs.length(); + for (int i = 0; i < length; i++) { + JSONObject jPref = jsonPrefs.getJSONObject(i); + final String prefName = jPref.getString("name"); + + if (DEFAULT_ORIENTATION_PREF.equals(prefName)) { + final String value = jPref.getString("value"); + mDefaultOrientation = orientationFromStringArray(value); + unlockScreenOrientation(); + + // this is the only pref we care about. unregister after we receive it + GeckoAppShell.unregisterEventListener("Preferences:Data", this); + } + } + } + } catch (Exception e) { + Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e); + } + } + + private short orientationFromStringArray(String val) { + List orientations = Arrays.asList(val.split(",")); + // if nothing is listed, return unspecified + if (orientations.size() == 0) + return DEFAULT_ORIENTATION; + + // we dont' support multiple orientations yet. To avoid developer confusion, + // just take the first one listed + return orientationFromString(orientations.get(0)); + } + + private short orientationFromString(String val) { + if ("portrait".equals(val)) + return (short)ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; + else if ("landscape".equals(val)) + return (short)ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; + else if ("portrait-primary".equals(val)) + return (short)ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; + else if ("portrait-secondary".equals(val)) + return (short)ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; + else if ("landscape-primary".equals(val)) + return (short)ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; + else if ("landscape-secondary".equals(val)) + return (short)ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; + return DEFAULT_ORIENTATION; + } + + private void updateScreenOrientation() { + int rotation = GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getRotation(); + short previousOrientation = mOrientation; + + if (rotation == Surface.ROTATION_0) { + mOrientation = eScreenOrientation_PortraitPrimary; + } else if (rotation == Surface.ROTATION_180) { + mOrientation = eScreenOrientation_PortraitSecondary; + } else if (rotation == Surface.ROTATION_270) { + mOrientation = eScreenOrientation_LandscapeSecondary; + } else if (rotation == Surface.ROTATION_90) { + mOrientation = eScreenOrientation_LandscapePrimary; + } else { + Log.e(LOGTAG, "Unexpected value received! (" + rotation + ")"); + return; + } + + if (mShouldNotify && mOrientation != previousOrientation) { + GeckoAppShell.sendEventToGecko(GeckoEvent.createScreenOrientationEvent(mOrientation)); + } + } + + public short getScreenOrientation() { + return mOrientation; + } + + public void lockScreenOrientation(int aOrientation) { + int orientation = 0; + + switch (aOrientation) { + case eScreenOrientation_PortraitPrimary: + orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; + break; + case eScreenOrientation_PortraitSecondary: + orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; + break; + case eScreenOrientation_Portrait: + orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; + break; + case eScreenOrientation_LandscapePrimary: + orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; + break; + case eScreenOrientation_LandscapeSecondary: + orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; + break; + case eScreenOrientation_Landscape: + orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; + break; + default: + Log.e(LOGTAG, "Unexpected value received! (" + aOrientation + ")"); + return; + } + + GeckoApp.mAppContext.setRequestedOrientation(orientation); + updateScreenOrientation(); + } + + public void unlockScreenOrientation() { + if (GeckoApp.mAppContext.getRequestedOrientation() == mDefaultOrientation) + return; + + GeckoApp.mAppContext.setRequestedOrientation(mDefaultOrientation); + updateScreenOrientation(); + } } diff --git a/mobile/android/chrome/content/sanitize.js b/mobile/android/chrome/content/sanitize.js index 09a15268c609..c79b12818cb5 100644 --- a/mobile/android/chrome/content/sanitize.js +++ b/mobile/android/chrome/content/sanitize.js @@ -123,9 +123,6 @@ Sanitizer.prototype = { try { cacheService.evictEntries(Ci.nsICache.STORE_OFFLINE); } catch(er) {} - - var storage = Cc["@mozilla.org/dom/storagemanager;1"].getService(Ci.nsIDOMStorageManager); - storage.clearOfflineApps(); }, get canClear() diff --git a/mobile/android/config/mozconfigs/android/debug b/mobile/android/config/mozconfigs/android/debug index 273522872af2..1ab3cf990635 100644 --- a/mobile/android/config/mozconfigs/android/debug +++ b/mobile/android/config/mozconfigs/android/debug @@ -14,9 +14,6 @@ ac_add_options --with-android-sdk="/tools/android-sdk-r16/platforms/android-16" ac_add_options --with-android-version=5 ac_add_options --with-system-zlib -# IonMonkey disabled in bug 789373 -ac_add_options --disable-ion - export JAVA_HOME=/tools/jdk6 export MOZILLA_OFFICIAL=1 export MOZ_TELEMETRY_REPORTING=1 diff --git a/mobile/android/config/mozconfigs/android/l10n-nightly b/mobile/android/config/mozconfigs/android/l10n-nightly index f4a9a61251a7..c319757be109 100644 --- a/mobile/android/config/mozconfigs/android/l10n-nightly +++ b/mobile/android/config/mozconfigs/android/l10n-nightly @@ -22,9 +22,6 @@ ac_add_options --with-system-zlib ac_add_options --enable-updater ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} -# IonMonkey disabled in bug 789373 -ac_add_options --disable-ion - export JAVA_HOME=/tools/jdk6 export MOZILLA_OFFICIAL=1 diff --git a/mobile/android/config/mozconfigs/android/l10n-release b/mobile/android/config/mozconfigs/android/l10n-release index 475bf58c644c..530a2b2607dc 100644 --- a/mobile/android/config/mozconfigs/android/l10n-release +++ b/mobile/android/config/mozconfigs/android/l10n-release @@ -18,9 +18,6 @@ ac_add_options --with-system-zlib ac_add_options --enable-updater ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} -# IonMonkey disabled in bug 789373 -ac_add_options --disable-ion - export JAVA_HOME=/tools/jdk6 export MOZILLA_OFFICIAL=1 diff --git a/mobile/android/config/mozconfigs/android/nightly b/mobile/android/config/mozconfigs/android/nightly index 8faaed783b33..017c00f677db 100644 --- a/mobile/android/config/mozconfigs/android/nightly +++ b/mobile/android/config/mozconfigs/android/nightly @@ -14,9 +14,6 @@ ac_add_options --with-android-version=5 ac_add_options --with-system-zlib ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} -# IonMonkey disabled in bug 789373 -ac_add_options --disable-ion - export JAVA_HOME=/tools/jdk6 export MOZILLA_OFFICIAL=1 export MOZ_TELEMETRY_REPORTING=1 diff --git a/mobile/android/config/mozconfigs/android/release b/mobile/android/config/mozconfigs/android/release index c95474e79eb0..6cf5bf64ef1c 100644 --- a/mobile/android/config/mozconfigs/android/release +++ b/mobile/android/config/mozconfigs/android/release @@ -15,9 +15,6 @@ ac_add_options --with-system-zlib ac_add_options --enable-updater ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} -# IonMonkey disabled in bug 789373 -ac_add_options --disable-ion - export JAVA_HOME=/tools/jdk6 export MOZILLA_OFFICIAL=1 export MOZ_TELEMETRY_REPORTING=1 diff --git a/mobile/android/installer/package-manifest.in b/mobile/android/installer/package-manifest.in index aef140e31f99..2344453c63be 100644 --- a/mobile/android/installer/package-manifest.in +++ b/mobile/android/installer/package-manifest.in @@ -275,8 +275,6 @@ @BINPATH@/components/nsHelperAppDlg.js @BINPATH@/components/nsDownloadManagerUI.manifest @BINPATH@/components/nsDownloadManagerUI.js -@BINPATH@/components/nsProxyAutoConfig.manifest -@BINPATH@/components/nsProxyAutoConfig.js @BINPATH@/components/NetworkGeolocationProvider.manifest @BINPATH@/components/NetworkGeolocationProvider.js @BINPATH@/components/GPSDGeolocationProvider.manifest diff --git a/mobile/xul/app/mobile.js b/mobile/xul/app/mobile.js index adbd6ff00353..eb87df53bef7 100644 --- a/mobile/xul/app/mobile.js +++ b/mobile/xul/app/mobile.js @@ -70,7 +70,6 @@ pref("image.cache.size", 1048576); // bytes pref("browser.offline-apps.notify", true); pref("browser.cache.offline.enable", true); pref("browser.cache.offline.capacity", 5120); // kilobytes -pref("offline-apps.quota.max", 2048); // kilobytes pref("offline-apps.quota.warn", 1024); // kilobytes // cache compression turned off for now - see bug #715198 diff --git a/mobile/xul/chrome/content/sanitize.js b/mobile/xul/chrome/content/sanitize.js index 4fb628c95afa..56e715977ac5 100644 --- a/mobile/xul/chrome/content/sanitize.js +++ b/mobile/xul/chrome/content/sanitize.js @@ -154,9 +154,6 @@ Sanitizer.prototype = { try { cacheService.evictEntries(Ci.nsICache.STORE_OFFLINE); } catch(er) {} - - var storage = Cc["@mozilla.org/dom/storagemanager;1"].getService(Ci.nsIDOMStorageManager); - storage.clearOfflineApps(); }, get canClear() diff --git a/mobile/xul/installer/package-manifest.in b/mobile/xul/installer/package-manifest.in index a9396e34c6bd..58be25c63235 100644 --- a/mobile/xul/installer/package-manifest.in +++ b/mobile/xul/installer/package-manifest.in @@ -342,8 +342,6 @@ @BINPATH@/components/nsHelperAppDlg.js @BINPATH@/components/nsDownloadManagerUI.manifest @BINPATH@/components/nsDownloadManagerUI.js -@BINPATH@/components/nsProxyAutoConfig.manifest -@BINPATH@/components/nsProxyAutoConfig.js @BINPATH@/components/NetworkGeolocationProvider.manifest @BINPATH@/components/NetworkGeolocationProvider.js @BINPATH@/components/GPSDGeolocationProvider.manifest diff --git a/modules/libpref/public/Preferences.h b/modules/libpref/public/Preferences.h index ed9f3c2db892..802ed5f23cb2 100644 --- a/modules/libpref/public/Preferences.h +++ b/modules/libpref/public/Preferences.h @@ -219,7 +219,7 @@ public: * Adds/Removes the observer for the root pref branch. * The observer is referenced strongly if AddStrongObserver is used. On the * other hand, it is referenced weakly, if AddWeakObserver is used. - * See nsIPrefBran2.idl for the detail. + * See nsIPrefBranch.idl for details. */ static nsresult AddStrongObserver(nsIObserver* aObserver, const char* aPref); static nsresult AddWeakObserver(nsIObserver* aObserver, const char* aPref); diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 683162170763..6c99e2d53d2d 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -62,10 +62,6 @@ pref("browser.cache.offline.enable", true); // offline cache capacity in kilobytes pref("browser.cache.offline.capacity", 512000); -// offline apps should be limited to this much data in global storage -// (in kilobytes) -pref("offline-apps.quota.max", 204800); - // the user should be warned if offline app disk usage exceeds this amount // (in kilobytes) pref("offline-apps.quota.warn", 51200); @@ -1122,6 +1118,9 @@ pref("network.dns.ipv4OnlyDomains", ""); // This preference can be used to turn off IPv6 name lookups. See bug 68796. pref("network.dns.disableIPv6", false); +// This preference can be used to turn off DNS prefetch. +pref("network.dns.disablePrefetch", false); + // This preference controls whether or not URLs with UTF-8 characters are // escaped. Set this preference to TRUE for strict RFC2396 conformance. pref("network.standard-url.escape-utf8", true); diff --git a/netwerk/base/public/Makefile.in b/netwerk/base/public/Makefile.in index 93ce67c47599..a1894762f26f 100644 --- a/netwerk/base/public/Makefile.in +++ b/netwerk/base/public/Makefile.in @@ -66,7 +66,6 @@ XPIDLSRCS = \ nsIProtocolProxyFilter.idl \ nsIProtocolProxyCallback.idl \ nsIProxiedProtocolHandler.idl \ - nsIProxyAutoConfig.idl \ nsIProxyInfo.idl \ nsITransport.idl \ nsISocketTransport.idl \ diff --git a/netwerk/base/public/nsIProtocolProxyService.idl b/netwerk/base/public/nsIProtocolProxyService.idl index a2aac086ef15..975f158568ea 100644 --- a/netwerk/base/public/nsIProtocolProxyService.idl +++ b/netwerk/base/public/nsIProtocolProxyService.idl @@ -17,24 +17,10 @@ interface nsIURI; * nsIProtocolProxyService provides methods to access information about * various network proxies. */ -[scriptable, uuid(d7ec6237-162e-40f5-a2b4-46ccd5fa83c9)] +[scriptable, uuid(e77c642b-026f-41ce-9b23-f829a6e3f300)] interface nsIProtocolProxyService : nsISupports { - /** - * This flag may be passed to the resolve method to request that it fail - * instead of block the calling thread. Proxy Auto Config (PAC) may - * perform a synchronous DNS query, which may not return immediately. So, - * calling resolve without this flag may result in locking up the calling - * thread for a lengthy period of time. - * - * By passing this flag to resolve, one can failover to asyncResolve to - * avoid locking up the calling thread if a PAC query is required. - * - * When this flag is passed to resolve, resolve may throw the exception - * NS_BASE_STREAM_WOULD_BLOCK to indicate that it failed due to this flag - * being present. - */ - const unsigned long RESOLVE_NON_BLOCKING = 1 << 0; + /** Flag 1 << 0 is unused **/ /** * When the proxy configuration is manual this flag may be passed to the @@ -77,44 +63,9 @@ interface nsIProtocolProxyService : nsISupports const unsigned long RESOLVE_ALWAYS_TUNNEL = (1 << 4); /** - * This method returns a nsIProxyInfo instance that identifies a proxy to - * be used for loading the given URI. Otherwise, this method returns null - * indicating that a direct connection should be used. - * - * @param aURI - * The URI to test. - * @param aFlags - * A bit-wise combination of the RESOLVE_ flags defined above. Pass - * 0 to specify the default behavior. Any additional bits that do - * not correspond to a RESOLVE_ flag are reserved for future use. - * - * NOTE: If this proxy is unavailable, getFailoverForProxy may be called - * to determine the correct secondary proxy to be used. - * - * NOTE: If the protocol handler for the given URI supports - * nsIProxiedProtocolHandler, then the nsIProxyInfo instance returned from - * resolve may be passed to the newProxiedChannel method to create a - * nsIChannel to the given URI that uses the specified proxy. - * - * NOTE: However, if the nsIProxyInfo type is "http", then it means that - * the given URI should be loaded using the HTTP protocol handler, which - * also supports nsIProxiedProtocolHandler. - * - * NOTE: If PAC is configured, and the PAC file has not yet been loaded, - * then this method will return a nsIProxyInfo instance with a type of - * "unknown" to indicate to the consumer that asyncResolve should be used - * to wait for the PAC file to finish loading. Otherwise, the consumer - * may choose to treat the result as type "direct" if desired. - * - * @see nsIProxiedProtocolHandler::newProxiedChannel - */ - nsIProxyInfo resolve(in nsIURI aURI, in unsigned long aFlags); - - /** - * This method is an asychronous version of the resolve method. Unlike - * resolve, this method is guaranteed not to block the calling thread - * waiting for DNS queries to complete. This method is intended as a - * substitute for resolve when the result is not needed immediately. + * This method returns via callback a nsIProxyInfo instance that identifies + * a proxy to be used for loading the given URI. Otherwise, this method returns + * null indicating that a direct connection should be used. * * @param aURI * The URI to test. @@ -128,6 +79,20 @@ interface nsIProtocolProxyService : nsISupports * @return An object that can be used to cancel the asychronous operation. * If canceled, the cancelation status (aReason) will be forwarded * to the callback's onProxyAvailable method via the aStatus param. + * + * NOTE: If this proxy is unavailable, getFailoverForProxy may be called + * to determine the correct secondary proxy to be used. + * + * NOTE: If the protocol handler for the given URI supports + * nsIProxiedProtocolHandler, then the nsIProxyInfo instance returned from + * resolve may be passed to the newProxiedChannel method to create a + * nsIChannel to the given URI that uses the specified proxy. + * + * NOTE: However, if the nsIProxyInfo type is "http", then it means that + * the given URI should be loaded using the HTTP protocol handler, which + * also supports nsIProxiedProtocolHandler. + * + * @see nsIProxiedProtocolHandler::newProxiedChannel */ nsICancelable asyncResolve(in nsIURI aURI, in unsigned long aFlags, in nsIProtocolProxyCallback aCallback); diff --git a/netwerk/base/public/nsIProtocolProxyService2.idl b/netwerk/base/public/nsIProtocolProxyService2.idl index 42f4698f6ffd..22b1a0a6a909 100644 --- a/netwerk/base/public/nsIProtocolProxyService2.idl +++ b/netwerk/base/public/nsIProtocolProxyService2.idl @@ -9,7 +9,7 @@ /** * An extension of nsIProtocolProxyService */ -[scriptable, uuid(dbd9565d-29b1-437a-bff5-2fc339e2c5df)] +[scriptable, uuid(bed3702d-9374-4804-a20f-32baed8e2954)] interface nsIProtocolProxyService2 : nsIProtocolProxyService { /** @@ -17,4 +17,13 @@ interface nsIProtocolProxyService2 : nsIProtocolProxyService * reloaded. The PAC file is loaded asynchronously. */ void reloadPAC(); + + /** + * This exists so Java(tm) can migrate to an asynchronous interface. + * Do not use this unless you are the plugin interface, and even then you + * ought to feel horribly guilty because you will create main thread jank. + * + * No documentation - it is deprecated! + **/ + nsIProxyInfo deprecatedBlockingResolve(in nsIURI aURI, in unsigned long aFlags); }; diff --git a/netwerk/base/public/nsIProxiedProtocolHandler.idl b/netwerk/base/public/nsIProxiedProtocolHandler.idl index 49b7a46f7631..7830c9884f36 100644 --- a/netwerk/base/public/nsIProxiedProtocolHandler.idl +++ b/netwerk/base/public/nsIProxiedProtocolHandler.idl @@ -9,12 +9,26 @@ interface nsIChannel; interface nsIURI; interface nsIProxyInfo; -[scriptable, uuid(0a24fed4-1dd2-11b2-a75c-9f8b9a8f9ba7)] +[scriptable, uuid(2b63fe69-b0fc-48f2-a2df-adb795a4ce5c)] interface nsIProxiedProtocolHandler : nsIProtocolHandler { /** Create a new channel with the given proxyInfo * + * @param uri the channel uri + * @param proxyInfo any proxy information that has already been determined, + * or null if channel should later determine the proxy on its own using + * proxyResolveFlags/proxyURI + * @param proxyResolveFlags used if the proxy is later determined + * from nsIProtocolProxyService::asyncResolve + * @param proxyURI used if the proxy is later determined from + * nsIProtocolProxyService::asyncResolve with this as the proxyURI name. + * Generally this is the same as uri (or null which has the same + * effect), except in the case of websockets which wants to bootstrap + * to an http:// channel but make its proxy determination based on + * a ws:// uri. */ - nsIChannel newProxiedChannel(in nsIURI uri, in nsIProxyInfo proxyInfo); + nsIChannel newProxiedChannel(in nsIURI uri, in nsIProxyInfo proxyInfo, + in unsigned long proxyResolveFlags, + in nsIURI proxyURI); }; diff --git a/netwerk/base/public/nsIProxyAutoConfig.idl b/netwerk/base/public/nsIProxyAutoConfig.idl deleted file mode 100644 index 29e697236d9c..000000000000 --- a/netwerk/base/public/nsIProxyAutoConfig.idl +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -/** - * The nsIProxyAutoConfig interface is used for setting arbitrary proxy - * configurations based on the specified URL. - * - * Note this interface wraps (at least in the implementation) the older - * hacks of proxy auto config. - * - * - Gagan Saksena 04/23/00 - */ - -[scriptable, uuid(a42619df-0a1c-46fb-8154-0e9b8f8f1ea8)] -interface nsIProxyAutoConfig : nsISupports -{ - /** - * This method initializes the object. This method may be called multiple - * times. If either parameter is an empty value, then the object is - * reset to its initial state. - * - * @param aPACURI - * URI used to fetch the PAC script. This is needed for properly - * constructing the JS sandbox used to evaluate the PAC script. - * @param aPACScript - * Javascript program text. - */ - void init(in ACString aPACURI, in AString aPACScript); - - /** - * Get the proxy string for the specified URI. The proxy string is - * given by the following: - * - * result = proxy-spec *( proxy-sep proxy-spec ) - * proxy-spec = direct-type | proxy-type LWS proxy-host [":" proxy-port] - * direct-type = "DIRECT" - * proxy-type = "PROXY" | "SOCKS" | "SOCKS4" | "SOCKS5" - * proxy-sep = ";" LWS - * proxy-host = hostname | ipv4-address-literal - * proxy-port = - * LWS = *( SP | HT ) - * SP = - * HT = - * - * NOTE: direct-type and proxy-type are case insensitive - * NOTE: SOCKS implies SOCKS4 - * - * Examples: - * "PROXY proxy1.foo.com:8080; PROXY proxy2.foo.com:8080; DIRECT" - * "SOCKS socksproxy" - * "DIRECT" - * - * XXX add support for IPv6 address literals. - * XXX quote whatever the official standard is for PAC. - * - * @param aTestURI - * The URI as an ASCII string to test. - * @param aTestHost - * The ASCII hostname to test. - * - * @return PAC result string as defined above. - */ - ACString getProxyForURI(in ACString aTestURI, in ACString aTestHost); -}; diff --git a/netwerk/base/public/nsISystemProxySettings.idl b/netwerk/base/public/nsISystemProxySettings.idl index 48176f5102ef..eb99d012a92a 100644 --- a/netwerk/base/public/nsISystemProxySettings.idl +++ b/netwerk/base/public/nsISystemProxySettings.idl @@ -13,17 +13,31 @@ * either return the proper proxy data from the autoconfig URL specified in the system proxy, * or generate proxy data based on the system's manual proxy settings. */ -[scriptable, uuid(a9f3ae38-b769-4e0b-9317-578388e326c9)] +[scriptable, uuid(971591cd-277e-409a-bbf6-0a79879cd307)] interface nsISystemProxySettings : nsISupports { + /** + * Whether or not it is appropriate to execute getProxyForURI off the main thread. + * If that method can block (e.g. for WPAD as windows does) then it must be + * not mainThreadOnly to avoid creating main thread jank. The main thread only option is + * provided for implementations that do not block but use other main thread only + * functions such as dbus. + */ + readonly attribute bool mainThreadOnly; + /** * If non-empty, use this PAC file. If empty, call getProxyForURI instead. */ readonly attribute AUTF8String PACURI; /** - * See nsIProxyAutoConfig::getProxyForURI; this function behaves exactly - * the same way. + * See ProxyAutoConfig::getProxyForURI; this function behaves similarly except + * a more relaxed return string is allowed that includes full urls instead of just + * host:port syntax. e.g. "PROXY http://www.foo.com:8080" instead of + * "PROXY www.foo.com:8080" */ - AUTF8String getProxyForURI(in nsIURI aURI); + AUTF8String getProxyForURI(in AUTF8String testSpec, + in AUTF8String testScheme, + in AUTF8String testHost, + in int32_t testPort); }; diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h index bf665cb31a49..ed9663ca4127 100644 --- a/netwerk/base/public/nsNetUtil.h +++ b/netwerk/base/public/nsNetUtil.h @@ -851,40 +851,6 @@ NS_GetReferrerFromChannel(nsIChannel *channel, return rv; } -#ifdef MOZILLA_INTERNAL_API -inline nsresult -NS_ExamineForProxy(const char *scheme, - const char *host, - int32_t port, - nsIProxyInfo **proxyInfo) -{ - nsresult rv; - nsCOMPtr pps = - do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv); - if (NS_SUCCEEDED(rv)) { - nsAutoCString spec(scheme); - spec.Append("://"); - spec.Append(host); - spec.Append(':'); - spec.AppendInt(port); - // XXXXX - Under no circumstances whatsoever should any code which - // wants a uri do this. I do this here because I do not, in fact, - // actually want a uri (the dummy uris created here may not be - // syntactically valid for the specific protocol), and all we need - // is something which has a valid scheme, hostname, and a string - // to pass to PAC if needed - bbaetz - nsCOMPtr uri = - do_CreateInstance(NS_STANDARDURL_CONTRACTID, &rv); - if (NS_SUCCEEDED(rv)) { - rv = uri->SetSpec(spec); - if (NS_SUCCEEDED(rv)) - rv = pps->Resolve(uri, 0, proxyInfo); - } - } - return rv; -} -#endif - inline nsresult NS_ParseContentType(const nsACString &rawContentType, nsCString &contentType, diff --git a/netwerk/base/src/Makefile.in b/netwerk/base/src/Makefile.in index a12d3d20d1e2..035510fc048f 100644 --- a/netwerk/base/src/Makefile.in +++ b/netwerk/base/src/Makefile.in @@ -66,8 +66,11 @@ CPPSRCS = \ RedirectChannelRegistrar.cpp \ nsPreloadedStream.cpp \ nsStreamListenerWrapper.cpp \ + ProxyAutoConfig.cpp \ $(NULL) +LOCAL_INCLUDES += -I$(topsrcdir)/dom/base + ifeq ($(MOZ_WIDGET_TOOLKIT),os2) CPPSRCS += nsURLHelperOS2.cpp else @@ -97,11 +100,6 @@ ifdef MOZ_ENABLE_QTNETWORK endif endif -EXTRA_COMPONENTS = \ - $(srcdir)/nsProxyAutoConfig.js \ - $(srcdir)/nsProxyAutoConfig.manifest \ - $(NULL) - EXTRA_JS_MODULES = \ NetUtil.jsm \ $(NULL) diff --git a/netwerk/base/src/ProxyAutoConfig.cpp b/netwerk/base/src/ProxyAutoConfig.cpp new file mode 100644 index 000000000000..1b6a688a79ab --- /dev/null +++ b/netwerk/base/src/ProxyAutoConfig.cpp @@ -0,0 +1,790 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 "ProxyAutoConfig.h" +#include "nsICancelable.h" +#include "nsIDNSListener.h" +#include "nsIDNSRecord.h" +#include "nsIDNSService.h" +#include "nsNetUtil.h" +#include "nsThreadUtils.h" +#include "nsIConsoleService.h" +#include "nsJSUtils.h" +#include "prnetdb.h" +#include "nsITimer.h" + +namespace mozilla { +namespace net { + +// These are some global helper symbols the PAC format requires that we provide that +// are initialized as part of the global javascript context used for PAC evaluations. +// Additionally dnsResolve(host) and myIpAddress() are supplied in the same context +// but are implemented as c++ helpers. proxyAlert(msg) is similarly defined, but that +// is a gecko specific extension. + +static const char *sPacUtils = + "function dnsDomainIs(host, domain) {\n" + " return (host.length >= domain.length &&\n" + " host.substring(host.length - domain.length) == domain);\n" + "}\n" + "" + "function dnsDomainLevels(host) {\n" + " return host.split('.').length - 1;\n" + "}\n" + "" + "function convert_addr(ipchars) {\n" + " var bytes = ipchars.split('.');\n" + " var result = ((bytes[0] & 0xff) << 24) |\n" + " ((bytes[1] & 0xff) << 16) |\n" + " ((bytes[2] & 0xff) << 8) |\n" + " (bytes[3] & 0xff);\n" + " return result;\n" + "}\n" + "" + "function isInNet(ipaddr, pattern, maskstr) {\n" + " var test = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(ipaddr);\n" + " if (test == null) {\n" + " ipaddr = dnsResolve(ipaddr);\n" + " if (ipaddr == null)\n" + " return false;\n" + " } else if (test[1] > 255 || test[2] > 255 || \n" + " test[3] > 255 || test[4] > 255) {\n" + " return false; // not an IP address\n" + " }\n" + " var host = convert_addr(ipaddr);\n" + " var pat = convert_addr(pattern);\n" + " var mask = convert_addr(maskstr);\n" + " return ((host & mask) == (pat & mask));\n" + " \n" + "}\n" + "" + "function isPlainHostName(host) {\n" + " return (host.search('\\\\.') == -1);\n" + "}\n" + "" + "function isResolvable(host) {\n" + " var ip = dnsResolve(host);\n" + " return (ip != null);\n" + "}\n" + "" + "function localHostOrDomainIs(host, hostdom) {\n" + " return (host == hostdom) ||\n" + " (hostdom.lastIndexOf(host + '.', 0) == 0);\n" + "}\n" + "" + "function shExpMatch(url, pattern) {\n" + " pattern = pattern.replace(/\\./g, '\\\\.');\n" + " pattern = pattern.replace(/\\*/g, '.*');\n" + " pattern = pattern.replace(/\\?/g, '.');\n" + " var newRe = new RegExp('^'+pattern+'$');\n" + " return newRe.test(url);\n" + "}\n" + "" + "var wdays = {SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6};\n" + "var months = {JAN: 0, FEB: 1, MAR: 2, APR: 3, MAY: 4, JUN: 5, JUL: 6, AUG: 7, SEP: 8, OCT: 9, NOV: 10, DEC: 11};\n" + "" + "function weekdayRange() {\n" + " function getDay(weekday) {\n" + " if (weekday in wdays) {\n" + " return wdays[weekday];\n" + " }\n" + " return -1;\n" + " }\n" + " var date = new Date();\n" + " var argc = arguments.length;\n" + " var wday;\n" + " if (argc < 1)\n" + " return false;\n" + " if (arguments[argc - 1] == 'GMT') {\n" + " argc--;\n" + " wday = date.getUTCDay();\n" + " } else {\n" + " wday = date.getDay();\n" + " }\n" + " var wd1 = getDay(arguments[0]);\n" + " var wd2 = (argc == 2) ? getDay(arguments[1]) : wd1;\n" + " return (wd1 == -1 || wd2 == -1) ? false\n" + " : (wd1 <= wday && wday <= wd2);\n" + "}\n" + "" + "function dateRange() {\n" + " function getMonth(name) {\n" + " if (name in months) {\n" + " return months[name];\n" + " }\n" + " return -1;\n" + " }\n" + " var date = new Date();\n" + " var argc = arguments.length;\n" + " if (argc < 1) {\n" + " return false;\n" + " }\n" + " var isGMT = (arguments[argc - 1] == 'GMT');\n" + "\n" + " if (isGMT) {\n" + " argc--;\n" + " }\n" + " // function will work even without explict handling of this case\n" + " if (argc == 1) {\n" + " var tmp = parseInt(arguments[0]);\n" + " if (isNaN(tmp)) {\n" + " return ((isGMT ? date.getUTCMonth() : date.getMonth()) ==\n" + " getMonth(arguments[0]));\n" + " } else if (tmp < 32) {\n" + " return ((isGMT ? date.getUTCDate() : date.getDate()) == tmp);\n" + " } else { \n" + " return ((isGMT ? date.getUTCFullYear() : date.getFullYear()) ==\n" + " tmp);\n" + " }\n" + " }\n" + " var year = date.getFullYear();\n" + " var date1, date2;\n" + " date1 = new Date(year, 0, 1, 0, 0, 0);\n" + " date2 = new Date(year, 11, 31, 23, 59, 59);\n" + " var adjustMonth = false;\n" + " for (var i = 0; i < (argc >> 1); i++) {\n" + " var tmp = parseInt(arguments[i]);\n" + " if (isNaN(tmp)) {\n" + " var mon = getMonth(arguments[i]);\n" + " date1.setMonth(mon);\n" + " } else if (tmp < 32) {\n" + " adjustMonth = (argc <= 2);\n" + " date1.setDate(tmp);\n" + " } else {\n" + " date1.setFullYear(tmp);\n" + " }\n" + " }\n" + " for (var i = (argc >> 1); i < argc; i++) {\n" + " var tmp = parseInt(arguments[i]);\n" + " if (isNaN(tmp)) {\n" + " var mon = getMonth(arguments[i]);\n" + " date2.setMonth(mon);\n" + " } else if (tmp < 32) {\n" + " date2.setDate(tmp);\n" + " } else {\n" + " date2.setFullYear(tmp);\n" + " }\n" + " }\n" + " if (adjustMonth) {\n" + " date1.setMonth(date.getMonth());\n" + " date2.setMonth(date.getMonth());\n" + " }\n" + " if (isGMT) {\n" + " var tmp = date;\n" + " tmp.setFullYear(date.getUTCFullYear());\n" + " tmp.setMonth(date.getUTCMonth());\n" + " tmp.setDate(date.getUTCDate());\n" + " tmp.setHours(date.getUTCHours());\n" + " tmp.setMinutes(date.getUTCMinutes());\n" + " tmp.setSeconds(date.getUTCSeconds());\n" + " date = tmp;\n" + " }\n" + " return ((date1 <= date) && (date <= date2));\n" + "}\n" + "" + "function timeRange() {\n" + " var argc = arguments.length;\n" + " var date = new Date();\n" + " var isGMT= false;\n" + "" + " if (argc < 1) {\n" + " return false;\n" + " }\n" + " if (arguments[argc - 1] == 'GMT') {\n" + " isGMT = true;\n" + " argc--;\n" + " }\n" + "\n" + " var hour = isGMT ? date.getUTCHours() : date.getHours();\n" + " var date1, date2;\n" + " date1 = new Date();\n" + " date2 = new Date();\n" + "\n" + " if (argc == 1) {\n" + " return (hour == arguments[0]);\n" + " } else if (argc == 2) {\n" + " return ((arguments[0] <= hour) && (hour <= arguments[1]));\n" + " } else {\n" + " switch (argc) {\n" + " case 6:\n" + " date1.setSeconds(arguments[2]);\n" + " date2.setSeconds(arguments[5]);\n" + " case 4:\n" + " var middle = argc >> 1;\n" + " date1.setHours(arguments[0]);\n" + " date1.setMinutes(arguments[1]);\n" + " date2.setHours(arguments[middle]);\n" + " date2.setMinutes(arguments[middle + 1]);\n" + " if (middle == 2) {\n" + " date2.setSeconds(59);\n" + " }\n" + " break;\n" + " default:\n" + " throw 'timeRange: bad number of arguments'\n" + " }\n" + " }\n" + "\n" + " if (isGMT) {\n" + " date.setFullYear(date.getUTCFullYear());\n" + " date.setMonth(date.getUTCMonth());\n" + " date.setDate(date.getUTCDate());\n" + " date.setHours(date.getUTCHours());\n" + " date.setMinutes(date.getUTCMinutes());\n" + " date.setSeconds(date.getUTCSeconds());\n" + " }\n" + " return ((date1 <= date) && (date <= date2));\n" + "}\n" + ""; + +// sRunning is defined for the helper functions only while the +// Javascript engine is running and the PAC object cannot be deleted +// or reset. +static ProxyAutoConfig *sRunning = nullptr; + +// The PACResolver is used for dnsResolve() +class PACResolver MOZ_FINAL : public nsIDNSListener + , public nsITimerCallback +{ +public: + NS_DECL_ISUPPORTS + + PACResolver() + : mStatus(NS_ERROR_FAILURE) + { + } + + // nsIDNSListener + NS_IMETHODIMP OnLookupComplete(nsICancelable *request, + nsIDNSRecord *record, + nsresult status) + { + if (mTimer) { + mTimer->Cancel(); + mTimer = nullptr; + } + + mRequest = nullptr; + mStatus = status; + mResponse = record; + return NS_OK; + } + + // nsITimerCallback + NS_IMETHODIMP Notify(nsITimer *timer) + { + if (mRequest) + mRequest->Cancel(NS_ERROR_NET_TIMEOUT); + mTimer = nullptr; + return NS_OK; + } + + nsresult mStatus; + nsCOMPtr mRequest; + nsCOMPtr mResponse; + nsCOMPtr mTimer; +}; +NS_IMPL_THREADSAFE_ISUPPORTS2(PACResolver, nsIDNSListener, nsITimerCallback) + +static +void PACLogToConsole(nsString &aMessage) +{ + nsCOMPtr consoleService = + do_GetService(NS_CONSOLESERVICE_CONTRACTID); + if (!consoleService) + return; + + consoleService->LogStringMessage(aMessage.get()); +} + +// Javascript errors are logged to the main error console +static void +PACErrorReporter(JSContext *cx, const char *message, JSErrorReport *report) +{ + nsString formattedMessage(NS_LITERAL_STRING("PAC Execution Error: ")); + formattedMessage += report->ucmessage; + formattedMessage += NS_LITERAL_STRING(" ["); + formattedMessage += report->uclinebuf; + formattedMessage += NS_LITERAL_STRING("]"); + PACLogToConsole(formattedMessage); +} + +// timeout of 0 means the normal necko timeout strategy, otherwise the dns request +// will be canceled after aTimeout milliseconds +static +JSBool PACResolve(const nsCString &aHostName, PRNetAddr *aNetAddr, + unsigned int aTimeout) +{ + if (!sRunning) { + NS_WARNING("PACResolve without a running ProxyAutoConfig object"); + return false; + } + + return sRunning->ResolveAddress(aHostName, aNetAddr, aTimeout); +} + +bool +ProxyAutoConfig::ResolveAddress(const nsCString &aHostName, + PRNetAddr *aNetAddr, + unsigned int aTimeout) +{ + nsCOMPtr dns = do_GetService(NS_DNSSERVICE_CONTRACTID); + if (!dns) + return false; + + nsRefPtr helper = new PACResolver(); + + if (NS_FAILED(dns->AsyncResolve(aHostName, 0, helper, + NS_GetCurrentThread(), + getter_AddRefs(helper->mRequest)))) + return false; + + if (aTimeout && helper->mRequest) { + if (!mTimer) + mTimer = do_CreateInstance(NS_TIMER_CONTRACTID); + if (mTimer) { + mTimer->InitWithCallback(helper, aTimeout, nsITimer::TYPE_ONE_SHOT); + helper->mTimer = mTimer; + } + } + + // Spin the event loop of the pac thread until lookup is complete. + // nsPACman is responsible for keeping a queue and only allowing + // one PAC execution at a time even when it is called re-entrantly. + while (helper->mRequest) + NS_ProcessNextEvent(NS_GetCurrentThread()); + + if (NS_FAILED(helper->mStatus) || + NS_FAILED(helper->mResponse->GetNextAddr(0, aNetAddr))) + return false; + return true; +} + +static +bool PACResolveToString(const nsCString &aHostName, + nsCString &aDottedDecimal, + unsigned int aTimeout) +{ + PRNetAddr netAddr; + if (!PACResolve(aHostName, &netAddr, aTimeout)) + return false; + + char dottedDecimal[128]; + if (PR_NetAddrToString(&netAddr, dottedDecimal, sizeof(dottedDecimal)) != PR_SUCCESS) + return false; + + aDottedDecimal.Assign(dottedDecimal); + return true; +} + +// dnsResolve(host) javascript implementation +static +JSBool PACDnsResolve(JSContext *cx, unsigned int argc, jsval *vp) +{ + if (NS_IsMainThread()) { + NS_WARNING("DNS Resolution From PAC on Main Thread. How did that happen?"); + return false; + } + + JSString *arg1 = nullptr; + if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "S", &arg1)) + return false; + + nsDependentJSString hostName; + nsAutoCString dottedDecimal; + + if (!hostName.init(cx, arg1)) + return false; + if (!PACResolveToString(NS_ConvertUTF16toUTF8(hostName), dottedDecimal, 0)) + return false; + + JSString *dottedDecimalString = JS_NewStringCopyZ(cx, dottedDecimal.get()); + JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(dottedDecimalString)); + return true; +} + +// myIpAddress() javascript implementation +static +JSBool PACMyIpAddress(JSContext *cx, unsigned int argc, jsval *vp) +{ + if (NS_IsMainThread()) { + NS_WARNING("DNS Resolution From PAC on Main Thread. How did that happen?"); + return false; + } + + if (!sRunning) { + NS_WARNING("PAC myIPAddress without a running ProxyAutoConfig object"); + return JS_FALSE; + } + + return sRunning->MyIPAddress(vp); +} + +// proxyAlert(msg) javascript implementation +static +JSBool PACProxyAlert(JSContext *cx, unsigned int argc, jsval *vp) +{ + JSString *arg1 = nullptr; + if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "S", &arg1)) + return false; + + nsDependentJSString message; + if (!message.init(cx, arg1)) + return false; + + nsString alertMessage; + alertMessage.SetCapacity(32 + message.Length()); + alertMessage += NS_LITERAL_STRING("PAC-alert: "); + alertMessage += message; + PACLogToConsole(alertMessage); + + JS_SET_RVAL(cx, vp, JSVAL_VOID); /* return undefined */ + return true; +} + +static JSFunctionSpec PACGlobalFunctions[] = { + JS_FS("dnsResolve", PACDnsResolve, 1, 0), + JS_FS("myIpAddress", PACMyIpAddress, 0, 0), + JS_FS("proxyAlert", PACProxyAlert, 1, 0), + JS_FS_END +}; + +// JSRuntimeWrapper is a c++ object that manages the runtime and context +// for the JS engine used on the PAC thread. It is initialized and destroyed +// on the PAC thread. +class JSRuntimeWrapper +{ + public: + static JSRuntimeWrapper *Create() + { + JSRuntimeWrapper *entry = new JSRuntimeWrapper(); + + if (NS_FAILED(entry->Init())) { + delete entry; + return nullptr; + } + + return entry; + } + + JSContext *Context() const + { + return mContext; + } + + JSObject *Global() const + { + return mGlobal; + } + + ~JSRuntimeWrapper() + { + MOZ_COUNT_DTOR(JSRuntimeWrapper); + if (mContext) { + JS_DestroyContext(mContext); + } + + if (mRuntime) { + JS_DestroyRuntime(mRuntime); + } + } + + void SetOK() + { + mOK = true; + } + + bool IsOK() + { + return mOK; + } + +private: + static const unsigned sRuntimeHeapSize = 2 << 20; + + JSRuntime *mRuntime; + JSContext *mContext; + JSObject *mGlobal; + bool mOK; + + static JSClass sGlobalClass; + + JSRuntimeWrapper() + : mRuntime(nullptr), mContext(nullptr), mGlobal(nullptr), mOK(false) + { + MOZ_COUNT_CTOR(JSRuntimeWrapper); + } + + nsresult Init() + { + mRuntime = JS_NewRuntime(sRuntimeHeapSize); + NS_ENSURE_TRUE(mRuntime, NS_ERROR_OUT_OF_MEMORY); + + mContext = JS_NewContext(mRuntime, 0); + NS_ENSURE_TRUE(mContext, NS_ERROR_OUT_OF_MEMORY); + + JSAutoRequest ar(mContext); + + mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, nullptr); + NS_ENSURE_TRUE(mGlobal, NS_ERROR_OUT_OF_MEMORY); + + JS_SetGlobalObject(mContext, mGlobal); + JS_InitStandardClasses(mContext, mGlobal); + + JS_SetVersion(mContext, JSVERSION_LATEST); + JS_SetErrorReporter(mContext, PACErrorReporter); + + if (!JS_DefineFunctions(mContext, mGlobal, PACGlobalFunctions)) + return NS_ERROR_FAILURE; + + return NS_OK; + } +}; + +JSClass JSRuntimeWrapper::sGlobalClass = { + "PACResolutionThreadGlobal", + JSCLASS_GLOBAL_FLAGS, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub +}; + +nsresult +ProxyAutoConfig::Init(const nsCString &aPACURI, + const nsCString &aPACScript) +{ + mPACURI = aPACURI; + mPACScript = sPacUtils; + mPACScript.Append(aPACScript); + + if (!sRunning) + return SetupJS(); + + mJSNeedsSetup = true; + return NS_OK; +} + +nsresult +ProxyAutoConfig::SetupJS() +{ + mJSNeedsSetup = false; + NS_ABORT_IF_FALSE(!sRunning, "JIT is running"); + + delete mJSRuntime; + mJSRuntime = nullptr; + + if (mPACScript.IsEmpty()) + return NS_ERROR_FAILURE; + + mJSRuntime = JSRuntimeWrapper::Create(); + if (!mJSRuntime) + return NS_ERROR_FAILURE; + + JSAutoRequest ar(mJSRuntime->Context()); + + JSScript *script = JS_CompileScript(mJSRuntime->Context(), + mJSRuntime->Global(), + mPACScript.get(), mPACScript.Length(), + mPACURI.get(), 1); + if (!JS_ExecuteScript(mJSRuntime->Context(), mJSRuntime->Global(), script, nullptr)) { + nsString alertMessage(NS_LITERAL_STRING("PAC file failed to install from ")); + alertMessage += NS_ConvertUTF8toUTF16(mPACURI); + PACLogToConsole(alertMessage); + return NS_ERROR_FAILURE; + } + + mJSRuntime->SetOK(); + nsString alertMessage(NS_LITERAL_STRING("PAC file installed from ")); + alertMessage += NS_ConvertUTF8toUTF16(mPACURI); + PACLogToConsole(alertMessage); + + // we don't need these now + mPACScript.Truncate(); + mPACURI.Truncate(); + + return NS_OK; +} + +nsresult +ProxyAutoConfig::GetProxyForURI(const nsCString &aTestURI, + const nsCString &aTestHost, + nsACString &result) +{ + if (mJSNeedsSetup) + SetupJS(); + + if (!mJSRuntime || !mJSRuntime->IsOK()) + return NS_ERROR_NOT_AVAILABLE; + + JSContext *cx = mJSRuntime->Context(); + JSAutoRequest ar(cx); + + // the sRunning flag keeps a new PAC file from being installed + // while the event loop is spinning on a DNS function. Don't early return. + sRunning = this; + mRunningHost = aTestHost; + + nsresult rv = NS_ERROR_FAILURE; + JS::RootedString uriString(cx, JS_NewStringCopyZ(cx, aTestURI.get())); + JS::RootedString hostString(cx, JS_NewStringCopyZ(cx, aTestHost.get())); + + if (uriString && hostString) { + JS::RootedValue uriValue(cx, STRING_TO_JSVAL(uriString)); + JS::RootedValue hostValue(cx, STRING_TO_JSVAL(hostString)); + + jsval argv[2] = { uriValue, hostValue }; + jsval rval; + JSBool ok = JS_CallFunctionName(cx, mJSRuntime->Global(), + "FindProxyForURL", 2, argv, &rval); + + if (ok && rval.isString()) { + nsDependentJSString pacString; + if (pacString.init(cx, rval.toString())) { + CopyUTF16toUTF8(pacString, result); + rv = NS_OK; + } + } + } + + mRunningHost.Truncate(); + sRunning = nullptr; + return rv; +} + +void +ProxyAutoConfig::GC() +{ + if (!mJSRuntime || !mJSRuntime->IsOK()) + return; + + JS_MaybeGC(mJSRuntime->Context()); +} + +ProxyAutoConfig::~ProxyAutoConfig() +{ + MOZ_COUNT_DTOR(ProxyAutoConfig); + NS_ASSERTION(!mJSRuntime, + "~ProxyAutoConfig leaking JS runtime that " + "should have been deleted on pac thread"); +} + +void +ProxyAutoConfig::Shutdown() +{ + NS_ABORT_IF_FALSE(!NS_IsMainThread(), "wrong thread for shutdown"); + + if (sRunning || mShutdown) + return; + + mShutdown = true; + delete mJSRuntime; + mJSRuntime = nullptr; +} + +bool +ProxyAutoConfig::SrcAddress(const PRNetAddr *remoteAddress, nsCString &localAddress) +{ + PRFileDesc *fd; + fd = PR_OpenUDPSocket(remoteAddress->raw.family); + if (!fd) + return false; + + if (PR_Connect(fd, remoteAddress, 0) != PR_SUCCESS) { + PR_Close(fd); + return false; + } + + PRNetAddr localName; + if (PR_GetSockName(fd, &localName) != PR_SUCCESS) { + PR_Close(fd); + return false; + } + + PR_Close(fd); + + char dottedDecimal[128]; + if (PR_NetAddrToString(&localName, dottedDecimal, sizeof(dottedDecimal)) != PR_SUCCESS) + return false; + + localAddress.Assign(dottedDecimal); + + return true; +} + +// hostName is run through a dns lookup and then a udp socket is connected +// to the result. If that all works, the local IP address of the socket is +// returned to the javascript caller and true is returned from this function. +// otherwise false is returned. +bool +ProxyAutoConfig::MyIPAddressTryHost(const nsCString &hostName, + unsigned int timeout, + jsval *vp) +{ + PRNetAddr remoteAddress; + nsAutoCString localDottedDecimal; + JSContext *cx = mJSRuntime->Context(); + + if (PACResolve(hostName, &remoteAddress, timeout) && + SrcAddress(&remoteAddress, localDottedDecimal)) { + JSString *dottedDecimalString = + JS_NewStringCopyZ(cx, localDottedDecimal.get()); + JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(dottedDecimalString)); + return true; + } + return false; +} + +bool +ProxyAutoConfig::MyIPAddress(jsval *vp) +{ + nsAutoCString remoteDottedDecimal; + nsAutoCString localDottedDecimal; + JSContext *cx = mJSRuntime->Context(); + + // first, lookup the local address of a socket connected + // to the host of uri being resolved by the pac file. This is + // v6 safe.. but is the last step like that + if (MyIPAddressTryHost(mRunningHost, kTimeout, vp)) + return true; + + // next, look for a route to a public internet address that doesn't need DNS. + // This is the google anycast dns address, but it doesn't matter if it + // remains operable (as we don't contact it) as long as the address stays + // in commonly routed IP address space. + remoteDottedDecimal.AssignLiteral("8.8.8.8"); + if (MyIPAddressTryHost(remoteDottedDecimal, 0, vp)) + return true; + + // next, use the old algorithm based on the local hostname + nsAutoCString hostName; + nsCOMPtr dns = do_GetService(NS_DNSSERVICE_CONTRACTID); + if (dns && NS_SUCCEEDED(dns->GetMyHostName(hostName)) && + PACResolveToString(hostName, localDottedDecimal, kTimeout)) { + JSString *dottedDecimalString = + JS_NewStringCopyZ(cx, localDottedDecimal.get()); + JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(dottedDecimalString)); + return true; + } + + // next try a couple RFC 1918 variants.. maybe there is a + // local route + remoteDottedDecimal.AssignLiteral("192.168.0.1"); + if (MyIPAddressTryHost(remoteDottedDecimal, 0, vp)) + return true; + + // more RFC 1918 + remoteDottedDecimal.AssignLiteral("10.0.0.1"); + if (MyIPAddressTryHost(remoteDottedDecimal, 0, vp)) + return true; + + // who knows? let's fallback to localhost + localDottedDecimal.AssignLiteral("127.0.0.1"); + JSString *dottedDecimalString = + JS_NewStringCopyZ(cx, localDottedDecimal.get()); + JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(dottedDecimalString)); + return true; +} + +} // namespace mozilla +} // namespace mozilla::net diff --git a/netwerk/base/src/ProxyAutoConfig.h b/netwerk/base/src/ProxyAutoConfig.h new file mode 100644 index 000000000000..8f335ca82f14 --- /dev/null +++ b/netwerk/base/src/ProxyAutoConfig.h @@ -0,0 +1,102 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 ProxyAutoConfig_h__ +#define ProxyAutoConfig_h__ + +#include "nsString.h" +#include "jsapi.h" +#include "prio.h" +#include "nsITimer.h" +#include "nsAutoPtr.h" + +namespace mozilla { namespace net { + +class JSRuntimeWrapper; + +// The ProxyAutoConfig class is meant to be created and run on a +// non main thread. It synchronously resolves PAC files by blocking that +// thread and running nested event loops. GetProxyForURI is not re-entrant. + +class ProxyAutoConfig { +public: + ProxyAutoConfig() + : mJSRuntime(nullptr) + , mJSNeedsSetup(false) + , mShutdown(false) + { + MOZ_COUNT_CTOR(ProxyAutoConfig); + } + ~ProxyAutoConfig(); + + nsresult Init(const nsCString &aPACURI, + const nsCString &aPACScript); + void Shutdown(); + void GC(); + bool MyIPAddress(jsval *vp); + bool ResolveAddress(const nsCString &aHostName, + PRNetAddr *aNetAddr, unsigned int aTimeout); + + /** + * Get the proxy string for the specified URI. The proxy string is + * given by the following: + * + * result = proxy-spec *( proxy-sep proxy-spec ) + * proxy-spec = direct-type | proxy-type LWS proxy-host [":" proxy-port] + * direct-type = "DIRECT" + * proxy-type = "PROXY" | "SOCKS" | "SOCKS4" | "SOCKS5" + * proxy-sep = ";" LWS + * proxy-host = hostname | ipv4-address-literal + * proxy-port = + * LWS = *( SP | HT ) + * SP = + * HT = + * + * NOTE: direct-type and proxy-type are case insensitive + * NOTE: SOCKS implies SOCKS4 + * + * Examples: + * "PROXY proxy1.foo.com:8080; PROXY proxy2.foo.com:8080; DIRECT" + * "SOCKS socksproxy" + * "DIRECT" + * + * XXX add support for IPv6 address literals. + * XXX quote whatever the official standard is for PAC. + * + * @param aTestURI + * The URI as an ASCII string to test. + * @param aTestHost + * The ASCII hostname to test. + * + * @param result + * result string as defined above. + */ + nsresult GetProxyForURI(const nsCString &aTestURI, + const nsCString &aTestHost, + nsACString &result); + +private: + const static unsigned int kTimeout = 1000; // ms to allow for myipaddress dns queries + + // used to compile the PAC file and setup the execution context + nsresult SetupJS(); + + bool SrcAddress(const PRNetAddr *remoteAddress, nsCString &localAddress); + bool MyIPAddressTryHost(const nsCString &hostName, unsigned int timeout, + jsval *vp); + + JSRuntimeWrapper *mJSRuntime; + bool mJSNeedsSetup; + bool mShutdown; + nsCString mPACScript; + nsCString mPACURI; + nsCString mRunningHost; + nsCOMPtr mTimer; +}; + +}} // namespace mozilla::net + +#endif // ProxyAutoConfig_h__ diff --git a/netwerk/base/src/nsBaseChannel.cpp b/netwerk/base/src/nsBaseChannel.cpp index 4eb85c1d7644..164ab4d44b07 100644 --- a/netwerk/base/src/nsBaseChannel.cpp +++ b/netwerk/base/src/nsBaseChannel.cpp @@ -701,7 +701,9 @@ nsBaseChannel::OnStartRequest(nsIRequest *request, nsISupports *ctxt) SUSPEND_PUMP_FOR_SCOPE(); - return mListener->OnStartRequest(this, mListenerContext); + if (mListener) // null in case of redirect + return mListener->OnStartRequest(this, mListenerContext); + return NS_OK; } NS_IMETHODIMP @@ -716,7 +718,8 @@ nsBaseChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, // Cause IsPending to return false. mPump = nullptr; - mListener->OnStopRequest(this, mListenerContext, mStatus); + if (mListener) // null in case of redirect + mListener->OnStopRequest(this, mListenerContext, mStatus); mListener = nullptr; mListenerContext = nullptr; diff --git a/netwerk/base/src/nsIOService.cpp b/netwerk/base/src/nsIOService.cpp index 1c225d81d641..75d2b86b4b59 100644 --- a/netwerk/base/src/nsIOService.cpp +++ b/netwerk/base/src/nsIOService.cpp @@ -39,6 +39,9 @@ #include "nsIConsoleService.h" #include "nsIUploadChannel2.h" #include "nsXULAppAPI.h" +#include "nsIProxiedChannel.h" +#include "nsIProtocolProxyCallback.h" +#include "nsICancelable.h" #include "mozilla/FunctionTimer.h" @@ -576,31 +579,6 @@ nsIOService::NewChannelFromURI(nsIURI *aURI, nsIChannel **result) return NewChannelFromURIWithProxyFlags(aURI, nullptr, 0, result); } -void -nsIOService::LookupProxyInfo(nsIURI *aURI, - nsIURI *aProxyURI, - uint32_t aProxyFlags, - nsCString *aScheme, - nsIProxyInfo **outPI) -{ - nsresult rv; - nsCOMPtr pi; - - if (!mProxyService) { - mProxyService = do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID); - if (!mProxyService) - NS_WARNING("failed to get protocol proxy service"); - } - if (mProxyService) { - rv = mProxyService->Resolve(aProxyURI ? aProxyURI : aURI, aProxyFlags, - getter_AddRefs(pi)); - if (NS_FAILED(rv)) - pi = nullptr; - } - pi.forget(outPI); -} - - NS_IMETHODIMP nsIOService::NewChannelFromURIWithProxyFlags(nsIURI *aURI, nsIURI *aProxyURI, @@ -625,26 +603,11 @@ nsIOService::NewChannelFromURIWithProxyFlags(nsIURI *aURI, if (NS_FAILED(rv)) return rv; - // Talk to the PPS if the protocol handler allows proxying. Otherwise, - // skip this step. This allows us to lazily load the PPS at startup. - if (protoFlags & nsIProtocolHandler::ALLOWS_PROXY) { - nsCOMPtr pi; - LookupProxyInfo(aURI, aProxyURI, aProxyFlags, &scheme, getter_AddRefs(pi)); - if (pi) { - nsAutoCString type; - if (NS_SUCCEEDED(pi->GetType(type)) && type.EqualsLiteral("http")) { - // we are going to proxy this channel using an http proxy - rv = GetProtocolHandler("http", getter_AddRefs(handler)); - if (NS_FAILED(rv)) - return rv; - } - nsCOMPtr pph = do_QueryInterface(handler); - if (pph) - return pph->NewProxiedChannel(aURI, pi, result); - } - } - - rv = handler->NewChannel(aURI, result); + nsCOMPtr pph = do_QueryInterface(handler); + if (pph) + rv = pph->NewProxiedChannel(aURI, nullptr, aProxyFlags, aProxyURI, result); + else + rv = handler->NewChannel(aURI, result); NS_ENSURE_SUCCESS(rv, rv); // Some extensions override the http protocol handler and provide their own @@ -1212,35 +1175,79 @@ nsIOService::ExtractCharsetFromContentType(const nsACString &aTypeHeader, } // nsISpeculativeConnect -NS_IMETHODIMP -nsIOService::SpeculativeConnect(nsIURI *aURI, - nsIInterfaceRequestor *aCallbacks, - nsIEventTarget *aTarget) +class IOServiceProxyCallback MOZ_FINAL : public nsIProtocolProxyCallback { +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIPROTOCOLPROXYCALLBACK + + IOServiceProxyCallback(nsIInterfaceRequestor *aCallbacks, + nsIEventTarget *aTarget, + nsIOService *aIOService) + : mCallbacks(aCallbacks) + , mTarget(aTarget) + , mIOService(aIOService) + { } + +private: + nsRefPtr mCallbacks; + nsRefPtr mTarget; + nsRefPtr mIOService; +}; + +NS_IMPL_ISUPPORTS1(IOServiceProxyCallback, nsIProtocolProxyCallback) + +NS_IMETHODIMP +IOServiceProxyCallback::OnProxyAvailable(nsICancelable *request, nsIURI *aURI, + nsIProxyInfo *pi, nsresult status) +{ + // Checking proxy status for speculative connect + nsAutoCString type; + if (NS_SUCCEEDED(status) && pi && + NS_SUCCEEDED(pi->GetType(type)) && + !type.EqualsLiteral("direct")) { + // proxies dont do speculative connect + return NS_OK; + } + nsAutoCString scheme; nsresult rv = aURI->GetScheme(scheme); if (NS_FAILED(rv)) - return rv; - - // Check for proxy information. If there is a proxy configured then a - // speculative connect should not be performed because the potential - // reward is slim with tcp peers closely located to the browser. - nsCOMPtr pi; - LookupProxyInfo(aURI, nullptr, 0, &scheme, getter_AddRefs(pi)); - if (pi) return NS_OK; nsCOMPtr handler; - rv = GetProtocolHandler(scheme.get(), getter_AddRefs(handler)); + rv = mIOService->GetProtocolHandler(scheme.get(), + getter_AddRefs(handler)); if (NS_FAILED(rv)) - return rv; + return NS_OK; nsCOMPtr speculativeHandler = do_QueryInterface(handler); if (!speculativeHandler) return NS_OK; - return speculativeHandler->SpeculativeConnect(aURI, - aCallbacks, - aTarget); + speculativeHandler->SpeculativeConnect(aURI, + mCallbacks, + mTarget); + return NS_OK; +} + +NS_IMETHODIMP +nsIOService::SpeculativeConnect(nsIURI *aURI, + nsIInterfaceRequestor *aCallbacks, + nsIEventTarget *aTarget) +{ + // Check for proxy information. If there is a proxy configured then a + // speculative connect should not be performed because the potential + // reward is slim with tcp peers closely located to the browser. + nsresult rv; + nsCOMPtr pps = + do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr cancelable; + nsRefPtr callback = + new IOServiceProxyCallback(aCallbacks, aTarget, this); + return pps->AsyncResolve(aURI, 0, callback, getter_AddRefs(cancelable)); } diff --git a/netwerk/base/src/nsPACMan.cpp b/netwerk/base/src/nsPACMan.cpp index 9191709a382a..594d8c0830de 100644 --- a/netwerk/base/src/nsPACMan.cpp +++ b/netwerk/base/src/nsPACMan.cpp @@ -6,21 +6,24 @@ #include "nsPACMan.h" #include "nsThreadUtils.h" -#include "nsIDNSService.h" -#include "nsIDNSListener.h" -#include "nsICancelable.h" #include "nsIAuthPrompt.h" #include "nsIPromptFactory.h" #include "nsIHttpChannel.h" #include "nsIPrefService.h" #include "nsIPrefBranch.h" #include "nsNetUtil.h" -#include "nsAutoPtr.h" #include "nsCRT.h" #include "prmon.h" #include "nsIAsyncVerifyRedirectCallback.h" +#include "nsProxyRelease.h" //----------------------------------------------------------------------------- +using namespace mozilla; +using namespace mozilla::net; + +// The PAC thread does evaluations of both PAC files and +// nsISystemProxySettings because they can both block the calling thread and we +// don't want that on the main thread // Check to see if the underlying request was not an error page in the case of // a HTTP request. For other types of channels, just return true. @@ -41,100 +44,206 @@ HttpRequestSucceeded(nsIStreamLoader *loader) //----------------------------------------------------------------------------- -// These objects are stored in nsPACMan::mPendingQ +// The ExecuteCallback runnable is triggered by +// nsPACManCallback::OnQueryComplete on the Main thread when its completion is +// discovered on the pac thread -class PendingPACQuery MOZ_FINAL : public PRCList, - public nsIDNSListener +class ExecuteCallback MOZ_FINAL : public nsRunnable { public: - NS_DECL_ISUPPORTS - NS_DECL_NSIDNSLISTENER - - PendingPACQuery(nsPACMan *pacMan, nsIURI *uri, nsPACManCallback *callback) - : mPACMan(pacMan) - , mURI(uri) - , mCallback(callback) + ExecuteCallback(nsPACManCallback *aCallback, + nsresult status) + : mCallback(aCallback) + , mStatus(status) { - PR_INIT_CLIST(this); } - nsresult Start(uint32_t flags); - void Complete(nsresult status, const nsCString &pacString); + void SetPACString(const nsCString &pacString) + { + mPACString = pacString; + } + + void SetPACURL(const nsCString &pacURL) + { + mPACURL = pacURL; + } + + NS_IMETHODIMP Run() + { + mCallback->OnQueryComplete(mStatus, mPACString, mPACURL); + mCallback = nullptr; + return NS_OK; + } private: - nsPACMan *mPACMan; // weak reference - nsCOMPtr mURI; nsRefPtr mCallback; - nsCOMPtr mDNSRequest; + nsresult mStatus; + nsCString mPACString; + nsCString mPACURL; }; -// This is threadsafe because we implement nsIDNSListener -NS_IMPL_THREADSAFE_ISUPPORTS1(PendingPACQuery, nsIDNSListener) +//----------------------------------------------------------------------------- -nsresult -PendingPACQuery::Start(uint32_t flags) +// The PAC thread must be deleted from the main thread, this class +// acts as a proxy to do that, as the PACMan is reference counted +// and might be destroyed on either thread + +class ShutdownThread MOZ_FINAL : public nsRunnable { - if (mDNSRequest) - return NS_OK; // already started - - nsresult rv; - nsCOMPtr dns = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) { - NS_WARNING("unable to get the DNS service"); - return rv; +public: + ShutdownThread(nsIThread *thread) + : mThread(thread) + { } - nsAutoCString host; - rv = mURI->GetAsciiHost(host); - if (NS_FAILED(rv)) - return rv; + NS_IMETHODIMP Run() + { + NS_ABORT_IF_FALSE(NS_IsMainThread(), "wrong thread"); + mThread->Shutdown(); + return NS_OK; + } - rv = dns->AsyncResolve(host, flags, this, NS_GetCurrentThread(), - getter_AddRefs(mDNSRequest)); - if (NS_FAILED(rv)) - NS_WARNING("DNS AsyncResolve failed"); +private: + nsCOMPtr mThread; +}; - return rv; +//----------------------------------------------------------------------------- + +// PACLoadComplete allows the PAC thread to tell the main thread that +// the javascript PAC file has been installed (perhaps unsuccessfully) +// and that there is no reason to queue executions anymore + +class PACLoadComplete MOZ_FINAL : public nsRunnable +{ +public: + PACLoadComplete(nsPACMan *aPACMan) + : mPACMan(aPACMan) + { + } + + NS_IMETHODIMP Run() + { + NS_ABORT_IF_FALSE(NS_IsMainThread(), "wrong thread"); + mPACMan->mLoader = nullptr; + mPACMan->PostProcessPendingQ(); + return NS_OK; + } + +private: + nsRefPtr mPACMan; +}; + +//----------------------------------------------------------------------------- + +// ExecutePACThreadAction is used to proxy actions from the main +// thread onto the PAC thread. There are 3 options: process the queue, +// cancel the queue, and setup the javascript context with a new PAC file + +class ExecutePACThreadAction MOZ_FINAL : public nsRunnable +{ +public: + // by default we just process the queue + ExecutePACThreadAction(nsPACMan *aPACMan) + : mPACMan(aPACMan) + , mCancel(false) + , mSetupPAC(false) + { } + + void CancelQueue (nsresult status) + { + mCancel = true; + mCancelStatus = status; + } + + void SetupPAC (const char *text, uint32_t datalen, nsCString &pacURI) + { + mSetupPAC = true; + mSetupPACData.Assign(text, datalen); + mSetupPACURI = pacURI; + } + + NS_IMETHODIMP Run() + { + NS_ABORT_IF_FALSE(!NS_IsMainThread(), "wrong thread"); + if (mCancel) { + mPACMan->CancelPendingQ(mCancelStatus); + mCancel = false; + return NS_OK; + } + + if (mSetupPAC) { + mSetupPAC = false; + + mPACMan->mPAC.Init(mSetupPACURI, + mSetupPACData); + + nsRefPtr runnable = new PACLoadComplete(mPACMan); + NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL); + return NS_OK; + } + + mPACMan->ProcessPendingQ(); + return NS_OK; + } + +private: + nsRefPtr mPACMan; + + bool mCancel; + nsresult mCancelStatus; + + bool mSetupPAC; + nsCString mSetupPACData; + nsCString mSetupPACURI; +}; + +//----------------------------------------------------------------------------- + +PendingPACQuery::PendingPACQuery(nsPACMan *pacMan, nsIURI *uri, + nsPACManCallback *callback, + bool mainThreadResponse) + : mPACMan(pacMan) + , mCallback(callback) + , mOnMainThreadOnly(mainThreadResponse) +{ + uri->GetAsciiSpec(mSpec); + uri->GetAsciiHost(mHost); + uri->GetScheme(mScheme); + uri->GetPort(&mPort); } -// This may be called before or after OnLookupComplete void PendingPACQuery::Complete(nsresult status, const nsCString &pacString) { if (!mCallback) return; + nsRefPtr runnable = new ExecuteCallback(mCallback, status); + runnable->SetPACString(pacString); + if (mOnMainThreadOnly) + NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL); + else + runnable->Run(); +} - mCallback->OnQueryComplete(status, pacString); - mCallback = nullptr; +void +PendingPACQuery::UseAlternatePACFile(const nsCString &pacURL) +{ + if (!mCallback) + return; - if (mDNSRequest) { - mDNSRequest->Cancel(NS_ERROR_ABORT); - mDNSRequest = nullptr; - } + nsRefPtr runnable = new ExecuteCallback(mCallback, NS_OK); + runnable->SetPACURL(pacURL); + if (mOnMainThreadOnly) + NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL); + else + runnable->Run(); } NS_IMETHODIMP -PendingPACQuery::OnLookupComplete(nsICancelable *request, - nsIDNSRecord *record, - nsresult status) +PendingPACQuery::Run() { - // NOTE: we don't care about the results of this DNS query. We issued - // this DNS query just to pre-populate our DNS cache. - - mDNSRequest = nullptr; // break reference cycle - - // If we've already completed this query then do nothing. - if (!mCallback) - return NS_OK; - - // We're no longer pending, so we can remove ourselves. - PR_REMOVE_LINK(this); - - nsAutoCString pacString; - status = mPACMan->GetProxyForURI(mURI, pacString); - Complete(status, pacString); - - NS_RELEASE_THIS(); + NS_ABORT_IF_FALSE(!NS_IsMainThread(), "wrong thread"); + mPACMan->PostQuery(this); return NS_OK; } @@ -143,87 +252,87 @@ PendingPACQuery::OnLookupComplete(nsICancelable *request, nsPACMan::nsPACMan() : mLoadPending(false) , mShutdown(false) - , mScheduledReload(LL_MAXINT) , mLoadFailureCount(0) + , mInProgress(false) { - PR_INIT_CLIST(&mPendingQ); + NS_ABORT_IF_FALSE(NS_IsMainThread(), "pacman must be created on main thread"); } nsPACMan::~nsPACMan() { + if (mPACThread) { + if (NS_IsMainThread()) { + mPACThread->Shutdown(); + } + else { + nsRefPtr runnable = new ShutdownThread(mPACThread); + NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL); + } + } + if (!NS_IsMainThread()) { + nsCOMPtr mainThread; + NS_GetMainThread(getter_AddRefs(mainThread)); + + if (mPACURI) { + nsIURI *forgettable; + mPACURI.forget(&forgettable); + NS_ProxyRelease(mainThread, forgettable, false); + } + } + NS_ASSERTION(mLoader == nullptr, "pac man not shutdown properly"); - NS_ASSERTION(mPAC == nullptr, "pac man not shutdown properly"); - NS_ASSERTION(PR_CLIST_IS_EMPTY(&mPendingQ), "pac man not shutdown properly"); + NS_ASSERTION(mPendingQ.isEmpty(), "pac man not shutdown properly"); } void nsPACMan::Shutdown() { + NS_ABORT_IF_FALSE(NS_IsMainThread(), "pacman must be shutdown on main thread"); CancelExistingLoad(); - ProcessPendingQ(NS_ERROR_ABORT); - - mPAC = nullptr; mShutdown = true; + PostCancelPendingQ(NS_ERROR_ABORT); } nsresult -nsPACMan::GetProxyForURI(nsIURI *uri, nsACString &result) +nsPACMan::AsyncGetProxyForURI(nsIURI *uri, nsPACManCallback *callback, + bool mainThreadResponse) { - NS_ENSURE_STATE(!mShutdown); - - if (IsPACURI(uri)) { - result.Truncate(); - return NS_OK; - } - - MaybeReloadPAC(); - - if (IsLoading()) - return NS_ERROR_IN_PROGRESS; - if (!mPAC) + NS_ABORT_IF_FALSE(NS_IsMainThread(), "wrong thread"); + if (mShutdown) return NS_ERROR_NOT_AVAILABLE; - nsAutoCString spec, host; - uri->GetAsciiSpec(spec); - uri->GetAsciiHost(host); + // Maybe Reload PAC + if (mPACURI && !mScheduledReload.IsNull() && + TimeStamp::Now() > mScheduledReload) + LoadPACFromURI(nullptr); - return mPAC->GetProxyForURI(spec, host, result); + nsRefPtr query = + new PendingPACQuery(this, uri, callback, mainThreadResponse); + + if (IsPACURI(uri)) { + // deal with this directly instead of queueing it + query->Complete(NS_OK, EmptyCString()); + return NS_OK; + } + + return mPACThread->Dispatch(query, nsIEventTarget::DISPATCH_NORMAL); } nsresult -nsPACMan::AsyncGetProxyForURI(nsIURI *uri, nsPACManCallback *callback) +nsPACMan::PostQuery(PendingPACQuery *query) { - NS_ENSURE_STATE(!mShutdown); + NS_ABORT_IF_FALSE(!NS_IsMainThread(), "wrong thread"); - MaybeReloadPAC(); - - PendingPACQuery *query = new PendingPACQuery(this, uri, callback); - if (!query) - return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(query); - PR_APPEND_LINK(query, &mPendingQ); - - // If we're waiting for the PAC file to load, then delay starting the query. - // See OnStreamComplete. However, if this is the PAC URI then query right - // away since we know the result will be DIRECT. We could shortcut some code - // in this case by issuing the callback directly from here, but that would - // require extra code, so we just go through the usual async code path. - int isPACURI = IsPACURI(uri); - - if (IsLoading() && !isPACURI) + if (mShutdown) { + query->Complete(NS_ERROR_NOT_AVAILABLE, EmptyCString()); return NS_OK; - - nsresult rv = query->Start(isPACURI ? 0 : nsIDNSService::RESOLVE_SPECULATE); - if (rv == NS_ERROR_DNS_LOOKUP_QUEUE_FULL && !isPACURI) { - query->OnLookupComplete(NULL, NULL, NS_OK); - rv = NS_OK; - } else if (NS_FAILED(rv)) { - NS_WARNING("failed to start PAC query"); - PR_REMOVE_LINK(query); - NS_RELEASE(query); } - return rv; + // add a reference to the query while it is in the pending list + nsRefPtr addref(query); + mPendingQ.insertBack(addref.forget().get()); + ProcessPendingQ(); + return NS_OK; } nsresult @@ -256,21 +365,24 @@ nsPACMan::LoadPACFromURI(nsIURI *pacURI) mLoader = loader; if (pacURI) { mPACURI = pacURI; + mPACURI->GetSpec(mPACURISpec); mLoadFailureCount = 0; // reset } - mScheduledReload = LL_MAXINT; - mPAC = nullptr; + + // reset to Null + mScheduledReload = TimeStamp(); return NS_OK; } void nsPACMan::StartLoading() { + NS_ABORT_IF_FALSE(NS_IsMainThread(), "wrong thread"); mLoadPending = false; // CancelExistingLoad was called... if (!mLoader) { - ProcessPendingQ(NS_ERROR_ABORT); + PostCancelPendingQ(NS_ERROR_ABORT); return; } @@ -293,18 +405,9 @@ nsPACMan::StartLoading() } CancelExistingLoad(); - ProcessPendingQ(NS_ERROR_UNEXPECTED); + PostCancelPendingQ(NS_ERROR_UNEXPECTED); } -void -nsPACMan::MaybeReloadPAC() -{ - if (!mPACURI) - return; - - if (PR_Now() > mScheduledReload) - LoadPACFromURI(nullptr); -} void nsPACMan::OnLoadFailure() @@ -324,11 +427,11 @@ nsPACMan::OnLoadFailure() if (!interval || interval > maxInterval) interval = maxInterval; -#ifdef DEBUG - printf("PAC load failure: will retry in %d seconds\n", interval); -#endif + mScheduledReload = TimeStamp::Now() + TimeDuration::FromSeconds(interval); - mScheduledReload = PR_Now() + int64_t(interval) * PR_USEC_PER_SEC; + // while we wait for the retry queued members should try direct + // even if that means fast failure. + PostCancelPendingQ(NS_ERROR_NOT_AVAILABLE); } void @@ -344,32 +447,110 @@ nsPACMan::CancelExistingLoad() } void -nsPACMan::ProcessPendingQ(nsresult status) +nsPACMan::PostProcessPendingQ() { - // Now, start any pending queries - PRCList *node = PR_LIST_HEAD(&mPendingQ); - while (node != &mPendingQ) { - PendingPACQuery *query = static_cast(node); - node = PR_NEXT_LINK(node); - if (NS_SUCCEEDED(status)) { - // keep the query in the list (so we can complete it from Shutdown if - // necessary). - status = query->Start(nsIDNSService::RESOLVE_SPECULATE); - } - if (status == NS_ERROR_DNS_LOOKUP_QUEUE_FULL) { - query->OnLookupComplete(NULL, NULL, NS_OK); - status = NS_OK; - } else if (NS_FAILED(status)) { - // remove the query from the list - PR_REMOVE_LINK(query); - query->Complete(status, EmptyCString()); - NS_RELEASE(query); - } - } + NS_ABORT_IF_FALSE(NS_IsMainThread(), "wrong thread"); + nsRefPtr pending = + new ExecutePACThreadAction(this); + if (mPACThread) + mPACThread->Dispatch(pending, nsIEventTarget::DISPATCH_NORMAL); } -NS_IMPL_ISUPPORTS3(nsPACMan, nsIStreamLoaderObserver, nsIInterfaceRequestor, - nsIChannelEventSink) +void +nsPACMan::PostCancelPendingQ(nsresult status) +{ + NS_ABORT_IF_FALSE(NS_IsMainThread(), "wrong thread"); + nsRefPtr pending = + new ExecutePACThreadAction(this); + pending->CancelQueue(status); + if (mPACThread) + mPACThread->Dispatch(pending, nsIEventTarget::DISPATCH_NORMAL); +} + +void +nsPACMan::CancelPendingQ(nsresult status) +{ + NS_ABORT_IF_FALSE(!NS_IsMainThread(), "wrong thread"); + nsRefPtr query; + + while (!mPendingQ.isEmpty()) { + query = dont_AddRef(mPendingQ.popLast()); + query->Complete(status, EmptyCString()); + } + + if (mShutdown) + mPAC.Shutdown(); +} + +void +nsPACMan::ProcessPendingQ() +{ + NS_ABORT_IF_FALSE(!NS_IsMainThread(), "wrong thread"); + while (ProcessPending()); + + // do GC while the thread has nothing pending + mPAC.GC(); + + if (mShutdown) + mPAC.Shutdown(); +} + +// returns true if progress was made by shortening the queue +bool +nsPACMan::ProcessPending() +{ + if (mPendingQ.isEmpty()) + return false; + + // queue during normal load, but if we are retrying a failed load then + // fast fail the queries + if (mInProgress || (IsLoading() && !mLoadFailureCount)) + return false; + + nsRefPtr query(dont_AddRef(mPendingQ.popFirst())); + + if (mShutdown || IsLoading()) { + query->Complete(NS_ERROR_NOT_AVAILABLE, EmptyCString()); + return true; + } + + nsAutoCString pacString; + bool completed = false; + mInProgress = true; + nsAutoCString PACURI; + + // first we need to consider the system proxy changing the pac url + if (mSystemProxySettings && + NS_SUCCEEDED(mSystemProxySettings->GetPACURI(PACURI)) && + !PACURI.IsEmpty() && + !PACURI.Equals(mPACURISpec)) { + query->UseAlternatePACFile(PACURI); + completed = true; + } + + // now try the system proxy settings for this particular url if + // PAC was not specified + if (!completed && mSystemProxySettings && PACURI.IsEmpty() && + NS_SUCCEEDED(mSystemProxySettings-> + GetProxyForURI(query->mSpec, query->mScheme, + query->mHost, query->mPort, + pacString))) { + query->Complete(NS_OK, pacString); + completed = true; + } + + // the systemproxysettings didn't complete the resolution. try via PAC + if (!completed) { + nsresult status = mPAC.GetProxyForURI(query->mSpec, query->mHost, pacString); + query->Complete(status, pacString); + } + + mInProgress = false; + return true; +} + +NS_IMPL_THREADSAFE_ISUPPORTS3(nsPACMan, nsIStreamLoaderObserver, + nsIInterfaceRequestor, nsIChannelEventSink) NS_IMETHODIMP nsPACMan::OnStreamComplete(nsIStreamLoader *loader, @@ -378,6 +559,7 @@ nsPACMan::OnStreamComplete(nsIStreamLoader *loader, uint32_t dataLen, const uint8_t *data) { + NS_ABORT_IF_FALSE(NS_IsMainThread(), "wrong thread"); if (mLoader != loader) { // If this happens, then it means that LoadPACFromURI was called more // than once before the initial call completed. In this case, status @@ -387,8 +569,6 @@ nsPACMan::OnStreamComplete(nsIStreamLoader *loader, return NS_OK; } - mLoader = nullptr; - if (NS_SUCCEEDED(status) && HttpRequestSucceeded(loader)) { // Get the URI spec used to load this PAC script. nsAutoCString pacURI; @@ -404,18 +584,21 @@ nsPACMan::OnStreamComplete(nsIStreamLoader *loader, } } - if (!mPAC) { - mPAC = do_CreateInstance(NS_PROXYAUTOCONFIG_CONTRACTID, &status); - if (!mPAC) - NS_WARNING("failed to instantiate PAC component"); - } - if (NS_SUCCEEDED(status)) { - // We assume that the PAC text is ASCII (or ISO-Latin-1). We've had this - // assumption forever, and some real-world PAC scripts actually have some - // non-ASCII text in comment blocks (see bug 296163). - const char *text = (const char *) data; - status = mPAC->Init(pacURI, NS_ConvertASCIItoUTF16(text, dataLen)); - } + // We assume that the PAC text is ASCII (or ISO-Latin-1). We've had this + // assumption forever, and some real-world PAC scripts actually have some + // non-ASCII text in comment blocks (see bug 296163). + const char *text = (const char *) data; + + // we have succeeded in loading the pac file using a bunch of interfaces that + // are main thread only, unfortunately we have to initialize the instance of + // the PAC evaluator (NS_PROXYAUTOCONFIG_CONTRACTID) on the pac thread, because + // that is where it will be used. + + nsRefPtr pending = + new ExecutePACThreadAction(this); + pending->SetupPAC(text, dataLen, pacURI); + if (mPACThread) + mPACThread->Dispatch(pending, nsIEventTarget::DISPATCH_NORMAL); // Even if the PAC file could not be parsed, we did succeed in loading the // data for it. @@ -426,11 +609,11 @@ nsPACMan::OnStreamComplete(nsIStreamLoader *loader, OnLoadFailure(); } - // Reset mPAC if necessary - if (mPAC && NS_FAILED(status)) - mPAC = nullptr; + if (NS_SUCCEEDED(status)) + PostProcessPendingQ(); + else + PostCancelPendingQ(status); - ProcessPendingQ(status); return NS_OK; } @@ -466,3 +649,26 @@ nsPACMan::AsyncOnChannelRedirect(nsIChannel *oldChannel, nsIChannel *newChannel, callback->OnRedirectVerifyCallback(NS_OK); return NS_OK; } + +void +nsPACMan::NamePACThread() +{ + NS_ABORT_IF_FALSE(!NS_IsMainThread(), "wrong thread"); + PR_SetCurrentThreadName("Proxy Resolution"); +} + +nsresult +nsPACMan::Init(nsISystemProxySettings *systemProxySettings) +{ + mSystemProxySettings = systemProxySettings; + + nsresult rv = NS_NewThread(getter_AddRefs(mPACThread), nullptr); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr event = NS_NewRunnableMethod(this, &nsPACMan::NamePACThread); + // don't check return value as it is not a big deal for this to fail. + mPACThread->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL); + + return NS_OK; +} diff --git a/netwerk/base/src/nsPACMan.h b/netwerk/base/src/nsPACMan.h index 04ba4d7917d9..704ec4017b86 100644 --- a/netwerk/base/src/nsPACMan.h +++ b/netwerk/base/src/nsPACMan.h @@ -10,12 +10,20 @@ #include "nsIStreamLoader.h" #include "nsIInterfaceRequestor.h" #include "nsIChannelEventSink.h" -#include "nsIProxyAutoConfig.h" +#include "ProxyAutoConfig.h" +#include "nsICancelable.h" +#include "nsThreadUtils.h" #include "nsIURI.h" #include "nsCOMPtr.h" #include "nsString.h" -#include "prclist.h" #include "mozilla/Attributes.h" +#include "mozilla/LinkedList.h" +#include "nsIThread.h" +#include "nsAutoPtr.h" +#include "nsISystemProxySettings.h" +#include "mozilla/TimeStamp.h" + +class nsPACMan; /** * This class defines a callback interface used by AsyncGetProxyForURI. @@ -31,14 +39,45 @@ public: * @param pacString * This parameter holds the value of the PAC string. It is empty when * status is a failure code. + * @param newPACURL + * This parameter holds the URL of a new PAC file that should be loaded + * before the query is evaluated again. At least one of pacString and + * newPACURL should be 0 length. */ - virtual void OnQueryComplete(nsresult status, const nsCString &pacString) = 0; + virtual void OnQueryComplete(nsresult status, + const nsCString &pacString, + const nsCString &newPACURL) = 0; +}; + +class PendingPACQuery MOZ_FINAL : public nsRunnable, + public mozilla::LinkedListElement +{ +public: + PendingPACQuery(nsPACMan *pacMan, nsIURI *uri, + nsPACManCallback *callback, bool mainThreadResponse); + + // can be called from either thread + void Complete(nsresult status, const nsCString &pacString); + void UseAlternatePACFile(const nsCString &pacURL); + + nsCString mSpec; + nsCString mScheme; + nsCString mHost; + int32_t mPort; + + NS_IMETHOD Run(void); /* nsRunnable */ + +private: + nsPACMan *mPACMan; // weak reference + nsRefPtr mCallback; + bool mOnMainThreadOnly; }; /** * This class provides an abstraction layer above the PAC thread. The methods * defined on this class are intended to be called on the main thread only. */ + class nsPACMan MOZ_FINAL : public nsIStreamLoaderObserver , public nsIInterfaceRequestor , public nsIChannelEventSink @@ -55,19 +94,6 @@ public: */ void Shutdown(); - /** - * This method queries a PAC result synchronously. - * - * @param uri - * The URI to query. - * @param result - * Holds the PAC result string upon return. - * - * @return NS_ERROR_IN_PROGRESS if the PAC file is not yet loaded. - * @return NS_ERROR_NOT_AVAILABLE if the PAC file could not be loaded. - */ - nsresult GetProxyForURI(nsIURI *uri, nsACString &result); - /** * This method queries a PAC result asynchronously. The callback runs on the * calling thread. If the PAC file has not yet been loaded, then this method @@ -78,8 +104,11 @@ public: * The URI to query. * @param callback * The callback to run once the PAC result is available. + * @param mustCallbackOnMainThread + * If set to false the callback can be made from the PAC thread */ - nsresult AsyncGetProxyForURI(nsIURI *uri, nsPACManCallback *callback); + nsresult AsyncGetProxyForURI(nsIURI *uri, nsPACManCallback *callback, + bool mustCallbackOnMainThread); /** * This method may be called to reload the PAC file. While we are loading @@ -105,11 +134,28 @@ public: return mPACURI && NS_SUCCEEDED(mPACURI->Equals(uri, &result)) && result; } + bool IsPACURI(nsACString &spec) + { + nsAutoCString tmp; + return (mPACURI && NS_SUCCEEDED(mPACURI->GetSpec(tmp)) && tmp.Equals(spec)); + } + + NS_HIDDEN_(nsresult) Init(nsISystemProxySettings *); + static nsPACMan *sInstance; + + // PAC thread operations only + void ProcessPendingQ(); + void CancelPendingQ(nsresult); + private: NS_DECL_NSISTREAMLOADEROBSERVER NS_DECL_NSIINTERFACEREQUESTOR NS_DECL_NSICHANNELEVENTSINK + friend class PendingPACQuery; + friend class PACLoadComplete; + friend class ExecutePACThreadAction; + ~nsPACMan(); /** @@ -117,13 +163,6 @@ private: */ void CancelExistingLoad(); - /** - * Process mPendingQ. If status is a failure code, then the pending queue - * will be emptied. If status is a success code, then the pending requests - * will be processed (i.e., their Start method will be called). - */ - void ProcessPendingQ(nsresult status); - /** * Start loading the PAC file. */ @@ -139,15 +178,35 @@ private: */ void OnLoadFailure(); + /** + * PostQuery() only runs on the PAC thread and it is used to + * place a pendingPACQuery into the queue and potentially + * execute the queue if it was otherwise empty + */ + nsresult PostQuery(PendingPACQuery *query); + + // PAC thread operations only + void PostProcessPendingQ(); + void PostCancelPendingQ(nsresult); + bool ProcessPending(); + void NamePACThread(); + private: - nsCOMPtr mPAC; + mozilla::net::ProxyAutoConfig mPAC; + nsCOMPtr mPACThread; + nsCOMPtr mSystemProxySettings; + + mozilla::LinkedList mPendingQ; /* pac thread only */ + nsCOMPtr mPACURI; - PRCList mPendingQ; + nsCString mPACURISpec; // for use off main thread nsCOMPtr mLoader; bool mLoadPending; bool mShutdown; - PRTime mScheduledReload; + mozilla::TimeStamp mScheduledReload; uint32_t mLoadFailureCount; + + bool mInProgress; }; #endif // nsPACMan_h__ diff --git a/netwerk/base/src/nsProtocolProxyService.cpp b/netwerk/base/src/nsProtocolProxyService.cpp index 52a11c8e4b50..afa47e00345f 100644 --- a/netwerk/base/src/nsProtocolProxyService.cpp +++ b/netwerk/base/src/nsProtocolProxyService.cpp @@ -12,13 +12,13 @@ #include "nsIClassInfoImpl.h" #include "nsIServiceManager.h" #include "nsXPIDLString.h" -#include "nsIProxyAutoConfig.h" #include "nsIIOService.h" #include "nsIObserverService.h" #include "nsIProtocolHandler.h" #include "nsIProtocolProxyCallback.h" #include "nsICancelable.h" #include "nsIDNSService.h" +#include "nsPIDNSService.h" #include "nsIPrefService.h" #include "nsIPrefBranch.h" #include "nsReadableUtils.h" @@ -29,6 +29,9 @@ #include "nsCRT.h" #include "prnetdb.h" #include "nsPACMan.h" +#include "nsProxyRelease.h" +#include "mozilla/Mutex.h" +#include "mozilla/CondVar.h" //---------------------------------------------------------------------------- @@ -72,12 +75,49 @@ public: , mDispatched(false) , mResolveFlags(aResolveFlags) , mPPS(pps) + , mXPComPPS(pps) , mURI(uri) , mCallback(callback) { NS_ASSERTION(mCallback, "null callback"); } + ~nsAsyncResolveRequest() + { + if (!NS_IsMainThread()) { + // these xpcom pointers might need to be proxied back to the + // main thread to delete safely, but if this request had its + // callbacks called normally they will all be null and this is a nop + + nsCOMPtr mainThread; + NS_GetMainThread(getter_AddRefs(mainThread)); + + if (mURI) { + nsIURI *forgettable; + mURI.forget(&forgettable); + NS_ProxyRelease(mainThread, forgettable, false); + } + + if (mCallback) { + nsIProtocolProxyCallback *forgettable; + mCallback.forget(&forgettable); + NS_ProxyRelease(mainThread, forgettable, false); + } + + if (mProxyInfo) { + nsIProxyInfo *forgettable; + mProxyInfo.forget(&forgettable); + NS_ProxyRelease(mainThread, forgettable, false); + } + + if (mXPComPPS) { + nsIProtocolProxyService *forgettable; + mXPComPPS.forget(&forgettable); + NS_ProxyRelease(mainThread, forgettable, false); + } + } + } + void SetResult(nsresult status, nsIProxyInfo *pi) { mStatus = status; @@ -124,7 +164,9 @@ private: // Called asynchronously, so we do not need to post another PLEvent // before calling DoCallback. - void OnQueryComplete(nsresult status, const nsCString &pacString) + void OnQueryComplete(nsresult status, + const nsCString &pacString, + const nsCString &newPACURL) { // If we've already called DoCallback then, nothing more to do. if (!mCallback) @@ -134,6 +176,7 @@ private: if (mStatus == NS_OK) { mStatus = status; mPACString = pacString; + mPACURL = newPACURL; } // In the cancelation case, we may still have another PLEvent in @@ -156,26 +199,63 @@ private: mPPS->ApplyFilters(mURI, info, mProxyInfo); else mProxyInfo = nullptr; + + LOG(("pac thread callback %s\n", mPACString.get())); + if (NS_SUCCEEDED(mStatus)) + mPPS->MaybeDisableDNSPrefetch(mProxyInfo); + mCallback->OnProxyAvailable(this, mURI, mProxyInfo, mStatus); + } + else if (NS_SUCCEEDED(mStatus) && !mPACURL.IsEmpty()) { + LOG(("pac thread callback indicates new pac file load\n")); + + // trigger load of new pac url + nsresult rv = mPPS->ConfigureFromPAC(mPACURL, false); + if (NS_SUCCEEDED(rv)) { + // now that the load is triggered, we can resubmit the query + nsRefPtr newRequest = + new nsAsyncResolveRequest(mPPS, mURI, mResolveFlags, mCallback); + rv = mPPS->mPACMan->AsyncGetProxyForURI(mURI, newRequest, false); + } + + if (NS_FAILED(rv)) + mCallback->OnProxyAvailable(this, mURI, nullptr, rv); + + // do not call onproxyavailable() in SUCCESS case - the newRequest will + // take care of that + } + else { + LOG(("pac thread callback did not provide information %X\n", mStatus)); + if (NS_SUCCEEDED(mStatus)) + mPPS->MaybeDisableDNSPrefetch(mProxyInfo); + mCallback->OnProxyAvailable(this, mURI, mProxyInfo, mStatus); } - mCallback->OnProxyAvailable(this, mURI, mProxyInfo, mStatus); + // We are on the main thread now and don't need these any more so + // release them to avoid having to proxy them back to the main thread + // in the dtor mCallback = nullptr; // in case the callback holds an owning ref to us + mPPS = nullptr; + mXPComPPS = nullptr; + mURI = nullptr; + mProxyInfo = nullptr; } private: nsresult mStatus; nsCString mPACString; + nsCString mPACURL; bool mDispatched; uint32_t mResolveFlags; - nsRefPtr mPPS; + nsProtocolProxyService *mPPS; + nsCOMPtr mXPComPPS; nsCOMPtr mURI; nsCOMPtr mCallback; nsCOMPtr mProxyInfo; }; -NS_IMPL_ISUPPORTS2(nsAsyncResolveRequest, nsICancelable, nsIRunnable) +NS_IMPL_THREADSAFE_ISUPPORTS2(nsAsyncResolveRequest, nsICancelable, nsIRunnable) //---------------------------------------------------------------------------- @@ -386,8 +466,12 @@ nsProtocolProxyService::PrefsChanged(nsIPrefBranch *prefBranch, mSystemProxySettings = do_GetService(NS_SYSTEMPROXYSETTINGS_CONTRACTID); if (!mSystemProxySettings) mProxyConfig = PROXYCONFIG_DIRECT; + ResetPACThread(); } else { - mSystemProxySettings = nullptr; + if (mSystemProxySettings) { + mSystemProxySettings = nullptr; + ResetPACThread(); + } } } @@ -572,7 +656,7 @@ nsProtocolProxyService::ExtractProxyInfo(const char *start, *result = nullptr; uint32_t flags = 0; - // see BNF in nsIProxyAutoConfig.idl + // see BNF in ProxyAutoConfig.h and notes in nsISystemProxySettings.idl // find end of proxy info delimiter const char *end = start; @@ -616,33 +700,57 @@ nsProtocolProxyService::ExtractProxyInfo(const char *start, start = sp; while ((*start == ' ' || *start == '\t') && start < end) start++; - if (start < end) { - host = start; - hostEnd = strchr(host, ':'); - if (!hostEnd || hostEnd > end) { - hostEnd = end; - // no port, so assume default - if (type == kProxyType_HTTP) - port = 80; - else - port = 1080; + + // port defaults + if (type == kProxyType_HTTP) + port = 80; + else + port = 1080; + + nsProxyInfo *pi = new nsProxyInfo(); + pi->mType = type; + pi->mFlags = flags; + pi->mResolveFlags = aResolveFlags; + pi->mTimeout = mFailedProxyTimeout; + + // www.foo.com:8080 and http://www.foo.com:8080 + nsDependentCSubstring maybeURL(start, end - start); + nsCOMPtr pacURI; + + nsAutoCString urlHost; + if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(pacURI), maybeURL)) && + NS_SUCCEEDED(pacURI->GetAsciiHost(urlHost)) && + !urlHost.IsEmpty()) { + // http://www.example.com:8080 + + pi->mHost = urlHost; + + int32_t tPort; + if (NS_SUCCEEDED(pacURI->GetPort(&tPort)) && tPort != -1) { + port = tPort; } - else - port = atoi(hostEnd + 1); + pi->mPort = port; } - nsProxyInfo *pi = new nsProxyInfo; - if (pi) { - pi->mType = type; - pi->mFlags = flags; - pi->mResolveFlags = aResolveFlags; - pi->mTimeout = mFailedProxyTimeout; + else { + // www.example.com:8080 + if (start < end) { + host = start; + hostEnd = strchr(host, ':'); + if (!hostEnd || hostEnd > end) { + hostEnd = end; + // no port, so assume default + } + else { + port = atoi(hostEnd + 1); + } + } // YES, it is ok to specify a null proxy host. if (host) { pi->mHost.Assign(host, hostEnd - host); pi->mPort = port; } - NS_ADDREF(*result = pi); } + NS_ADDREF(*result = pi); } while (*end == ';' || *end == ' ' || *end == '\t') @@ -739,15 +847,46 @@ nsProtocolProxyService::IsProxyDisabled(nsProxyInfo *pi) return true; } +nsresult +nsProtocolProxyService::SetupPACThread() +{ + if (mPACMan) + return NS_OK; + + mPACMan = new nsPACMan(); + + bool mainThreadOnly; + nsresult rv; + if (mSystemProxySettings && + NS_SUCCEEDED(mSystemProxySettings->GetMainThreadOnly(&mainThreadOnly)) && + !mainThreadOnly) { + rv = mPACMan->Init(mSystemProxySettings); + } + else { + rv = mPACMan->Init(nullptr); + } + + if (NS_FAILED(rv)) + mPACMan = nullptr; + return rv; +} + +nsresult +nsProtocolProxyService::ResetPACThread() +{ + if (!mPACMan) + return NS_OK; + + mPACMan->Shutdown(); + mPACMan = nullptr; + return SetupPACThread(); +} + nsresult nsProtocolProxyService::ConfigureFromPAC(const nsCString &spec, bool forceReload) { - if (!mPACMan) { - mPACMan = new nsPACMan(); - if (!mPACMan) - return NS_ERROR_OUT_OF_MEMORY; - } + SetupPACThread(); nsCOMPtr pacURI; nsresult rv = NS_NewURI(getter_AddRefs(pacURI), spec); @@ -814,53 +953,125 @@ nsProtocolProxyService::ReloadPAC() return NS_OK; } -// nsIProtocolProxyService -NS_IMETHODIMP -nsProtocolProxyService::Resolve(nsIURI *uri, uint32_t flags, - nsIProxyInfo **result) +// When sync interface is removed this can go away too +class nsAsyncBridgeRequest MOZ_FINAL : public nsPACManCallback { - NS_ENSURE_ARG_POINTER(uri); + NS_DECL_ISUPPORTS + + nsAsyncBridgeRequest() + : mMutex("nsDeprecatedCallback") + , mCondVar(mMutex, "nsDeprecatedCallback") + , mCompleted(false) + { + } + + void OnQueryComplete(nsresult status, + const nsCString &pacString, + const nsCString &newPACURL) + { + MutexAutoLock lock(mMutex); + mCompleted = true; + mStatus = status; + mPACString = pacString; + mPACURL = newPACURL; + mCondVar.Notify(); + } + + void Lock() { mMutex.Lock(); } + void Unlock() { mMutex.Unlock(); } + void Wait() { mCondVar.Wait(PR_SecondsToInterval(3)); } + +private: + ~nsAsyncBridgeRequest() + { + } + + friend class nsProtocolProxyService; + + Mutex mMutex; + CondVar mCondVar; + + nsresult mStatus; + nsCString mPACString; + nsCString mPACURL; + bool mCompleted; +}; +NS_IMPL_THREADSAFE_ISUPPORTS1(nsAsyncBridgeRequest, nsPACManCallback) + +// nsIProtocolProxyService2 +NS_IMETHODIMP +nsProtocolProxyService::DeprecatedBlockingResolve(nsIURI *aURI, + uint32_t aFlags, + nsIProxyInfo **retval) +{ + NS_ENSURE_ARG_POINTER(aURI); nsProtocolInfo info; - nsresult rv = GetProtocolInfo(uri, &info); + nsresult rv = GetProtocolInfo(aURI, &info); if (NS_FAILED(rv)) return rv; - bool usePAC; - rv = Resolve_Internal(uri, info, flags, &usePAC, result); - if (NS_FAILED(rv)) { - LOG(("Resolve_Internal returned rv(0x%08x)\n", rv)); + nsCOMPtr pi; + bool usePACThread; + + // SystemProxySettings and PAC files can block the main thread + // but if neither of them are in use, we can just do the work + // right here and directly invoke the callback + + rv = Resolve_Internal(aURI, info, aFlags, &usePACThread, getter_AddRefs(pi)); + if (NS_FAILED(rv)) return rv; + + if (!usePACThread || !mPACMan) { + ApplyFilters(aURI, info, pi); + pi.forget(retval); + return NS_OK; } - if (usePAC && mPACMan) { - NS_ASSERTION(*result == nullptr, "we should not have a result yet"); + // Use the PAC thread to do the work, so we don't have to reimplement that + // code, but block this thread on that completion. + nsRefPtr ctx = new nsAsyncBridgeRequest(); + ctx->Lock(); + if (NS_SUCCEEDED(mPACMan->AsyncGetProxyForURI(aURI, ctx, false))) { + // this can really block the main thread, so cap it at 3 seconds + ctx->Wait(); + } + ctx->Unlock(); + if (!ctx->mCompleted) + return NS_ERROR_FAILURE; + if (NS_FAILED(ctx->mStatus)) + return ctx->mStatus; - // If the caller didn't want us to invoke PAC, then error out. - if (flags & RESOLVE_NON_BLOCKING) - return NS_BASE_STREAM_WOULD_BLOCK; + // pretty much duplicate real DoCallback logic - // Query the PAC file synchronously. - nsCString pacString; - rv = mPACMan->GetProxyForURI(uri, pacString); - if (NS_SUCCEEDED(rv)) - ProcessPACString(pacString, flags, result); - else if (rv == NS_ERROR_IN_PROGRESS) { - // Construct a special UNKNOWN proxy entry that informs the caller - // that the proxy info is yet to be determined. - rv = NewProxyInfo_Internal(kProxyType_UNKNOWN, EmptyCString(), -1, - 0, 0, nullptr, flags, result); - if (NS_FAILED(rv)) - return rv; - } - else - NS_WARNING("failed querying PAC file; trying DIRECT"); + // Generate proxy info from the PAC string if appropriate + if (!ctx->mPACString.IsEmpty()) { + LOG(("sync pac thread callback %s\n", ctx->mPACString.get())); + ProcessPACString(ctx->mPACString, 0, getter_AddRefs(pi)); + ApplyFilters(aURI, info, pi); + pi.forget(retval); + return NS_OK; } - ApplyFilters(uri, info, result); + if (!ctx->mPACURL.IsEmpty()) { + NS_WARNING("sync pac thread callback indicates new pac file load\n"); + // This is a problem and is one of the reasons this blocking interface + // is deprecated. The main loop needs to spin to make this reload happen. So + // we are going to kick off the reload and return an error - it will work + // next time. Because this sync interface is only used in the java plugin it + // is extremely likely that the pac file has already been loaded anyhow. + + rv = ConfigureFromPAC(ctx->mPACURL, false); + if (NS_FAILED(rv)) + return rv; + return NS_ERROR_NOT_AVAILABLE; + } + + *retval = nullptr; return NS_OK; } +// nsIProtocolProxyService NS_IMETHODIMP nsProtocolProxyService::AsyncResolve(nsIURI *uri, uint32_t flags, nsIProtocolProxyCallback *callback, @@ -871,29 +1082,33 @@ nsProtocolProxyService::AsyncResolve(nsIURI *uri, uint32_t flags, nsRefPtr ctx = new nsAsyncResolveRequest(this, uri, flags, callback); - if (!ctx) - return NS_ERROR_OUT_OF_MEMORY; nsProtocolInfo info; nsresult rv = GetProtocolInfo(uri, &info); if (NS_FAILED(rv)) return rv; - bool usePAC; nsCOMPtr pi; - rv = Resolve_Internal(uri, info, flags, &usePAC, getter_AddRefs(pi)); + bool usePACThread; + + // SystemProxySettings and PAC files can block the main thread + // but if neither of them are in use, we can just do the work + // right here and directly invoke the callback + + rv = Resolve_Internal(uri, info, flags, &usePACThread, getter_AddRefs(pi)); if (NS_FAILED(rv)) return rv; - if (!usePAC || !mPACMan) { + if (!usePACThread || !mPACMan) { + // we can do it locally ApplyFilters(uri, info, pi); - ctx->SetResult(NS_OK, pi); return ctx->DispatchCallback(); } - // else kick off a PAC query - rv = mPACMan->AsyncGetProxyForURI(uri, ctx); + // else kick off a PAC thread query + + rv = mPACMan->AsyncGetProxyForURI(uri, ctx, true); if (NS_SUCCEEDED(rv)) { *result = ctx; NS_ADDREF(*result); @@ -1241,42 +1456,76 @@ nsresult nsProtocolProxyService::Resolve_Internal(nsIURI *uri, const nsProtocolInfo &info, uint32_t flags, - bool *usePAC, + bool *usePACThread, nsIProxyInfo **result) { NS_ENSURE_ARG_POINTER(uri); + nsresult rv = SetupPACThread(); + if (NS_FAILED(rv)) + return rv; - *usePAC = false; + *usePACThread = false; *result = nullptr; if (!(info.flags & nsIProtocolHandler::ALLOWS_PROXY)) return NS_OK; // Can't proxy this (filters may not override) - if (mSystemProxySettings) { + // See bug #586908. + // Avoid endless loop if |uri| is the current PAC-URI. Returning OK + // here means that we will not use a proxy for this connection. + if (mPACMan && mPACMan->IsPACURI(uri)) + return NS_OK; + + bool mainThreadOnly; + if (mSystemProxySettings && + mProxyConfig == PROXYCONFIG_SYSTEM && + NS_SUCCEEDED(mSystemProxySettings->GetMainThreadOnly(&mainThreadOnly)) && + !mainThreadOnly) { + *usePACThread = true; + return NS_OK; + } + + if (mSystemProxySettings && mProxyConfig == PROXYCONFIG_SYSTEM) { + // If the system proxy setting implementation is not threadsafe (e.g + // linux gconf), we'll do it inline here. Such implementations promise + // not to block + nsAutoCString PACURI; - if (NS_FAILED(mSystemProxySettings->GetPACURI(PACURI)) || - PACURI.IsEmpty()) { - nsAutoCString proxy; - nsresult rv = mSystemProxySettings->GetProxyForURI(uri, proxy); - if (NS_SUCCEEDED(rv)) { - ProcessPACString(proxy, flags, result); + nsAutoCString pacString; + + if (NS_SUCCEEDED(mSystemProxySettings->GetPACURI(PACURI)) && + !PACURI.IsEmpty()) { + // There is a PAC URI configured. If it is unchanged, then + // just execute the PAC thread. If it is changed then load + // the new value + + if (mPACMan && mPACMan->IsPACURI(PACURI)) { + // unchanged + *usePACThread = true; return NS_OK; } - // no proxy, stop search + + ConfigureFromPAC(PACURI, false); return NS_OK; } - // See bug #586908. - // Avoid endless loop if |uri| is the current PAC-URI. Returning OK - // here means that we will not use a proxy for this connection. - if (mPACMan && mPACMan->IsPACURI(uri)) - return NS_OK; + nsAutoCString spec; + nsAutoCString host; + nsAutoCString scheme; + int32_t port = -1; - // Switch to new PAC file if that setting has changed. If the setting - // hasn't changed, ConfigureFromPAC will exit early. - nsresult rv = ConfigureFromPAC(PACURI, false); - if (NS_FAILED(rv)) - return rv; + uri->GetAsciiSpec(spec); + uri->GetAsciiHost(host); + uri->GetScheme(scheme); + uri->GetPort(&port); + + // now try the system proxy settings for this particular url + if (NS_SUCCEEDED(mSystemProxySettings-> + GetProxyForURI(spec, scheme, host, port, + pacString))) { + ProcessPACString(pacString, 0, result); + return NS_OK; + } } // if proxies are enabled and this host:port combo is supposed to use a @@ -1287,10 +1536,9 @@ nsProtocolProxyService::Resolve_Internal(nsIURI *uri, return NS_OK; // Proxy auto config magic... - if (mProxyConfig == PROXYCONFIG_PAC || mProxyConfig == PROXYCONFIG_WPAD || - mProxyConfig == PROXYCONFIG_SYSTEM) { + if (mProxyConfig == PROXYCONFIG_PAC || mProxyConfig == PROXYCONFIG_WPAD) { // Do not query PAC now. - *usePAC = true; + *usePACThread = true; return NS_OK; } @@ -1304,7 +1552,7 @@ nsProtocolProxyService::Resolve_Internal(nsIURI *uri, if ((flags & RESOLVE_PREFER_SOCKS_PROXY) && !mSOCKSProxyHost.IsEmpty() && mSOCKSProxyPort > 0) { host = &mSOCKSProxyHost; - if (mSOCKSProxyVersion == 4) + if (mSOCKSProxyVersion == 4) type = kProxyType_SOCKS4; else type = kProxyType_SOCKS; @@ -1341,7 +1589,7 @@ nsProtocolProxyService::Resolve_Internal(nsIURI *uri, } else if (!mSOCKSProxyHost.IsEmpty() && mSOCKSProxyPort > 0) { host = &mSOCKSProxyHost; - if (mSOCKSProxyVersion == 4) + if (mSOCKSProxyVersion == 4) type = kProxyType_SOCKS4; else type = kProxyType_SOCKS; @@ -1351,9 +1599,9 @@ nsProtocolProxyService::Resolve_Internal(nsIURI *uri, } if (type) { - nsresult rv = NewProxyInfo_Internal(type, *host, port, proxyFlags, - PR_UINT32_MAX, nullptr, flags, - result); + rv = NewProxyInfo_Internal(type, *host, port, proxyFlags, + PR_UINT32_MAX, nullptr, flags, + result); if (NS_FAILED(rv)) return rv; } @@ -1361,6 +1609,30 @@ nsProtocolProxyService::Resolve_Internal(nsIURI *uri, return NS_OK; } +void +nsProtocolProxyService::MaybeDisableDNSPrefetch(nsIProxyInfo *aProxy) +{ + // Disable Prefetch in the DNS service if a proxy is in use. + if (!aProxy) + return; + + nsCOMPtr pi = do_QueryInterface(aProxy); + if (!pi || + !pi->mType || + pi->mType == kProxyType_DIRECT) + return; + + nsCOMPtr dns = do_GetService(NS_DNSSERVICE_CONTRACTID); + if (!dns) + return; + nsCOMPtr pdns = do_QueryInterface(dns); + if (!pdns) + return; + + // We lose the prefetch optimization for the life of the dns service. + pdns->SetPrefetchEnabled(false); +} + void nsProtocolProxyService::ApplyFilters(nsIURI *uri, const nsProtocolInfo &info, nsIProxyInfo **list) @@ -1411,7 +1683,7 @@ nsProtocolProxyService::PruneProxyInfo(const nsProtocolInfo &info, // Start by removing all disallowed proxies if required: if (!(info.flags & nsIProtocolHandler::ALLOWS_PROXY_HTTP)) { - nsProxyInfo *last = nullptr, *iter = head; + nsProxyInfo *last = nullptr, *iter = head; while (iter) { if (iter->Type() == kProxyType_HTTP) { // reject! @@ -1435,7 +1707,7 @@ nsProtocolProxyService::PruneProxyInfo(const nsProtocolInfo &info, // Now, scan to see if all remaining proxies are disabled. If so, then // we'll just bail and return them all. Otherwise, we'll go and prune the // disabled ones. - + bool allDisabled = true; nsProxyInfo *iter; @@ -1450,7 +1722,7 @@ nsProtocolProxyService::PruneProxyInfo(const nsProtocolInfo &info, LOG(("All proxies are disabled, so trying all again")); else { // remove any disabled proxies. - nsProxyInfo *last = nullptr; + nsProxyInfo *last = nullptr; for (iter = head; iter; ) { if (IsProxyDisabled(iter)) { // reject! diff --git a/netwerk/base/src/nsProtocolProxyService.h b/netwerk/base/src/nsProtocolProxyService.h index ebc4b6d90e17..dede166e9b1f 100644 --- a/netwerk/base/src/nsProtocolProxyService.h +++ b/netwerk/base/src/nsProtocolProxyService.h @@ -13,7 +13,6 @@ #include "nsIPrefBranch.h" #include "nsIProtocolProxyService2.h" #include "nsIProtocolProxyFilter.h" -#include "nsIProxyAutoConfig.h" #include "nsISystemProxySettings.h" #include "nsIProxyInfo.h" #include "nsIObserver.h" @@ -272,6 +271,18 @@ protected: */ NS_HIDDEN_(bool) CanUseProxy(nsIURI *uri, int32_t defaultPort); + /** + * Disable Prefetch in the DNS service if a proxy is in use. + * + * @param aProxy + * The proxy information + */ + NS_HIDDEN_(void) MaybeDisableDNSPrefetch(nsIProxyInfo *aProxy); + +private: + nsresult SetupPACThread(); + nsresult ResetPACThread(); + public: // The Sun Forte compiler and others implement older versions of the // C++ standard's rules on access and nested classes. These structs diff --git a/netwerk/base/src/nsProxyAutoConfig.js b/netwerk/base/src/nsProxyAutoConfig.js deleted file mode 100644 index 204d24187d2b..000000000000 --- a/netwerk/base/src/nsProxyAutoConfig.js +++ /dev/null @@ -1,314 +0,0 @@ -/* -*- Mode: Java; tab-width: 4; c-basic-offset: 4; -*- */ -/* vim:set ts=4 sw=4 sts=4 et: */ -/* 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/. */ - -/* - Script for Proxy Auto Config in the new world order. - - Gagan Saksena 04/24/00 -*/ - -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); - -const kDNS_CONTRACTID = "@mozilla.org/network/dns-service;1"; - -const nsISupports = Components.interfaces.nsISupports; -const nsIProxyAutoConfig = Components.interfaces.nsIProxyAutoConfig; -const nsIDNSService = Components.interfaces.nsIDNSService; - -var dns; - -// implementor of nsIProxyAutoConfig -function nsProxyAutoConfig() { - dns = Components.classes[kDNS_CONTRACTID].getService(nsIDNSService); -}; - -nsProxyAutoConfig.prototype = { - classID: Components.ID("63ac8c66-1dd2-11b2-b070-84d00d3eaece"), - - // sandbox in which we eval loaded autoconfig js file - _sandBox: null, - - QueryInterface: XPCOMUtils.generateQI([nsIProxyAutoConfig]), - - init: function(pacURI, pacText) { - // remove PAC configuration if requested - if (pacURI == "" || pacText == "") { - this._sandBox = null; - return; - } - - // allocate a fresh Sandbox to clear global scope for new PAC script - this._sandBox = new Components.utils.Sandbox(pacURI, - {sandboxName: 'nsProxyAutoConfig'}); - Components.utils.evalInSandbox(pacUtils, this._sandBox); - - // add predefined functions to pac - this._sandBox.importFunction(myIpAddress); - this._sandBox.importFunction(dnsResolve); - this._sandBox.importFunction(proxyAlert, "alert"); - - // evaluate loaded js file - Components.utils.evalInSandbox(pacText, this._sandBox); - }, - - getProxyForURI: function(testURI, testHost) { - if (!("FindProxyForURL" in this._sandBox)) - return null; - - // Call the original function - try { - var rval = this._sandBox.FindProxyForURL(testURI, testHost); - } catch (e) { - throw XPCSafeJSObjectWrapper(e); - } - return rval; - } -} - -function proxyAlert(msg) { - try { - // It would appear that the console service is threadsafe. - var cns = Components.classes["@mozilla.org/consoleservice;1"] - .getService(Components.interfaces.nsIConsoleService); - cns.logStringMessage("PAC-alert: "+msg); - } catch (e) { - dump("PAC: proxyAlert ERROR: "+e+"\n"); - } -} - -// wrapper for getting local IP address called by PAC file -function myIpAddress() { - try { - return dns.resolve(dns.myHostName, 0).getNextAddrAsString(); - } catch (e) { - return '127.0.0.1'; - } -} - -// wrapper for resolving hostnames called by PAC file -function dnsResolve(host) { - try { - return dns.resolve(host, 0).getNextAddrAsString(); - } catch (e) { - return null; - } -} - -NSGetFactory = XPCOMUtils.generateNSGetFactory([nsProxyAutoConfig]); - -var pacUtils = -"function dnsDomainIs(host, domain) {\n" + -" return (host.length >= domain.length &&\n" + -" host.substring(host.length - domain.length) == domain);\n" + -"}\n" + - -"function dnsDomainLevels(host) {\n" + -" return host.split('.').length-1;\n" + -"}\n" + - -"function convert_addr(ipchars) {\n"+ -" var bytes = ipchars.split('.');\n"+ -" var result = ((bytes[0] & 0xff) << 24) |\n"+ -" ((bytes[1] & 0xff) << 16) |\n"+ -" ((bytes[2] & 0xff) << 8) |\n"+ -" (bytes[3] & 0xff);\n"+ -" return result;\n"+ -"}\n"+ - -"function isInNet(ipaddr, pattern, maskstr) {\n"+ -" var test = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(ipaddr);\n"+ -" if (test == null) {\n"+ -" ipaddr = dnsResolve(ipaddr);\n"+ -" if (ipaddr == null)\n"+ -" return false;\n"+ -" } else if (test[1] > 255 || test[2] > 255 || \n"+ -" test[3] > 255 || test[4] > 255) {\n"+ -" return false; // not an IP address\n"+ -" }\n"+ -" var host = convert_addr(ipaddr);\n"+ -" var pat = convert_addr(pattern);\n"+ -" var mask = convert_addr(maskstr);\n"+ -" return ((host & mask) == (pat & mask));\n"+ -" \n"+ -"}\n"+ - -"function isPlainHostName(host) {\n" + -" return (host.search('\\\\.') == -1);\n" + -"}\n" + - -"function isResolvable(host) {\n" + -" var ip = dnsResolve(host);\n" + -" return (ip != null);\n" + -"}\n" + - -"function localHostOrDomainIs(host, hostdom) {\n" + -" return (host == hostdom) ||\n" + -" (hostdom.lastIndexOf(host + '.', 0) == 0);\n" + -"}\n" + - -"function shExpMatch(url, pattern) {\n" + -" pattern = pattern.replace(/\\./g, '\\\\.');\n" + -" pattern = pattern.replace(/\\*/g, '.*');\n" + -" pattern = pattern.replace(/\\?/g, '.');\n" + -" var newRe = new RegExp('^'+pattern+'$');\n" + -" return newRe.test(url);\n" + -"}\n" + - -"var wdays = {SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6};\n" + - -"var months = {JAN: 0, FEB: 1, MAR: 2, APR: 3, MAY: 4, JUN: 5, JUL: 6, AUG: 7, SEP: 8, OCT: 9, NOV: 10, DEC: 11};\n"+ - -"function weekdayRange() {\n" + -" function getDay(weekday) {\n" + -" if (weekday in wdays) {\n" + -" return wdays[weekday];\n" + -" }\n" + -" return -1;\n" + -" }\n" + -" var date = new Date();\n" + -" var argc = arguments.length;\n" + -" var wday;\n" + -" if (argc < 1)\n" + -" return false;\n" + -" if (arguments[argc - 1] == 'GMT') {\n" + -" argc--;\n" + -" wday = date.getUTCDay();\n" + -" } else {\n" + -" wday = date.getDay();\n" + -" }\n" + -" var wd1 = getDay(arguments[0]);\n" + -" var wd2 = (argc == 2) ? getDay(arguments[1]) : wd1;\n" + -" return (wd1 == -1 || wd2 == -1) ? false\n" + -" : (wd1 <= wday && wday <= wd2);\n" + -"}\n" + - -"function dateRange() {\n" + -" function getMonth(name) {\n" + -" if (name in months) {\n" + -" return months[name];\n" + -" }\n" + -" return -1;\n" + -" }\n" + -" var date = new Date();\n" + -" var argc = arguments.length;\n" + -" if (argc < 1) {\n" + -" return false;\n" + -" }\n" + -" var isGMT = (arguments[argc - 1] == 'GMT');\n" + -"\n" + -" if (isGMT) {\n" + -" argc--;\n" + -" }\n" + -" // function will work even without explict handling of this case\n" + -" if (argc == 1) {\n" + -" var tmp = parseInt(arguments[0]);\n" + -" if (isNaN(tmp)) {\n" + -" return ((isGMT ? date.getUTCMonth() : date.getMonth()) ==\n" + -"getMonth(arguments[0]));\n" + -" } else if (tmp < 32) {\n" + -" return ((isGMT ? date.getUTCDate() : date.getDate()) == tmp);\n" + -" } else { \n" + -" return ((isGMT ? date.getUTCFullYear() : date.getFullYear()) ==\n" + -"tmp);\n" + -" }\n" + -" }\n" + -" var year = date.getFullYear();\n" + -" var date1, date2;\n" + -" date1 = new Date(year, 0, 1, 0, 0, 0);\n" + -" date2 = new Date(year, 11, 31, 23, 59, 59);\n" + -" var adjustMonth = false;\n" + -" for (var i = 0; i < (argc >> 1); i++) {\n" + -" var tmp = parseInt(arguments[i]);\n" + -" if (isNaN(tmp)) {\n" + -" var mon = getMonth(arguments[i]);\n" + -" date1.setMonth(mon);\n" + -" } else if (tmp < 32) {\n" + -" adjustMonth = (argc <= 2);\n" + -" date1.setDate(tmp);\n" + -" } else {\n" + -" date1.setFullYear(tmp);\n" + -" }\n" + -" }\n" + -" for (var i = (argc >> 1); i < argc; i++) {\n" + -" var tmp = parseInt(arguments[i]);\n" + -" if (isNaN(tmp)) {\n" + -" var mon = getMonth(arguments[i]);\n" + -" date2.setMonth(mon);\n" + -" } else if (tmp < 32) {\n" + -" date2.setDate(tmp);\n" + -" } else {\n" + -" date2.setFullYear(tmp);\n" + -" }\n" + -" }\n" + -" if (adjustMonth) {\n" + -" date1.setMonth(date.getMonth());\n" + -" date2.setMonth(date.getMonth());\n" + -" }\n" + -" if (isGMT) {\n" + -" var tmp = date;\n" + -" tmp.setFullYear(date.getUTCFullYear());\n" + -" tmp.setMonth(date.getUTCMonth());\n" + -" tmp.setDate(date.getUTCDate());\n" + -" tmp.setHours(date.getUTCHours());\n" + -" tmp.setMinutes(date.getUTCMinutes());\n" + -" tmp.setSeconds(date.getUTCSeconds());\n" + -" date = tmp;\n" + -" }\n" + -" return ((date1 <= date) && (date <= date2));\n" + -"}\n" + - -"function timeRange() {\n" + -" var argc = arguments.length;\n" + -" var date = new Date();\n" + -" var isGMT= false;\n"+ -"\n" + -" if (argc < 1) {\n" + -" return false;\n" + -" }\n" + -" if (arguments[argc - 1] == 'GMT') {\n" + -" isGMT = true;\n" + -" argc--;\n" + -" }\n" + -"\n" + -" var hour = isGMT ? date.getUTCHours() : date.getHours();\n" + -" var date1, date2;\n" + -" date1 = new Date();\n" + -" date2 = new Date();\n" + -"\n" + -" if (argc == 1) {\n" + -" return (hour == arguments[0]);\n" + -" } else if (argc == 2) {\n" + -" return ((arguments[0] <= hour) && (hour <= arguments[1]));\n" + -" } else {\n" + -" switch (argc) {\n" + -" case 6:\n" + -" date1.setSeconds(arguments[2]);\n" + -" date2.setSeconds(arguments[5]);\n" + -" case 4:\n" + -" var middle = argc >> 1;\n" + -" date1.setHours(arguments[0]);\n" + -" date1.setMinutes(arguments[1]);\n" + -" date2.setHours(arguments[middle]);\n" + -" date2.setMinutes(arguments[middle + 1]);\n" + -" if (middle == 2) {\n" + -" date2.setSeconds(59);\n" + -" }\n" + -" break;\n" + -" default:\n" + -" throw 'timeRange: bad number of arguments'\n" + -" }\n" + -" }\n" + -"\n" + -" if (isGMT) {\n" + -" date.setFullYear(date.getUTCFullYear());\n" + -" date.setMonth(date.getUTCMonth());\n" + -" date.setDate(date.getUTCDate());\n" + -" date.setHours(date.getUTCHours());\n" + -" date.setMinutes(date.getUTCMinutes());\n" + -" date.setSeconds(date.getUTCSeconds());\n" + -" }\n" + -" return ((date1 <= date) && (date <= date2));\n" + -"}\n" - diff --git a/netwerk/base/src/nsProxyAutoConfig.manifest b/netwerk/base/src/nsProxyAutoConfig.manifest deleted file mode 100644 index ade07352fcef..000000000000 --- a/netwerk/base/src/nsProxyAutoConfig.manifest +++ /dev/null @@ -1,2 +0,0 @@ -component {63ac8c66-1dd2-11b2-b070-84d00d3eaece} nsProxyAutoConfig.js -contract @mozilla.org/network/proxy-auto-config;1 {63ac8c66-1dd2-11b2-b070-84d00d3eaece} diff --git a/netwerk/build/nsNetCID.h b/netwerk/build/nsNetCID.h index 081c2786a150..287384f1c8ea 100644 --- a/netwerk/build/nsNetCID.h +++ b/netwerk/build/nsNetCID.h @@ -689,17 +689,6 @@ {0xae, 0xb7, 0xda, 0x62, 0xe7, 0x27, 0x3e, 0xd5} \ } -#ifdef MOZ_WIDGET_GONK -#define NS_B2GPROTOCOLHANDLER_CLASSNAME \ - "nsB2GProtocolHandler" -#define NS_B2GPROTOCOLHANDLER_CID \ -{ \ -/* {e50d101a-9db2-466f-977c-ae6af19e3b2f} */ \ - 0x50d101a, 0x9db2, 0x466f, \ - {0x97, 0x7c, 0xae, 0x6a, 0xf1, 0x9e, 0x3b, 0x2f} \ -} -#endif - /****************************************************************************** * netwerk/protocol/viewsource/ classes */ diff --git a/netwerk/build/nsNetModule.cpp b/netwerk/build/nsNetModule.cpp index 0e3fc592990d..b204fafddbb5 100644 --- a/netwerk/build/nsNetModule.cpp +++ b/netwerk/build/nsNetModule.cpp @@ -235,10 +235,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsResURL) #ifdef NECKO_PROTOCOL_device #include "nsDeviceProtocolHandler.h" NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceProtocolHandler) -#ifdef MOZ_WIDGET_GONK -#include "nsB2GProtocolHandler.h" -NS_GENERIC_FACTORY_CONSTRUCTOR(nsB2GProtocolHandler) -#endif #endif #ifdef NECKO_PROTOCOL_viewsource @@ -755,9 +751,6 @@ NS_DEFINE_NAMED_CID(NS_DATAPROTOCOLHANDLER_CID); #endif #ifdef NECKO_PROTOCOL_device NS_DEFINE_NAMED_CID(NS_DEVICEPROTOCOLHANDLER_CID); -#ifdef MOZ_WIDGET_GONK -NS_DEFINE_NAMED_CID(NS_B2GPROTOCOLHANDLER_CID); -#endif #endif #ifdef NECKO_PROTOCOL_viewsource NS_DEFINE_NAMED_CID(NS_VIEWSOURCEHANDLER_CID); @@ -890,9 +883,6 @@ static const mozilla::Module::CIDEntry kNeckoCIDs[] = { #endif #ifdef NECKO_PROTOCOL_device { &kNS_DEVICEPROTOCOLHANDLER_CID, false, NULL, nsDeviceProtocolHandlerConstructor}, -#ifdef MOZ_WIDGET_GONK - { &kNS_B2GPROTOCOLHANDLER_CID, false, NULL, nsB2GProtocolHandlerConstructor}, -#endif #endif #ifdef NECKO_PROTOCOL_viewsource { &kNS_VIEWSOURCEHANDLER_CID, false, NULL, nsViewSourceHandlerConstructor }, @@ -1034,9 +1024,6 @@ static const mozilla::Module::ContractIDEntry kNeckoContracts[] = { #endif #ifdef NECKO_PROTOCOL_device { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "moz-device", &kNS_DEVICEPROTOCOLHANDLER_CID }, -#ifdef MOZ_WIDGET_GONK - { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "b2g-camera", &kNS_B2GPROTOCOLHANDLER_CID }, -#endif #endif #ifdef NECKO_PROTOCOL_viewsource { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "view-source", &kNS_VIEWSOURCEHANDLER_CID }, diff --git a/netwerk/cookie/nsCookieService.cpp b/netwerk/cookie/nsCookieService.cpp index e428c3e77c36..4f5e655e676f 100644 --- a/netwerk/cookie/nsCookieService.cpp +++ b/netwerk/cookie/nsCookieService.cpp @@ -607,6 +607,9 @@ nsCookieService::Init() mIDNService = do_GetService(NS_IDNSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); + mThirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID); + NS_ENSURE_SUCCESS(rv, rv); + // init our pref and observer nsCOMPtr prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID); if (prefBranch) { @@ -1417,8 +1420,7 @@ nsCookieService::GetCookieStringCommon(nsIURI *aHostURI, // Determine whether the request is foreign. Failure is acceptable. bool isForeign = true; - if (RequireThirdPartyCheck()) - mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign); + mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign); nsAutoCString result; GetCookieStringInternal(aHostURI, isForeign, aHttpBound, result); @@ -1459,8 +1461,7 @@ nsCookieService::SetCookieStringCommon(nsIURI *aHostURI, // Determine whether the request is foreign. Failure is acceptable. bool isForeign = true; - if (RequireThirdPartyCheck()) - mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign); + mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign); nsDependentCString cookieString(aCookieHeader); nsDependentCString serverTime(aServerTime ? aServerTime : ""); @@ -1594,12 +1595,6 @@ nsCookieService::PrefChanged(nsIPrefBranch *aPrefBranch) bool boolval; if (NS_SUCCEEDED(aPrefBranch->GetBoolPref(kPrefThirdPartySession, &boolval))) mThirdPartySession = boolval; - - // Lazily instantiate the third party service if necessary. - if (!mThirdPartyUtil && RequireThirdPartyCheck()) { - mThirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID); - NS_ABORT_IF_FALSE(mThirdPartyUtil, "require ThirdPartyUtil service"); - } } /****************************************************************************** @@ -3055,13 +3050,6 @@ static inline bool IsSubdomainOf(const nsCString &a, const nsCString &b) return false; } -bool -nsCookieService::RequireThirdPartyCheck() -{ - // 'true' iff we need to perform a third party test. - return mCookieBehavior == BEHAVIOR_REJECTFOREIGN || mThirdPartySession; -} - CookieStatus nsCookieService::CheckPrefs(nsIURI *aHostURI, bool aIsForeign, @@ -3090,11 +3078,23 @@ nsCookieService::CheckPrefs(nsIURI *aHostURI, if (NS_SUCCEEDED(rv)) { switch (access) { case nsICookiePermission::ACCESS_DENY: - COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "cookies are blocked for this site"); + COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, + aCookieHeader, "cookies are blocked for this site"); return STATUS_REJECTED; case nsICookiePermission::ACCESS_ALLOW: return STATUS_ACCEPTED; + + case nsICookiePermission::ACCESS_ALLOW_FIRST_PARTY_ONLY: + if (aIsForeign) { + COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, + aCookieHeader, "third party cookies are blocked " + "for this site"); + return STATUS_REJECTED; + + } + return STATUS_ACCEPTED; + } } } @@ -3105,13 +3105,15 @@ nsCookieService::CheckPrefs(nsIURI *aHostURI, return STATUS_REJECTED; } - if (RequireThirdPartyCheck() && aIsForeign) { - // check if cookie is foreign + // check if cookie is foreign + if (aIsForeign) { if (mCookieBehavior == BEHAVIOR_ACCEPT && mThirdPartySession) return STATUS_ACCEPT_SESSION; - COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "context is third party"); - return STATUS_REJECTED; + if (mCookieBehavior == BEHAVIOR_REJECTFOREIGN) { + COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "context is third party"); + return STATUS_REJECTED; + } } // if nothing has complained, accept cookie diff --git a/netwerk/cookie/nsCookieService.h b/netwerk/cookie/nsCookieService.h index 95327dc4742b..517012eef5f8 100644 --- a/netwerk/cookie/nsCookieService.h +++ b/netwerk/cookie/nsCookieService.h @@ -235,7 +235,6 @@ class nsCookieService : public nsICookieService void UpdateCookieInList(nsCookie *aCookie, int64_t aLastAccessed, mozIStorageBindingParamsArray *aParamsArray); static bool GetTokenValue(nsASingleFragmentCString::const_char_iterator &aIter, nsASingleFragmentCString::const_char_iterator &aEndIter, nsDependentCSubstring &aTokenString, nsDependentCSubstring &aTokenValue, bool &aEqualsFound); static bool ParseAttributes(nsDependentCString &aCookieHeader, nsCookieAttributes &aCookie); - bool RequireThirdPartyCheck(); CookieStatus CheckPrefs(nsIURI *aHostURI, bool aIsForeign, const nsCString &aBaseDomain, bool aRequireHostMatch, const char *aCookieHeader); bool CheckDomain(nsCookieAttributes &aCookie, nsIURI *aHostURI, const nsCString &aBaseDomain, bool aRequireHostMatch); static bool CheckPath(nsCookieAttributes &aCookie, nsIURI *aHostURI); diff --git a/netwerk/cookie/nsICookiePermission.idl b/netwerk/cookie/nsICookiePermission.idl index 9b5744f50139..802171ff88a2 100644 --- a/netwerk/cookie/nsICookiePermission.idl +++ b/netwerk/cookie/nsICookiePermission.idl @@ -24,12 +24,13 @@ interface nsICookiePermission : nsISupports const nsCookieAccess ACCESS_DENY = 2; /** - * additional values for nsCookieAccess, which are not directly used by - * any methods on this interface, but are nevertheless convenient to define - * here. these may be relocated somewhere else if we ever consider freezing - * this interface. + * additional values for nsCookieAccess which may not match + * nsIPermissionManager. Keep 3-7 available to allow nsIPermissionManager to + * add values without colliding. ACCESS_SESSION is not directly returned by + * any methods on this interface. */ const nsCookieAccess ACCESS_SESSION = 8; + const nsCookieAccess ACCESS_ALLOW_FIRST_PARTY_ONLY = 9; /** * setAccess @@ -58,7 +59,8 @@ interface nsICookiePermission : nsISupports * the channel corresponding to aURI * * @return one of the following nsCookieAccess values: - * ACCESS_DEFAULT, ACCESS_ALLOW, or ACCESS_DENY + * ACCESS_DEFAULT, ACCESS_ALLOW, ACCESS_DENY, or + * ACCESS_ALLOW_FIRST_PARTY_ONLY */ nsCookieAccess canAccess(in nsIURI aURI, in nsIChannel aChannel); diff --git a/netwerk/dns/effective_tld_names.dat b/netwerk/dns/effective_tld_names.dat index dc243aeb0255..4a07c5c6a686 100644 --- a/netwerk/dns/effective_tld_names.dat +++ b/netwerk/dns/effective_tld_names.dat @@ -415,13 +415,13 @@ b.br bio.br blog.br bmd.br -can.br cim.br cng.br cnt.br com.br coop.br ecn.br +eco.br edu.br emp.br eng.br @@ -442,6 +442,7 @@ ind.br inf.br jor.br jus.br +leg.br lel.br mat.br med.br diff --git a/netwerk/dns/nsDNSService2.cpp b/netwerk/dns/nsDNSService2.cpp index beba06e8cdc7..1ed9474f0a0b 100644 --- a/netwerk/dns/nsDNSService2.cpp +++ b/netwerk/dns/nsDNSService2.cpp @@ -482,6 +482,20 @@ nsDNSService::Shutdown() return NS_OK; } +NS_IMETHODIMP +nsDNSService::GetPrefetchEnabled(bool *outVal) +{ + *outVal = !mDisablePrefetch; + return NS_OK; +} + +NS_IMETHODIMP +nsDNSService::SetPrefetchEnabled(bool inVal) +{ + mDisablePrefetch = !inVal; + return NS_OK; +} + namespace { class DNSListenerProxy MOZ_FINAL : public nsIDNSListener diff --git a/netwerk/dns/nsPIDNSService.idl b/netwerk/dns/nsPIDNSService.idl index 2dc32623cdea..5bb53f2f53fc 100644 --- a/netwerk/dns/nsPIDNSService.idl +++ b/netwerk/dns/nsPIDNSService.idl @@ -10,7 +10,7 @@ * This is a private interface used by the internals of the networking library. * It will never be frozen. Do not use it in external code. */ -[scriptable, uuid(a26c5b45-7707-4412-bbc1-2462b890848d)] +[scriptable, uuid(6b16fb1f-5709-4c94-a89f-a22be873c54d)] interface nsPIDNSService : nsIDNSService { /** @@ -26,4 +26,9 @@ interface nsPIDNSService : nsIDNSService * this method. */ void shutdown(); + + /** + * Whether or not DNS prefetching (aka RESOLVE_SPECULATE) is enabled + */ + attribute boolean prefetchEnabled; }; diff --git a/netwerk/protocol/device/Makefile.in b/netwerk/protocol/device/Makefile.in index 02cf2b33fbce..cf47e7435774 100644 --- a/netwerk/protocol/device/Makefile.in +++ b/netwerk/protocol/device/Makefile.in @@ -35,7 +35,6 @@ endif ifeq (gonk,$(MOZ_WIDGET_TOOLKIT)) CPPSRCS += GonkCaptureProvider.cpp \ - nsB2GProtocolHandler.cpp \ $(NULL) endif diff --git a/netwerk/protocol/device/nsB2GProtocolHandler.cpp b/netwerk/protocol/device/nsB2GProtocolHandler.cpp deleted file mode 100644 index 7b876bff7435..000000000000 --- a/netwerk/protocol/device/nsB2GProtocolHandler.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsB2GProtocolHandler.h" -#include "nsDeviceChannel.h" -#include "nsNetCID.h" -#include "nsAutoPtr.h" -#include "nsCOMPtr.h" -#include "nsSimpleURI.h" -#include "mozilla/Preferences.h" -//----------------------------------------------------------------------------- - -NS_IMPL_THREADSAFE_ISUPPORTS1(nsB2GProtocolHandler, - nsIProtocolHandler) - -nsresult -nsB2GProtocolHandler::Init(){ - return NS_OK; -} - -NS_IMETHODIMP -nsB2GProtocolHandler::GetScheme(nsACString &aResult) -{ - aResult.AssignLiteral("b2g-camera"); - return NS_OK; -} - -NS_IMETHODIMP -nsB2GProtocolHandler::GetDefaultPort(int32_t *aResult) -{ - *aResult = -1; // no port for b2g-camera: URLs - return NS_OK; -} - -NS_IMETHODIMP -nsB2GProtocolHandler::GetProtocolFlags(uint32_t *aResult) -{ - *aResult = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_ANYONE | URI_IS_LOCAL_RESOURCE; - return NS_OK; -} - -NS_IMETHODIMP -nsB2GProtocolHandler::NewURI(const nsACString &spec, - const char *originCharset, - nsIURI *baseURI, - nsIURI **result) -{ - nsRefPtr uri = new nsSimpleURI(); - nsresult rv; - - // XXX get the "real" uri from the pref - // should use ipdl when we'll use e10s - nsCString key("b2g.camera."); - key.Append(spec); - nsCString pref; - rv = mozilla::Preferences::GetCString(key.get(), &pref); - NS_ENSURE_SUCCESS(rv, rv); - rv = uri->SetSpec(pref); - mozilla::Preferences::ClearUser(key.BeginReading()); - NS_ENSURE_SUCCESS(rv, rv); - - return CallQueryInterface(uri, result); -} - -NS_IMETHODIMP -nsB2GProtocolHandler::NewChannel(nsIURI* aURI, nsIChannel **aResult) -{ - nsRefPtr channel = new nsDeviceChannel(); - nsresult rv = channel->Init(aURI); - NS_ENSURE_SUCCESS(rv, rv); - - return CallQueryInterface(channel, aResult); -} - -NS_IMETHODIMP -nsB2GProtocolHandler::AllowPort(int32_t port, - const char *scheme, - bool *aResult) -{ - // don't override anything. - *aResult = false; - return NS_OK; -} diff --git a/netwerk/protocol/device/nsB2GProtocolHandler.h b/netwerk/protocol/device/nsB2GProtocolHandler.h deleted file mode 100644 index f400702b2456..000000000000 --- a/netwerk/protocol/device/nsB2GProtocolHandler.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nsB2GProtocolHandler_h_ -#define nsB2GProtocolHandler_h_ - -#include "nsIProtocolHandler.h" -#include "nsString.h" - -// {e50d101a-9db2-466f-977c-ae6af19e3b2f} -#define NS_B2GPROTOCOLHANDLER_CID \ -{ 0x50d101a, 0x9db2, 0x466f, \ - {0x97, 0x7c, 0xae, 0x6a, 0xf1, 0x9e, 0x3b, 0x2f} } - -class nsB2GProtocolHandler : public nsIProtocolHandler { -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPROTOCOLHANDLER - - nsB2GProtocolHandler() {} - ~nsB2GProtocolHandler() {} - - nsresult Init(); -}; - -#endif diff --git a/netwerk/protocol/ftp/nsFTPChannel.h b/netwerk/protocol/ftp/nsFTPChannel.h index aa512eb97970..cde6d9d36721 100644 --- a/netwerk/protocol/ftp/nsFTPChannel.h +++ b/netwerk/protocol/ftp/nsFTPChannel.h @@ -55,6 +55,11 @@ public: return mProxyInfo; } + void SetProxyInfo(nsIProxyInfo *pi) + { + mProxyInfo = pi; + } + // Were we asked to resume a download? bool ResumeRequested() { return mResumeRequested; } diff --git a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp index 06a3c30f257b..8e02e70c2b17 100644 --- a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp +++ b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp @@ -33,6 +33,8 @@ #include "nsIStringBundle.h" #include "nsAuthInformationHolder.h" #include "nsICharsetConverterManager.h" +#include "nsIProtocolProxyService.h" +#include "nsICancelable.h" #if defined(PR_LOGGING) extern PRLogModuleInfo* gFTPLog; @@ -50,12 +52,13 @@ removeParamsFromPath(nsCString& path) } } -NS_IMPL_ISUPPORTS_INHERITED4(nsFtpState, +NS_IMPL_ISUPPORTS_INHERITED5(nsFtpState, nsBaseContentStream, nsIInputStreamCallback, nsITransportEventSink, nsICacheListener, - nsIRequestObserver) + nsIRequestObserver, + nsIProtocolProxyCallback) nsFtpState::nsFtpState() : nsBaseContentStream(true) @@ -78,6 +81,7 @@ nsFtpState::nsFtpState() , mAddressChecked(false) , mServerIsIPv6(false) , mControlStatus(NS_OK) + , mDeferredCallbackPending(false) { LOG_ALWAYS(("FTP:(%x) nsFtpState created", this)); @@ -89,6 +93,9 @@ nsFtpState::~nsFtpState() { LOG_ALWAYS(("FTP:(%x) nsFtpState destroyed", this)); + if (mProxyRequest) + mProxyRequest->Cancel(NS_ERROR_FAILURE); + // release reference to handler nsFtpProtocolHandler *handler = gFtpHandler; NS_RELEASE(handler); @@ -1759,6 +1766,19 @@ nsFtpState::Init(nsFtpChannel *channel) if (port > 0) mPort = port; + // Lookup Proxy information asynchronously if it isn't already set + // on the channel and if we aren't configured explicitly to go directly + uint32_t proxyConfigType; + nsCOMPtr pps = + do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID); + + if (pps && !mChannel->ProxyInfo() && + NS_SUCCEEDED(pps->GetProxyConfigType(&proxyConfigType)) && + proxyConfigType != nsIProtocolProxyService::PROXYCONFIG_DIRECT) { + pps->AsyncResolve(mChannel->URI(), 0, this, + getter_AddRefs(mProxyRequest)); + } + return NS_OK; } @@ -2155,6 +2175,67 @@ nsFtpState::CloseWithStatus(nsresult status) return nsBaseContentStream::CloseWithStatus(status); } +static nsresult +CreateHTTPProxiedChannel(nsIURI *uri, nsIProxyInfo *pi, nsIChannel **newChannel) +{ + nsresult rv; + nsCOMPtr ioService = do_GetIOService(&rv); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr handler; + rv = ioService->GetProtocolHandler("http", getter_AddRefs(handler)); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr pph = do_QueryInterface(handler, &rv); + if (NS_FAILED(rv)) + return rv; + + return pph->NewProxiedChannel(uri, pi, 0, nullptr, newChannel); +} + +NS_IMETHODIMP +nsFtpState::OnProxyAvailable(nsICancelable *request, nsIURI *uri, + nsIProxyInfo *pi, nsresult status) +{ + mProxyRequest = nullptr; + + // failed status code just implies DIRECT processing + + if (NS_SUCCEEDED(status)) { + nsAutoCString type; + if (pi && NS_SUCCEEDED(pi->GetType(type)) && type.EqualsLiteral("http")) { + // Proxy the FTP url via HTTP + // This would have been easier to just return a HTTP channel directly + // from nsIIOService::NewChannelFromURI(), but the proxy type cannot + // be reliabliy determined synchronously without jank due to pac, etc.. + LOG(("FTP:(%p) Configured to use a HTTP proxy channel\n", this)); + + nsCOMPtr newChannel; + if (NS_SUCCEEDED(CreateHTTPProxiedChannel(uri, pi, + getter_AddRefs(newChannel))) && + NS_SUCCEEDED(mChannel->Redirect(newChannel, + nsIChannelEventSink::REDIRECT_INTERNAL, + true))) { + LOG(("FTP:(%p) Redirected to use a HTTP proxy channel\n", this)); + return NS_OK; + } + } + else if (pi) { + // Proxy using the FTP protocol routed through a socks proxy + LOG(("FTP:(%p) Configured to use a SOCKS proxy channel\n", this)); + mChannel->SetProxyInfo(pi); + } + } + + if (mDeferredCallbackPending) { + mDeferredCallbackPending = false; + OnCallbackPending(); + } + return NS_OK; +} + void nsFtpState::OnCallbackPending() { @@ -2163,6 +2244,11 @@ nsFtpState::OnCallbackPending() // connect to the server. if (mState == FTP_INIT) { + if (mProxyRequest) { + mDeferredCallbackPending = true; + return; + } + if (CheckCache()) { mState = FTP_WAIT_CACHE; return; diff --git a/netwerk/protocol/ftp/nsFtpConnectionThread.h b/netwerk/protocol/ftp/nsFtpConnectionThread.h index ffa66b249dc8..262c2ffb8172 100644 --- a/netwerk/protocol/ftp/nsFtpConnectionThread.h +++ b/netwerk/protocol/ftp/nsFtpConnectionThread.h @@ -35,6 +35,7 @@ #include "nsICacheEntryDescriptor.h" #include "nsICacheListener.h" +#include "nsIProtocolProxyCallback.h" // ftp server types #define FTP_GENERIC_TYPE 0 @@ -77,6 +78,7 @@ typedef enum _FTP_STATE { typedef enum _FTP_ACTION {GET, PUT} FTP_ACTION; class nsFtpChannel; +class nsICancelable; // The nsFtpState object is the content stream for the channel. It implements // nsIInputStreamCallback, so it can read data from the control connection. It @@ -88,13 +90,16 @@ class nsFtpState : public nsBaseContentStream, public nsITransportEventSink, public nsICacheListener, public nsIRequestObserver, - public nsFtpControlConnectionListener { + public nsFtpControlConnectionListener, + public nsIProtocolProxyCallback +{ public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIINPUTSTREAMCALLBACK NS_DECL_NSITRANSPORTEVENTSINK NS_DECL_NSICACHELISTENER NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSIPROTOCOLPROXYCALLBACK // Override input stream methods: NS_IMETHOD CloseWithStatus(nsresult status); @@ -263,6 +268,9 @@ private: bool mDoomCache; nsCString mSuppliedEntityID; + + nsCOMPtr mProxyRequest; + bool mDeferredCallbackPending; }; #endif //__nsFtpState__h_ diff --git a/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp b/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp index 5e0aeb4f410f..d6605ce36b28 100644 --- a/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp +++ b/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp @@ -211,11 +211,13 @@ nsFtpProtocolHandler::NewURI(const nsACString &aSpec, NS_IMETHODIMP nsFtpProtocolHandler::NewChannel(nsIURI* url, nsIChannel* *result) { - return NewProxiedChannel(url, nullptr, result); + return NewProxiedChannel(url, nullptr, 0, nullptr, result); } NS_IMETHODIMP nsFtpProtocolHandler::NewProxiedChannel(nsIURI* uri, nsIProxyInfo* proxyInfo, + uint32_t proxyResolveFlags, + nsIURI *proxyURI, nsIChannel* *result) { NS_ENSURE_ARG_POINTER(uri); diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index c28ebc862e6c..7355faad0028 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -50,6 +50,7 @@ HttpBaseChannel::HttpBaseChannel() , mAllowSpdy(true) , mPrivateBrowsing(false) , mSuspendCount(0) + , mProxyResolveFlags(0) { LOG(("Creating HttpBaseChannel @%x\n", this)); @@ -74,7 +75,9 @@ HttpBaseChannel::~HttpBaseChannel() nsresult HttpBaseChannel::Init(nsIURI *aURI, uint8_t aCaps, - nsProxyInfo *aProxyInfo) + nsProxyInfo *aProxyInfo, + uint32_t aProxyResolveFlags, + nsIURI *aProxyURI) { LOG(("HttpBaseChannel::Init [this=%p]\n", this)); @@ -87,6 +90,8 @@ HttpBaseChannel::Init(nsIURI *aURI, mOriginalURI = aURI; mDocumentURI = nullptr; mCaps = aCaps; + mProxyResolveFlags = aProxyResolveFlags; + mProxyURI = aProxyURI; // Construct connection info object nsAutoCString host; @@ -112,11 +117,6 @@ HttpBaseChannel::Init(nsIURI *aURI, if (NS_FAILED(rv)) return rv; LOG(("uri=%s\n", mSpec.get())); - mConnectionInfo = new nsHttpConnectionInfo(host, port, - aProxyInfo, usingSSL); - if (!mConnectionInfo) - return NS_ERROR_OUT_OF_MEMORY; - // Set default request method mRequestHead.SetMethod(nsHttp::Get); @@ -128,8 +128,13 @@ HttpBaseChannel::Init(nsIURI *aURI, rv = mRequestHead.SetHeader(nsHttp::Host, hostLine); if (NS_FAILED(rv)) return rv; - rv = gHttpHandler-> - AddStandardRequestHeaders(&mRequestHead.Headers(), aCaps); + rv = gHttpHandler->AddStandardRequestHeaders(&mRequestHead.Headers()); + if (NS_FAILED(rv)) return rv; + + nsAutoCString type; + if (aProxyInfo && NS_SUCCEEDED(aProxyInfo->GetType(type)) && + !type.EqualsLiteral("unknown")) + mProxyInfo = aProxyInfo; return rv; } @@ -1522,7 +1527,9 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI, // set, then allow the flag to apply to the redirected channel as well. // since we force set INHIBIT_PERSISTENT_CACHING on all HTTPS channels, // we only need to check if the original channel was using SSL. - if (mConnectionInfo->UsingSSL()) + bool usingSSL = false; + nsresult rv = mURI->SchemeIs("https", &usingSSL); + if (NS_SUCCEEDED(rv) && usingSSL) newLoadFlags &= ~INHIBIT_PERSISTENT_CACHING; // Do not pass along LOAD_CHECK_OFFLINE_CACHE diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h index 971958c122ec..1fa8546d4866 100644 --- a/netwerk/protocol/http/HttpBaseChannel.h +++ b/netwerk/protocol/http/HttpBaseChannel.h @@ -60,7 +60,9 @@ public: HttpBaseChannel(); virtual ~HttpBaseChannel(); - virtual nsresult Init(nsIURI *aURI, uint8_t aCaps, nsProxyInfo *aProxyInfo); + virtual nsresult Init(nsIURI *aURI, uint8_t aCaps, nsProxyInfo *aProxyInfo, + uint32_t aProxyResolveFlags, + nsIURI *aProxyURI); // nsIRequest NS_IMETHOD GetName(nsACString& aName); @@ -224,6 +226,7 @@ protected: nsCOMPtr mUploadStream; nsAutoPtr mResponseHead; nsRefPtr mConnectionInfo; + nsCOMPtr mProxyInfo; nsCString mSpec; // ASCII encoded URL spec nsCString mContentTypeHint; @@ -269,6 +272,9 @@ protected: uint32_t mSuspendCount; nsAutoPtr > mRedirectedCachekeys; + + uint32_t mProxyResolveFlags; + nsCOMPtr mProxyURI; }; // Share some code while working around C++'s absurd inability to handle casting diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 99ec61d67867..bfb45ff22154 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -333,21 +333,17 @@ nsHttpChannel::~nsHttpChannel() nsresult nsHttpChannel::Init(nsIURI *uri, uint8_t caps, - nsProxyInfo *proxyInfo) + nsProxyInfo *proxyInfo, + uint32_t proxyResolveFlags, + nsIURI *proxyURI) { - nsresult rv = HttpBaseChannel::Init(uri, caps, proxyInfo); + nsresult rv = HttpBaseChannel::Init(uri, caps, proxyInfo, + proxyResolveFlags, proxyURI); if (NS_FAILED(rv)) return rv; LOG(("nsHttpChannel::Init [this=%p]\n", this)); - mAuthProvider = - do_CreateInstance("@mozilla.org/network/http-channel-auth-provider;1", - &rv); - if (NS_FAILED(rv)) - return rv; - rv = mAuthProvider->Init(this); - return rv; } //----------------------------------------------------------------------------- @@ -407,13 +403,6 @@ nsHttpChannel::Connect() // Consider opening a TCP connection right away SpeculativeConnect(); - // are we offline? - bool offline = gIOService->IsOffline(); - if (offline) - mLoadFlags |= LOAD_ONLY_FROM_CACHE; - else if (PL_strcmp(mConnectionInfo->ProxyType(), "unknown") == 0) - return ResolveProxy(); // Lazily resolve proxy info - // Don't allow resuming when cache must be used if (mResuming && (mLoadFlags & LOAD_ONLY_FROM_CACHE)) { LOG(("Resuming from cache is not supported yet")); @@ -1532,54 +1521,6 @@ nsHttpChannel::ProxyFailover() return AsyncDoReplaceWithProxy(pi); } -void -nsHttpChannel::HandleAsyncReplaceWithProxy() -{ - NS_PRECONDITION(!mCallOnResume, "How did that happen?"); - - if (mSuspendCount) { - LOG(("Waiting until resume to do async proxy replacement [this=%p]\n", - this)); - mCallOnResume = &nsHttpChannel::HandleAsyncReplaceWithProxy; - return; - } - - nsresult status = mStatus; - - nsCOMPtr pi; - pi.swap(mTargetProxyInfo); - if (!mCanceled) { - PushRedirectAsyncFunc(&nsHttpChannel::ContinueHandleAsyncReplaceWithProxy); - status = AsyncDoReplaceWithProxy(pi); - if (NS_SUCCEEDED(status)) - return; - PopRedirectAsyncFunc(&nsHttpChannel::ContinueHandleAsyncReplaceWithProxy); - } - - if (NS_FAILED(status)) { - ContinueHandleAsyncReplaceWithProxy(status); - } -} - -nsresult -nsHttpChannel::ContinueHandleAsyncReplaceWithProxy(nsresult status) -{ - if (mLoadGroup && NS_SUCCEEDED(status)) { - mLoadGroup->RemoveRequest(this, nullptr, mStatus); - } - else if (NS_FAILED(status)) { - AsyncAbort(status); - } - - // Return NS_OK here, even it seems to be breaking the async function stack - // contract (i.e. passing the result code to a function bellow). - // ContinueHandleAsyncReplaceWithProxy will always be at the bottom of the - // stack. If we would return the failure code, the async function stack - // logic would cancel the channel synchronously, which is undesired after - // invoking AsyncAbort above. - return NS_OK; -} - void nsHttpChannel::HandleAsyncRedirectChannelToHttps() { @@ -1724,7 +1665,8 @@ nsHttpChannel::AsyncDoReplaceWithProxy(nsIProxyInfo* pi) nsresult rv; nsCOMPtr newChannel; - rv = gHttpHandler->NewProxiedChannel(mURI, pi, getter_AddRefs(newChannel)); + rv = gHttpHandler->NewProxiedChannel(mURI, pi, mProxyResolveFlags, + mProxyURI, getter_AddRefs(newChannel)); if (NS_FAILED(rv)) return rv; @@ -1795,11 +1737,16 @@ nsHttpChannel::ResolveProxy() if (NS_FAILED(rv)) return rv; - uint32_t resolveFlags = 0; - if (mConnectionInfo->ProxyInfo()) - mConnectionInfo->ProxyInfo()->GetResolveFlags(&resolveFlags); + // Check if we are configured to directly connect. This will save us + // a round trip through the event dispatch system + uint32_t proxyConfigType; + if (NS_SUCCEEDED(pps->GetProxyConfigType(&proxyConfigType)) && + proxyConfigType == nsIProtocolProxyService::PROXYCONFIG_DIRECT) { + return NS_ERROR_FAILURE; + } - return pps->AsyncResolve(mURI, resolveFlags, this, getter_AddRefs(mProxyRequest)); + return pps->AsyncResolve(mProxyURI ? mProxyURI : mURI, mProxyResolveFlags, + this, getter_AddRefs(mProxyRequest)); } bool @@ -4357,7 +4304,102 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context) if (NS_FAILED(rv)) return rv; - if (!(mConnectionInfo && mConnectionInfo->UsingHttpProxy())) { + // Remember the cookie header that was set, if any + const char *cookieHeader = mRequestHead.PeekHeader(nsHttp::Cookie); + if (cookieHeader) { + mUserSetCookieHeader = cookieHeader; + } + + AddCookiesToRequest(); + + // notify "http-on-modify-request" observers + gHttpHandler->OnModifyRequest(this); + + mIsPending = true; + mWasOpened = true; + + mListener = listener; + mListenerContext = context; + + // add ourselves to the load group. from this point forward, we'll report + // all failures asynchronously. + if (mLoadGroup) + mLoadGroup->AddRequest(this, nullptr); + + // Collect mAsyncOpenTime after we have called all observers like + // "http-on-modify-request" and load group observers that may set + // mTimingEnabled flag. + if (mTimingEnabled) + mAsyncOpenTime = mozilla::TimeStamp::Now(); + + // are we offline? + bool offline = gIOService->IsOffline(); + if (offline) + mLoadFlags |= LOAD_ONLY_FROM_CACHE; + + // the only time we would already know the proxy information at this + // point would be if we were proxying a non-http protocol like ftp + if (!mProxyInfo && NS_SUCCEEDED(ResolveProxy())) + return NS_OK; + + return BeginConnect(); +} + +nsresult +nsHttpChannel::BeginConnect() +{ + LOG(("nsHttpChannel::BeginConnect [this=%p]\n", this)); + nsresult rv; + + // Construct connection info object + nsAutoCString host; + int32_t port = -1; + bool usingSSL = false; + + rv = mURI->SchemeIs("https", &usingSSL); + if (NS_SUCCEEDED(rv)) + rv = mURI->GetAsciiHost(host); + if (NS_SUCCEEDED(rv)) + rv = mURI->GetPort(&port); + if (NS_SUCCEEDED(rv)) + rv = mURI->GetAsciiSpec(mSpec); + if (NS_FAILED(rv)) + return rv; + + // Reject the URL if it doesn't specify a host + if (host.IsEmpty()) + return NS_ERROR_MALFORMED_URI; + LOG(("host=%s port=%d\n", host.get(), port)); + LOG(("uri=%s\n", mSpec.get())); + + nsCOMPtr proxyInfo; + if (mProxyInfo) + proxyInfo = do_QueryInterface(mProxyInfo); + + mConnectionInfo = new nsHttpConnectionInfo(host, port, proxyInfo, usingSSL); + + mAuthProvider = + do_CreateInstance("@mozilla.org/network/http-channel-auth-provider;1", + &rv); + if (NS_SUCCEEDED(rv)) + rv = mAuthProvider->Init(this); + if (NS_FAILED(rv)) + return rv; + + // check to see if authorization headers should be included + mAuthProvider->AddAuthorizationHeaders(); + + // when proxying only use the pipeline bit if ProxyPipelining() allows it. + if (!mConnectionInfo->UsingConnect() && mConnectionInfo->UsingHttpProxy()) { + mCaps &= ~NS_HTTP_ALLOW_PIPELINING; + if (gHttpHandler->ProxyPipelining()) + mCaps |= NS_HTTP_ALLOW_PIPELINING; + } + + // if this somehow fails we can go on without it + gHttpHandler->AddConnectionHeader(&mRequestHead.Headers(), mCaps); + + if (!mConnectionInfo->UsingHttpProxy()) { // Start a DNS lookup very early in case the real open is queued the DNS can // happen in parallel. Do not do so in the presence of an HTTP proxy as // all lookups other than for the proxy itself are done by the proxy. @@ -4373,20 +4415,6 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context) mDNSPrefetch->PrefetchHigh(); } - // Remember the cookie header that was set, if any - const char *cookieHeader = mRequestHead.PeekHeader(nsHttp::Cookie); - if (cookieHeader) { - mUserSetCookieHeader = cookieHeader; - } - - AddCookiesToRequest(); - - // check to see if authorization headers should be included - mAuthProvider->AddAuthorizationHeaders(); - - // notify "http-on-modify-request" observers - gHttpHandler->OnModifyRequest(this); - // Adjust mCaps according to our request headers: // - If "Connection: close" is set as a request header, then do not bother // trying to establish a keep-alive connection. @@ -4400,23 +4428,6 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context) // Force-Reload should reset the persistent connection pool for this host if (mLoadFlags & LOAD_FRESH_CONNECTION) mCaps |= NS_HTTP_CLEAR_KEEPALIVES; - - mIsPending = true; - mWasOpened = true; - - mListener = listener; - mListenerContext = context; - - // add ourselves to the load group. from this point forward, we'll report - // all failures asynchronously. - if (mLoadGroup) - mLoadGroup->AddRequest(this, nullptr); - - // Collect mAsyncOpenTime after we have called all obsrevers like - // "http-on-modify-request" and load group observers that may set - // mTimingEnabled flag. - if (mTimingEnabled) - mAsyncOpenTime = mozilla::TimeStamp::Now(); // We may have been cancelled already, either by on-modify-request // listeners or by load group observers; in that case, we should @@ -4431,14 +4442,10 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context) AsyncAbort(rv); } else if (mLoadFlags & LOAD_CLASSIFY_URI) { nsRefPtr classifier = new nsChannelClassifier(); - if (!classifier) { - Cancel(NS_ERROR_OUT_OF_MEMORY); - return NS_OK; - } - rv = classifier->Start(this); if (NS_FAILED(rv)) { Cancel(rv); + return rv; } } @@ -4486,18 +4493,33 @@ NS_IMETHODIMP nsHttpChannel::OnProxyAvailable(nsICancelable *request, nsIURI *uri, nsIProxyInfo *pi, nsresult status) { + LOG(("nsHttpChannel::OnProxyAvailable [this=%p pi=%p status=%x mStatus=%x]\n", + this, pi, status, mStatus)); mProxyRequest = nullptr; + nsresult rv; + // If status is a failure code, then it means that we failed to resolve // proxy info. That is a non-fatal error assuming it wasn't because the // request was canceled. We just failover to DIRECT when proxy resolution // fails (failure can mean that the PAC URL could not be loaded). - // Need to replace this channel with a new one. It would be complex to try - // to change the value of mConnectionInfo since so much of our state may - // depend on its state. - mTargetProxyInfo = pi; - HandleAsyncReplaceWithProxy(); + if (NS_SUCCEEDED(status)) + mProxyInfo = pi; + + if (!gHttpHandler->Active()) { + LOG(("nsHttpChannel::OnProxyAvailable [this=%p] " + "Handler no longer active.\n", this)); + rv = NS_ERROR_NOT_AVAILABLE; + } + else { + rv = BeginConnect(); + } + + if (NS_FAILED(rv)) { + Cancel(rv); + DoNotifyListener(); + } return NS_OK; } diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h index 117a5437e1b9..c579184684da 100644 --- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -95,7 +95,9 @@ public: nsHttpChannel(); virtual ~nsHttpChannel(); - virtual nsresult Init(nsIURI *aURI, uint8_t aCaps, nsProxyInfo *aProxyInfo); + virtual nsresult Init(nsIURI *aURI, uint8_t aCaps, nsProxyInfo *aProxyInfo, + uint32_t aProxyResolveFlags, + nsIURI *aProxyURI); // Methods HttpBaseChannel didn't implement for us or that we override. // @@ -150,6 +152,7 @@ private: typedef nsresult (nsHttpChannel::*nsContinueRedirectionFunc)(nsresult result); bool RequestIsConditional(); + nsresult BeginConnect(); nsresult Connect(); nsresult ContinueConnect(); void SpeculativeConnect(); @@ -186,8 +189,6 @@ private: nsresult ProxyFailover(); nsresult AsyncDoReplaceWithProxy(nsIProxyInfo *); nsresult ContinueDoReplaceWithProxy(nsresult); - void HandleAsyncReplaceWithProxy(); - nsresult ContinueHandleAsyncReplaceWithProxy(nsresult); nsresult ResolveProxy(); // cache specific methods @@ -303,9 +304,6 @@ private: // auth specific data nsCOMPtr mAuthProvider; - // Proxy info to replace with - nsCOMPtr mTargetProxyInfo; - // If the channel is associated with a cache, and the URI matched // a fallback namespace, this will hold the key for the fallback // cache entry. diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index 874987c94b9c..1c47434c77b7 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -131,9 +131,9 @@ nsHttpHandler::nsHttpHandler() , mHttpVersion(NS_HTTP_VERSION_1_1) , mProxyHttpVersion(NS_HTTP_VERSION_1_1) , mCapabilities(NS_HTTP_ALLOW_KEEPALIVE) - , mProxyCapabilities(NS_HTTP_ALLOW_KEEPALIVE) , mReferrerLevel(0xff) // by default we always send a referrer , mFastFallbackToIPv4(false) + , mProxyPipelining(true) , mIdleTimeout(PR_SecondsToInterval(10)) , mSpdyTimeout(PR_SecondsToInterval(180)) , mMaxRequestAttempts(10) @@ -167,6 +167,7 @@ nsHttpHandler::nsHttpHandler() , mDoNotTrackEnabled(false) , mTelemetryEnabled(false) , mAllowExperiments(true) + , mHandlerActive(false) , mEnableSpdy(false) , mSpdyV2(true) , mSpdyV3(true) @@ -264,6 +265,7 @@ nsHttpHandler::Init() } mSessionStartTime = NowInSeconds(); + mHandlerActive = true; rv = mAuthCache.Init(); if (NS_FAILED(rv)) return rv; @@ -331,8 +333,7 @@ nsHttpHandler::InitConnectionMgr() } nsresult -nsHttpHandler::AddStandardRequestHeaders(nsHttpHeaderArray *request, - uint8_t caps) +nsHttpHandler::AddStandardRequestHeaders(nsHttpHeaderArray *request) { nsresult rv; @@ -356,6 +357,20 @@ nsHttpHandler::AddStandardRequestHeaders(nsHttpHeaderArray *request, rv = request->SetHeader(nsHttp::Accept_Encoding, mAcceptEncodings); if (NS_FAILED(rv)) return rv; + // Add the "Do-Not-Track" header + if (mDoNotTrackEnabled) { + rv = request->SetHeader(nsHttp::DoNotTrack, + NS_LITERAL_CSTRING("1")); + if (NS_FAILED(rv)) return rv; + } + + return NS_OK; +} + +nsresult +nsHttpHandler::AddConnectionHeader(nsHttpHeaderArray *request, + uint8_t caps) +{ // RFC2616 section 19.6.2 states that the "Connection: keep-alive" // and "Keep-alive" request headers should not be sent by HTTP/1.1 // user-agents. But this is not a problem in practice, and the @@ -369,13 +384,6 @@ nsHttpHandler::AddStandardRequestHeaders(nsHttpHeaderArray *request, connectionType = &keepAlive; } - // Add the "Do-Not-Track" header - if (mDoNotTrackEnabled) { - rv = request->SetHeader(nsHttp::DoNotTrack, - NS_LITERAL_CSTRING("1")); - if (NS_FAILED(rv)) return rv; - } - return request->SetHeader(nsHttp::Connection, *connectionType); } @@ -943,12 +951,8 @@ nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref) if (PREF_CHANGED(HTTP_PREF("proxy.pipelining"))) { rv = prefs->GetBoolPref(HTTP_PREF("proxy.pipelining"), &cVar); - if (NS_SUCCEEDED(rv)) { - if (cVar) - mProxyCapabilities |= NS_HTTP_ALLOW_PIPELINING; - else - mProxyCapabilities &= ~NS_HTTP_ALLOW_PIPELINING; - } + if (NS_SUCCEEDED(rv)) + mProxyPipelining = cVar; } if (PREF_CHANGED(HTTP_PREF("qos"))) { @@ -1375,7 +1379,7 @@ nsHttpHandler::NewChannel(nsIURI *uri, nsIChannel **result) } } - return NewProxiedChannel(uri, nullptr, result); + return NewProxiedChannel(uri, nullptr, 0, nullptr, result); } NS_IMETHODIMP @@ -1393,6 +1397,8 @@ nsHttpHandler::AllowPort(int32_t port, const char *scheme, bool *_retval) NS_IMETHODIMP nsHttpHandler::NewProxiedChannel(nsIURI *uri, nsIProxyInfo* givenProxyInfo, + uint32_t proxyResolveFlags, + nsIURI *proxyURI, nsIChannel **result) { nsRefPtr httpChannel; @@ -1417,13 +1423,7 @@ nsHttpHandler::NewProxiedChannel(nsIURI *uri, httpChannel = new nsHttpChannel(); } - // select proxy caps if using a non-transparent proxy. SSL tunneling - // should not use proxy settings. - int8_t caps; - if (proxyInfo && !nsCRT::strcmp(proxyInfo->Type(), "http") && !https) - caps = mProxyCapabilities; - else - caps = mCapabilities; + uint8_t caps = mCapabilities; if (https) { // enable pipelining over SSL if requested @@ -1436,7 +1436,7 @@ nsHttpHandler::NewProxiedChannel(nsIURI *uri, } } - rv = httpChannel->Init(uri, caps, proxyInfo); + rv = httpChannel->Init(uri, caps, proxyInfo, proxyResolveFlags, proxyURI); if (NS_FAILED(rv)) return rv; @@ -1509,6 +1509,8 @@ nsHttpHandler::Observe(nsISupports *subject, else if (strcmp(topic, "profile-change-net-teardown") == 0 || strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) { + mHandlerActive = false; + // clear cache of all authentication credentials. mAuthCache.ClearAll(); diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h index fbdd8d4cab94..e4df12542d86 100644 --- a/netwerk/protocol/http/nsHttpHandler.h +++ b/netwerk/protocol/http/nsHttpHandler.h @@ -58,8 +58,9 @@ public: virtual ~nsHttpHandler(); nsresult Init(); - nsresult AddStandardRequestHeaders(nsHttpHeaderArray *, - uint8_t capabilities); + nsresult AddStandardRequestHeaders(nsHttpHeaderArray *); + nsresult AddConnectionHeader(nsHttpHeaderArray *, + uint8_t capabilities); bool IsAcceptableEncoding(const char *encoding); const nsAFlatCString &UserAgent(); @@ -78,6 +79,7 @@ public: uint8_t GetQoSBits() { return mQoSBits; } uint16_t GetIdleSynTimeout() { return mIdleSynTimeout; } bool FastFallbackToIPv4() { return mFastFallbackToIPv4; } + bool ProxyPipelining() { return mProxyPipelining; } uint32_t MaxSocketCount(); bool EnforceAssocReq() { return mEnforceAssocReq; } @@ -233,6 +235,9 @@ public: mozilla::net::SpdyInformation *SpdyInfo() { return &mSpdyInfo; } + // returns true in between Init and Shutdown states + bool Active() { return mHandlerActive; } + private: // @@ -273,11 +278,10 @@ private: uint8_t mHttpVersion; uint8_t mProxyHttpVersion; uint8_t mCapabilities; - uint8_t mProxyCapabilities; uint8_t mReferrerLevel; bool mFastFallbackToIPv4; - + bool mProxyPipelining; PRIntervalTime mIdleTimeout; PRIntervalTime mSpdyTimeout; @@ -356,6 +360,9 @@ private: // The value of network.allow-experiments bool mAllowExperiments; + // true in between init and shutdown states + bool mHandlerActive; + // Try to use SPDY features instead of HTTP/1.1 over SSL mozilla::net::SpdyInformation mSpdyInfo; bool mEnableSpdy; diff --git a/netwerk/protocol/websocket/WebSocketChannel.cpp b/netwerk/protocol/websocket/WebSocketChannel.cpp index 233c9594c34c..48c78351641e 100644 --- a/netwerk/protocol/websocket/WebSocketChannel.cpp +++ b/netwerk/protocol/websocket/WebSocketChannel.cpp @@ -1456,7 +1456,7 @@ WebSocketChannel::ApplyMask(uint32_t mask, uint8_t *data, uint64_t len) // but the buffer might not be alligned. So we first deal with // 0 to 3 bytes of preamble individually - while (len && (reinterpret_cast(data) & 3)) { + while (len && (reinterpret_cast(data) & 3)) { *data ^= mask >> 24; mask = PR_ROTATE_LEFT32(mask, 8); data++; diff --git a/netwerk/test/unit/test_protocolproxyservice.js b/netwerk/test/unit/test_protocolproxyservice.js index aae2b67b6d14..6a910ad6f8f4 100644 --- a/netwerk/test/unit/test_protocolproxyservice.js +++ b/netwerk/test/unit/test_protocolproxyservice.js @@ -6,10 +6,22 @@ // This testcase exercises the Protocol Proxy Service +// These are the major sub tests: +// run_filter_test(); +// run_filter_test2() +// run_filter_test3() +// run_pref_test(); +// run_pac_test(); +// run_pac_cancel_test(); +// run_proxy_host_filters_test(); +// run_myipaddress_test(); + var ios = Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService); var pps = Components.classes["@mozilla.org/network/protocol-proxy-service;1"] .getService(); +var prefs = Components.classes["@mozilla.org/preferences-service;1"] + .getService(Components.interfaces.nsIPrefBranch); /** * Test nsIProtocolHandler that allows proxying, but doesn't allow HTTP @@ -143,61 +155,109 @@ function run_filter_test() { var uri = ios.newURI("http://www.mozilla.org/", null, null); // Verify initial state + var cb = new resolveCallback(); + cb.nextFunction = filter_test0_1; + var req = pps.asyncResolve(uri, 0, cb); +} - var pi = pps.resolve(uri, 0); +var filter01; +var filter02; + +function filter_test0_1(pi) { do_check_eq(pi, null); // Push a filter and verify the results - var filter1 = new BasicFilter(); - var filter2 = new BasicFilter(); - pps.registerFilter(filter1, 10); - pps.registerFilter(filter2, 20); + filter01 = new BasicFilter(); + filter02 = new BasicFilter(); + pps.registerFilter(filter01, 10); + pps.registerFilter(filter02, 20); - pi = pps.resolve(uri, 0); + var cb = new resolveCallback(); + cb.nextFunction = filter_test0_2; + var uri = ios.newURI("http://www.mozilla.org/", null, null); + var req = pps.asyncResolve(uri, 0, cb); +} + +function filter_test0_2(pi) +{ check_proxy(pi, "http", "localhost", 8080, 0, 10, true); check_proxy(pi.failoverProxy, "direct", "", -1, 0, 0, false); - pps.unregisterFilter(filter2); - pi = pps.resolve(uri, 0); + pps.unregisterFilter(filter02); + + var cb = new resolveCallback(); + cb.nextFunction = filter_test0_3; + var uri = ios.newURI("http://www.mozilla.org/", null, null); + var req = pps.asyncResolve(uri, 0, cb); +} + +function filter_test0_3(pi) +{ check_proxy(pi, "http", "localhost", 8080, 0, 10, true); check_proxy(pi.failoverProxy, "direct", "", -1, 0, 0, false); // Remove filter and verify that we return to the initial state - pps.unregisterFilter(filter1); - pi = pps.resolve(uri, 0); - do_check_eq(pi, null); + pps.unregisterFilter(filter01); + + var cb = new resolveCallback(); + cb.nextFunction = filter_test0_4; + var uri = ios.newURI("http://www.mozilla.org/", null, null); + var req = pps.asyncResolve(uri, 0, cb); } -function run_filter_test2() { - var uri = ios.newURI("http://www.mozilla.org/", null, null); - - // Verify initial state - - var pi = pps.resolve(uri, 0); +function filter_test0_4(pi) +{ do_check_eq(pi, null); + run_filter_test2(); +} +var filter11; +var filter12; + +function run_filter_test2() { // Push a filter and verify the results - var filter1 = new TestFilter("http", "foo", 8080, 0, 10); - var filter2 = new TestFilter("http", "bar", 8090, 0, 10); - pps.registerFilter(filter1, 20); - pps.registerFilter(filter2, 10); + filter11 = new TestFilter("http", "foo", 8080, 0, 10); + filter12 = new TestFilter("http", "bar", 8090, 0, 10); + pps.registerFilter(filter11, 20); + pps.registerFilter(filter12, 10); - pi = pps.resolve(uri, 0); + var cb = new resolveCallback(); + cb.nextFunction = filter_test1_1; + var uri = ios.newURI("http://www.mozilla.org/", null, null); + var req = pps.asyncResolve(uri, 0, cb); +} + +function filter_test1_1(pi) { check_proxy(pi, "http", "bar", 8090, 0, 10, true); check_proxy(pi.failoverProxy, "http", "foo", 8080, 0, 10, false); - pps.unregisterFilter(filter2); - pi = pps.resolve(uri, 0); + pps.unregisterFilter(filter12); + + var cb = new resolveCallback(); + cb.nextFunction = filter_test1_2; + var uri = ios.newURI("http://www.mozilla.org/", null, null); + var req = pps.asyncResolve(uri, 0, cb); +} + +function filter_test1_2(pi) { check_proxy(pi, "http", "foo", 8080, 0, 10, false); // Remove filter and verify that we return to the initial state - pps.unregisterFilter(filter1); - pi = pps.resolve(uri, 0); + pps.unregisterFilter(filter11); + + var cb = new resolveCallback(); + cb.nextFunction = filter_test1_3; + var uri = ios.newURI("http://www.mozilla.org/", null, null); + var req = pps.asyncResolve(uri, 0, cb); +} + +function filter_test1_3(pi) { do_check_eq(pi, null); + run_filter_test3(); } var filter_3_1; @@ -213,42 +273,56 @@ function run_filter_test3() { var cb = new resolveCallback(); cb.nextFunction = filter_test3_1; var req = pps.asyncResolve(uri, 0, cb); - do_test_pending(); } function filter_test3_1(pi) { check_proxy(pi, "http", "foo", 8080, 0, 10, false); pps.unregisterFilter(filter_3_1); - run_test_continued_3(); - do_test_finished(); + run_pref_test(); } function run_pref_test() { var uri = ios.newURI("http://www.mozilla.org/", null, null); - var prefs = Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefBranch); - // Verify 'direct' setting prefs.setIntPref("network.proxy.type", 0); - var pi = pps.resolve(uri, 0); + var cb = new resolveCallback(); + cb.nextFunction = pref_test1_1; + var req = pps.asyncResolve(uri, 0, cb); +} + +function pref_test1_1(pi) +{ do_check_eq(pi, null); // Verify 'manual' setting - prefs.setIntPref("network.proxy.type", 1); + var cb = new resolveCallback(); + cb.nextFunction = pref_test1_2; + var uri = ios.newURI("http://www.mozilla.org/", null, null); + var req = pps.asyncResolve(uri, 0, cb); +} + +function pref_test1_2(pi) +{ // nothing yet configured - pi = pps.resolve(uri, 0); do_check_eq(pi, null); // try HTTP configuration prefs.setCharPref("network.proxy.http", "foopy"); prefs.setIntPref("network.proxy.http_port", 8080); - pi = pps.resolve(uri, 0); + var cb = new resolveCallback(); + cb.nextFunction = pref_test1_3; + var uri = ios.newURI("http://www.mozilla.org/", null, null); + var req = pps.asyncResolve(uri, 0, cb); +} + +function pref_test1_3(pi) +{ check_proxy(pi, "http", "foopy", 8080, 0, -1, false); prefs.setCharPref("network.proxy.http", ""); @@ -258,15 +332,33 @@ function run_pref_test() { prefs.setCharPref("network.proxy.socks", "barbar"); prefs.setIntPref("network.proxy.socks_port", 1203); - pi = pps.resolve(uri, 0); + var cb = new resolveCallback(); + cb.nextFunction = pref_test1_4; + var uri = ios.newURI("http://www.mozilla.org/", null, null); + var req = pps.asyncResolve(uri, 0, cb); +} + +function pref_test1_4(pi) +{ check_proxy(pi, "socks", "barbar", 1203, 0, -1, false); + run_pac_test(); } function run_protocol_handler_test() { var uri = ios.newURI("moz-test:foopy", null, null); - var pi = pps.resolve(uri, 0); + var cb = new resolveCallback(); + cb.nextFunction = protocol_handler_test_1; + var req = pps.asyncResolve(uri, 0, cb); +} + +function protocol_handler_test_1(pi) +{ do_check_eq(pi, null); + prefs.setCharPref("network.proxy.autoconfig_url", ""); + prefs.setIntPref("network.proxy.type", 0); + + run_pac_cancel_test(); } function TestResolveCallback() { @@ -292,21 +384,7 @@ TestResolveCallback.prototype = { check_proxy(pi, "http", "foopy", 8080, 0, -1, true); check_proxy(pi.failoverProxy, "direct", "", -1, -1, -1, false); - // verify direct query now that we know the PAC file is loaded - pi = pps.resolve(ios.newURI("http://bazbat.com/", null, null), 0); - do_check_neq(pi, null); - check_proxy(pi, "http", "foopy", 8080, 0, -1, true); - check_proxy(pi.failoverProxy, "direct", "", -1, -1, -1, false); - run_protocol_handler_test(); - - var prefs = Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefBranch); - prefs.setCharPref("network.proxy.autoconfig_url", ""); - prefs.setIntPref("network.proxy.type", 0); - - run_test_continued(); - do_test_finished(); } }; @@ -317,31 +395,12 @@ function run_pac_test() { '}'; var uri = ios.newURI("http://www.mozilla.org/", null, null); - var prefs = Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefBranch); - // Configure PAC prefs.setIntPref("network.proxy.type", 2); prefs.setCharPref("network.proxy.autoconfig_url", pac); - // Test it out (we expect an "unknown" result since the PAC load is async) - var pi = pps.resolve(uri, 0); - do_check_neq(pi, null); - do_check_eq(pi.type, "unknown"); - - // We expect the NON_BLOCKING flag to trigger an exception here since - // we have configured the PPS to use PAC. - var hit_exception = false; - try { - pps.resolve(uri, pps.RESOLVE_NON_BLOCKING); - } catch (e) { - hit_exception = true; - } - do_check_eq(hit_exception, true); - var req = pps.asyncResolve(uri, 0, new TestResolveCallback()); - do_test_pending(); } function TestResolveCancelationCallback() { @@ -364,13 +423,10 @@ TestResolveCancelationCallback.prototype = { do_check_eq(status, Components.results.NS_ERROR_ABORT); do_check_eq(pi, null); - var prefs = Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefBranch); prefs.setCharPref("network.proxy.autoconfig_url", ""); prefs.setIntPref("network.proxy.type", 0); - run_test_continued_2(); - do_test_finished(); + run_proxy_host_filters_test(); } }; @@ -382,42 +438,70 @@ function run_pac_cancel_test() { 'function FindProxyForURL(url, host) {' + ' return "PROXY foopy:8080; DIRECT";' + '}'; - var prefs = Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefBranch); prefs.setIntPref("network.proxy.type", 2); prefs.setCharPref("network.proxy.autoconfig_url", pac); var req = pps.asyncResolve(uri, 0, new TestResolveCancelationCallback()); req.cancel(Components.results.NS_ERROR_ABORT); - do_test_pending(); } -function check_host_filters(hostList, bShouldBeFiltered) { +var hostList; +var hostIDX; +var bShouldBeFiltered; +var hostNextFX; + +function check_host_filters(hl, shouldBe, nextFX) { + hostList = hl; + hostIDX = 0; + bShouldBeFiltered = shouldBe; + hostNextFX = nextFX; + + if (hostList.length > hostIDX) + check_host_filter(hostIDX); +} + +function check_host_filters_cb() +{ + hostIDX++; + if (hostList.length > hostIDX) + check_host_filter(hostIDX); + else + hostNextFX(); +} + +function check_host_filter(i) { var uri; - var proxy; - for (var i=0; i"); do_check_eq(prefs.getCharPref("network.proxy.no_proxies_on"), hostFilterList + ", "); - // Amend lists - move local domain to filtered list uriStrFilterList.push(uriStrUseProxyList.pop()); - check_host_filters(uriStrFilterList, true); - check_host_filters(uriStrUseProxyList, false); + check_host_filters(uriStrFilterList, true, host_filters_3); +} +function host_filters_3() +{ + check_host_filters(uriStrUseProxyList, false, host_filters_4); +} + +function host_filters_4() +{ // Cleanup prefs.setCharPref("network.proxy.no_proxies_on", ""); do_check_eq(prefs.getCharPref("network.proxy.no_proxies_on"), ""); + run_myipaddress_test(); +} + +function run_myipaddress_test() +{ + // This test makes sure myIpAddress() comes up with some valid + // IP address other than localhost. The DUT must be configured with + // an Internet route for this to work - though no Internet traffic + // should be created. + + var pac = 'data:text/plain,' + + 'function FindProxyForURL(url, host) {' + + ' return "PROXY " + myIpAddress() + ":1234";' + + '}'; + + // no traffic to this IP is ever sent, it is just a public IP that + // does not require DNS to determine a route. + var uri = ios.newURI("http://192.0.43.10/", null, null); + + prefs.setIntPref("network.proxy.type", 2); + prefs.setCharPref("network.proxy.autoconfig_url", pac); + + var cb = new resolveCallback(); + cb.nextFunction = myipaddress_callback; + var req = pps.asyncResolve(uri, 0, cb); +} + +function myipaddress_callback(pi) +{ + do_check_neq(pi, null); + do_check_eq(pi.type, "http"); + do_check_eq(pi.port, 1234); + + // make sure we didn't return localhost + do_check_neq(pi.host, null); + do_check_neq(pi.host, "127.0.0.1"); + do_check_neq(pi.host, "::1"); + + prefs.setIntPref("network.proxy.type", 0); do_test_finished(); } +function run_deprecated_sync_test() +{ + var uri = ios.newURI("http://www.mozilla.org/", null, null); + + pps.QueryInterface(Components.interfaces.nsIProtocolProxyService2); + + // Verify initial state + var pi = pps.deprecatedBlockingResolve(uri, 0); + do_check_eq(pi, null); + + // Push a filter and verify the results + var filter1 = new BasicFilter(); + var filter2 = new BasicFilter(); + pps.registerFilter(filter1, 10); + pps.registerFilter(filter2, 20); + + pi = pps.deprecatedBlockingResolve(uri, 0); + check_proxy(pi, "http", "localhost", 8080, 0, 10, true); + check_proxy(pi.failoverProxy, "direct", "", -1, 0, 0, false); + + pps.unregisterFilter(filter2); + pi = pps.deprecatedBlockingResolve(uri, 0); + check_proxy(pi, "http", "localhost", 8080, 0, 10, true); + check_proxy(pi.failoverProxy, "direct", "", -1, 0, 0, false); + + // Remove filter and verify that we return to the initial state + pps.unregisterFilter(filter1); + pi = pps.deprecatedBlockingResolve(uri, 0); + do_check_eq(pi, null); +} + function run_test() { register_test_protocol_handler(); + + // any synchronous tests + run_deprecated_sync_test(); + + // start of asynchronous test chain run_filter_test(); - run_filter_test2(); - run_pref_test(); - run_pac_test(); - // additional tests may be added to run_test_continued -} - -function run_test_continued() { - run_pac_cancel_test(); - // additional tests may be added to run_test_continued_3 -} - -function run_test_continued_2() { - run_filter_test3(); -} - -function run_test_continued_3() { - run_proxy_host_filters_test(); + do_test_pending(); } diff --git a/netwerk/test/unit/test_proxy-failover_canceled.js b/netwerk/test/unit/test_proxy-failover_canceled.js index 6d02380a5fb9..24a8c73a4d4b 100644 --- a/netwerk/test/unit/test_proxy-failover_canceled.js +++ b/netwerk/test/unit/test_proxy-failover_canceled.js @@ -33,24 +33,11 @@ function run_test() httpServer.registerPathHandler("/content", contentHandler); httpServer.start(4444); + // we want to cancel the failover proxy engage, so, do not allow + // redirects from now. + var nc = new ChannelEventSink(); - var on_modify_request_count = 0; - - modifyrequestobserver = {observe: function() { - // We get 2 on-modify-request notifications: - // 1. when proxy service resolves the proxy settings from PAC function - // 2. when we try to fail over the first proxy (moving to the second one) - // - // In the second case we want to cancel the proxy engage, so, do not allow - // redirects from now. - - if (++on_modify_request_count == 2) - nc._flags = ES_ABORT_REDIRECT; - }} - - var os = Cc["@mozilla.org/observer-service;1"]. - getService(Ci.nsIObserverService); - os.addObserver(modifyrequestobserver, "http-on-modify-request", false); + nc._flags = ES_ABORT_REDIRECT; var prefserv = Cc["@mozilla.org/preferences-service;1"]. getService(Ci.nsIPrefService); diff --git a/netwerk/test/unit/test_proxy-replace_canceled.js b/netwerk/test/unit/test_proxy-replace_canceled.js index 7768e7c42684..bafb57d0c5c7 100644 --- a/netwerk/test/unit/test_proxy-replace_canceled.js +++ b/netwerk/test/unit/test_proxy-replace_canceled.js @@ -41,8 +41,16 @@ function run_test() "function FindProxyForURL(url, host) {return 'PROXY localhost:4444';}" ); + // this test assumed that a AsyncOnChannelRedirect query is made for + // each proxy failover or on the inital proxy only when PAC mode is used. + // Neither of those are documented anywhere that I can find and the latter + // hasn't been a useful property because it is PAC dependent and the type + // is generally unknown and OS driven. 769764 changed that to remove the + // internal redirect used to setup the initial proxy/channel as that isn't + // a redirect in any sense. + var chan = make_channel("http://localhost:4444/content"); - chan.notificationCallbacks = new ChannelEventSink(ES_ABORT_REDIRECT); chan.asyncOpen(new ChannelListener(finish_test, null, CL_EXPECT_FAILURE), null); + chan.cancel(Cr.NS_BINDING_ABORTED); do_test_pending(); } diff --git a/testing/mochitest/android.json b/testing/mochitest/android.json index 441de98947b1..832afdfda78e 100644 --- a/testing/mochitest/android.json +++ b/testing/mochitest/android.json @@ -303,6 +303,7 @@ "toolkit/components/prompts/test/test_modal_prompts.html": "TIMED_OUT", "toolkit/components/prompts/test/test_modal_select.html": "TIMED_OUT", "toolkit/components/satchel/test/test_bug_511615.html": "", + "toolkit/components/satchel/test/test_bug_787624.html": "", "toolkit/components/satchel/test/test_form_autocomplete.html": "TIMED_OUT", "toolkit/components/satchel/test/test_form_autocomplete_with_list.html": "", "toolkit/components/satchel/test/test_form_submission.html": "", diff --git a/testing/mozbase/generate_diff.py b/testing/mozbase/generate_diff.py new file mode 100644 index 000000000000..27357db9596b --- /dev/null +++ b/testing/mozbase/generate_diff.py @@ -0,0 +1,179 @@ +#!/usr/bin/env python + +# 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/. + +""" +generate a diff appropriate for mirroring +https://github.com/mozilla/mozbase +to http://hg.mozilla.org/mozilla-central/file/tip/testing/mozbase + +Note that this shells out to `cp` for simplicity, so you should run this +somewhere that has the `cp` command available. + +Your mozilla-central repository must have no outstanding changes before this +script is run. The repository must also have no untracked +files that show up in `hg st`. + +See: https://bugzilla.mozilla.org/show_bug.cgi?id=702832 +""" + +from __future__ import with_statement + +import optparse +import os +import shutil +import subprocess +import sys +import tempfile + +from subprocess import check_call as call + +# globals +here = os.path.dirname(os.path.abspath(__file__)) +MOZBASE = 'git://github.com/mozilla/mozbase.git' + +# paths we don't want in m-c from mozbase's github repo +git_excludes = ['.git', + '.gitignore', + 'versionbump.py'] + +# top-level paths we want to keep in m-c that aren't in the github repo +keep = ['Makefile.in', + 'generate_diff.py'] + +def error(msg): + """err out with a message""" + print >> sys.stdout, msg + sys.exit(1) + +def remove(path): + """remove a file or directory""" + if os.path.isdir(path): + shutil.rmtree(path) + else: + os.remove(path) + +def latest_commit(git_dir): + """returns last commit hash from a git repository directory""" + command = ['git', 'log', '--pretty=format:%H', 'HEAD^..HEAD'] + process = subprocess.Popen(command, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + cwd=git_dir) + stdout, stderr = process.communicate() + return stdout.strip() + +def untracked_files(hg_dir): + """untracked files in an hg repository""" + process = subprocess.Popen(['hg', 'st'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + cwd=hg_dir) + stdout, stderr = process.communicate() + lines = [line.strip() for line in stdout.strip().splitlines()] + status = [line.split(None, 1) for line in lines] + return [j for i, j in status if i == '?'] + +def revert(hg_dir, excludes=()): + """revert a hg repository directory""" + call(['hg', 'revert', '--no-backup', '--all'], cwd=hg_dir) + newfiles = untracked_files(hg_dir) + for f in newfiles: + path = os.path.join(hg_dir, f) + if path not in excludes: + os.remove(path) + +def main(args=sys.argv[1:]): + """command line entry point""" + + # parse command line options + usage = '%prog output' + class PlainDescriptionFormatter(optparse.IndentedHelpFormatter): + """description formatter for console script entry point""" + def format_description(self, description): + if description: + return description.strip() + '\n' + else: + return '' + parser = optparse.OptionParser(usage=usage, + description=__doc__, + formatter=PlainDescriptionFormatter()) + options, args = parser.parse_args(args) + if len(args) > 1: + parser.print_help() + parser.exit() + if args: + output = args[0] + else: + output = None + + # calculate hg root + hg_root = os.path.dirname(os.path.dirname(here)) # testing/mozbase + hg_dir = os.path.join(hg_root, '.hg') + assert os.path.exists(hg_dir) and os.path.isdir(hg_dir) + + # ensure there are no outstanding changes to m-c + process = subprocess.Popen(['hg', 'diff'], cwd=here, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = process.communicate() + if stdout.strip(): + error("Outstanding changes in %s; aborting" % hg_root) + + # ensure that there are no untracked files in testing/mozbase + untracked = untracked_files(hg_root) + if untracked: + error("Untracked files in %s:\n %s\naborting" % (hg_root, '\n'.join([' %s' % i for i in untracked]))) + + tempdir = tempfile.mkdtemp() + try: + + # download mozbase + call(['git', 'clone', MOZBASE], cwd=tempdir) + src = os.path.join(tempdir, 'mozbase') + assert os.path.isdir(src) + if output is None: + commit_hash = latest_commit(src) + output = os.path.join(os.getcwd(), '%s.diff' % commit_hash) + + # remove files from github clone we don't want to copy + for path in git_excludes: + path = os.path.join(src, path) + if not os.path.exists(path): + continue + remove(path) + + # remove the files from m-c we don't want to keep + for path in os.listdir(here): + if path in keep: + continue + path = os.path.join(here, path) + remove(path) + + # copy mozbase to m-c + for path in os.listdir(src): + call(['cp', '-r', path, here], cwd=src) + + # generate the diff and write to output file + call(['hg', 'addremove'], cwd=hg_root) + process = subprocess.Popen(['hg', 'diff'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + cwd=hg_root) + stdout, stderr = process.communicate() + with file(output, 'w') as f: + f.write(stdout) + f.close() + + # ensure that the diff you just wrote isn't deleted + untracked.append(os.path.abspath(output)) + + finally: + # cleanup + revert(hg_root, untracked) + shutil.rmtree(tempdir) + + print "Diff at %s" % output + +if __name__ == '__main__': + main() diff --git a/testing/xpcshell/xpcshell.ini b/testing/xpcshell/xpcshell.ini index 29def8dabb7f..ad415cf5d60a 100644 --- a/testing/xpcshell/xpcshell.ini +++ b/testing/xpcshell/xpcshell.ini @@ -47,6 +47,7 @@ skip-if = os == "android" [include:toolkit/components/startup/tests/unit/xpcshell.ini] [include:toolkit/components/telemetry/tests/unit/xpcshell.ini] [include:toolkit/components/social/test/xpcshell/xpcshell.ini] +[include:toolkit/components/mediasniffer/test/unit/xpcshell.ini] [include:toolkit/content/tests/unit/xpcshell.ini] [include:toolkit/identity/tests/unit/xpcshell.ini] [include:toolkit/mozapps/downloads/tests/unit/xpcshell.ini] diff --git a/toolkit/components/mediasniffer/Makefile.in b/toolkit/components/mediasniffer/Makefile.in index 738ba006da8c..05e758668b9e 100644 --- a/toolkit/components/mediasniffer/Makefile.in +++ b/toolkit/components/mediasniffer/Makefile.in @@ -26,5 +26,7 @@ EXPORTS = \ nsMediaSniffer.h \ $(NULL) +TEST_DIRS += test + include $(topsrcdir)/config/config.mk include $(topsrcdir)/config/rules.mk diff --git a/toolkit/components/mediasniffer/test/Makefile.in b/toolkit/components/mediasniffer/test/Makefile.in new file mode 100644 index 000000000000..2693f26112da --- /dev/null +++ b/toolkit/components/mediasniffer/test/Makefile.in @@ -0,0 +1,17 @@ +# 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/. + +DEPTH = @DEPTH@ +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ +relativesrcdir = @relativesrcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = test_mediasniffer + +XPCSHELL_TESTS = unit + +include $(topsrcdir)/config/rules.mk diff --git a/toolkit/components/mediasniffer/test/unit/test_mediasniffer.js b/toolkit/components/mediasniffer/test/unit/test_mediasniffer.js new file mode 100644 index 000000000000..fa489a9d1513 --- /dev/null +++ b/toolkit/components/mediasniffer/test/unit/test_mediasniffer.js @@ -0,0 +1,97 @@ +/* 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/. */ + +const Ci = Components.interfaces; +const Cu = Components.utils; + +Cu.import("resource://testing-common/httpd.js"); + +const PATH = "/file.meh"; +var httpserver = new HttpServer(); + +// Each time, the data consist in a string that should be sniffed as Ogg. +const data = "OggS\0meeeh."; +var testRan = 0; + +// If the content-type is not present, or if it's application/octet-stream, it +// should be sniffed to application/ogg by the media sniffer. Otherwise, it +// should not be changed. +const tests = [ + // Those three first case are the case of a media loaded in a media element. + // The first two should be sniffeed. + { contentType: "", + expectedContentType: "application/ogg", + flags: Ci.nsIChannel.LOAD_TREAT_APPLICATION_OCTET_STREAM_AS_UNKNOWN }, + { contentType: "application/octet-stream", + expectedContentType: "application/ogg", + flags: Ci.nsIChannel.LOAD_TREAT_APPLICATION_OCTET_STREAM_AS_UNKNOWN }, + { contentType: "application/something", + expectedContentType: "application/something", + flags: Ci.nsIChannel.LOAD_TREAT_APPLICATION_OCTET_STREAM_AS_UNKNOWN }, + // This last case tests the case of a channel opened while allowing content + // sniffers to override the content-type, like in the docshell. + { contentType: "application/octet-stream", + expectedContentType: "application/ogg", + flags: Ci.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS }, + { contentType: "", + expectedContentType: "application/octet-stream", + flags: Ci.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS }, +]; + +// A basic listener that reads checks the if we sniffed properly. +var listener = { + onStartRequest: function(request, context) { + do_check_eq(request.QueryInterface(Ci.nsIChannel).contentType, + tests[testRan].expectedContentType); + }, + + onDataAvailable: function(request, context, stream, offset, count) { + try { + var bis = Components.classes["@mozilla.org/binaryinputstream;1"] + .createInstance(Components.interfaces.nsIBinaryInputStream); + bis.setInputStream(stream); + bis.readByteArray(bis.available()); + } catch (ex) { + do_throw("Error in onDataAvailable: " + ex); + } + }, + + onStopRequest: function(request, context, status) { + testRan++; + runNext(); + } +}; + +function setupChannel(url, flags) +{ + var ios = Components.classes["@mozilla.org/network/io-service;1"]. + getService(Ci.nsIIOService); + var chan = ios.newChannel("http://localhost:4444" + url, "", null); + chan.loadFlags |= flags; + var httpChan = chan.QueryInterface(Components.interfaces.nsIHttpChannel); + return httpChan; +} + +function runNext() { + if (testRan == tests.length) { + do_test_finished(); + return; + } + var channel = setupChannel(PATH, tests[testRan].flags); + httpserver.registerPathHandler(PATH, function(request, response) { + response.setHeader("Content-Type", tests[testRan].contentType, false); + response.bodyOutputStream.write(data, data.length); + }); + channel.asyncOpen(listener, channel, null); +} + +function run_test() { + httpserver.start(4444); + do_test_pending(); + try { + runNext(); + } catch (e) { + print("ERROR - " + e + "\n"); + } +} diff --git a/toolkit/components/mediasniffer/test/unit/xpcshell.ini b/toolkit/components/mediasniffer/test/unit/xpcshell.ini new file mode 100644 index 000000000000..756377bc3350 --- /dev/null +++ b/toolkit/components/mediasniffer/test/unit/xpcshell.ini @@ -0,0 +1,5 @@ +[DEFAULT] +head = +tail = + +[test_mediasniffer.js] diff --git a/toolkit/components/passwordmgr/test/test_bug_627616.html b/toolkit/components/passwordmgr/test/test_bug_627616.html index 7b498bfdfac5..c0e7eaeeb893 100644 --- a/toolkit/components/passwordmgr/test/test_bug_627616.html +++ b/toolkit/components/passwordmgr/test/test_bug_627616.html @@ -15,13 +15,33 @@ testNum = 1; var login, login2; - function init() { + + var resolveCallback = { + + QueryInterface : function (iid) { + const interfaces = [Ci.nsIProtocolProxyCallback, Ci.nsISupports]; + + if (!interfaces.some( function(v) { return iid.equals(v) } )) + throw Components.results.NS_ERROR_NO_INTERFACE; + return this; + }, + + onProxyAvailable : function (req, uri, pi, status) { + init2(SpecialPowers.wrap(pi).host, SpecialPowers.wrap(pi).port); + } + }; + + function init1() { var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); var pps = Cc["@mozilla.org/network/protocol-proxy-service;1"].getService(); var uri = ios.newURI("http://example.com", null, null); - var pi = pps.resolve(uri, 0); - var mozproxy = "moz-proxy://" + pi.host + ":" + pi.port; + pps.asyncResolve(uri, 0, resolveCallback); + } + + function init2(proxyHost, proxyPort) { + + var mozproxy = "moz-proxy://" + proxyHost + ":" + proxyPort; var pwmgr = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager); login = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance(Ci.nsILoginInfo); @@ -96,7 +116,7 @@ var pendingTests = [{expectedDialogs: 2, test: testNonAnonymousCredentials}, {expectedDialogs: 1, test: testAnonymousCredentials}, {expectedDialogs: 0, test: testAnonymousNoAuth}]; - init(); + init1(); runNextTest(); function handleDialog(doc, testNum) diff --git a/toolkit/components/passwordmgr/test/test_prompt.html b/toolkit/components/passwordmgr/test/test_prompt.html index 3517865385bd..26ce43c5d47a 100644 --- a/toolkit/components/passwordmgr/test/test_prompt.html +++ b/toolkit/components/passwordmgr/test/test_prompt.html @@ -23,19 +23,16 @@ Login Manager test: username/password prompts var pwmgr, ioService var tmplogin, login1, login2A, login2B, login2C, login2D, login2E, login3A, login3B, login4, proxyLogin; var mozproxy, proxiedHost = "http://mochi.test:8888"; +var testNum = 1; -function initLogins() { +function initLogins(pi) { pwmgr = Cc["@mozilla.org/login-manager;1"]. getService(Ci.nsILoginManager); ioService = Cc["@mozilla.org/network/io-service;1"]. getService(Ci.nsIIOService); - // Figure out what our proxy is set to -- can't just hardcode this, because - // mobile platforms don't use localhost. - var pps = Cc["@mozilla.org/network/protocol-proxy-service;1"].getService(); - var uri = ioService.newURI(proxiedHost, null, null); - var pi = pps.resolve(uri, 0); - mozproxy = "moz-proxy://" + pi.host + ":" + pi.port; + mozproxy = "moz-proxy://" + SpecialPowers.wrap(pi).host + ":" + + SpecialPowers.wrap(pi).port; tmpLogin = Cc["@mozilla.org/login-manager/loginInfo;1"]. createInstance(Ci.nsILoginInfo); @@ -124,6 +121,35 @@ ok(true, "whee, done!"); SimpleTest.finish(); } +var resolveCallback = { +QueryInterface : function (iid) { +const interfaces = [Ci.nsIProtocolProxyCallback, Ci.nsISupports]; + + if (!interfaces.some( function(v) { return iid.equals(v) } )) + throw Components.results.NS_ERROR_NO_INTERFACE; + return this; +}, + + onProxyAvailable : function (req, uri, pi, status) { + initLogins(pi); + doTests(); + } +}; + +function startup() { + //need to allow for arbitrary network servers defined in PAC instead of a hardcoded moz-proxy. + var ios = SpecialPowers.wrap(Components) + .classes["@mozilla.org/network/io-service;1"] + .getService(Components.interfaces.nsIIOService); + + var pps = SpecialPowers.wrap(Components) + .classes["@mozilla.org/network/protocol-proxy-service;1"] + .getService(); + + var uri = ios.newURI("http://example.com", null, null); + pps.asyncResolve(uri, 0, resolveCallback); +} + function addNotificationCallback(cb) { storageObserver.notificationCallbacks.push(cb); @@ -569,8 +595,9 @@ dumpNotifications(); } -initLogins(); +startup(); +function doTests() { var authinfo = { username : "", password : "", @@ -624,7 +651,7 @@ var popupNotifications = getPopupNotifications(window.top); ok(popupNotifications, "Got popupNotifications"); // ===== test 1 ===== -var testNum = 1; +testNum = 1; startCallbackTimer(); isOk = prompter1.prompt(dialogTitle(), dialogText, "http://example.com", Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, "abc", result); @@ -1136,6 +1163,7 @@ iframe.src = "authenticate.sjs?user=mochiuser1&pass=mochipass1"; // ...remaining tests are driven by handleLoad()... SimpleTest.waitForExplicitFinish(); +} diff --git a/toolkit/components/passwordmgr/test/test_prompt_async.html b/toolkit/components/passwordmgr/test/test_prompt_async.html index a7298c4ff2ac..37ef926a99b8 100644 --- a/toolkit/components/passwordmgr/test/test_prompt_async.html +++ b/toolkit/components/passwordmgr/test/test_prompt_async.html @@ -69,7 +69,7 @@ var pwmgr, logins = []; - function initLogins() { + function initLogins(pi) { pwmgr = SpecialPowers.wrap(Components) .classes["@mozilla.org/login-manager;1"] .getService(Ci.nsILoginManager); @@ -83,18 +83,9 @@ logins.push(login); } - //need to allow for arbitrary network servers defined in PAC instead of a hardcoded moz-proxy. - var ios = SpecialPowers.wrap(Components) - .classes["@mozilla.org/network/io-service;1"] - .getService(Components.interfaces.nsIIOService); - - var pps = SpecialPowers.wrap(Components) - .classes["@mozilla.org/network/protocol-proxy-service;1"] - .getService(); - - var uri = ios.newURI("http://example.com", null, null); - var pi = pps.resolve(uri, 0); - var mozproxy = "moz-proxy://" + pi.host + ":" + pi.port; + var mozproxy = "moz-proxy://" + + SpecialPowers.wrap(pi).host + ":" + + SpecialPowers.wrap(pi).port; addLogin(mozproxy, "proxy_realm", "proxy_user", "proxy_pass"); @@ -134,6 +125,34 @@ SimpleTest.finish(); } + var resolveCallback = { + QueryInterface : function (iid) { + const interfaces = [Ci.nsIProtocolProxyCallback, Ci.nsISupports]; + + if (!interfaces.some( function(v) { return iid.equals(v) } )) + throw Components.results.NS_ERROR_NO_INTERFACE; + return this; + }, + + onProxyAvailable : function (req, uri, pi, status) { + initLogins(pi); + doTest(testNum); + } + }; + + function startup() { + //need to allow for arbitrary network servers defined in PAC instead of a hardcoded moz-proxy. + var ios = SpecialPowers.wrap(Components) + .classes["@mozilla.org/network/io-service;1"] + .getService(Components.interfaces.nsIIOService); + + var pps = SpecialPowers.wrap(Components) + .classes["@mozilla.org/network/protocol-proxy-service;1"] + .getService(); + + var uri = ios.newURI("http://example.com", null, null); + pps.asyncResolve(uri, 0, resolveCallback); + } // --------------- Test loop spin ---------------- var testNum = 1; @@ -148,8 +167,7 @@ iframe2a.onload = onFrameLoad; iframe2b.onload = onFrameLoad; - initLogins(); - doTest(testNum); + startup(); } var expectedLoads; diff --git a/toolkit/components/satchel/test/Makefile.in b/toolkit/components/satchel/test/Makefile.in index a1b3b96f67b0..9c9007d991a4 100644 --- a/toolkit/components/satchel/test/Makefile.in +++ b/toolkit/components/satchel/test/Makefile.in @@ -19,6 +19,7 @@ XPCSHELL_TESTS = \ MOCHITEST_FILES = \ test_bug_511615.html \ + test_bug_787624.html \ test_form_autocomplete.html \ test_form_autocomplete_with_list.html \ test_form_submission.html \ diff --git a/toolkit/components/satchel/test/test_bug_787624.html b/toolkit/components/satchel/test/test_bug_787624.html new file mode 100644 index 000000000000..1d0e1317e068 --- /dev/null +++ b/toolkit/components/satchel/test/test_bug_787624.html @@ -0,0 +1,184 @@ + + + + Test for Layout of Form History Autocomplete: Bug 787624 + + + + + + + +Form History Layout test: form field autocomplete: Bug 787624 +

      + + +
      + +
      + +
      + + +
      +
      +
      + + +
      +
      +
      +
      + +
      +
      +
      + + diff --git a/toolkit/system/osxproxy/nsOSXSystemProxySettings.mm b/toolkit/system/osxproxy/nsOSXSystemProxySettings.mm index a725bf211cee..8c66003c2388 100644 --- a/toolkit/system/osxproxy/nsOSXSystemProxySettings.mm +++ b/toolkit/system/osxproxy/nsOSXSystemProxySettings.mm @@ -34,7 +34,7 @@ public: nsresult GetAutoconfigURL(nsAutoCString& aResult) const; // Find the SystemConfiguration proxy & port for a given URI - nsresult FindSCProxyPort(nsIURI* aURI, nsACString& aResultHost, int32_t& aResultPort, bool& aResultSocksProxy); + nsresult FindSCProxyPort(const nsACString &aScheme, nsACString& aResultHost, int32_t& aResultPort, bool& aResultSocksProxy); // is host:port on the proxy exception list? bool IsInExceptionList(const nsACString& aHost) const; @@ -58,7 +58,14 @@ private: static const SchemeMapping gSchemeMappingList[]; }; -NS_IMPL_ISUPPORTS1(nsOSXSystemProxySettings, nsISystemProxySettings) +NS_IMPL_THREADSAFE_ISUPPORTS1(nsOSXSystemProxySettings, nsISystemProxySettings) + +NS_IMETHODIMP +nsOSXSystemProxySettings::GetMainThreadOnly(bool *aMainThreadOnly) +{ + *aMainThreadOnly = false; + return NS_OK; +} // Mapping of URI schemes to SystemConfiguration keys const nsOSXSystemProxySettings::SchemeMapping nsOSXSystemProxySettings::gSchemeMappingList[] = { @@ -156,7 +163,7 @@ nsOSXSystemProxySettings::ProxyHasChanged() } nsresult -nsOSXSystemProxySettings::FindSCProxyPort(nsIURI* aURI, nsACString& aResultHost, int32_t& aResultPort, bool& aResultSocksProxy) +nsOSXSystemProxySettings::FindSCProxyPort(const nsACString &aScheme, nsACString& aResultHost, int32_t& aResultPort, bool& aResultSocksProxy) { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; @@ -164,8 +171,8 @@ nsOSXSystemProxySettings::FindSCProxyPort(nsIURI* aURI, nsACString& aResultHost, for (const SchemeMapping* keys = gSchemeMappingList; keys->mScheme != NULL; ++keys) { // Check for matching scheme (when appropriate) - bool res; - if ((NS_FAILED(aURI->SchemeIs(keys->mScheme, &res)) || !res) && !keys->mIsSocksProxy) + if (strcasecmp(keys->mScheme, PromiseFlatCString(aScheme).get()) && + !keys->mIsSocksProxy) continue; // Check the proxy is enabled @@ -303,20 +310,20 @@ nsOSXSystemProxySettings::GetPACURI(nsACString& aResult) } nsresult -nsOSXSystemProxySettings::GetProxyForURI(nsIURI* aURI, nsACString& aResult) +nsOSXSystemProxySettings::GetProxyForURI(const nsACString & aSpec, + const nsACString & aScheme, + const nsACString & aHost, + const int32_t aPort, + nsACString & aResult) { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; - nsAutoCString host; - nsresult rv = aURI->GetHost(host); - NS_ENSURE_SUCCESS(rv, rv); - int32_t proxyPort; nsAutoCString proxyHost; bool proxySocks; - rv = FindSCProxyPort(aURI, proxyHost, proxyPort, proxySocks); + nsresult rv = FindSCProxyPort(aScheme, proxyHost, proxyPort, proxySocks); - if (NS_FAILED(rv) || IsInExceptionList(host)) { + if (NS_FAILED(rv) || IsInExceptionList(aHost)) { aResult.AssignLiteral("DIRECT"); } else if (proxySocks) { aResult.Assign(NS_LITERAL_CSTRING("SOCKS ") + proxyHost + nsPrintfCString(":%d", proxyPort)); diff --git a/toolkit/system/unixproxy/nsLibProxySettings.cpp b/toolkit/system/unixproxy/nsLibProxySettings.cpp index c6b181b2a138..76137b818fb6 100644 --- a/toolkit/system/unixproxy/nsLibProxySettings.cpp +++ b/toolkit/system/unixproxy/nsLibProxySettings.cpp @@ -6,7 +6,6 @@ #include "nsISystemProxySettings.h" #include "mozilla/ModuleUtils.h" #include "nsIServiceManager.h" -#include "nsIIOService.h" #include "nsIURI.h" #include "nsString.h" #include "nsNetUtil.h" @@ -34,7 +33,14 @@ private: pxProxyFactory *mProxyFactory; }; -NS_IMPL_ISUPPORTS1(nsUnixSystemProxySettings, nsISystemProxySettings) +NS_IMPL_THREADSAFE_ISUPPORTS1(nsUnixSystemProxySettings, nsISystemProxySettings) + +NS_IMETHODIMP +nsUnixSystemProxySettings::GetMainThreadOnly(bool *aMainThreadOnly) +{ + *aMainThreadOnly = false; + return NS_OK; +} nsresult nsUnixSystemProxySettings::Init() @@ -51,7 +57,11 @@ nsUnixSystemProxySettings::GetPACURI(nsACString& aResult) } nsresult -nsUnixSystemProxySettings::GetProxyForURI(nsIURI* aURI, nsACString& aResult) +nsUnixSystemProxySettings::GetProxyForURI(const nsACString & aSpec, + const nsACString & aScheme, + const nsACString & aHost, + const int32_t aPort, + nsACString & aResult) { nsresult rv; @@ -60,15 +70,9 @@ nsUnixSystemProxySettings::GetProxyForURI(nsIURI* aURI, nsACString& aResult) } NS_ENSURE_TRUE(mProxyFactory, NS_ERROR_NOT_AVAILABLE); - nsCOMPtr ios = do_GetIOService(&rv); - NS_ENSURE_SUCCESS(rv, rv); - - nsAutoCString spec; - rv = aURI->GetSpec(spec); - NS_ENSURE_SUCCESS(rv, rv); - char **proxyArray = nullptr; - proxyArray = px_proxy_factory_get_proxies(mProxyFactory, (char*)(spec.get())); + proxyArray = px_proxy_factory_get_proxies(mProxyFactory, + PromiseFlatCString(aSpec).get()); NS_ENSURE_TRUE(proxyArray, NS_ERROR_NOT_AVAILABLE); // Translate libproxy's output to PAC string as expected @@ -78,45 +82,34 @@ nsUnixSystemProxySettings::GetProxyForURI(nsIURI* aURI, nsACString& aResult) // direct:// // // PAC format: "PROXY proxy1.foo.com:8080; PROXY proxy2.foo.com:8080; DIRECT" + // but nsISystemProxySettings allows "PROXY http://proxy.foo.com:8080" as well. + int c = 0; while (proxyArray[c] != NULL) { if (!aResult.IsEmpty()) { aResult.AppendLiteral("; "); } - bool isScheme = false; - nsXPIDLCString schemeString; - nsXPIDLCString hostPortString; - nsCOMPtr proxyURI; - - rv = ios->NewURI(nsDependentCString(proxyArray[c]), - nullptr, - nullptr, - getter_AddRefs(proxyURI)); - if (NS_FAILED(rv)) { + // figure out the scheme, and we can't use nsIIOService::NewURI because + // this is not the main thread. + char *colon = strchr (proxyArray[c], ':'); + uint32_t schemelen = colon ? colon - proxyArray[c] : 0; + if (schemelen < 1) { c++; continue; } - proxyURI->GetScheme(schemeString); - if (NS_SUCCEEDED(proxyURI->SchemeIs("http", &isScheme)) && isScheme) { - schemeString.AssignLiteral("proxy"); + if (schemelen == 6 && !strncasecmp(proxyArray[c], "direct", 6)) { + aResult.AppendLiteral("DIRECT"); } - aResult.Append(schemeString); - if (NS_SUCCEEDED(proxyURI->SchemeIs("direct", &isScheme)) && !isScheme) { - // Add the proxy URI only if it's not DIRECT - proxyURI->GetHostPort(hostPortString); - aResult.AppendLiteral(" "); - aResult.Append(hostPortString); + else { + aResult.AppendLiteral("PROXY "); + aResult.Append(proxyArray[c]); } c++; } -#ifdef DEBUG - printf("returned PAC proxy string: %s\n", PromiseFlatCString(aResult).get()); -#endif - PR_Free(proxyArray); return NS_OK; } diff --git a/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp b/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp index 97d058cbec62..6322768a5618 100644 --- a/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp +++ b/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp @@ -18,6 +18,7 @@ #include "nsIGSettingsService.h" #include "nsInterfaceHashtable.h" #include "mozilla/Attributes.h" +#include "nsIURI.h" class nsUnixSystemProxySettings MOZ_FINAL : public nsISystemProxySettings { public: @@ -43,6 +44,14 @@ private: NS_IMPL_ISUPPORTS1(nsUnixSystemProxySettings, nsISystemProxySettings) +NS_IMETHODIMP +nsUnixSystemProxySettings::GetMainThreadOnly(bool *aMainThreadOnly) +{ + // dbus prevents us from being threadsafe, but this routine should not block anyhow + *aMainThreadOnly = true; + return NS_OK; +} + nsresult nsUnixSystemProxySettings::Init() { @@ -151,8 +160,10 @@ static void SetProxyResult(const char* aType, const nsACString& aHost, aResult.AppendASCII(aType); aResult.Append(' '); aResult.Append(aHost); - aResult.Append(':'); - aResult.Append(nsPrintfCString("%d", aPort)); + if (aPort > 0) { + aResult.Append(':'); + aResult.Append(nsPrintfCString("%d", aPort)); + } } static nsresult @@ -481,29 +492,21 @@ nsUnixSystemProxySettings::GetProxyFromGSettings(const nsACString& aScheme, } nsresult -nsUnixSystemProxySettings::GetProxyForURI(nsIURI* aURI, nsACString& aResult) +nsUnixSystemProxySettings::GetProxyForURI(const nsACString & aSpec, + const nsACString & aScheme, + const nsACString & aHost, + const int32_t aPort, + nsACString & aResult) { - nsAutoCString scheme; - nsresult rv = aURI->GetScheme(scheme); - NS_ENSURE_SUCCESS(rv, rv); - - nsAutoCString host; - rv = aURI->GetHost(host); - NS_ENSURE_SUCCESS(rv, rv); - - int32_t port; - rv = aURI->GetPort(&port); - NS_ENSURE_SUCCESS(rv, rv); - if (mProxySettings) { - rv = GetProxyFromGSettings(scheme, host, port, aResult); - if (rv == NS_OK) + nsresult rv = GetProxyFromGSettings(aScheme, aHost, aPort, aResult); + if (NS_SUCCEEDED(rv)) return rv; } if (mGConf) - return GetProxyFromGConf(scheme, host, port, aResult); + return GetProxyFromGConf(aScheme, aHost, aPort, aResult); - return GetProxyFromEnvironment(scheme, host, port, aResult); + return GetProxyFromEnvironment(aScheme, aHost, aPort, aResult); } #define NS_UNIXSYSTEMPROXYSERVICE_CID /* 0fa3158c-d5a7-43de-9181-a285e74cf1d4 */\ diff --git a/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp b/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp index bf379ff55ef9..87c133f3488c 100644 --- a/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp +++ b/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp @@ -32,7 +32,15 @@ private: bool PatternMatch(const nsACString& aHost, const nsACString& aOverride); }; -NS_IMPL_ISUPPORTS1(nsWindowsSystemProxySettings, nsISystemProxySettings) +NS_IMPL_THREADSAFE_ISUPPORTS1(nsWindowsSystemProxySettings, nsISystemProxySettings) + +NS_IMETHODIMP +nsWindowsSystemProxySettings::GetMainThreadOnly(bool *aMainThreadOnly) +{ + *aMainThreadOnly = false; + return NS_OK; +} + nsresult nsWindowsSystemProxySettings::Init() @@ -40,33 +48,12 @@ nsWindowsSystemProxySettings::Init() return NS_OK; } -static void SetProxyResult(const char* aType, const nsACString& aHost, - int32_t aPort, nsACString& aResult) -{ - aResult.AssignASCII(aType); - aResult.Append(' '); - aResult.Append(aHost); - aResult.Append(':'); - aResult.Append(nsPrintfCString("%d", aPort)); -} - static void SetProxyResult(const char* aType, const nsACString& aHostPort, nsACString& aResult) { - nsCOMPtr uri; - nsAutoCString host; - int32_t port; - - // Try parsing it as a URI. - if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), aHostPort)) && - NS_SUCCEEDED(uri->GetHost(host)) && !host.IsEmpty() && - NS_SUCCEEDED(uri->GetPort(&port))) { - SetProxyResult(aType, host, port, aResult); - } else { - aResult.AssignASCII(aType); - aResult.Append(' '); - aResult.Append(aHostPort); - } + aResult.AssignASCII(aType); + aResult.Append(' '); + aResult.Append(aHostPort); } static void SetProxyResultDirect(nsACString& aResult) @@ -222,7 +209,11 @@ nsWindowsSystemProxySettings::GetPACURI(nsACString& aResult) } nsresult -nsWindowsSystemProxySettings::GetProxyForURI(nsIURI* aURI, nsACString& aResult) +nsWindowsSystemProxySettings::GetProxyForURI(const nsACString & aSpec, + const nsACString & aScheme, + const nsACString & aHost, + const int32_t aPort, + nsACString & aResult) { nsresult rv; uint32_t flags = 0; @@ -234,15 +225,7 @@ nsWindowsSystemProxySettings::GetProxyForURI(nsIURI* aURI, nsACString& aResult) return NS_OK; } - nsAutoCString scheme; - rv = aURI->GetScheme(scheme); - NS_ENSURE_SUCCESS(rv, rv); - - nsAutoCString host; - rv = aURI->GetHost(host); - NS_ENSURE_SUCCESS(rv, rv); - - if (MatchOverride(host)) { + if (MatchOverride(aHost)) { SetProxyResultDirect(aResult); return NS_OK; } @@ -250,7 +233,7 @@ nsWindowsSystemProxySettings::GetProxyForURI(nsIURI* aURI, nsACString& aResult) NS_ConvertUTF16toUTF8 cbuf(buf); nsAutoCString prefix; - ToLowerCase(scheme, prefix); + ToLowerCase(aScheme, prefix); prefix.Append('='); diff --git a/tools/trace-malloc/lib/nsTraceMalloc.c b/tools/trace-malloc/lib/nsTraceMalloc.c index 19e19a8eb60b..310299c0a2c0 100644 --- a/tools/trace-malloc/lib/nsTraceMalloc.c +++ b/tools/trace-malloc/lib/nsTraceMalloc.c @@ -1053,7 +1053,7 @@ static void alloc_freeentry(void *pool, PLHashEntry *he, unsigned flag) if (flag != HT_FREE_ENTRY) return; alloc = (allocation*) he; - if ((PRUptrdiff)(alloc - alloc_heap) < (PRUptrdiff)ALLOC_HEAP_SIZE) { + if ((ptrdiff_t)(alloc - alloc_heap) < (ptrdiff_t)ALLOC_HEAP_SIZE) { alloc->entry.next = &alloc_freelist->entry; alloc_freelist = alloc; } else { diff --git a/widget/gtk2/gtk2compat.h b/widget/gtk2/gtk2compat.h index 766c6514d2f3..a77f2ed5cc45 100644 --- a/widget/gtk2/gtk2compat.h +++ b/widget/gtk2/gtk2compat.h @@ -177,6 +177,20 @@ gtk_window_group_get_current_grab(GtkWindowGroup *window_group) return GTK_WIDGET(window_group->grabs->data); } + +static inline GList * +gdk_drag_context_list_targets(GdkDragContext *context) +{ + return context->targets; +} +#endif + +#if !GTK_CHECK_VERSION(2, 23, 3) +static inline GdkWindow * +gdk_drag_context_get_dest_window(GdkDragContext *context) +{ + return context->dest_window; +} #endif #if !GTK_CHECK_VERSION(2, 24, 0) diff --git a/widget/gtk2/nsBidiKeyboard.cpp b/widget/gtk2/nsBidiKeyboard.cpp index 460521904e72..6e68704e4bde 100644 --- a/widget/gtk2/nsBidiKeyboard.cpp +++ b/widget/gtk2/nsBidiKeyboard.cpp @@ -10,38 +10,40 @@ #include "nsBidiKeyboard.h" #include - -static PRLibrary *gtklib = nullptr; - +#if (MOZ_WIDGET_GTK == 2) typedef gboolean (*GdkKeymapHaveBidiLayoutsType)(GdkKeymap *keymap); static GdkKeymapHaveBidiLayoutsType GdkKeymapHaveBidiLayouts = nullptr; - +#endif NS_IMPL_ISUPPORTS1(nsBidiKeyboard, nsIBidiKeyboard) nsBidiKeyboard::nsBidiKeyboard() { +#if (MOZ_WIDGET_GTK == 2) + PRLibrary *gtklib = nullptr; #if defined(MOZ_X11) - if (!gtklib) - gtklib = PR_LoadLibrary("libgtk-x11-2.0.so.0"); -#else - return; + if (!GdkKeymapHaveBidiLayouts) { + GdkKeymapHaveBidiLayouts = (GdkKeymapHaveBidiLayoutsType) + PR_FindFunctionSymbolAndLibrary("gdk_keymap_have_bidi_layouts", + >klib); + if (gtklib) + PR_UnloadLibrary(gtklib); + } #endif - if (gtklib && !GdkKeymapHaveBidiLayouts) - GdkKeymapHaveBidiLayouts = (GdkKeymapHaveBidiLayoutsType) PR_FindFunctionSymbol(gtklib, "gdk_keymap_have_bidi_layouts"); - - SetHaveBidiKeyboards(); + mHaveBidiKeyboards = false; + if (GdkKeymapHaveBidiLayouts) + mHaveBidiKeyboards = (*GdkKeymapHaveBidiLayouts)(NULL); +#else + mHaveBidiKeyboards = gdk_keymap_have_bidi_layouts(gdk_keymap_get_default()); +#endif } nsBidiKeyboard::~nsBidiKeyboard() { - if (gtklib) { - PR_UnloadLibrary(gtklib); - gtklib = nullptr; - - GdkKeymapHaveBidiLayouts = nullptr; - } +#if (MOZ_WIDGET_GTK == 2) + GdkKeymapHaveBidiLayouts = nullptr; +#endif } NS_IMETHODIMP @@ -50,20 +52,7 @@ nsBidiKeyboard::IsLangRTL(bool *aIsRTL) if (!mHaveBidiKeyboards) return NS_ERROR_FAILURE; - *aIsRTL = (gdk_keymap_get_direction(NULL) == PANGO_DIRECTION_RTL); - - return NS_OK; -} - -nsresult -nsBidiKeyboard::SetHaveBidiKeyboards() -{ - mHaveBidiKeyboards = false; - - if (!gtklib || !GdkKeymapHaveBidiLayouts) - return NS_ERROR_FAILURE; - - mHaveBidiKeyboards = (*GdkKeymapHaveBidiLayouts)(NULL); + *aIsRTL = (gdk_keymap_get_direction(gdk_keymap_get_default()) == PANGO_DIRECTION_RTL); return NS_OK; } diff --git a/widget/gtk2/nsBidiKeyboard.h b/widget/gtk2/nsBidiKeyboard.h index ebc239d11148..08c02f354b5e 100644 --- a/widget/gtk2/nsBidiKeyboard.h +++ b/widget/gtk2/nsBidiKeyboard.h @@ -21,7 +21,6 @@ protected: virtual ~nsBidiKeyboard(); bool mHaveBidiKeyboards; - nsresult SetHaveBidiKeyboards(); }; #endif // __nsBidiKeyboard diff --git a/widget/gtk2/nsClipboard.cpp b/widget/gtk2/nsClipboard.cpp index 1eaabb8c408e..36a3adf54432 100644 --- a/widget/gtk2/nsClipboard.cpp +++ b/widget/gtk2/nsClipboard.cpp @@ -31,6 +31,10 @@ #include #include +#if (MOZ_WIDGET_GTK == 2) +#include "gtk2compat.h" +#endif + using namespace mozilla; // Callback when someone asks us for the data @@ -331,8 +335,10 @@ nsClipboard::GetData(nsITransferable *aTransferable, int32_t aWhichClipboard) continue; nsCOMPtr byteStream; - NS_NewByteInputStream(getter_AddRefs(byteStream), (const char*)selectionData->data, - selectionData->length, NS_ASSIGNMENT_COPY); + NS_NewByteInputStream(getter_AddRefs(byteStream), + (const char*)gtk_selection_data_get_data(selectionData), + gtk_selection_data_get_length(selectionData), + NS_ASSIGNMENT_COPY); aTransferable->SetTransferData(flavorStr, byteStream, sizeof(nsIInputStream*)); gtk_selection_data_free(selectionData); return NS_OK; @@ -344,13 +350,14 @@ nsClipboard::GetData(nsITransferable *aTransferable, int32_t aWhichClipboard) GtkSelectionData *selectionData; selectionData = wait_for_contents(clipboard, atom); if (selectionData) { - length = selectionData->length; + const guchar *clipboardData = gtk_selection_data_get_data(selectionData); + length = gtk_selection_data_get_length(selectionData); // Special case text/html since we can convert into UCS2 if (!strcmp(flavorStr, kHTMLMime)) { PRUnichar* htmlBody= nullptr; int32_t htmlBodyLen = 0; // Convert text/html into our unicode format - ConvertHTMLtoUCS2((guchar *)selectionData->data, length, + ConvertHTMLtoUCS2(const_cast(clipboardData), length, &htmlBody, htmlBodyLen); // Try next data format? if (!htmlBodyLen) @@ -361,7 +368,7 @@ nsClipboard::GetData(nsITransferable *aTransferable, int32_t aWhichClipboard) data = (guchar *)nsMemory::Alloc(length); if (!data) break; - memcpy(data, selectionData->data, length); + memcpy(data, clipboardData, length); } foundData = true; foundFlavor = flavorStr; @@ -513,9 +520,10 @@ nsClipboard::SelectionGetEvent(GtkClipboard *aClipboard, int32_t whichClipboard; // which clipboard? - if (aSelectionData->selection == GDK_SELECTION_PRIMARY) + GdkAtom selection = gtk_selection_data_get_selection(aSelectionData); + if (selection == GDK_SELECTION_PRIMARY) whichClipboard = kSelectionClipboard; - else if (aSelectionData->selection == GDK_SELECTION_CLIPBOARD) + else if (selection == GDK_SELECTION_CLIPBOARD) whichClipboard = kGlobalClipboard; else return; // THAT AIN'T NO CLIPBOARD I EVER HEARD OF @@ -534,12 +542,15 @@ nsClipboard::SelectionGetEvent(GtkClipboard *aClipboard, nsCOMPtr item; uint32_t len; + + GdkAtom selectionTarget = gtk_selection_data_get_target(aSelectionData); + // Check to see if the selection data includes any of the string // types that we support. - if (aSelectionData->target == gdk_atom_intern ("STRING", FALSE) || - aSelectionData->target == gdk_atom_intern ("TEXT", FALSE) || - aSelectionData->target == gdk_atom_intern ("COMPOUND_TEXT", FALSE) || - aSelectionData->target == gdk_atom_intern ("UTF8_STRING", FALSE)) { + if (selectionTarget == gdk_atom_intern ("STRING", FALSE) || + selectionTarget == gdk_atom_intern ("TEXT", FALSE) || + selectionTarget == gdk_atom_intern ("COMPOUND_TEXT", FALSE) || + selectionTarget == gdk_atom_intern ("UTF8_STRING", FALSE)) { // Try to convert our internal type into a text string. Get // the transferable for this clipboard and try to get the // text/unicode type for it. @@ -567,7 +578,7 @@ nsClipboard::SelectionGetEvent(GtkClipboard *aClipboard, } // Check to see if the selection data is an image type - if (gtk_targets_include_image(&aSelectionData->target, 1, TRUE)) { + if (gtk_targets_include_image(&selectionTarget, 1, TRUE)) { // Look through our transfer data for the image static const char* const imageMimeTypes[] = { kNativeImageMime, kPNGImageMime, kJPEGImageMime, kJPGImageMime, kGIFImageMime }; @@ -598,7 +609,7 @@ nsClipboard::SelectionGetEvent(GtkClipboard *aClipboard, // Try to match up the selection data target to something our // transferable provides. - gchar *target_name = gdk_atom_name(aSelectionData->target); + gchar *target_name = gdk_atom_name(selectionTarget); if (!target_name) return; @@ -615,7 +626,7 @@ nsClipboard::SelectionGetEvent(GtkClipboard *aClipboard, if (primitive_data) { // Check to see if the selection data is text/html - if (aSelectionData->target == gdk_atom_intern (kHTMLMime, FALSE)) { + if (selectionTarget == gdk_atom_intern (kHTMLMime, FALSE)) { /* * "text/html" can be encoded UCS2. It is recommended that * documents transmitted as UCS2 always begin with a ZERO-WIDTH @@ -635,7 +646,7 @@ nsClipboard::SelectionGetEvent(GtkClipboard *aClipboard, len += sizeof(prefix); } - gtk_selection_data_set(aSelectionData, aSelectionData->target, + gtk_selection_data_set(aSelectionData, selectionTarget, 8, /* 8 bits in a unit */ (const guchar *)primitive_data, len); nsMemory::Free(primitive_data); @@ -816,7 +827,7 @@ DispatchSelectionNotifyEvent(GtkWidget *widget, XEvent *xevent) { GdkEvent event; event.selection.type = GDK_SELECTION_NOTIFY; - event.selection.window = widget->window; + event.selection.window = gtk_widget_get_window(widget); event.selection.selection = gdk_x11_xatom_to_atom(xevent->xselection.selection); event.selection.target = gdk_x11_xatom_to_atom(xevent->xselection.target); event.selection.property = gdk_x11_xatom_to_atom(xevent->xselection.property); @@ -828,10 +839,11 @@ DispatchSelectionNotifyEvent(GtkWidget *widget, XEvent *xevent) static void DispatchPropertyNotifyEvent(GtkWidget *widget, XEvent *xevent) { - if (((GdkWindowObject *) widget->window)->event_mask & GDK_PROPERTY_CHANGE_MASK) { + GdkWindow *window = gtk_widget_get_window(widget); + if ((gdk_window_get_events(window)) & GDK_PROPERTY_CHANGE_MASK) { GdkEvent event; event.property.type = GDK_PROPERTY_NOTIFY; - event.property.window = widget->window; + event.property.window = window; event.property.atom = gdk_x11_xatom_to_atom(xevent->xproperty.atom); event.property.time = xevent->xproperty.time; event.property.state = xevent->xproperty.state; @@ -855,7 +867,9 @@ checkEventProc(Display *display, XEvent *event, XPointer arg) (event->xany.type == PropertyNotify && event->xproperty.atom == context->selAtom)) { - GdkWindow *cbWindow = gdk_window_lookup(event->xany.window); + GdkWindow *cbWindow = + gdk_x11_window_lookup_for_display(gdk_x11_lookup_xdisplay(display), + event->xany.window); if (cbWindow) { GtkWidget *cbWidget = NULL; gdk_window_get_user_data(cbWindow, (gpointer *)&cbWidget); @@ -878,7 +892,7 @@ wait_for_retrieval(GtkClipboard *clipboard, retrieval_context *r_context) if (r_context->completed) // the request completed synchronously return true; - Display *xDisplay = GDK_DISPLAY(); + Display *xDisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()) ; checkEventContext context; context.cbWidget = NULL; context.selAtom = gdk_x11_atom_to_xatom(gdk_atom_intern("GDK_SELECTION", @@ -937,7 +951,7 @@ clipboard_contents_received(GtkClipboard *clipboard, context->completed = true; - if (selection_data->length >= 0) + if (gtk_selection_data_get_length(selection_data) >= 0) context->data = gtk_selection_data_copy(selection_data); } diff --git a/widget/gtk2/nsDeviceContextSpecG.h b/widget/gtk2/nsDeviceContextSpecG.h index b273718e55ef..e7823c70287f 100644 --- a/widget/gtk2/nsDeviceContextSpecG.h +++ b/widget/gtk2/nsDeviceContextSpecG.h @@ -16,8 +16,12 @@ #include "nsCRT.h" /* should be ? */ #include +#if (MOZ_WIDGET_GTK == 2) #include #include +#else +#include +#endif #define NS_PORTRAIT 0 #define NS_LANDSCAPE 1 diff --git a/widget/gtk2/nsDragService.cpp b/widget/gtk2/nsDragService.cpp index 78be20309d6f..d2deaf393b81 100644 --- a/widget/gtk2/nsDragService.cpp +++ b/widget/gtk2/nsDragService.cpp @@ -25,7 +25,7 @@ #include "nsCRT.h" #include "mozilla/Services.h" -#if defined(MOZ_WIDGET_GTK2) +#if (MOZ_WIDGET_GTK == 2) #include "gtk2compat.h" #endif @@ -351,7 +351,7 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, GdkEvent event; memset(&event, 0, sizeof(GdkEvent)); event.type = GDK_BUTTON_PRESS; - event.button.window = mHiddenWidget->window; + event.button.window = gtk_widget_get_window(mHiddenWidget); event.button.time = nsWindow::GetLastUserInputTime(); // Put the drag widget in the window group of the source node so that the @@ -362,6 +362,13 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, gtk_window_group_add_window(window_group, GTK_WINDOW(mHiddenWidget)); +#if (MOZ_WIDGET_GTK == 3) + // Get device for event source + GdkDisplay *display = gdk_display_get_default(); + GdkDeviceManager *device_manager = gdk_display_get_device_manager(display); + event.button.device = gdk_device_manager_get_client_pointer(device_manager); +#endif + // start our drag. GdkDragContext *context = gtk_drag_begin(mHiddenWidget, sourceList, @@ -402,6 +409,7 @@ nsDragService::SetAlphaPixmap(gfxASurface *aSurface, int32_t aYOffset, const nsIntRect& dragRect) { +#if (MOZ_WIDGET_GTK == 2) GdkScreen* screen = gtk_widget_get_screen(mHiddenWidget); // Transparent drag icons need, like a lot of transparency-related things, @@ -443,6 +451,10 @@ nsDragService::SetAlphaPixmap(gfxASurface *aSurface, aXOffset, aYOffset); g_object_unref(pixmap); return true; +#else + // TODO GTK3 + return false; +#endif } NS_IMETHODIMP @@ -974,7 +986,8 @@ nsDragService::IsDataFlavorSupported(const char *aDataFlavor, // check the target context vs. this flavor, one at a time GList *tmp; - for (tmp = mTargetDragContext->targets; tmp; tmp = tmp->next) { + for (tmp = gdk_drag_context_list_targets(mTargetDragContext); + tmp; tmp = tmp->next) { /* Bug 331198 */ GdkAtom atom = GDK_POINTER_TO_ATOM(tmp->data); gchar *name = NULL; @@ -1058,15 +1071,16 @@ nsDragService::TargetDataReceived(GtkWidget *aWidget, PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::TargetDataReceived")); TargetResetData(); mTargetDragDataReceived = true; - if (aSelectionData->length > 0) { - mTargetDragDataLen = aSelectionData->length; + mTargetDragDataLen = gtk_selection_data_get_length(aSelectionData); + if (mTargetDragDataLen > 0) { mTargetDragData = g_malloc(mTargetDragDataLen); - memcpy(mTargetDragData, aSelectionData->data, mTargetDragDataLen); + memcpy(mTargetDragData, gtk_selection_data_get_data(aSelectionData), + mTargetDragDataLen); } else { PR_LOG(sDragLm, PR_LOG_DEBUG, ("Failed to get data. selection data len was %d\n", - aSelectionData->length)); + mTargetDragDataLen)); } } @@ -1086,7 +1100,8 @@ nsDragService::IsTargetContextList(void) // walk the list of context targets and see if one of them is a list // of items. - for (tmp = mTargetDragContext->targets; tmp; tmp = tmp->next) { + for (tmp = gdk_drag_context_list_targets(mTargetDragContext); + tmp; tmp = tmp->next) { /* Bug 331198 */ GdkAtom atom = GDK_POINTER_TO_ATOM(tmp->data); gchar *name = NULL; @@ -1363,7 +1378,8 @@ nsDragService::SourceEndDragSession(GdkDragContext *aContext, // cancelled (but no drag-failed signal would have been sent). // aContext->dest_window will be non-NULL only if the drop was sent. GdkDragAction action = - aContext->dest_window ? aContext->action : (GdkDragAction)0; + gdk_drag_context_get_dest_window(aContext) ? + gdk_drag_context_get_actions(aContext) : (GdkDragAction)0; // Only one bit of action should be set, but, just in case someone // does something funny, erring away from MOVE, and not recording @@ -1556,7 +1572,7 @@ nsDragService::SourceDataGet(GtkWidget *aWidget, if (tmpData) { // this copies the data gtk_selection_data_set(aSelectionData, - aSelectionData->target, + gtk_selection_data_get_target(aSelectionData), 8, (guchar *)tmpData, tmpDataLen); // this wasn't allocated with glib @@ -1569,7 +1585,7 @@ nsDragService::SourceDataGet(GtkWidget *aWidget, gint length; CreateUriList(mSourceDataItems, &uriList, &length); gtk_selection_data_set(aSelectionData, - aSelectionData->target, + gtk_selection_data_get_target(aSelectionData), 8, (guchar *)uriList, length); g_free(uriList); return; diff --git a/widget/gtk2/nsFilePicker.cpp b/widget/gtk2/nsFilePicker.cpp index 56629cde613f..2a54d3c5347c 100644 --- a/widget/gtk2/nsFilePicker.cpp +++ b/widget/gtk2/nsFilePicker.cpp @@ -433,8 +433,9 @@ nsFilePicker::Open(nsIFilePickerShownCallback *aCallback) gtk_window_set_modal(window, TRUE); if (parent_widget) { gtk_window_set_destroy_with_parent(window, TRUE); - if (parent_widget->group) { - gtk_window_group_add_window(parent_widget->group, window); + GtkWindowGroup *parentGroup = gtk_window_get_group(parent_widget); + if (parentGroup) { + gtk_window_group_add_window(parentGroup, window); } } diff --git a/widget/gtk2/nsGTKToolkit.h b/widget/gtk2/nsGTKToolkit.h index df5d81183494..ae0d55b632e9 100644 --- a/widget/gtk2/nsGTKToolkit.h +++ b/widget/gtk2/nsGTKToolkit.h @@ -21,7 +21,6 @@ class nsGTKToolkit { public: nsGTKToolkit(); - virtual ~nsGTKToolkit(); static nsGTKToolkit* GetToolkit(); @@ -30,9 +29,6 @@ public: gToolkit = nullptr; } - void CreateSharedGC(void); - GdkGC *GetSharedGC(void); - /** * Get/set our value of DESKTOP_STARTUP_ID. When non-empty, this is applied * to the next toplevel window to be shown or focused (and then immediately @@ -51,7 +47,6 @@ public: private: static nsGTKToolkit* gToolkit; - GdkGC *mSharedGC; nsCString mDesktopStartupID; uint32_t mFocusTimestamp; }; diff --git a/widget/gtk2/nsGtkIMModule.cpp b/widget/gtk2/nsGtkIMModule.cpp index f3e7877b3ec2..5b1629f1962e 100644 --- a/widget/gtk2/nsGtkIMModule.cpp +++ b/widget/gtk2/nsGtkIMModule.cpp @@ -24,6 +24,10 @@ #include "mozilla/Services.h" #endif +#if (MOZ_WIDGET_GTK == 2) +#include "gtk2compat.h" +#endif + using namespace mozilla; using namespace mozilla::widget; @@ -101,7 +105,7 @@ nsGtkIMModule::Init() MozContainer* container = mOwnerWindow->GetMozContainer(); NS_PRECONDITION(container, "container is null"); - GdkWindow* gdkWindow = GTK_WIDGET(container)->window; + GdkWindow* gdkWindow = gtk_widget_get_window(GTK_WIDGET(container)); // NOTE: gtk_im_*_new() abort (kill) the whole process when it fails. // So, we don't need to check the result. @@ -255,7 +259,11 @@ nsGtkIMModule::PrepareToDestroyContext(GtkIMContext *aContext) NS_PRECONDITION(container, "The container of the window is null"); GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT(aContext); +#if (MOZ_WIDGET_GTK == 2) GtkIMContext *slave = multicontext->slave; +#else + GtkIMContext *slave = NULL; //TODO GTK3 +#endif if (!slave) { return; } diff --git a/widget/gtk2/nsGtkKeyUtils.cpp b/widget/gtk2/nsGtkKeyUtils.cpp index 026e342f4989..7166b83a8727 100644 --- a/widget/gtk2/nsGtkKeyUtils.cpp +++ b/widget/gtk2/nsGtkKeyUtils.cpp @@ -18,6 +18,9 @@ #ifdef MOZ_X11 #include #endif /* MOZ_X11 */ +#if (MOZ_WIDGET_GTK == 3) +#include +#endif #include "nsGUIEvent.h" #include "WidgetUtils.h" #include "keysym2ucs.h" diff --git a/widget/gtk2/nsIdleServiceGTK.cpp b/widget/gtk2/nsIdleServiceGTK.cpp index 8fa5f4b16d84..89a4043583f2 100644 --- a/widget/gtk2/nsIdleServiceGTK.cpp +++ b/widget/gtk2/nsIdleServiceGTK.cpp @@ -5,12 +5,16 @@ * 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 + #include "nsIdleServiceGTK.h" #include "nsIServiceManager.h" #include "nsDebug.h" #include "prlink.h" #include "prlog.h" - +#if (MOZ_WIDGET_GTK == 2) +#include "gtk2compat.h" +#endif #ifdef PR_LOGGING static PRLogModuleInfo* sIdleLog = nullptr; @@ -102,7 +106,7 @@ nsIdleServiceGTK::PollIdleTime(uint32_t *aIdleTime) *aIdleTime = 0; // We might not have a display (cf. in xpcshell) - Display *dplay = GDK_DISPLAY(); + Display *dplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); if (!dplay) { #ifdef PR_LOGGING PR_LOG(sIdleLog, PR_LOG_WARNING, ("No display found!\n")); diff --git a/widget/gtk2/nsNativeKeyBindings.cpp b/widget/gtk2/nsNativeKeyBindings.cpp index cb8ea9c2900e..655e6864346d 100644 --- a/widget/gtk2/nsNativeKeyBindings.cpp +++ b/widget/gtk2/nsNativeKeyBindings.cpp @@ -308,9 +308,13 @@ nsNativeKeyBindings::KeyPressInternal(const nsNativeKeyEvent& aEvent, gCurrentCallbackData = aCallbackData; gHandled = false; - +#if (MOZ_WIDGET_GTK == 2) gtk_bindings_activate(GTK_OBJECT(mNativeTarget), aKeyCode, GdkModifierType(modifiers)); +#else + gtk_bindings_activate(G_OBJECT(mNativeTarget), + aKeyCode, GdkModifierType(modifiers)); +#endif gCurrentCallback = nullptr; gCurrentCallbackData = nullptr; diff --git a/widget/gtk2/nsPrintDialogGTK.cpp b/widget/gtk2/nsPrintDialogGTK.cpp index ae8776caed28..0be3f62d674a 100644 --- a/widget/gtk2/nsPrintDialogGTK.cpp +++ b/widget/gtk2/nsPrintDialogGTK.cpp @@ -4,7 +4,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include +#if (MOZ_WIDGET_GTK == 2) #include +#include "gtk2compat.h" +#else +#include +#endif #include #include "mozilla/Util.h" @@ -77,7 +82,11 @@ ShowCustomDialog(GtkComboBox *changed_box, gpointer user_data) printBundle->GetStringFromName(NS_LITERAL_STRING("headerFooterCustom").get(), getter_Copies(intlString)); GtkWidget* prompt_dialog = gtk_dialog_new_with_buttons(NS_ConvertUTF16toUTF8(intlString).get(), printDialog, +#if (MOZ_WIDGET_GTK == 2) (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR), +#else + (GtkDialogFlags)(GTK_DIALOG_MODAL), +#endif GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); @@ -110,7 +119,8 @@ ShowCustomDialog(GtkComboBox *changed_box, gpointer user_data) gtk_container_set_border_width(GTK_CONTAINER(custom_hbox), 2); gtk_widget_show_all(custom_hbox); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(prompt_dialog)->vbox), custom_hbox, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(prompt_dialog))), + custom_hbox, FALSE, FALSE, 0); gint diag_response = gtk_dialog_run(GTK_DIALOG(prompt_dialog)); if (diag_response == GTK_RESPONSE_ACCEPT) { @@ -481,14 +491,23 @@ nsPrintDialogWidgetGTK::ExportSettings(nsIPrintSettings *aNSSettings) GtkWidget* nsPrintDialogWidgetGTK::ConstructHeaderFooterDropdown(const PRUnichar *currentString) { +#if (MOZ_WIDGET_GTK == 2) GtkWidget* dropdown = gtk_combo_box_new_text(); +#else + GtkWidget* dropdown = gtk_combo_box_text_new(); +#endif const char hf_options[][22] = {"headerFooterBlank", "headerFooterTitle", "headerFooterURL", "headerFooterDate", "headerFooterPage", "headerFooterPageTotal", "headerFooterCustom"}; for (unsigned int i = 0; i < ArrayLength(hf_options); i++) { +#if (MOZ_WIDGET_GTK == 2) gtk_combo_box_append_text(GTK_COMBO_BOX(dropdown), GetUTF8FromBundle(hf_options[i]).get()); +#else + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(dropdown), NULL, + GetUTF8FromBundle(hf_options[i]).get()); +#endif } bool shouldBeCustom = true; diff --git a/widget/gtk2/nsPrintSettingsGTK.h b/widget/gtk2/nsPrintSettingsGTK.h index d85d0c72a948..d008e847719e 100644 --- a/widget/gtk2/nsPrintSettingsGTK.h +++ b/widget/gtk2/nsPrintSettingsGTK.h @@ -11,8 +11,12 @@ extern "C" { #include +#if (MOZ_WIDGET_GTK == 2) #include #include +#else +#include +#endif } #define NS_PRINTSETTINGSGTK_IID \ diff --git a/widget/gtk2/nsScreenGtk.cpp b/widget/gtk2/nsScreenGtk.cpp index 076b7de9a24e..31545e50f7c4 100644 --- a/widget/gtk2/nsScreenGtk.cpp +++ b/widget/gtk2/nsScreenGtk.cpp @@ -11,6 +11,9 @@ #include #endif #include +#if (MOZ_WIDGET_GTK == 2) +#include "gtk2compat.h" +#endif nsScreenGtk :: nsScreenGtk ( ) : mScreenNum(0), @@ -54,8 +57,8 @@ nsScreenGtk :: GetAvailRect(int32_t *outLeft, int32_t *outTop, int32_t *outWidth NS_IMETHODIMP nsScreenGtk :: GetPixelDepth(int32_t *aPixelDepth) { - GdkVisual * rgb_visual = gdk_rgb_get_visual(); - *aPixelDepth = rgb_visual->depth; + GdkVisual * visual = gdk_screen_get_system_visual(gdk_screen_get_default()); + *aPixelDepth = gdk_visual_get_depth(visual); return NS_OK; diff --git a/widget/gtk2/nsScreenManagerGtk.cpp b/widget/gtk2/nsScreenManagerGtk.cpp index 9311abfd9532..c9428ade6331 100644 --- a/widget/gtk2/nsScreenManagerGtk.cpp +++ b/widget/gtk2/nsScreenManagerGtk.cpp @@ -132,9 +132,9 @@ nsScreenManagerGtk :: Init() PR_FindFunctionSymbol(mXineramalib, "XineramaQueryScreens"); // get the number of screens via xinerama - if (_XnrmIsActive && _XnrmQueryScreens && - _XnrmIsActive(GDK_DISPLAY())) { - screenInfo = _XnrmQueryScreens(GDK_DISPLAY(), &numScreens); + Display *display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); + if (_XnrmIsActive && _XnrmQueryScreens && _XnrmIsActive(display)) { + screenInfo = _XnrmQueryScreens(display, &numScreens); } } @@ -297,11 +297,18 @@ nsScreenManagerGtk :: ScreenForNativeWidget (void *aWidget, nsIScreen **outScree if (mCachedScreenArray.Count() > 1) { // I don't know how to go from GtkWindow to nsIScreen, especially // given xinerama and stuff, so let's just do this - gint x, y, width, height, depth; + gint x, y, width, height; +#if (MOZ_WIDGET_GTK == 2) + gint depth; +#endif x = y = width = height = 0; +#if (MOZ_WIDGET_GTK == 2) gdk_window_get_geometry(GDK_WINDOW(aWidget), &x, &y, &width, &height, &depth); +#else + gdk_window_get_geometry(GDK_WINDOW(aWidget), &x, &y, &width, &height); +#endif gdk_window_get_origin(GDK_WINDOW(aWidget), &x, &y); rv = ScreenForRect(x, y, width, height, outScreen); } else { diff --git a/widget/gtk2/nsToolkit.cpp b/widget/gtk2/nsToolkit.cpp index f5b71a787568..41d47ff9605d 100644 --- a/widget/gtk2/nsToolkit.cpp +++ b/widget/gtk2/nsToolkit.cpp @@ -16,38 +16,8 @@ nsGTKToolkit* nsGTKToolkit::gToolkit = nullptr; // //------------------------------------------------------------------------- nsGTKToolkit::nsGTKToolkit() - : mSharedGC(nullptr), mFocusTimestamp(0) + : mFocusTimestamp(0) { - CreateSharedGC(); -} - -//------------------------------------------------------------------------- -// -// destructor -// -//------------------------------------------------------------------------- -nsGTKToolkit::~nsGTKToolkit() -{ - if (mSharedGC) { - g_object_unref(mSharedGC); - } -} - -void nsGTKToolkit::CreateSharedGC(void) -{ - GdkPixmap *pixmap; - - if (mSharedGC) - return; - - pixmap = gdk_pixmap_new(NULL, 1, 1, gdk_rgb_get_visual()->depth); - mSharedGC = gdk_gc_new(pixmap); - g_object_unref(pixmap); -} - -GdkGC *nsGTKToolkit::GetSharedGC(void) -{ - return (GdkGC *)g_object_ref(mSharedGC); } //------------------------------------------------------------------------------- diff --git a/widget/gtk2/nsWindow.cpp b/widget/gtk2/nsWindow.cpp index 8ae32cf9b31a..a7b62a36fbfa 100644 --- a/widget/gtk2/nsWindow.cpp +++ b/widget/gtk2/nsWindow.cpp @@ -26,7 +26,7 @@ #include "nsGtkCursors.h" #include -#if defined(MOZ_WIDGET_GTK3) +#if (MOZ_WIDGET_GTK == 3) #include #endif #ifdef MOZ_X11 @@ -34,7 +34,7 @@ #include #include #include -#if defined(MOZ_WIDGET_GTK3) +#if (MOZ_WIDGET_GTK == 3) #include #endif @@ -44,7 +44,9 @@ #include #endif +#if (MOZ_WIDGET_GTK == 2) #include "gtk2xtbin.h" +#endif #endif /* MOZ_X11 */ #include #if defined(MOZ_WIDGET_GTK2) @@ -1681,17 +1683,6 @@ nsWindow::GetNativeData(uint32_t aDataType) #endif /* MOZ_X11 */ break; - case NS_NATIVE_GRAPHIC: { -#if defined(MOZ_WIDGET_GTK2) - nsGTKToolkit* toolkit = nsGTKToolkit::GetToolkit(); - NS_ASSERTION(nullptr != toolkit, "NULL toolkit, unable to get a GC"); - return toolkit->GetSharedGC(); -#else - return nullptr; -#endif - break; - } - case NS_NATIVE_SHELLWIDGET: return (void *) mShell; diff --git a/widget/windows/GfxInfo.cpp b/widget/windows/GfxInfo.cpp index 147a3423796a..85d20401091a 100644 --- a/widget/windows/GfxInfo.cpp +++ b/widget/windows/GfxInfo.cpp @@ -757,6 +757,18 @@ GfxInfo::GetGfxDriverInfo() GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, DRIVER_LESS_THAN, V(8,741,0,0), "10.6" ); + /* + * Bug 783517 - crashes in AMD driver on Windows 8 + */ + APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_WINDOWS_8, + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices, + GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, + DRIVER_LESS_THAN_OR_EQUAL, V(8,982,0,0), "> 12.8" ); + APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_WINDOWS_8, + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAMD), GfxDriverInfo::allDevices, + GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, + DRIVER_LESS_THAN_OR_EQUAL, V(8,982,0,0), "> 12.8" ); + /* OpenGL on any ATI/AMD hardware is discouraged * See: * bug 619773 - WebGL: Crash with blue screen : "NMI: Parity Check / Memory Parity Error" diff --git a/widget/windows/nsTextStore.cpp b/widget/windows/nsTextStore.cpp index 46022dd5b159..26bcc720bfb5 100644 --- a/widget/windows/nsTextStore.cpp +++ b/widget/windows/nsTextStore.cpp @@ -352,7 +352,7 @@ nsTextStore::~nsTextStore() PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, ("TSF: 0x%p nsTextStore instance is destroyed, " "mWindow=0x%p, mDocumentMgr=0x%p, mContext=0x%p", - this, mWindow, mDocumentMgr, mContext)); + this, mWindow, mDocumentMgr.get(), mContext.get())); if (mCompositionTimer) { mCompositionTimer->Cancel(); @@ -414,7 +414,7 @@ nsTextStore::Create(nsWindow* aWindow, PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, ("TSF: 0x%p nsTextStore::Create() succeeded: " "mDocumentMgr=0x%p, mContext=0x%p, mEditCookie=0x%08X", - this, mDocumentMgr, mContext, mEditCookie)); + this, mDocumentMgr.get(), mContext.get(), mEditCookie)); return true; } @@ -494,7 +494,7 @@ nsTextStore::AdviseSink(REFIID riid, ("TSF: 0x%p nsTextStore::AdviseSink(riid=%s, punk=0x%p, dwMask=%s), " "mSink=0x%p, mSinkMask=%s", this, GetRIIDNameStr(riid).get(), punk, GetSinkMaskNameStr(dwMask).get(), - mSink, GetSinkMaskNameStr(mSinkMask).get())); + mSink.get(), GetSinkMaskNameStr(mSinkMask).get())); if (!punk) { PR_LOG(sTextStoreLog, PR_LOG_ERROR, @@ -542,7 +542,7 @@ nsTextStore::UnadviseSink(IUnknown *punk) { PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, ("TSF: 0x%p nsTextStore::UnadviseSink(punk=0x%p), mSink=0x%p", - this, punk, mSink)); + this, punk, mSink.get())); if (!punk) { PR_LOG(sTextStoreLog, PR_LOG_ERROR, @@ -951,7 +951,7 @@ nsTextStore::UpdateCompositionExtent(ITfRange* aRangeNew) { PR_LOG(sTextStoreLog, PR_LOG_DEBUG, ("TSF: 0x%p nsTextStore::UpdateCompositionExtent(aRangeNew=0x%p), " - "mCompositionView=0x%p", this, aRangeNew, mCompositionView)); + "mCompositionView=0x%p", this, aRangeNew, mCompositionView.get())); if (!mCompositionView) { PR_LOG(sTextStoreLog, PR_LOG_ERROR, @@ -1058,7 +1058,7 @@ nsTextStore::SendTextEventForCompositionString() PR_LOG(sTextStoreLog, PR_LOG_DEBUG, ("TSF: 0x%p nsTextStore::SendTextEventForCompositionString(), " "mCompositionView=0x%p, mCompositionString=\"%s\"", - this, mCompositionView, + this, mCompositionView.get(), NS_ConvertUTF16toUTF8(mCompositionString).get())); if (!mCompositionView) { @@ -1511,10 +1511,20 @@ nsTextStore::SetText(DWORD dwFlags, return hr; } // Replace just selected text - // XXX We should make something like InserTextAtSelectionInternal() for - // making the log clearer if InsertTextAtSelection() is called internally. - return InsertTextAtSelection(TS_IAS_NOQUERY, pchText, cch, - NULL, NULL, pChange); + if (!InsertTextAtSelectionInternal(nsDependentString(pchText, cch), + pChange)) { + PR_LOG(sTextStoreLog, PR_LOG_ERROR, + ("TSF: 0x%p nsTextStore::SetText() FAILED due to " + "InsertTextAtSelectionInternal() failure", this)); + return E_FAIL; + } + + PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, + ("TSF: 0x%p nsTextStore::SetText() succeeded: pChange={ " + "acpStart=%ld, acpOldEnd=%ld, acpNewEnd=%ld }", + this, pChange ? pChange->acpStart : 0, + pChange ? pChange->acpOldEnd : 0, pChange ? pChange->acpNewEnd : 0)); + return S_OK; } STDMETHODIMP @@ -1992,13 +2002,6 @@ nsTextStore::InsertTextAtSelection(DWORD dwFlags, mCompositionView ? "there is composition view" : "there is no composition view")); - if (!IsReadWriteLocked()) { - PR_LOG(sTextStoreLog, PR_LOG_ERROR, - ("TSF: 0x%p nsTextStore::InsertTextAtSelection() FAILED due to " - "not locked (read)", this)); - return TS_E_NOLOCK; - } - if (cch && !pchText) { PR_LOG(sTextStoreLog, PR_LOG_ERROR, ("TSF: 0x%p nsTextStore::InsertTextAtSelection() FAILED due to " @@ -2006,22 +2009,30 @@ nsTextStore::InsertTextAtSelection(DWORD dwFlags, return E_INVALIDARG; } - // Get selection first - TS_SELECTION_ACP sel; - if (!GetSelectionInternal(sel)) { - PR_LOG(sTextStoreLog, PR_LOG_ERROR, - ("TSF: 0x%p nsTextStore::InsertTextAtSelection() FAILED due to " - "GetSelectionInternal() failure", this)); - return E_FAIL; - } - if (TS_IAS_QUERYONLY == dwFlags) { + if (!IsReadLocked()) { + PR_LOG(sTextStoreLog, PR_LOG_ERROR, + ("TSF: 0x%p nsTextStore::InsertTextAtSelection() FAILED due to " + "not locked (read)", this)); + return TS_E_NOLOCK; + } + if (!pacpStart || !pacpEnd) { PR_LOG(sTextStoreLog, PR_LOG_ERROR, ("TSF: 0x%p nsTextStore::InsertTextAtSelection() FAILED due to " "null argument", this)); return E_INVALIDARG; } + + // Get selection first + TS_SELECTION_ACP sel; + if (!GetSelectionInternal(sel)) { + PR_LOG(sTextStoreLog, PR_LOG_ERROR, + ("TSF: 0x%p nsTextStore::InsertTextAtSelection() FAILED due to " + "GetSelectionInternal() failure", this)); + return E_FAIL; + } + // Simulate text insertion *pacpStart = sel.acpStart; *pacpEnd = sel.acpEnd; @@ -2031,12 +2042,20 @@ nsTextStore::InsertTextAtSelection(DWORD dwFlags, pChange->acpNewEnd = sel.acpStart + cch; } } else { + if (!IsReadWriteLocked()) { + PR_LOG(sTextStoreLog, PR_LOG_ERROR, + ("TSF: 0x%p nsTextStore::InsertTextAtSelection() FAILED due to " + "not locked (read-write)", this)); + return TS_E_NOLOCK; + } + if (!pChange) { PR_LOG(sTextStoreLog, PR_LOG_ERROR, ("TSF: 0x%p nsTextStore::InsertTextAtSelection() FAILED due to " "null pChange", this)); return E_INVALIDARG; } + if (TS_IAS_NOQUERY != dwFlags && (!pacpStart || !pacpEnd)) { PR_LOG(sTextStoreLog, PR_LOG_ERROR, ("TSF: 0x%p nsTextStore::InsertTextAtSelection() FAILED due to " @@ -2044,69 +2063,14 @@ nsTextStore::InsertTextAtSelection(DWORD dwFlags, return E_INVALIDARG; } - if (mCompositionView) { - // Emulate text insertion during compositions, because during a - // composition, editor expects the whole composition string to - // be sent in NS_TEXT_TEXT, not just the inserted part. - // The actual NS_TEXT_TEXT will be sent in SetSelection or - // OnUpdateComposition. - mCompositionString.Replace(uint32_t(sel.acpStart - mCompositionStart), - sel.acpEnd - sel.acpStart, pchText, cch); - - mCompositionSelection.acpStart += cch; - mCompositionSelection.acpEnd = mCompositionSelection.acpStart; - mCompositionSelection.style.ase = TS_AE_END; - PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, - ("TSF: 0x%p nsTextStore::InsertTextAtSelection() replaced a " - "part of (%lu-%lu) the composition string, waiting " - "SetSelection() or OnUpdateComposition()...", this, - sel.acpStart - mCompositionStart, - sel.acpEnd - mCompositionStart)); - } else { - // Use a temporary composition to contain the text - PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, - ("TSF: 0x%p nsTextStore::InsertTextAtSelection() dispatching " - "a compositionstart event...", this)); - nsCompositionEvent compEvent(true, NS_COMPOSITION_START, mWindow); - mWindow->InitEvent(compEvent); - mWindow->DispatchWindowEvent(&compEvent); - if (mWindow && !mWindow->Destroyed()) { - PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, - ("TSF: 0x%p nsTextStore::InsertTextAtSelection() dispatching " - "a compositionupdate event...", this)); - compEvent.message = NS_COMPOSITION_UPDATE; - compEvent.data.Assign(pchText, cch); - mWindow->DispatchWindowEvent(&compEvent); - if (mWindow && !mWindow->Destroyed()) { - PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, - ("TSF: 0x%p nsTextStore::InsertTextAtSelection() " - "dispatching a text event...", this)); - nsTextEvent event(true, NS_TEXT_TEXT, mWindow); - mWindow->InitEvent(event); - event.theText.Assign(pchText, cch); - event.theText.ReplaceSubstring(NS_LITERAL_STRING("\r\n"), - NS_LITERAL_STRING("\n")); - mWindow->DispatchWindowEvent(&event); - if (mWindow && !mWindow->Destroyed()) { - PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, - ("TSF: 0x%p nsTextStore::InsertTextAtSelection() " - "dispatching a compositionend event...", this)); - compEvent.message = NS_COMPOSITION_END; - mWindow->DispatchWindowEvent(&compEvent); - } - } - } - } - pChange->acpStart = sel.acpStart; - pChange->acpOldEnd = sel.acpEnd; - // Get new selection - if (!GetSelectionInternal(sel)) { + if (!InsertTextAtSelectionInternal(nsDependentString(pchText, cch), + pChange)) { PR_LOG(sTextStoreLog, PR_LOG_ERROR, ("TSF: 0x%p nsTextStore::InsertTextAtSelection() FAILED due to " - "GetSelectionInternal() failure after inserted the text", this)); + "InsertTextAtSelectionInternal() failure", this)); return E_FAIL; } - pChange->acpNewEnd = sel.acpEnd; + if (TS_IAS_NOQUERY != dwFlags) { *pacpStart = pChange->acpStart; *pacpEnd = pChange->acpNewEnd; @@ -2122,6 +2086,138 @@ nsTextStore::InsertTextAtSelection(DWORD dwFlags, return S_OK; } +bool +nsTextStore::InsertTextAtSelectionInternal(const nsAString &aInsertStr, + TS_TEXTCHANGE* aTextChange) +{ + PR_LOG(sTextStoreLog, PR_LOG_DEBUG, + ("TSF: 0x%p nsTextStore::InsertTextAtSelectionInternal(" + "aInsertStr=\"%s\", aTextChange=0x%p), %s", + this, NS_ConvertUTF16toUTF8(aInsertStr).get(), aTextChange, + mCompositionView ? "there is composition view" : + "there is no composition view")); + + TS_SELECTION_ACP oldSelection; + oldSelection.acpStart = 0; + oldSelection.acpEnd = 0; + + if (mCompositionView) { + oldSelection = mCompositionSelection; + // Emulate text insertion during compositions, because during a + // composition, editor expects the whole composition string to + // be sent in NS_TEXT_TEXT, not just the inserted part. + // The actual NS_TEXT_TEXT will be sent in SetSelection or + // OnUpdateComposition. + mCompositionString.Replace( + static_cast(oldSelection.acpStart) - mCompositionStart, + static_cast(oldSelection.acpEnd - oldSelection.acpStart), + aInsertStr); + + mCompositionSelection.acpStart += aInsertStr.Length(); + mCompositionSelection.acpEnd = mCompositionSelection.acpStart; + mCompositionSelection.style.ase = TS_AE_END; + PR_LOG(sTextStoreLog, PR_LOG_DEBUG, + ("TSF: 0x%p nsTextStore::InsertTextAtSelectionInternal() replaced " + "a part of (%lu-%lu) the composition string, waiting " + "SetSelection() or OnUpdateComposition()...", this, + oldSelection.acpStart - mCompositionStart, + oldSelection.acpEnd - mCompositionStart)); + } else { + // Use actual selection if it's not composing. + if (aTextChange && !GetSelectionInternal(oldSelection)) { + PR_LOG(sTextStoreLog, PR_LOG_ERROR, + ("TSF: 0x%p nsTextStore::InsertTextAtSelectionInternal() FAILED " + "due to GetSelectionInternal() failure", this)); + return false; + } + + // Use a temporary composition to contain the text + PR_LOG(sTextStoreLog, PR_LOG_DEBUG, + ("TSF: 0x%p nsTextStore::InsertTextAtSelectionInternal() " + "dispatching a compositionstart event...", this)); + nsCompositionEvent compStartEvent(true, NS_COMPOSITION_START, mWindow); + mWindow->InitEvent(compStartEvent); + mWindow->DispatchWindowEvent(&compStartEvent); + if (!mWindow || mWindow->Destroyed()) { + PR_LOG(sTextStoreLog, PR_LOG_ERROR, + ("TSF: 0x%p nsTextStore::InsertTextAtSelectionInternal() FAILED " + "due to the widget destroyed by compositionstart event", this)); + return false; + } + + if (!aInsertStr.IsEmpty()) { + PR_LOG(sTextStoreLog, PR_LOG_DEBUG, + ("TSF: 0x%p nsTextStore::InsertTextAtSelectionInternal() " + "dispatching a compositionupdate event...", this)); + nsCompositionEvent compUpdateEvent(true, NS_COMPOSITION_UPDATE, mWindow); + compUpdateEvent.data = aInsertStr; + mWindow->DispatchWindowEvent(&compUpdateEvent); + if (!mWindow || mWindow->Destroyed()) { + PR_LOG(sTextStoreLog, PR_LOG_ERROR, + ("TSF: 0x%p nsTextStore::InsertTextAtSelectionInternal() " + "FAILED due to the widget destroyed by compositionupdate event", + this)); + return false; + } + } + + PR_LOG(sTextStoreLog, PR_LOG_DEBUG, + ("TSF: 0x%p nsTextStore::InsertTextAtSelectionInternal() " + "dispatching a text event...", this)); + nsTextEvent textEvent(true, NS_TEXT_TEXT, mWindow); + mWindow->InitEvent(textEvent); + textEvent.theText = aInsertStr; + textEvent.theText.ReplaceSubstring(NS_LITERAL_STRING("\r\n"), + NS_LITERAL_STRING("\n")); + mWindow->DispatchWindowEvent(&textEvent); + if (!mWindow || mWindow->Destroyed()) { + PR_LOG(sTextStoreLog, PR_LOG_ERROR, + ("TSF: 0x%p nsTextStore::InsertTextAtSelectionInternal() FAILED " + "due to the widget destroyed by text event", this)); + return false; + } + + PR_LOG(sTextStoreLog, PR_LOG_DEBUG, + ("TSF: 0x%p nsTextStore::InsertTextAtSelectionInternal() " + "dispatching a compositionend event...", this)); + nsCompositionEvent compEndEvent(true, NS_COMPOSITION_END, mWindow); + compEndEvent.data = aInsertStr; + mWindow->DispatchWindowEvent(&compEndEvent); + if (!mWindow || mWindow->Destroyed()) { + PR_LOG(sTextStoreLog, PR_LOG_ERROR, + ("TSF: 0x%p nsTextStore::InsertTextAtSelectionInternal() FAILED " + "due to the widget destroyed by compositionend event", this)); + return false; + } + } + + if (aTextChange) { + aTextChange->acpStart = oldSelection.acpStart; + aTextChange->acpOldEnd = oldSelection.acpEnd; + + // Get new selection + TS_SELECTION_ACP newSelection; + if (!GetSelectionInternal(newSelection)) { + PR_LOG(sTextStoreLog, PR_LOG_ERROR, + ("TSF: 0x%p nsTextStore::InsertTextAtSelectionInternal() FAILED " + "due to GetSelectionInternal() failure after inserted the text", + this)); + return false; + } + aTextChange->acpNewEnd = newSelection.acpEnd; + } + + PR_LOG(sTextStoreLog, PR_LOG_DEBUG, + ("TSF: 0x%p nsTextStore::InsertTextAtSelectionInternal() succeeded: " + "mWindow=0x%p, mWindow->Destroyed()=%s, aTextChange={ acpStart=%ld, " + "acpOldEnd=%ld, acpNewEnd=%ld }", + this, mWindow, GetBoolName(mWindow ? mWindow->Destroyed() : true), + aTextChange ? aTextChange->acpStart : 0, + aTextChange ? aTextChange->acpOldEnd : 0, + aTextChange ? aTextChange->acpNewEnd : 0)); + return true; +} + STDMETHODIMP nsTextStore::InsertEmbeddedAtSelection(DWORD dwFlags, IDataObject *pDataObject, @@ -2147,7 +2243,7 @@ nsTextStore::OnStartCompositionInternal(ITfCompositionView* pComposition, "pComposition=0x%p, aRange=0x%p, aPreserveSelection=%s), " "mCompositionView=0x%p", this, pComposition, aRange, GetBoolName(aPreserveSelection), - mCompositionView)); + mCompositionView.get())); mCompositionView = pComposition; HRESULT hr = GetRangeExtent(aRange, &mCompositionStart, &mCompositionLength); @@ -2238,7 +2334,7 @@ nsTextStore::OnStartComposition(ITfCompositionView* pComposition, PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, ("TSF: 0x%p nsTextStore::OnStartComposition(pComposition=0x%p, " "pfOk=0x%p), mCompositionView=0x%p", - this, pComposition, pfOk, mCompositionView)); + this, pComposition, pfOk, mCompositionView.get())); *pfOk = FALSE; @@ -2286,7 +2382,7 @@ nsTextStore::OnUpdateComposition(ITfCompositionView* pComposition, PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, ("TSF: 0x%p nsTextStore::OnUpdateComposition(pComposition=0x%p, " "pRangeNew=0x%p), mCompositionView=0x%p", - this, pComposition, pRangeNew, mCompositionView)); + this, pComposition, pRangeNew, mCompositionView.get())); if (!mDocumentMgr || !mContext) { PR_LOG(sTextStoreLog, PR_LOG_ERROR, @@ -2350,7 +2446,7 @@ nsTextStore::OnEndComposition(ITfCompositionView* pComposition) PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, ("TSF: 0x%p nsTextStore::OnEndComposition(pComposition=0x%p), " "mCompositionView=0x%p, mCompositionString=\"%s\"", - this, pComposition, mCompositionView, + this, pComposition, mCompositionView.get(), NS_ConvertUTF16toUTF8(mCompositionString).get())); if (!mCompositionView) { @@ -2478,8 +2574,8 @@ nsTextStore::OnTextChangeInternal(uint32_t aStart, "aOldEnd=%lu, aNewEnd=%lu), mLock=%s, mSink=0x%p, mSinkMask=%s, " "mTextChange={ acpStart=%ld, acpOldEnd=%ld, acpNewEnd=%ld }", this, aStart, aOldEnd, aNewEnd, GetLockFlagNameStr(mLock).get(), - mSink, GetSinkMaskNameStr(mSinkMask).get(), mTextChange.acpStart, - mTextChange.acpOldEnd, mTextChange.acpNewEnd)); + mSink.get(), GetSinkMaskNameStr(mSinkMask).get(), + mTextChange.acpStart, mTextChange.acpOldEnd, mTextChange.acpNewEnd)); if (!mLock && mSink && 0 != (mSinkMask & TS_AS_TEXT_CHANGE)) { mTextChange.acpStart = NS_MIN(mTextChange.acpStart, LONG(aStart)); @@ -2498,7 +2594,7 @@ nsTextStore::OnTextChangeMsgInternal(void) ("TSF: 0x%p nsTextStore::OnTextChangeMsgInternal(), mLock=%s, " "mSink=0x%p, mSinkMask=%s, mTextChange={ acpStart=%ld, " "acpOldEnd=%ld, acpNewEnd=%ld }", - this, GetLockFlagNameStr(mLock).get(), mSink, + this, GetLockFlagNameStr(mLock).get(), mSink.get(), GetSinkMaskNameStr(mSinkMask).get(), mTextChange.acpStart, mTextChange.acpOldEnd, mTextChange.acpNewEnd)); @@ -2521,7 +2617,7 @@ nsTextStore::OnSelectionChangeInternal(void) PR_LOG(sTextStoreLog, PR_LOG_DEBUG, ("TSF: 0x%p nsTextStore::OnSelectionChangeInternal(), mLock=%s, " "mSink=0x%p, mSinkMask=%s", - this, GetLockFlagNameStr(mLock).get(), mSink, + this, GetLockFlagNameStr(mLock).get(), mSink.get(), GetSinkMaskNameStr(mSinkMask).get())); if (!mLock && mSink && 0 != (mSinkMask & TS_AS_SEL_CHANGE)) { @@ -2559,9 +2655,9 @@ nsTextStore::CommitCompositionInternal(bool aDiscard) ("TSF: 0x%p nsTextStore::CommitCompositionInternal(aDiscard=%s), " "mLock=%s, mSink=0x%p, mContext=0x%p, mCompositionView=0x%p, " "mCompositionString=\"%s\"", - this, GetBoolName(aDiscard), GetLockFlagNameStr(mLock).get(), mSink, - mContext, mCompositionView, - NS_ConvertUTF16toUTF8(mCompositionString))); + this, GetBoolName(aDiscard), GetLockFlagNameStr(mLock).get(), + mSink.get(), mContext.get(), mCompositionView.get(), + NS_ConvertUTF16toUTF8(mCompositionString).get())); if (mCompositionView && aDiscard) { mCompositionString.Truncate(0); @@ -2590,7 +2686,7 @@ nsTextStore::CommitCompositionInternal(bool aDiscard) PR_LOG(sTextStoreLog, PR_LOG_DEBUG, ("TSF: 0x%p nsTextStore::CommitCompositionInternal(), " "requesting TerminateComposition() for the context 0x%p...", - this, context)); + this, context.get())); services->TerminateComposition(NULL); } } @@ -2669,7 +2765,7 @@ nsTextStore::SetInputContextInternal(IMEState::Enabled aState) PR_LOG(sTextStoreLog, PR_LOG_DEBUG, ("TSF: 0x%p nsTextStore::SetInputContextInternal(aState=%s), " "mContext=0x%p", - this, GetIMEEnabledName(aState), mContext)); + this, GetIMEEnabledName(aState), mContext.get())); VARIANT variant; variant.vt = VT_I4; @@ -2685,7 +2781,7 @@ nsTextStore::SetInputContextInternal(IMEState::Enabled aState) PR_LOG(sTextStoreLog, PR_LOG_DEBUG, ("TSF: 0x%p nsTextStore::SetInputContextInternal(), setting " "0x%04X to GUID_COMPARTMENT_KEYBOARD_DISABLED of context 0x%p...", - this, variant.lVal, context)); + this, variant.lVal, context.get())); comp->SetValue(sTsfClientId, &variant); } diff --git a/widget/windows/nsTextStore.h b/widget/windows/nsTextStore.h index cedcfbb20328..82e0e617a2b2 100644 --- a/widget/windows/nsTextStore.h +++ b/widget/windows/nsTextStore.h @@ -174,6 +174,8 @@ protected: // event should not be sent from here. HRESULT SetSelectionInternal(const TS_SELECTION_ACP*, bool aDispatchTextEvent = false); + bool InsertTextAtSelectionInternal(const nsAString &aInsertStr, + TS_TEXTCHANGE* aTextChange); HRESULT OnStartCompositionInternal(ITfCompositionView*, ITfRange*, bool); void CommitCompositionInternal(bool); void SetInputContextInternal(IMEState::Enabled aState); diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index c18a460b39e1..e6a3191eb156 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -1345,8 +1345,13 @@ public: nsCOMPtr cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID); if (cs) { - cs->LogStringMessage(NS_ConvertUTF8toUTF16(ccname).get()); - cs->LogStringMessage(NS_ConvertUTF8toUTF16(gcname).get()); + nsString msg = NS_LITERAL_STRING("Cycle Collector log dumped to "); + AppendUTF8toUTF16(ccname, msg); + cs->LogStringMessage(msg.get()); + + msg = NS_LITERAL_STRING("Garbage Collector log dumped to "); + AppendUTF8toUTF16(gcname, msg); + cs->LogStringMessage(msg.get()); } return NS_OK; diff --git a/xpcom/base/nsMemoryReporterManager.cpp b/xpcom/base/nsMemoryReporterManager.cpp index a9aff582257b..637ed2162fd7 100644 --- a/xpcom/base/nsMemoryReporterManager.cpp +++ b/xpcom/base/nsMemoryReporterManager.cpp @@ -11,6 +11,7 @@ #include "nsServiceManagerUtils.h" #include "nsMemoryReporterManager.h" #include "nsArrayEnumerator.h" +#include "nsIConsoleService.h" #include "nsISimpleEnumerator.h" #include "nsIFile.h" #include "nsIFileStreams.h" @@ -1022,7 +1023,18 @@ nsMemoryReporterManager::DumpReports() rv = ostream->Close(); NS_ENSURE_SUCCESS(rv, rv); - return NS_OK; + nsCOMPtr cs = + do_GetService(NS_CONSOLESERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsString path; + tmpFile->GetPath(path); + NS_ENSURE_SUCCESS(rv, rv); + + nsString msg = + NS_LITERAL_STRING("nsIMemoryReporterManager::dumpReports() dumped reports to "); + msg.Append(path); + return cs->LogStringMessage(msg.get()); } #undef DUMP diff --git a/xpcom/base/nsStackWalk.h b/xpcom/base/nsStackWalk.h index a77e9cbd6368..78ba02ace18a 100644 --- a/xpcom/base/nsStackWalk.h +++ b/xpcom/base/nsStackWalk.h @@ -56,7 +56,7 @@ typedef struct { * string and zero if unknown. */ char library[256]; - PRUptrdiff loffset; + ptrdiff_t loffset; /* * The name of the file name and line number of the code * corresponding to the address, or empty string and zero if @@ -69,7 +69,7 @@ typedef struct { * offset within that function, or empty string and zero if unknown. */ char function[256]; - PRUptrdiff foffset; + ptrdiff_t foffset; } nsCodeAddressDetails; /** diff --git a/xpcom/io/nsBinaryStream.cpp b/xpcom/io/nsBinaryStream.cpp index 3c56f1312a54..e671c7fc4051 100644 --- a/xpcom/io/nsBinaryStream.cpp +++ b/xpcom/io/nsBinaryStream.cpp @@ -190,7 +190,7 @@ nsBinaryOutputStream::WriteWStringZ(const PRUnichar* aString) if (!copy) return NS_ERROR_OUT_OF_MEMORY; } - NS_ASSERTION((PRUptrdiff(aString) & 0x1) == 0, "aString not properly aligned"); + NS_ASSERTION((uintptr_t(aString) & 0x1) == 0, "aString not properly aligned"); for (uint32_t i = 0; i < length; i++) copy[i] = NS_SWAP16(aString[i]); rv = WriteBytes(reinterpret_cast(copy), byteCount);