diff --git a/b2g/chrome/content/settings.js b/b2g/chrome/content/settings.js index 1c5f5f78f284..248e286fe181 100644 --- a/b2g/chrome/content/settings.js +++ b/b2g/chrome/content/settings.js @@ -415,6 +415,10 @@ SettingsListener.observe('privacy.donottrackheader.enabled', false, function(val Services.prefs.setBoolPref('privacy.donottrackheader.enabled', value); }); +SettingsListener.observe('privacy.donottrackheader.value', 1, function(value) { + Services.prefs.setIntPref('privacy.donottrackheader.value', value); +}); + // =================== Crash Reporting ==================== SettingsListener.observe('app.reportCrashes', 'ask', function(value) { if (value == 'always') { diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 1bc59da8306f..3814bc4c40eb 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "2ffeaf7249731583606df7c14d6802d17f7bfa17", + "revision": "46a5f0d899394798b848e204a5a17e661e19aba6", "repo_path": "/integration/gaia-central" } diff --git a/browser/app/blocklist.xml b/browser/app/blocklist.xml index a5d03b701077..6046ed2b532c 100644 --- a/browser/app/blocklist.xml +++ b/browser/app/blocklist.xml @@ -1,5 +1,5 @@ - + @@ -480,6 +480,10 @@ + + + + diff --git a/browser/base/content/content.js b/browser/base/content/content.js index e734f4b18672..36f5e70d536f 100644 --- a/browser/base/content/content.js +++ b/browser/base/content/content.js @@ -16,18 +16,6 @@ XPCOMUtils.defineLazyModuleGetter(this, XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", "resource://gre/modules/PrivateBrowsingUtils.jsm"); -// Bug 671101 - directly using webNavigation in this context -// causes docshells to leak -this.__defineGetter__("webNavigation", function () { - return docShell.QueryInterface(Ci.nsIWebNavigation); -}); - -addMessageListener("WebNavigation:LoadURI", function (message) { - let flags = message.json.flags || webNavigation.LOAD_FLAGS_NONE; - - webNavigation.loadURI(message.json.uri, flags, null, null, null); -}); - addMessageListener("Browser:HideSessionRestoreButton", function (message) { // Hide session restore button on about:home let doc = content.document; diff --git a/browser/branding/aurora/content/aboutDialog.css b/browser/branding/aurora/content/aboutDialog.css index cc119cb4ed9e..9900291a854d 100644 --- a/browser/branding/aurora/content/aboutDialog.css +++ b/browser/branding/aurora/content/aboutDialog.css @@ -11,6 +11,7 @@ .text-link { color: #fff !important; + text-decoration: underline; } .text-link:-moz-focusring { diff --git a/browser/branding/nightly/content/aboutDialog.css b/browser/branding/nightly/content/aboutDialog.css index 4129d1f9f44e..f0df8b1aa20d 100644 --- a/browser/branding/nightly/content/aboutDialog.css +++ b/browser/branding/nightly/content/aboutDialog.css @@ -11,6 +11,7 @@ .text-link { color: #fff !important; + text-decoration: underline; } .text-link:-moz-focusring { diff --git a/browser/branding/unofficial/content/aboutDialog.css b/browser/branding/unofficial/content/aboutDialog.css index 1113fd1f2967..4c2a7b603e2f 100644 --- a/browser/branding/unofficial/content/aboutDialog.css +++ b/browser/branding/unofficial/content/aboutDialog.css @@ -11,6 +11,7 @@ .text-link { color: #fff !important; + text-decoration: underline; } #rightBox { diff --git a/browser/components/sessionstore/test/browser_sessionStorage.js b/browser/components/sessionstore/test/browser_sessionStorage.js index 92f9fb0f5786..3492a9c1ed8d 100644 --- a/browser/components/sessionstore/test/browser_sessionStorage.js +++ b/browser/components/sessionstore/test/browser_sessionStorage.js @@ -44,6 +44,11 @@ function test() { let tab; Task.spawn(function() { try { + let SESSION_STORAGE_KEY = "SESSION_STORAGE_KEY " + Math.random(); + let SESSION_STORAGE_VALUE = "SESSION_STORAGE_VALUE " + Math.random(); + let LOCAL_STORAGE_KEY = "LOCAL_STORAGE_KEY " + Math.random(); + let LOCAL_STORAGE_VALUE = "LOCAL_STORAGE_VALUE " + Math.random(); + tab = gBrowser.addTab("http://example.com"); // about:home supports sessionStorage and localStorage @@ -57,25 +62,27 @@ function test() { ss.getBrowserState(); info("Change sessionStorage, ensure that state is saved"); - win.sessionStorage["SESSION_STORAGE_KEY"] = "SESSION_STORAGE_VALUE"; - let storageChanged = yield waitForStorageChange(tab); + let storageChangedPromise = waitForStorageChange(tab); + win.sessionStorage[SESSION_STORAGE_KEY] = SESSION_STORAGE_VALUE; + let storageChanged = yield storageChangedPromise; ok(storageChanged, "Changing sessionStorage triggered the right message"); yield forceWriteState(); let state = ss.getBrowserState(); - ok(state.indexOf("SESSION_STORAGE_KEY") != -1, "Key appears in state"); - ok(state.indexOf("SESSION_STORAGE_VALUE") != -1, "Value appears in state"); + ok(state.indexOf(SESSION_STORAGE_KEY) != -1, "Key appears in state"); + ok(state.indexOf(SESSION_STORAGE_VALUE) != -1, "Value appears in state"); info("Change localStorage, ensure that state is not saved"); - win.localStorage["LOCAL_STORAGE_KEY"] = "LOCAL_STORAGE_VALUE"; - storageChanged = yield waitForStorageChange(tab); + storageChangedPromise = waitForStorageChange(tab); + win.localStorage[LOCAL_STORAGE_KEY] = LOCAL_STORAGE_VALUE; + storageChanged = yield storageChangedPromise; ok(!storageChanged, "Changing localStorage did not trigger a message"); yield forceWriteState(); state = ss.getBrowserState(); - ok(state.indexOf("LOCAL_STORAGE_KEY") == -1, "Key does not appear in state"); - ok(state.indexOf("LOCAL_STORAGE_VALUE") == -1, "Value does not appear in state"); + ok(state.indexOf(LOCAL_STORAGE_KEY) == -1, "Key does not appear in state"); + ok(state.indexOf(LOCAL_STORAGE_VALUE) == -1, "Value does not appear in state"); } catch (ex) { ok(false, ex); info(ex.stack); diff --git a/build/appini_header.py b/build/appini_header.py index 678c519764ef..c9feb92c64eb 100644 --- a/build/appini_header.py +++ b/build/appini_header.py @@ -27,6 +27,16 @@ def main(file): appdata = dict(("%s:%s" % (s, o), config.get(s, o)) for s in config.sections() for o in config.options(s)) appdata['flags'] = ' | '.join(flags) if flags else '0' appdata['App:profile'] = '"%s"' % appdata['App:profile'] if 'App:profile' in appdata else 'NULL' + expected = ('App:vendor', 'App:name', 'App:version', 'App:buildid', + 'App:id', 'Gecko:minversion', 'Gecko:maxversion') + missing = [var for var in expected if var not in appdata] + if missing: + print >>sys.stderr, \ + "Missing values in %s: %s" % (file, ', '.join(missing)) + sys.exit(1) + + if not 'Crash Reporter:serverurl' in appdata: + appdata['Crash Reporter:serverurl'] = '' print '''#include "nsXREAppData.h" static const nsXREAppData sAppData = { diff --git a/build/automation.py.in b/build/automation.py.in index 4fd23006bf32..b6147464f596 100644 --- a/build/automation.py.in +++ b/build/automation.py.in @@ -538,7 +538,10 @@ class Automation(object): return env def killPid(self, pid): - os.kill(pid, getattr(signal, "SIGKILL", signal.SIGTERM)) + try: + os.kill(pid, getattr(signal, "SIGKILL", signal.SIGTERM)) + except WindowsError: + self.log.info("Failed to kill process %d." % pid) if IS_WIN32: PeekNamedPipe = ctypes.windll.kernel32.PeekNamedPipe diff --git a/caps/idl/nsIPrincipal.idl b/caps/idl/nsIPrincipal.idl index 9cea30c1b9a7..9fa2d91b9573 100644 --- a/caps/idl/nsIPrincipal.idl +++ b/caps/idl/nsIPrincipal.idl @@ -8,7 +8,6 @@ #include "nsISerializable.idl" %{C++ -struct JSContext; struct JSPrincipals; #include "nsCOMPtr.h" #include "nsTArray.h" diff --git a/caps/include/nsScriptSecurityManager.h b/caps/include/nsScriptSecurityManager.h index c559d93e4c68..46e7563266d4 100644 --- a/caps/include/nsScriptSecurityManager.h +++ b/caps/include/nsScriptSecurityManager.h @@ -18,13 +18,10 @@ #include "pldhash.h" #include "plstr.h" #include "nsIScriptExternalNameSet.h" +#include "js/TypeDecls.h" #include -namespace JS { -template class Handle; -template class MutableHandle; -} class nsIDocShell; class nsString; class nsIClassInfo; diff --git a/client.mk b/client.mk index 95a0e2513782..5eb3f221f1b3 100644 --- a/client.mk +++ b/client.mk @@ -104,18 +104,9 @@ endif # Load mozconfig Options # See build pages, http://www.mozilla.org/build/ for how to set up mozconfig. - -MOZCONFIG_LOADER := build/autoconf/mozconfig2client-mk - -define CR - - -endef - -# As $(shell) doesn't preserve newlines, use sed to replace them with an -# unlikely sequence (||), which is then replaced back to newlines by make -# before evaluation. -$(eval $(subst ||,$(CR),$(shell _PYMAKE=$(.PYMAKE) $(TOPSRCDIR)/$(MOZCONFIG_LOADER) $(TOPSRCDIR) 2> $(TOPSRCDIR)/.mozconfig.out | sed 's/$$/||/'))) +# mozconfig.mk needs to be loaded multiple times by configure, so we don't check +# for INCLUDED_MOZCONFIG_MK +include $(TOPSRCDIR)/config/makefiles/mozconfig.mk ifdef AUTOCLOBBER export AUTOCLOBBER=1 diff --git a/config/makefiles/mozconfig.mk b/config/makefiles/mozconfig.mk new file mode 100644 index 000000000000..21408c46af48 --- /dev/null +++ b/config/makefiles/mozconfig.mk @@ -0,0 +1,33 @@ +# -*- makefile -*- +# vim:set ts=8 sw=8 sts=8 noet: +# +# 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/. +# + +INCLUDED_MOZCONFIG_MK = 1 + +# We are pulling in the mozconfig exports, so we only need to run once for the +# whole make process tree (not for each sub-make). Export this so the sub-makes +# don't read mozconfig multiple times. +export INCLUDED_MOZCONFIG_MK + +MOZCONFIG_LOADER := build/autoconf/mozconfig2client-mk + +define CR + + +endef + +# topsrcdir is used by rules.mk (set from the generated Makefile), while +# TOPSRCDIR is used by client.mk +ifneq (,$(topsrcdir)) +top := $(topsrcdir) +else +top := $(TOPSRCDIR) +endif +# As $(shell) doesn't preserve newlines, use sed to replace them with an +# unlikely sequence (||), which is then replaced back to newlines by make +# before evaluation. +$(eval $(subst ||,$(CR),$(shell _PYMAKE=$(.PYMAKE) $(top)/$(MOZCONFIG_LOADER) $(top) 2> $(top)/.mozconfig.out | sed 's/$$/||/'))) diff --git a/config/rules.mk b/config/rules.mk index 1642368e71da..45ca4ea68a55 100644 --- a/config/rules.mk +++ b/config/rules.mk @@ -10,6 +10,10 @@ ifndef topsrcdir $(error topsrcdir was not set)) endif +ifndef INCLUDED_MOZCONFIG_MK +include $(topsrcdir)/config/makefiles/mozconfig.mk +endif + # Integrate with mozbuild-generated make files. We first verify that no # variables provided by the automatically generated .mk files are # present. If they are, this is a violation of the separation of diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index ba1c3dd27d11..41fb068846ce 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -18,6 +18,7 @@ #include #endif +#include "js/TypeDecls.h" #include "js/RootingAPI.h" #include "mozilla/Assertions.h" #include "mozilla/GuardObjects.h" @@ -92,7 +93,6 @@ class nsTextFragment; class nsViewportInfo; class nsWrapperCache; -struct JSContext; struct JSPropertyDescriptor; struct JSRuntime; struct nsIntMargin; @@ -103,10 +103,6 @@ template class nsDataHashtable; template class nsRefPtrHashtable; template class nsReadingIterator; -namespace JS { -class Value; -} // namespace JS - namespace mozilla { class ErrorResult; class Selection; diff --git a/content/base/public/nsINode.h b/content/base/public/nsINode.h index c853a5b5429d..abde6c3bf8fe 100644 --- a/content/base/public/nsINode.h +++ b/content/base/public/nsINode.h @@ -19,6 +19,7 @@ #include "mozilla/ErrorResult.h" #include "mozilla/MemoryReporting.h" #include "mozilla/dom/EventTarget.h" // for base class +#include "js/TypeDecls.h" // for Handle, Value, JSObject, JSContext // Including 'windows.h' will #define GetClassInfo to something else. #ifdef XP_WIN @@ -67,11 +68,6 @@ template class Optional; } // namespace dom } // namespace mozilla -namespace JS { -class Value; -template class Handle; -} - #define NODE_FLAG_BIT(n_) (1U << (WRAPPER_CACHE_FLAGS_BITS_USED + (n_))) enum { diff --git a/content/base/src/nsFrameMessageManager.h b/content/base/src/nsFrameMessageManager.h index 55b2acc62110..5d57da54eae3 100644 --- a/content/base/src/nsFrameMessageManager.h +++ b/content/base/src/nsFrameMessageManager.h @@ -108,8 +108,6 @@ StructuredCloneData UnpackClonedMessageDataForChild(const ClonedMessageData& aDa } // namespace mozilla class nsAXPCNativeCallContext; -struct JSContext; -class JSObject; struct nsMessageListenerInfo { diff --git a/content/base/src/nsNodeUtils.h b/content/base/src/nsNodeUtils.h index f3df33763a74..d02d75d9e29b 100644 --- a/content/base/src/nsNodeUtils.h +++ b/content/base/src/nsNodeUtils.h @@ -8,10 +8,9 @@ #include "nsIContent.h" // for use in inline function (ParentChainChanged) #include "nsIMutationObserver.h" // for use in inline function (ParentChainChanged) +#include "js/TypeDecls.h" struct CharacterDataChangeInfo; -struct JSContext; -class JSObject; class nsIVariant; class nsIDOMNode; class nsIDOMUserDataHandler; diff --git a/content/base/test/Makefile.in b/content/base/test/Makefile.in index 50760d54e110..60d211fdb44c 100644 --- a/content/base/test/Makefile.in +++ b/content/base/test/Makefile.in @@ -552,6 +552,9 @@ MOCHITEST_FILES_C= \ test_bug708620.html \ file_bug708620.html \ file_bug708620-2.html \ + test_XHR_timeout.html \ + test_XHR_timeout.js \ + file_XHR_timeout.sjs \ test_bug717511.html \ file_bug717511.html \ file_bug717511.html^headers^ \ @@ -701,11 +704,6 @@ MOCHITEST_FILES_PARTS = $(foreach s,A B C,MOCHITEST_FILES_$(s)) # test_bug503473.html \ # file_bug503473-frame.sjs \ -# Disabled for frequent failures (bug 841505, bug 842344, etc) -# test_XHR_timeout.html \ -# test_XHR_timeout.js \ -# file_XHR_timeout.sjs \ - MOCHITEST_BROWSER_FILES = \ browser_bug593387.js \ browser_bug902350.js \ diff --git a/content/canvas/src/WebGLActiveInfo.h b/content/canvas/src/WebGLActiveInfo.h index fe24079669f3..54625c26e84d 100644 --- a/content/canvas/src/WebGLActiveInfo.h +++ b/content/canvas/src/WebGLActiveInfo.h @@ -9,12 +9,7 @@ #include "WebGLTypes.h" #include "nsISupports.h" #include "nsString.h" - -struct JSContext; -class JSObject; -namespace JS { -template class Handle; -} +#include "js/TypeDecls.h" namespace mozilla { diff --git a/content/events/src/nsDOMEvent.h b/content/events/src/nsDOMEvent.h index d307a1158f76..7d9da1107af0 100644 --- a/content/events/src/nsDOMEvent.h +++ b/content/events/src/nsDOMEvent.h @@ -18,12 +18,11 @@ #include "mozilla/dom/EventBinding.h" #include "nsIScriptGlobalObject.h" #include "Units.h" +#include "js/TypeDecls.h" class nsIContent; class nsIDOMEventTarget; class nsPresContext; -struct JSContext; -class JSObject; namespace mozilla { namespace dom { diff --git a/content/events/src/nsDOMUIEvent.cpp b/content/events/src/nsDOMUIEvent.cpp index faed83e1601d..6ea59d31ecd0 100644 --- a/content/events/src/nsDOMUIEvent.cpp +++ b/content/events/src/nsDOMUIEvent.cpp @@ -348,7 +348,7 @@ nsDOMUIEvent::IsChar() const case NS_KEY_EVENT: return static_cast(mEvent)->isChar; case NS_TEXT_EVENT: - return static_cast(mEvent)->isChar; + return static_cast(mEvent)->isChar; default: return false; } diff --git a/content/html/content/public/nsIHTMLCollection.h b/content/html/content/public/nsIHTMLCollection.h index 99e9e4baec92..76e5afac1bde 100644 --- a/content/html/content/public/nsIHTMLCollection.h +++ b/content/html/content/public/nsIHTMLCollection.h @@ -8,9 +8,8 @@ #include "nsIDOMHTMLCollection.h" #include "nsWrapperCache.h" +#include "js/TypeDecls.h" -struct JSContext; -class JSObject; class nsINode; class nsString; template class nsTArray; diff --git a/content/html/content/src/HTMLCanvasElement.cpp b/content/html/content/src/HTMLCanvasElement.cpp index 21eee4079c87..7312b86edc17 100644 --- a/content/html/content/src/HTMLCanvasElement.cpp +++ b/content/html/content/src/HTMLCanvasElement.cpp @@ -5,7 +5,7 @@ #include "mozilla/dom/HTMLCanvasElement.h" -#include "BasicLayers.h" +#include "Layers.h" #include "imgIEncoder.h" #include "jsapi.h" #include "jsfriendapi.h" diff --git a/content/html/content/src/HTMLMediaElement.cpp b/content/html/content/src/HTMLMediaElement.cpp index 7de7d8586d7c..9a0d5c9184e2 100644 --- a/content/html/content/src/HTMLMediaElement.cpp +++ b/content/html/content/src/HTMLMediaElement.cpp @@ -54,7 +54,7 @@ #include "nsICachingChannel.h" #include "nsLayoutUtils.h" #include "nsVideoFrame.h" -#include "BasicLayers.h" +#include "Layers.h" #include #include "nsIAsyncVerifyRedirectCallback.h" #include "nsIAppShell.h" diff --git a/content/html/content/src/ValidityState.h b/content/html/content/src/ValidityState.h index 1756741d76f5..28711be86b39 100644 --- a/content/html/content/src/ValidityState.h +++ b/content/html/content/src/ValidityState.h @@ -9,9 +9,7 @@ #include "nsIDOMValidityState.h" #include "nsIConstraintValidation.h" #include "nsWrapperCache.h" - -class JSObject; -struct JSContext; +#include "js/TypeDecls.h" namespace mozilla { namespace dom { diff --git a/content/media/AudioNodeEngineNEON.cpp b/content/media/AudioNodeEngineNEON.cpp index 28a61ac3cdc5..61138eb3fe44 100644 --- a/content/media/AudioNodeEngineNEON.cpp +++ b/content/media/AudioNodeEngineNEON.cpp @@ -174,77 +174,53 @@ AudioBlockPanStereoToStereo_NEON(const float aInputL[WEBAUDIO_BLOCK_SIZE], ASSERT_ALIGNED(aOutputL); ASSERT_ALIGNED(aOutputR); - float32x4_t vinL0, vinL1, vinL2, vinL3; - float32x4_t vinR0, vinR1, vinR2, vinR3; - float32x4_t voutL0, voutL1, voutL2, voutL3; - float32x4_t voutR0, voutR1, voutR2, voutR3; + float32x4_t vinL0, vinL1; + float32x4_t vinR0, vinR1; + float32x4_t voutL0, voutL1; + float32x4_t voutR0, voutR1; float32x4_t vscaleL = vmovq_n_f32(aGainL); float32x4_t vscaleR = vmovq_n_f32(aGainR); if (aIsOnTheLeft) { - for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; i+=16) { + for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; i+=8) { vinL0 = vld1q_f32(ADDRESS_OF(aInputL, i)); vinL1 = vld1q_f32(ADDRESS_OF(aInputL, i+4)); - vinL2 = vld1q_f32(ADDRESS_OF(aInputL, i+8)); - vinL3 = vld1q_f32(ADDRESS_OF(aInputL, i+12)); vinR0 = vld1q_f32(ADDRESS_OF(aInputR, i)); vinR1 = vld1q_f32(ADDRESS_OF(aInputR, i+4)); - vinR2 = vld1q_f32(ADDRESS_OF(aInputR, i+8)); - vinR3 = vld1q_f32(ADDRESS_OF(aInputR, i+12)); voutL0 = vmlaq_f32(vinL0, vinR0, vscaleL); voutL1 = vmlaq_f32(vinL1, vinR1, vscaleL); - voutL2 = vmlaq_f32(vinL2, vinR2, vscaleL); - voutL3 = vmlaq_f32(vinL3, vinR3, vscaleL); vst1q_f32(ADDRESS_OF(aOutputL, i), voutL0); vst1q_f32(ADDRESS_OF(aOutputL, i+4), voutL1); - vst1q_f32(ADDRESS_OF(aOutputL, i+8), voutL2); - vst1q_f32(ADDRESS_OF(aOutputL, i+12), voutL3); voutR0 = vmulq_f32(vinR0, vscaleR); voutR1 = vmulq_f32(vinR1, vscaleR); - voutR2 = vmulq_f32(vinR2, vscaleR); - voutR3 = vmulq_f32(vinR3, vscaleR); vst1q_f32(ADDRESS_OF(aOutputR, i), voutR0); vst1q_f32(ADDRESS_OF(aOutputR, i+4), voutR1); - vst1q_f32(ADDRESS_OF(aOutputR, i+8), voutR2); - vst1q_f32(ADDRESS_OF(aOutputR, i+12), voutR3); } } else { - for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; i+=16) { + for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; i+=8) { vinL0 = vld1q_f32(ADDRESS_OF(aInputL, i)); vinL1 = vld1q_f32(ADDRESS_OF(aInputL, i+4)); - vinL2 = vld1q_f32(ADDRESS_OF(aInputL, i+8)); - vinL3 = vld1q_f32(ADDRESS_OF(aInputL, i+12)); vinR0 = vld1q_f32(ADDRESS_OF(aInputR, i)); vinR1 = vld1q_f32(ADDRESS_OF(aInputR, i+4)); - vinR2 = vld1q_f32(ADDRESS_OF(aInputR, i+8)); - vinR3 = vld1q_f32(ADDRESS_OF(aInputR, i+12)); voutL0 = vmulq_f32(vinL0, vscaleL); voutL1 = vmulq_f32(vinL1, vscaleL); - voutL2 = vmulq_f32(vinL2, vscaleL); - voutL3 = vmulq_f32(vinL3, vscaleL); vst1q_f32(ADDRESS_OF(aOutputL, i), voutL0); vst1q_f32(ADDRESS_OF(aOutputL, i+4), voutL1); - vst1q_f32(ADDRESS_OF(aOutputL, i+8), voutL2); - vst1q_f32(ADDRESS_OF(aOutputL, i+12), voutL3); voutR0 = vmlaq_f32(vinR0, vinL0, vscaleR); voutR1 = vmlaq_f32(vinR1, vinL1, vscaleR); - voutR2 = vmlaq_f32(vinR2, vinL2, vscaleR); - voutR3 = vmlaq_f32(vinR3, vinL3, vscaleR); vst1q_f32(ADDRESS_OF(aOutputR, i), voutR0); vst1q_f32(ADDRESS_OF(aOutputR, i+4), voutR1); - vst1q_f32(ADDRESS_OF(aOutputR, i+8), voutR2); - vst1q_f32(ADDRESS_OF(aOutputR, i+12), voutR3); } } } -} \ No newline at end of file +} diff --git a/content/media/webaudio/AudioBuffer.h b/content/media/webaudio/AudioBuffer.h index 18b02c63b8d3..5c999c846610 100644 --- a/content/media/webaudio/AudioBuffer.h +++ b/content/media/webaudio/AudioBuffer.h @@ -14,9 +14,7 @@ #include "nsAutoPtr.h" #include "nsTArray.h" #include "AudioContext.h" - -struct JSContext; -class JSObject; +#include "js/TypeDecls.h" namespace mozilla { diff --git a/content/media/webaudio/AudioContext.h b/content/media/webaudio/AudioContext.h index 8773a272f0dc..a3e518c10f8e 100644 --- a/content/media/webaudio/AudioContext.h +++ b/content/media/webaudio/AudioContext.h @@ -17,6 +17,7 @@ #include "nsDOMEventTargetHelper.h" #include "nsHashKeys.h" #include "nsTHashtable.h" +#include "js/TypeDecls.h" // X11 has a #define for CurrentTime. Unbelievable :-(. // See content/media/DOMMediaStream.h for more fun! @@ -24,8 +25,6 @@ #undef CurrentTime #endif -struct JSContext; -class JSObject; class nsPIDOMWindow; namespace mozilla { diff --git a/content/media/webaudio/AudioListener.h b/content/media/webaudio/AudioListener.h index 48c9bd172233..91bd4733529e 100644 --- a/content/media/webaudio/AudioListener.h +++ b/content/media/webaudio/AudioListener.h @@ -16,8 +16,7 @@ #include "AudioContext.h" #include "PannerNode.h" #include "WebAudioUtils.h" - -struct JSContext; +#include "js/TypeDecls.h" namespace mozilla { diff --git a/content/media/webaudio/AudioParam.h b/content/media/webaudio/AudioParam.h index 353aa96c4662..877ee4a01f99 100644 --- a/content/media/webaudio/AudioParam.h +++ b/content/media/webaudio/AudioParam.h @@ -15,8 +15,7 @@ #include "AudioNode.h" #include "mozilla/dom/TypedArray.h" #include "WebAudioUtils.h" - -struct JSContext; +#include "js/TypeDecls.h" namespace mozilla { diff --git a/content/media/webaudio/DelayProcessor.cpp b/content/media/webaudio/DelayProcessor.cpp index e20dace1b16d..e1805d56d82d 100644 --- a/content/media/webaudio/DelayProcessor.cpp +++ b/content/media/webaudio/DelayProcessor.cpp @@ -38,9 +38,7 @@ DelayProcessor::Process(const double *aPerFrameDelays, 0.0, static_cast(mMaxDelayFrames)); // Write the input sample to the correct location in our buffer - if (input) { - buffer[writeIndex] = input[i]; - } + buffer[writeIndex] = input ? input[i] : 0.0f; // Now, determine the correct read position. We adjust the read position to be // from currentDelayFrames frames in the past. We also interpolate the two input @@ -109,7 +107,10 @@ DelayProcessor::EnsureBuffer(uint32_t aNumberOfChannels) if (!mBuffer.SetLength(aNumberOfChannels)) { return false; } - const int numFrames = mMaxDelayFrames; + // The length of the buffer is one greater than the maximum delay so that + // writing an input frame does not overwrite the frame that would + // subsequently be read at maximum delay. + const int numFrames = mMaxDelayFrames + 1; for (uint32_t channel = 0; channel < aNumberOfChannels; ++channel) { if (!mBuffer[channel].SetLength(numFrames)) { return false; diff --git a/content/media/webaudio/test/Makefile.in b/content/media/webaudio/test/Makefile.in index 4193c446a7de..abd4d27ddac1 100644 --- a/content/media/webaudio/test/Makefile.in +++ b/content/media/webaudio/test/Makefile.in @@ -57,9 +57,11 @@ MOCHITEST_FILES := \ test_channelSplitterNode.html \ test_channelSplitterNodeWithVolume.html \ test_convolverNode.html \ + test_convolverNodeWithGain.html \ test_convolverNode_mono_mono.html \ test_currentTime.html \ test_delayNode.html \ + test_delayNodeAtMax.html \ test_delayNodeSmallMaxDelay.html \ test_delayNodeWithGain.html \ test_dynamicsCompressorNode.html \ diff --git a/content/media/webaudio/test/test_convolverNodeWithGain.html b/content/media/webaudio/test/test_convolverNodeWithGain.html new file mode 100644 index 000000000000..7bbe240890b6 --- /dev/null +++ b/content/media/webaudio/test/test_convolverNodeWithGain.html @@ -0,0 +1,62 @@ + + + + Test ConvolverNode after a GainNode - Bug 891254 + + + + +
+
+
+
+ + diff --git a/content/media/webaudio/test/test_delayNodeAtMax.html b/content/media/webaudio/test/test_delayNodeAtMax.html new file mode 100644 index 000000000000..6c7dde3d18cf --- /dev/null +++ b/content/media/webaudio/test/test_delayNodeAtMax.html @@ -0,0 +1,53 @@ + + + + Test DelayNode with maxDelayTime delay - bug 890528 + + + + +
+
+
+
+ + diff --git a/content/media/webaudio/test/webaudio.js b/content/media/webaudio/test/webaudio.js index 77d9366c92e4..e722ca0ae9a2 100644 --- a/content/media/webaudio/test/webaudio.js +++ b/content/media/webaudio/test/webaudio.js @@ -68,8 +68,6 @@ function getEmptyBuffer(context, length) { * This function assumes that the test file defines a single gTest variable with * the following properties and methods: * - * + length: mandatory property equal to the total number of frames which we - * are waiting to see in the output. * + numberOfChannels: optional property which specifies the number of channels * in the output. The default value is 2. * + createGraph: mandatory method which takes a context object and does @@ -84,9 +82,17 @@ function getEmptyBuffer(context, length) { * returns either one expected buffer or an array of * them, designating what is expected to be observed * in the output. If omitted, the output is expected - * to be silence. The sum of the length of the expected - * buffers should be equal to gTest.length. This - * function is guaranteed to be called before createGraph. + * to be silence. All buffers must have the same + * length, which must be a bufferSize supported by + * ScriptProcessorNode. This function is guaranteed + * to be called before createGraph. + * + length: property equal to the total number of frames which we are waiting + * to see in the output, mandatory if createExpectedBuffers is not + * provided, in which case it must be a bufferSize supported by + * ScriptProcessorNode (256, 512, 1024, 2048, 4096, 8192, or 16384). + * If createExpectedBuffers is provided then this must be equal to + * the number of expected buffers * the expected buffer length. + * * + skipOfflineContextTests: optional. when true, skips running tests on an offline * context by circumventing testOnOfflineContext. */ @@ -120,7 +126,9 @@ function runTest() "Correct number of channels for expected buffer " + i); expectedFrames += expectedBuffers[i].length; } - is(expectedFrames, gTest.length, "Correct number of expected frames"); + if (gTest.length && gTest.createExpectedBuffers) { + is(expectedFrames, gTest.length, "Correct number of expected frames"); + } if (gTest.createGraphAsync) { gTest.createGraphAsync(context, function(nodeToInspect) { diff --git a/content/media/webspeech/recognition/SpeechGrammar.h b/content/media/webspeech/recognition/SpeechGrammar.h index 15d3f8ddcf11..d1ccbbc31262 100644 --- a/content/media/webspeech/recognition/SpeechGrammar.h +++ b/content/media/webspeech/recognition/SpeechGrammar.h @@ -10,14 +10,13 @@ #include "nsCycleCollectionParticipant.h" #include "nsString.h" #include "nsWrapperCache.h" +#include "js/TypeDecls.h" #include "mozilla/Attributes.h" #include "mozilla/ErrorResult.h" #include "EnableWebSpeechRecognitionCheck.h" -struct JSContext; - namespace mozilla { namespace dom { diff --git a/content/media/webspeech/recognition/SpeechGrammarList.h b/content/media/webspeech/recognition/SpeechGrammarList.h index 75c2681cda1f..8771f4b595c2 100644 --- a/content/media/webspeech/recognition/SpeechGrammarList.h +++ b/content/media/webspeech/recognition/SpeechGrammarList.h @@ -9,6 +9,7 @@ #include "nsCOMPtr.h" #include "nsCycleCollectionParticipant.h" #include "nsWrapperCache.h" +#include "js/TypeDecls.h" #include "mozilla/Attributes.h" #include "mozilla/dom/BindingUtils.h" @@ -16,8 +17,6 @@ #include "EnableWebSpeechRecognitionCheck.h" #include "SpeechGrammar.h" -struct JSContext; - namespace mozilla { namespace dom { diff --git a/content/media/webspeech/recognition/SpeechRecognition.h b/content/media/webspeech/recognition/SpeechRecognition.h index 27ca1128d908..1480fdc428ce 100644 --- a/content/media/webspeech/recognition/SpeechRecognition.h +++ b/content/media/webspeech/recognition/SpeechRecognition.h @@ -12,6 +12,7 @@ #include "nsString.h" #include "nsWrapperCache.h" #include "nsTArray.h" +#include "js/TypeDecls.h" #include "nsIDOMNavigatorUserMedia.h" #include "nsITimer.h" @@ -30,7 +31,6 @@ #include "mozilla/dom/SpeechRecognitionError.h" -struct JSContext; class nsIDOMWindow; namespace mozilla { diff --git a/content/media/webspeech/recognition/SpeechRecognitionAlternative.h b/content/media/webspeech/recognition/SpeechRecognitionAlternative.h index d99490b733bd..b85702bd94f7 100644 --- a/content/media/webspeech/recognition/SpeechRecognitionAlternative.h +++ b/content/media/webspeech/recognition/SpeechRecognitionAlternative.h @@ -10,13 +10,12 @@ #include "nsString.h" #include "nsWrapperCache.h" #include "nsAutoPtr.h" +#include "js/TypeDecls.h" #include "mozilla/Attributes.h" #include "EnableWebSpeechRecognitionCheck.h" -struct JSContext; - namespace mozilla { namespace dom { diff --git a/content/media/webspeech/recognition/SpeechRecognitionResult.h b/content/media/webspeech/recognition/SpeechRecognitionResult.h index d1152feae7cd..678a0e7877d4 100644 --- a/content/media/webspeech/recognition/SpeechRecognitionResult.h +++ b/content/media/webspeech/recognition/SpeechRecognitionResult.h @@ -11,14 +11,13 @@ #include "nsWrapperCache.h" #include "nsAutoPtr.h" #include "nsTArray.h" +#include "js/TypeDecls.h" #include "mozilla/Attributes.h" #include "EnableWebSpeechRecognitionCheck.h" #include "SpeechRecognitionAlternative.h" -struct JSContext; - namespace mozilla { namespace dom { diff --git a/content/media/webspeech/recognition/SpeechRecognitionResultList.h b/content/media/webspeech/recognition/SpeechRecognitionResultList.h index 034b06ef2d35..ccdf310dddee 100644 --- a/content/media/webspeech/recognition/SpeechRecognitionResultList.h +++ b/content/media/webspeech/recognition/SpeechRecognitionResultList.h @@ -10,14 +10,13 @@ #include "nsWrapperCache.h" #include "nsAutoPtr.h" #include "nsTArray.h" +#include "js/TypeDecls.h" #include "mozilla/Attributes.h" #include "EnableWebSpeechRecognitionCheck.h" #include "SpeechRecognitionResult.h" -struct JSContext; - namespace mozilla { namespace dom { diff --git a/content/media/webspeech/synth/SpeechSynthesis.h b/content/media/webspeech/synth/SpeechSynthesis.h index 35fadeaf7185..bfa450ea92b4 100644 --- a/content/media/webspeech/synth/SpeechSynthesis.h +++ b/content/media/webspeech/synth/SpeechSynthesis.h @@ -10,12 +10,12 @@ #include "nsString.h" #include "nsWrapperCache.h" #include "nsRefPtrHashtable.h" +#include "js/TypeDecls.h" #include "EnableSpeechSynthesisCheck.h" #include "SpeechSynthesisUtterance.h" #include "SpeechSynthesisVoice.h" -struct JSContext; class nsIDOMWindow; namespace mozilla { diff --git a/content/media/webspeech/synth/SpeechSynthesisUtterance.h b/content/media/webspeech/synth/SpeechSynthesisUtterance.h index b2497eb758b0..d7fea62ae31d 100644 --- a/content/media/webspeech/synth/SpeechSynthesisUtterance.h +++ b/content/media/webspeech/synth/SpeechSynthesisUtterance.h @@ -9,12 +9,11 @@ #include "nsCOMPtr.h" #include "nsDOMEventTargetHelper.h" #include "nsString.h" +#include "js/TypeDecls.h" #include "EnableSpeechSynthesisCheck.h" #include "nsSpeechTask.h" -struct JSContext; - namespace mozilla { namespace dom { diff --git a/content/media/webspeech/synth/SpeechSynthesisVoice.h b/content/media/webspeech/synth/SpeechSynthesisVoice.h index ba5ea42f1809..d036fab94d3d 100644 --- a/content/media/webspeech/synth/SpeechSynthesisVoice.h +++ b/content/media/webspeech/synth/SpeechSynthesisVoice.h @@ -9,12 +9,11 @@ #include "nsCOMPtr.h" #include "nsString.h" #include "nsWrapperCache.h" +#include "js/TypeDecls.h" #include "EnableSpeechSynthesisCheck.h" #include "nsISpeechService.h" -struct JSContext; - namespace mozilla { namespace dom { diff --git a/content/xbl/src/nsXBLBinding.h b/content/xbl/src/nsXBLBinding.h index 28f3897ad3f9..534535ecf7ef 100644 --- a/content/xbl/src/nsXBLBinding.h +++ b/content/xbl/src/nsXBLBinding.h @@ -15,6 +15,7 @@ #include "nsTArray.h" #include "nsCycleCollectionParticipant.h" #include "nsISupportsImpl.h" +#include "js/TypeDecls.h" class nsXBLPrototypeBinding; class nsIContent; @@ -31,8 +32,6 @@ class XBLChildrenElement; } class nsAnonymousContentList; -struct JSContext; -class JSObject; // *********************************************************************/ // The XBLBinding class diff --git a/content/xbl/src/nsXBLPrototypeHandler.h b/content/xbl/src/nsXBLPrototypeHandler.h index 80b93f093643..be6d0a498993 100644 --- a/content/xbl/src/nsXBLPrototypeHandler.h +++ b/content/xbl/src/nsXBLPrototypeHandler.h @@ -15,8 +15,8 @@ #include "nsIWeakReference.h" #include "nsIScriptGlobalObject.h" #include "nsCycleCollectionParticipant.h" +#include "js/TypeDecls.h" -class JSObject; class nsIDOMEvent; class nsIContent; class nsIDOMUIEvent; @@ -26,10 +26,6 @@ class nsIObjectInputStream; class nsIObjectOutputStream; class nsXBLPrototypeBinding; -namespace JS { -template class MutableHandle; -} - namespace mozilla { namespace dom { class EventTarget; diff --git a/content/xbl/src/nsXBLSerialize.h b/content/xbl/src/nsXBLSerialize.h index 847c9b7d2c88..45f56266f994 100644 --- a/content/xbl/src/nsXBLSerialize.h +++ b/content/xbl/src/nsXBLSerialize.h @@ -9,11 +9,7 @@ #include "nsIObjectInputStream.h" #include "nsIObjectOutputStream.h" #include "nsINameSpaceManager.h" - -namespace JS { -template class Handle; -template class MutableHandle; -} +#include "js/TypeDecls.h" typedef uint8_t XBLBindingSerializeDetails; diff --git a/content/xul/document/src/XULDocument.h b/content/xul/document/src/XULDocument.h index 0462d2738649..c417f53a8a26 100644 --- a/content/xul/document/src/XULDocument.h +++ b/content/xul/document/src/XULDocument.h @@ -25,6 +25,8 @@ #include "mozilla/Attributes.h" +#include "js/TypeDecls.h" + class nsIRDFResource; class nsIRDFService; class nsPIWindowRoot; @@ -40,7 +42,6 @@ class nsIXULPrototypeScript; #include "nsURIHashKey.h" #include "nsInterfaceHashtable.h" -class JSObject; struct JSTracer; struct PRLogModuleInfo; diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl index 61829c5aaad2..24b512d7114b 100644 --- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -9,9 +9,9 @@ #include "nsIAtom.idl" %{ C++ +#include "js/TypeDecls.h" class nsPresContext; class nsIPresShell; -struct JSContext; %} /** diff --git a/dom/base/nsIGlobalObject.h b/dom/base/nsIGlobalObject.h index f9ec31995ee7..e088386c803a 100644 --- a/dom/base/nsIGlobalObject.h +++ b/dom/base/nsIGlobalObject.h @@ -8,8 +8,7 @@ #include "nsISupports.h" #include "nsIScriptObjectPrincipal.h" - -class JSObject; +#include "js/TypeDecls.h" #define NS_IGLOBALOBJECT_IID \ { 0x8503e9a9, 0x530, 0x4b26, \ diff --git a/dom/base/nsIScriptGlobalObject.h b/dom/base/nsIScriptGlobalObject.h index 0e6c9733153a..c7620937a3c0 100644 --- a/dom/base/nsIScriptGlobalObject.h +++ b/dom/base/nsIScriptGlobalObject.h @@ -10,11 +10,11 @@ #include "nsISupports.h" #include "nsEvent.h" #include "nsIGlobalObject.h" +#include "js/TypeDecls.h" class nsIScriptContext; class nsScriptErrorEvent; class nsIScriptGlobalObject; -class JSObject; // A helper function for nsIScriptGlobalObject implementations to use // when handling a script error. Generally called by the global when a context diff --git a/dom/base/nsIScriptTimeoutHandler.h b/dom/base/nsIScriptTimeoutHandler.h index b19f4fc2e21e..db03a38ad6aa 100644 --- a/dom/base/nsIScriptTimeoutHandler.h +++ b/dom/base/nsIScriptTimeoutHandler.h @@ -7,10 +7,8 @@ #define nsIScriptTimeoutHandler_h___ #include "nsTArray.h" +#include "js/TypeDecls.h" -namespace JS { -class Value; -} // namespace JS namespace mozilla { namespace dom { class Function; diff --git a/dom/base/nsLocation.h b/dom/base/nsLocation.h index 082e261c3e4d..615c67b49a69 100644 --- a/dom/base/nsLocation.h +++ b/dom/base/nsLocation.h @@ -12,10 +12,10 @@ #include "nsIWeakReferenceUtils.h" #include "nsWrapperCache.h" #include "nsCycleCollectionParticipant.h" +#include "js/TypeDecls.h" class nsIURI; class nsIDocShell; -struct JSContext; class nsIDocShellLoadInfo; //***************************************************************************** diff --git a/dom/base/nsPIDOMWindow.h b/dom/base/nsPIDOMWindow.h index 095327e843e3..4058a9822b10 100644 --- a/dom/base/nsPIDOMWindow.h +++ b/dom/base/nsPIDOMWindow.h @@ -14,12 +14,12 @@ #include "nsAutoPtr.h" #include "nsTArray.h" #include "mozilla/dom/EventTarget.h" +#include "js/TypeDecls.h" #define DOM_WINDOW_DESTROYED_TOPIC "dom-window-destroyed" #define DOM_WINDOW_FROZEN_TOPIC "dom-window-frozen" #define DOM_WINDOW_THAWED_TOPIC "dom-window-thawed" -class JSObject; class nsIArray; class nsIContent; class nsIDocShell; @@ -33,10 +33,6 @@ class nsPIWindowRoot; class nsXBLPrototypeHandler; struct nsTimeout; -namespace JS { -template class Handle; -} - namespace mozilla { namespace dom { class AudioContext; diff --git a/dom/base/nsPIWindowRoot.h b/dom/base/nsPIWindowRoot.h index 57acdeac9a3d..36450f623cf5 100644 --- a/dom/base/nsPIWindowRoot.h +++ b/dom/base/nsPIWindowRoot.h @@ -13,7 +13,6 @@ class nsPIDOMWindow; class nsIControllers; class nsIController; -struct JSContext; #define NS_IWINDOWROOT_IID \ { 0x3f71f50c, 0xa7e0, 0x43bc, \ diff --git a/dom/base/nsPerformance.h b/dom/base/nsPerformance.h index 15c50e88ef0e..aedc3e188faa 100644 --- a/dom/base/nsPerformance.h +++ b/dom/base/nsPerformance.h @@ -12,11 +12,10 @@ #include "nsDOMNavigationTiming.h" #include "nsContentUtils.h" #include "nsIDOMWindow.h" +#include "js/TypeDecls.h" class nsITimedChannel; class nsPerformance; -class JSObject; -struct JSContext; // Script "performance.timing" object class nsPerformanceTiming MOZ_FINAL : public nsWrapperCache diff --git a/dom/base/nsWrapperCache.h b/dom/base/nsWrapperCache.h index 76a5973f8284..4af57d3d9e50 100644 --- a/dom/base/nsWrapperCache.h +++ b/dom/base/nsWrapperCache.h @@ -13,8 +13,6 @@ #include "js/RootingAPI.h" struct JSTracer; -class JSObject; -struct JSContext; class XPCWrappedNativeScope; namespace mozilla { diff --git a/dom/bindings/BindingDeclarations.h b/dom/bindings/BindingDeclarations.h index 660a3a565f67..1f82a1d592ad 100644 --- a/dom/bindings/BindingDeclarations.h +++ b/dom/bindings/BindingDeclarations.h @@ -23,8 +23,6 @@ #include "nsTArray.h" #include "nsAutoPtr.h" // for nsRefPtr member variables -struct JSContext; -class JSObject; class nsWrapperCache; // nsGlobalWindow implements nsWrapperCache, but doesn't always use it. Don't diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 808b08ac8d2b..d1aa360775fb 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -7376,12 +7376,9 @@ class CGDOMJSProxyHandler_defineProperty(ClassMethod): " return true;\n" + "}\n") % (self.descriptor.nativeType) elif self.descriptor.supportsIndexedProperties(): - # XXXbz Once this is fixed to only throw in strict mode, update the - # code that decides whether to do a - # CGDOMJSProxyHandler_defineProperty at all. - set += ("if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {\n" + - " return ThrowErrorMessage(cx, MSG_NO_PROPERTY_SETTER, \"%s\");\n" + - "}\n") % self.descriptor.name + set += ("if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {\n" + " return js::IsInNonStrictPropertySet(cx) || ThrowErrorMessage(cx, MSG_NO_INDEXED_SETTER, \"%s\");\n" + "}\n" % self.descriptor.name) if UseHolderForUnforgeable(self.descriptor): defineOnUnforgeable = ("bool hasUnforgeable;\n" @@ -7408,15 +7405,10 @@ class CGDOMJSProxyHandler_defineProperty(ClassMethod): "return true;\n") else: if self.descriptor.supportsNamedProperties(): - # XXXbz Once this is fixed to only throw in strict mode, update - # the code that decides whether to do a - # CGDOMJSProxyHandler_defineProperty at all. If we support - # indexed properties, we won't get down here for indices, so we - # can just do our setter unconditionally here. set += (CGProxyNamedPresenceChecker(self.descriptor).define() + "\n" + "if (found) {\n" - " return ThrowErrorMessage(cx, MSG_NO_PROPERTY_SETTER, \"%s\");\n" - "}" % self.descriptor.name) + " return js::IsInNonStrictPropertySet(cx) || ThrowErrorMessage(cx, MSG_NO_NAMED_SETTER, \"%s\");\n" + "}\n" % self.descriptor.name) set += ("return mozilla::dom::DOMProxyHandler::defineProperty(%s);" % ", ".join(a.name for a in self.args)) return set @@ -7799,26 +7791,22 @@ return &instance;""" class CGDOMJSProxyHandler(CGClass): def __init__(self, descriptor): + assert (descriptor.supportsIndexedProperties() or + descriptor.supportsNamedProperties()) constructors = [CGDOMJSProxyHandler_CGDOMJSProxyHandler()] - methods = [CGDOMJSProxyHandler_getOwnPropertyDescriptor(descriptor)] - # XXXbz This should really just test supportsIndexedProperties() and - # supportsNamedProperties(), but that would make us throw in all cases - # because we don't know whether we're in strict mode. - if (descriptor.operations['IndexedSetter'] or - descriptor.operations['NamedSetter'] or - UseHolderForUnforgeable(descriptor)): - methods.extend([CGDOMJSProxyHandler_defineProperty(descriptor), - ClassUsingDeclaration("mozilla::dom::DOMProxyHandler", - "defineProperty")]) - methods.extend([CGDOMJSProxyHandler_getOwnPropertyNames(descriptor), - CGDOMJSProxyHandler_hasOwn(descriptor), - CGDOMJSProxyHandler_get(descriptor), - CGDOMJSProxyHandler_className(descriptor), - CGDOMJSProxyHandler_finalizeInBackground(descriptor), - CGDOMJSProxyHandler_finalize(descriptor), - CGDOMJSProxyHandler_getElementIfPresent(descriptor), - CGDOMJSProxyHandler_getInstance(), - CGDOMJSProxyHandler_delete(descriptor)]) + methods = [CGDOMJSProxyHandler_getOwnPropertyDescriptor(descriptor), + CGDOMJSProxyHandler_defineProperty(descriptor), + ClassUsingDeclaration("mozilla::dom::DOMProxyHandler", + "defineProperty"), + CGDOMJSProxyHandler_getOwnPropertyNames(descriptor), + CGDOMJSProxyHandler_hasOwn(descriptor), + CGDOMJSProxyHandler_get(descriptor), + CGDOMJSProxyHandler_className(descriptor), + CGDOMJSProxyHandler_finalizeInBackground(descriptor), + CGDOMJSProxyHandler_finalize(descriptor), + CGDOMJSProxyHandler_getElementIfPresent(descriptor), + CGDOMJSProxyHandler_getInstance(), + CGDOMJSProxyHandler_delete(descriptor)] CGClass.__init__(self, 'DOMProxyHandler', bases=[ClassBase('mozilla::dom::DOMProxyHandler')], constructors=constructors, diff --git a/dom/bindings/Date.h b/dom/bindings/Date.h index 26448e077b1c..da7b2c7af4d9 100644 --- a/dom/bindings/Date.h +++ b/dom/bindings/Date.h @@ -9,13 +9,7 @@ #ifndef mozilla_dom_Date_h #define mozilla_dom_Date_h -class JSObject; -struct JSContext; - -namespace JS { -class Value; -template class MutableHandle; -} // namespace JS +#include "js/TypeDecls.h" namespace mozilla { namespace dom { diff --git a/dom/bindings/ErrorResult.h b/dom/bindings/ErrorResult.h index d32a7a719a0f..51b10eb3f83e 100644 --- a/dom/bindings/ErrorResult.h +++ b/dom/bindings/ErrorResult.h @@ -18,8 +18,6 @@ #include "nsStringGlue.h" #include "mozilla/Assertions.h" -struct JSContext; - namespace mozilla { namespace dom { diff --git a/dom/bindings/Errors.msg b/dom/bindings/Errors.msg index 911b75a74b47..d6a6e37d64cc 100644 --- a/dom/bindings/Errors.msg +++ b/dom/bindings/Errors.msg @@ -30,7 +30,8 @@ MSG_DEF(MSG_SETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, "'{0}' setter called on MSG_DEF(MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 1, "\"this\" object does not implement interface {0}.") MSG_DEF(MSG_NOT_IN_UNION, 2, "{0} could not be converted to any of: {1}.") MSG_DEF(MSG_ILLEGAL_CONSTRUCTOR, 0, "Illegal constructor.") -MSG_DEF(MSG_NO_PROPERTY_SETTER, 1, "{0} doesn't have an indexed property setter.") +MSG_DEF(MSG_NO_INDEXED_SETTER, 1, "{0} doesn't have an indexed property setter.") +MSG_DEF(MSG_NO_NAMED_SETTER, 1, "{0} doesn't have a named property setter.") MSG_DEF(MSG_ENFORCE_RANGE_NON_FINITE, 1, "Non-finite value is out of range for {0}.") MSG_DEF(MSG_ENFORCE_RANGE_OUT_OF_RANGE, 1, "Value is out of range for {0}.") MSG_DEF(MSG_NOT_SEQUENCE, 1, "{0} can't be converted to a sequence.") diff --git a/dom/bindings/test/Makefile.in b/dom/bindings/test/Makefile.in index f032f562f315..bd2b82da1cae 100644 --- a/dom/bindings/test/Makefile.in +++ b/dom/bindings/test/Makefile.in @@ -76,6 +76,7 @@ MOCHITEST_FILES := \ test_exception_messages.html \ test_bug707564.html \ test_bug907548.html \ + test_defineProperty.html \ $(NULL) MOCHITEST_CHROME_FILES = \ diff --git a/dom/bindings/test/test_defineProperty.html b/dom/bindings/test/test_defineProperty.html new file mode 100644 index 000000000000..f8f5f6283edb --- /dev/null +++ b/dom/bindings/test/test_defineProperty.html @@ -0,0 +1,157 @@ + + + + + + Test for Bug 910220 + + + + +Mozilla Bug 910220 +

+ +
+
+ + + diff --git a/dom/bluetooth/BluetoothUtils.h b/dom/bluetooth/BluetoothUtils.h index f10fa8edcfe5..2156207f1d4f 100644 --- a/dom/bluetooth/BluetoothUtils.h +++ b/dom/bluetooth/BluetoothUtils.h @@ -8,9 +8,7 @@ #define mozilla_dom_bluetooth_bluetoothutils_h__ #include "BluetoothCommon.h" - -struct JSContext; -class JSObject; +#include "js/TypeDecls.h" BEGIN_BLUETOOTH_NAMESPACE diff --git a/dom/cellbroadcast/src/CellBroadcast.h b/dom/cellbroadcast/src/CellBroadcast.h index 34d5ff7e461b..7ee1f73ad962 100644 --- a/dom/cellbroadcast/src/CellBroadcast.h +++ b/dom/cellbroadcast/src/CellBroadcast.h @@ -10,9 +10,7 @@ #include "mozilla/ErrorResult.h" #include "nsDOMEventTargetHelper.h" #include "nsICellBroadcastProvider.h" - -class JSObject; -struct JSContext; +#include "js/TypeDecls.h" class nsPIDOMWindow; diff --git a/dom/imptests/failures/webapps/DOMCore/tests/submissions/Ms2ger/test_Document-getElementsByTagName.html.json b/dom/imptests/failures/webapps/DOMCore/tests/submissions/Ms2ger/test_Document-getElementsByTagName.html.json index 53be448185a3..fd54d80729b8 100644 --- a/dom/imptests/failures/webapps/DOMCore/tests/submissions/Ms2ger/test_Document-getElementsByTagName.html.json +++ b/dom/imptests/failures/webapps/DOMCore/tests/submissions/Ms2ger/test_Document-getElementsByTagName.html.json @@ -1,5 +1,4 @@ { - "Shouldn't be able to set unsigned properties on a HTMLCollection (strict mode)": true, "Document.getElementsByTagName 1": true, "Document.getElementsByTagName 2": true } diff --git a/dom/interfaces/base/nsIDOMHistory.idl b/dom/interfaces/base/nsIDOMHistory.idl index 080e9dc3172c..d2804240afe8 100644 --- a/dom/interfaces/base/nsIDOMHistory.idl +++ b/dom/interfaces/base/nsIDOMHistory.idl @@ -5,10 +5,6 @@ #include "domstubs.idl" -%{ C++ -struct JSContext; -%} - [scriptable, uuid(55226663-fe68-48ba-addf-08e32eaab569)] interface nsIDOMHistory : nsISupports { diff --git a/dom/interfaces/base/nsIStructuredCloneContainer.idl b/dom/interfaces/base/nsIStructuredCloneContainer.idl index 4d7dac470158..d1df5d50df3a 100644 --- a/dom/interfaces/base/nsIStructuredCloneContainer.idl +++ b/dom/interfaces/base/nsIStructuredCloneContainer.idl @@ -11,7 +11,7 @@ interface nsIVariant; interface nsIDocument; %{C++ -struct JSContext; +#include "js/TypeDecls.h" %} /** diff --git a/dom/interfaces/events/nsIDOMEventTarget.idl b/dom/interfaces/events/nsIDOMEventTarget.idl index 4b848bfde1a1..bb00563295dd 100644 --- a/dom/interfaces/events/nsIDOMEventTarget.idl +++ b/dom/interfaces/events/nsIDOMEventTarget.idl @@ -8,6 +8,7 @@ %{C++ #include "nsEvent.h" #include "mozilla/dom/Nullable.h" +#include "js/TypeDecls.h" using mozilla::dom::Nullable; @@ -20,7 +21,6 @@ class EventTarget; class nsPresContext; class nsEventChainPreVisitor; class nsEventChainPostVisitor; -struct JSContext; class nsEventListenerManager; %} diff --git a/dom/interfaces/json/nsIJSON.idl b/dom/interfaces/json/nsIJSON.idl index 41ac516e76a8..b09e4e069f0b 100644 --- a/dom/interfaces/json/nsIJSON.idl +++ b/dom/interfaces/json/nsIJSON.idl @@ -13,7 +13,7 @@ interface nsIScriptGlobalObject; [ptr] native JSContext(JSContext); %{C++ -namespace JS { class Value; } +#include "js/TypeDecls.h" %} /** diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 51e9cac0859f..2d0fe89a6c18 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -8,7 +8,7 @@ #include "TabChild.h" -#include "BasicLayers.h" +#include "Layers.h" #include "Blob.h" #include "ContentChild.h" #include "IndexedDBChild.h" diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 480395b1d4f4..e2c93bc15119 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -22,10 +22,9 @@ #include "nsITabParent.h" #include "nsWeakReference.h" #include "Units.h" +#include "js/TypeDecls.h" struct gfxMatrix; -struct JSContext; -class JSObject; class mozIApplication; class nsFrameLoader; class nsIURI; diff --git a/dom/network/interfaces/nsIDOMTCPSocket.idl b/dom/network/interfaces/nsIDOMTCPSocket.idl index 2983ed0627d2..f12afa40934b 100644 --- a/dom/network/interfaces/nsIDOMTCPSocket.idl +++ b/dom/network/interfaces/nsIDOMTCPSocket.idl @@ -32,7 +32,7 @@ interface nsISocketTransport; // Bug 797561 - Expose a server tcp socket API to web applications -[scriptable, uuid(b7803a0b-4492-45ec-ac7a-3e29f6445fa4)] +[scriptable, uuid(65f6d2c8-4be6-4695-958d-0735e8935289)] interface nsIDOMTCPSocket : nsISupports { /** @@ -44,7 +44,7 @@ interface nsIDOMTCPSocket : nsISupports * @param options An object specifying one or more parameters which * determine the details of the socket. * - * useSSL: true to create an SSL socket. Defaults to false. + * useSecureTransport: true to create an SSL socket. Defaults to false. * * binaryType: "arraybuffer" to use ArrayBuffer * instances in the ondata callback and as the argument @@ -74,6 +74,11 @@ interface nsIDOMTCPSocket : nsISupports nsIDOMTCPServerSocket listen(in unsigned short localPort, [optional] in jsval options, [optional] in unsigned short backlog); + /** + * Enable secure on channel. + */ + void upgradeToSecure(); + /** * The host of this socket object. */ diff --git a/dom/network/interfaces/nsITCPSocketChild.idl b/dom/network/interfaces/nsITCPSocketChild.idl index 1696873ebfb9..aa725918e9d1 100644 --- a/dom/network/interfaces/nsITCPSocketChild.idl +++ b/dom/network/interfaces/nsITCPSocketChild.idl @@ -8,7 +8,7 @@ interface nsITCPSocketInternal; interface nsIDOMWindow; // Interface to allow the content process socket to reach the IPC bridge. -[scriptable, uuid(edf07a93-36a6-4574-8e23-40f64ab5f596)] +[scriptable, uuid(ada5342d-6d45-4ff1-a7d3-6a4b150d0385)] interface nsITCPSocketChild : nsISupports { // Tell the chrome process to open a corresponding connection with the given parameters @@ -23,6 +23,7 @@ interface nsITCPSocketChild : nsISupports void resume(); void suspend(); void close(); + void startTLS(); /** * Initialize the TCP socket on the child side for IPC. It is called from the child side, diff --git a/dom/network/src/PTCPSocket.ipdl b/dom/network/src/PTCPSocket.ipdl index 538fb9715e4a..6e257cc54408 100644 --- a/dom/network/src/PTCPSocket.ipdl +++ b/dom/network/src/PTCPSocket.ipdl @@ -37,6 +37,7 @@ protocol PTCPSocket parent: Open(nsString host, uint16_t port, bool useSSL, nsString binaryType); Data(SendableData data); + StartTLS(); Suspend(); Resume(); Close(); diff --git a/dom/network/src/TCPServerSocketChild.h b/dom/network/src/TCPServerSocketChild.h index 05026ba47f2d..bbbfdd262981 100644 --- a/dom/network/src/TCPServerSocketChild.h +++ b/dom/network/src/TCPServerSocketChild.h @@ -11,8 +11,6 @@ { 0x41a77ec8, 0xfd86, 0x409e, { 0xae, 0xa9, 0xaf, 0x2c, 0xa4, 0x07, 0xef, 0x8e } } class nsITCPServerSocketInternal; -struct JSContext; -struct JSObject; namespace mozilla { namespace dom { diff --git a/dom/network/src/TCPServerSocketParent.h b/dom/network/src/TCPServerSocketParent.h index 881bb2a87973..1bc621b066cf 100644 --- a/dom/network/src/TCPServerSocketParent.h +++ b/dom/network/src/TCPServerSocketParent.h @@ -10,9 +10,6 @@ #include "nsCOMPtr.h" #include "nsIDOMTCPSocket.h" -struct JSContext; -struct JSObject; - namespace mozilla { namespace dom { diff --git a/dom/network/src/TCPSocket.js b/dom/network/src/TCPSocket.js index 50564dbe988e..fbb7288fd58e 100644 --- a/dom/network/src/TCPSocket.js +++ b/dom/network/src/TCPSocket.js @@ -157,6 +157,10 @@ TCPSocket.prototype = { // IPC socket actor _socketBridge: null, + // StartTLS + _waitingForStartTLS: false, + _pendingDataAfterStartTLS: [], + // Public accessors. get readyState() { return this._readyState; @@ -210,19 +214,23 @@ TCPSocket.prototype = { this._onclose = f; }, + _activateTLS: function() { + let securityInfo = this._transport.securityInfo + .QueryInterface(Ci.nsISSLSocketControl); + securityInfo.StartTLS(); + }, + // Helper methods. _createTransport: function ts_createTransport(host, port, sslMode) { - let options, optlen; - if (sslMode) { - options = [sslMode]; - optlen = 1; + let options; + if (sslMode === 'ssl') { + options = ['ssl']; } else { - options = null; - optlen = 0; + options = ['starttls']; } return Cc["@mozilla.org/network/socket-transport-service;1"] .getService(Ci.nsISocketTransportService) - .createTransport(options, optlen, host, port, null); + .createTransport(options, 1, host, port, null); }, _ensureCopying: function ts_ensureCopying() { @@ -248,6 +256,21 @@ TCPSocket.prototype = { if (self._multiplexStream.count) { self._ensureCopying(); } else { + // If we are waiting for initiating starttls, we can begin to + // activate tls now. + if (self._waitingForStartTLS && self._readyState == kOPEN) { + self._activateTLS(); + self._waitingForStartTLS = false; + // If we have pending data, we should send them, or fire + // a drain event if we are waiting for it. + if (self._pendingDataAfterStartTLS.length > 0) { + while (self._pendingDataAfterStartTLS.length) + self._multiplexStream.appendStream(self._pendingDataAfterStartTLS.shift()); + self._ensureCopying(); + return; + } + } + if (self._waitingForDrain) { self._waitingForDrain = false; self.callListener("drain"); @@ -435,7 +458,7 @@ TCPSocket.prototype = { that._host = host; that._port = port; if (options !== undefined) { - if (options.useSSL) { + if (options.useSecureTransport) { that._ssl = 'ssl'; } else { that._ssl = false; @@ -458,7 +481,30 @@ TCPSocket.prototype = { that._initStream(that._binaryType); return that; }, - + + upgradeToSecure: function ts_upgradeToSecure() { + if (this._readyState !== kOPEN) { + throw new Error("Socket not open."); + } + if (this._ssl == 'ssl') { + // Already SSL + return; + } + + this._ssl = 'ssl'; + + if (this._inChild) { + this._socketBridge.startTLS(); + return; + } + + if (this._multiplexStream.count == 0) { + this._activateTLS(); + } else { + this._waitingForStartTLS = true; + } + }, + listen: function ts_listen(localPort, options, backlog) { if (!this.initWindowless()) return null; @@ -524,7 +570,14 @@ TCPSocket.prototype = { new_stream = new StringInputStream(); new_stream.setData(data, length); } - this._multiplexStream.appendStream(new_stream); + + if (this._waitingForStartTLS) { + // When we are waiting for starttls, new_stream is added to pendingData + // and will be appended to multiplexStream after tls had been set up. + this._pendingDataAfterStartTLS.push(new_stream); + } else { + this._multiplexStream.appendStream(new_stream); + } if (newBufferedAmount >= BUFFER_SIZE) { // If we buffered more than some arbitrary amount of data, diff --git a/dom/network/src/TCPSocketChild.cpp b/dom/network/src/TCPSocketChild.cpp index 8ee234b205b7..9a3576ccf643 100644 --- a/dom/network/src/TCPSocketChild.cpp +++ b/dom/network/src/TCPSocketChild.cpp @@ -158,6 +158,13 @@ TCPSocketChild::RecvCallback(const nsString& aType, return true; } +NS_IMETHODIMP +TCPSocketChild::StartTLS() +{ + SendStartTLS(); + return NS_OK; +} + NS_IMETHODIMP TCPSocketChild::Suspend() { diff --git a/dom/network/src/TCPSocketChild.h b/dom/network/src/TCPSocketChild.h index d29496001224..966f49a6fd4e 100644 --- a/dom/network/src/TCPSocketChild.h +++ b/dom/network/src/TCPSocketChild.h @@ -6,13 +6,12 @@ #include "nsITCPSocketChild.h" #include "nsCycleCollectionParticipant.h" #include "nsCOMPtr.h" +#include "js/TypeDecls.h" #define TCPSOCKETCHILD_CID \ { 0xa589d96f, 0x7e09, 0x4edf, { 0xa0, 0x1a, 0xeb, 0x49, 0x51, 0xf4, 0x2f, 0x37 } } class nsITCPSocketInternal; -struct JSContext; -class JSObject; namespace mozilla { namespace dom { diff --git a/dom/network/src/TCPSocketParent.cpp b/dom/network/src/TCPSocketParent.cpp index 6de19a3f907d..3ac96ea38dde 100644 --- a/dom/network/src/TCPSocketParent.cpp +++ b/dom/network/src/TCPSocketParent.cpp @@ -115,6 +115,15 @@ TCPSocketParent::InitJS(const JS::Value& aIntermediary, JSContext* aCx) return NS_OK; } +bool +TCPSocketParent::RecvStartTLS() +{ + NS_ENSURE_TRUE(mSocket, true); + nsresult rv = mSocket->UpgradeToSecure(); + NS_ENSURE_SUCCESS(rv, true); + return true; +} + bool TCPSocketParent::RecvSuspend() { diff --git a/dom/network/src/TCPSocketParent.h b/dom/network/src/TCPSocketParent.h index b9e0b74cfccf..d3ad9fd3128c 100644 --- a/dom/network/src/TCPSocketParent.h +++ b/dom/network/src/TCPSocketParent.h @@ -7,9 +7,7 @@ #include "nsCycleCollectionParticipant.h" #include "nsCOMPtr.h" #include "nsIDOMTCPSocket.h" - -struct JSContext; -class JSObject; +#include "js/TypeDecls.h" #define TCPSOCKETPARENT_CID \ { 0x4e7246c6, 0xa8b3, 0x426d, { 0x9c, 0x17, 0x76, 0xda, 0xb1, 0xe1, 0xe1, 0x4a } } @@ -49,6 +47,7 @@ public: virtual bool RecvOpen(const nsString& aHost, const uint16_t& aPort, const bool& useSSL, const nsString& aBinaryType); + virtual bool RecvStartTLS() MOZ_OVERRIDE; virtual bool RecvSuspend() MOZ_OVERRIDE; virtual bool RecvResume() MOZ_OVERRIDE; virtual bool RecvClose() MOZ_OVERRIDE; diff --git a/dom/plugins/base/nsNPAPIPluginInstance.h b/dom/plugins/base/nsNPAPIPluginInstance.h index 9e3beeebd9c6..490f00bc343e 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.h +++ b/dom/plugins/base/nsNPAPIPluginInstance.h @@ -16,6 +16,7 @@ #include "nsInterfaceHashtable.h" #include "nsHashKeys.h" #include +#include "js/TypeDecls.h" #ifdef MOZ_WIDGET_ANDROID #include "nsAutoPtr.h" #include "nsIRunnable.h" @@ -30,8 +31,6 @@ class SharedPluginTexture; #include "mozilla/TimeStamp.h" #include "mozilla/PluginLibrary.h" -class JSObject; - class nsPluginStreamListenerPeer; // browser-initiated stream class class nsNPAPIPluginStreamListener; // plugin-initiated stream class class nsIPluginInstanceOwner; diff --git a/dom/promise/Promise.h b/dom/promise/Promise.h index d8617815929f..1ef7c6500af7 100644 --- a/dom/promise/Promise.h +++ b/dom/promise/Promise.h @@ -15,8 +15,7 @@ #include "nsWrapperCache.h" #include "nsAutoPtr.h" #include "nsPIDOMWindow.h" - -struct JSContext; +#include "js/TypeDecls.h" namespace mozilla { namespace dom { diff --git a/dom/promise/PromiseResolver.h b/dom/promise/PromiseResolver.h index fcd9e949b6e8..f6b8975964ca 100644 --- a/dom/promise/PromiseResolver.h +++ b/dom/promise/PromiseResolver.h @@ -12,8 +12,7 @@ #include "mozilla/dom/BindingDeclarations.h" #include "nsCycleCollectionParticipant.h" #include "nsWrapperCache.h" - -struct JSContext; +#include "js/TypeDecls.h" namespace mozilla { namespace dom { diff --git a/dom/src/geolocation/nsGeoPosition.h b/dom/src/geolocation/nsGeoPosition.h index 457e95a4c385..375826a3cff4 100644 --- a/dom/src/geolocation/nsGeoPosition.h +++ b/dom/src/geolocation/nsGeoPosition.h @@ -14,8 +14,7 @@ #include "nsCycleCollectionParticipant.h" #include "nsWrapperCache.h" #include "mozilla/dom/Nullable.h" - -struct JSContext; +#include "js/TypeDecls.h" //////////////////////////////////////////////////// // nsGeoPositionCoords diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js index bb8884d9d943..fb5c06529fc5 100644 --- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -3129,11 +3129,11 @@ RadioInterface.prototype = { .setMessageDeliveryByMessageId(context.sms.id, null, context.sms.delivery, - message.deliveryStatus, + response.deliveryStatus, null, function notifyResult(rv, domMessage) { // TODO bug 832140 handle !Components.isSuccessCode(rv) - let topic = (message.deliveryStatus == RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS) + let topic = (response.deliveryStatus == RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS) ? kSmsDeliverySuccessObserverTopic : kSmsDeliveryErrorObserverTopic; Services.obs.notifyObservers(domMessage, topic, null); diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html index 8f7370c1c6d1..eaeda570150b 100644 --- a/dom/tests/mochitest/general/test_interfaces.html +++ b/dom/tests/mochitest/general/test_interfaces.html @@ -80,6 +80,7 @@ var interfaceNamesInGlobalScope = "Attr", "Audio", "AudioBuffer", + {name: "AudioChannelManager", b2g: true}, "AudioContext", "AudioBufferSourceNode", "AudioDestinationNode", @@ -94,8 +95,14 @@ var interfaceNamesInGlobalScope = "BiquadFilterNode", "Blob", "BlobEvent", + {name: "BluetoothAdapter", b2g: true}, + {name: "BluetoothDevice", b2g: true}, + {name: "BluetoothDeviceEvent", b2g: true}, + {name: "BluetoothManager", b2g: true}, + {name: "BluetoothStatusChangedEvent", b2g: true}, {name: "BoxObject", xbl: true}, - {name: "BrowserFeedWriter", android: false}, + {name: "BrowserFeedWriter", desktop: true}, + {name: "CallEvent", b2g: true}, "CameraCapabilities", "CameraControl", "CameraManager", @@ -104,6 +111,7 @@ var interfaceNamesInGlobalScope = "CanvasRenderingContext2D", "CaretPosition", "CDATASection", + {name: "CFStateChangeEvent", b2g: true}, "ChannelMergerNode", "ChannelSplitterNode", "CharacterData", @@ -117,7 +125,7 @@ var interfaceNamesInGlobalScope = "CompositionEvent", "Controllers", "ConvolverNode", - {name: "CRMFObject", android: false}, + {name: "CRMFObject", desktop: true}, "Crypto", "CSS", "CSS2Properties", @@ -144,6 +152,7 @@ var interfaceNamesInGlobalScope = "CustomEvent", "DataChannel", "DataContainerEvent", + {name: "DataErrorEvent", b2g: true}, "DataTransfer", "DelayNode", "DesktopNotification", @@ -185,13 +194,14 @@ var interfaceNamesInGlobalScope = "FileList", "FileReader", "FileRequest", + {name: "FMRadio", b2g: true}, "FocusEvent", "FormData", "GainNode", - {name: "Gamepad", android: false}, - {name: "GamepadAxisMoveEvent", android: false}, - {name: "GamepadButtonEvent", android: false}, - {name: "GamepadEvent", android: false}, + {name: "Gamepad", desktop: true}, + {name: "GamepadAxisMoveEvent", desktop: true}, + {name: "GamepadButtonEvent", desktop: true}, + {name: "GamepadEvent", desktop: true}, "HashChangeEvent", "History", "HTMLAnchorElement", @@ -265,6 +275,7 @@ var interfaceNamesInGlobalScope = "HTMLUListElement", "HTMLUnknownElement", "HTMLVideoElement", + {name: "IccCardLockErrorEvent", b2g: true}, "IDBCursor", "IDBCursorWithValue", "IDBDatabase", @@ -279,7 +290,7 @@ var interfaceNamesInGlobalScope = "IDBVersionChangeEvent", "Image", "ImageData", - {name: "InstallTrigger", xbl: false}, + {name: "InstallTrigger", b2g: false, xbl: false}, "KeyEvent", "KeyboardEvent", "LoadStatus", @@ -302,18 +313,28 @@ var interfaceNamesInGlobalScope = "ModalContentWindow", "MouseEvent", "MouseScrollEvent", + {name: "MozActivity", b2g: true}, "MozApplicationEvent", "MozCanvasPrintState", + {name: "MozCellBroadcast", b2g: true}, + {name: "MozCellBroadcastEvent", b2g: true}, "MozConnection", "mozContact", "MozContactChangeEvent", "MozCSSKeyframeRule", "MozCSSKeyframesRule", + {name: "MozEmergencyCbModeEvent", b2g: true}, + {name: "MozIccManager", b2g: true}, + {name: "MozInputContext", b2g: true}, + {name: "MozInputMethod", b2g: true}, + {name: "MozInputMethodManager", b2g: true}, "MozMmsEvent", "MozMmsMessage", + {name: "MozMobileConnection", b2g: true}, "MozMobileMessageManager", "MozMobileMessageThread", "MozNamedAttrMap", + {name: "MozOtaStatusEvent", b2g: true}, "MozPowerManager", "mozRTCIceCandidate", "mozRTCPeerConnection", @@ -323,7 +344,13 @@ var interfaceNamesInGlobalScope = "MozSmsFilter", "MozSmsMessage", "MozSmsSegmentInfo", + {name: "MozStkCommandEvent", b2g: true}, + {name: "MozTimeManager", b2g: true}, + {name: "MozVoicemail", b2g: true}, + {name: "MozVoicemailEvent", b2g: true}, "MozWakeLock", + {name: "MozWifiConnectionInfoEvent", b2g: true}, + {name: "MozWifiStatusChangeEvent", b2g: true}, "MutationEvent", "MutationObserver", "MutationRecord", @@ -355,8 +382,8 @@ var interfaceNamesInGlobalScope = "PopupBlockedEvent", "ProcessingInstruction", "ProgressEvent", - {name: "Promise", release: false}, - {name: "PromiseResolver", release: false}, + {name: "Promise", b2g: false, release: false}, + {name: "PromiseResolver", b2g: false, release: false}, "PropertyNodeList", "Range", "RecordErrorEvent", @@ -504,6 +531,9 @@ var interfaceNamesInGlobalScope = "SVGViewElement", "SVGZoomAndPan", "SVGZoomEvent", + {name: "Telephony", b2g: true}, + {name: "TelephonyCall", b2g: true}, + {name: "TelephonyCallGroup", b2g: true}, "Text", "TextDecoder", "TextEncoder", @@ -524,6 +554,7 @@ var interfaceNamesInGlobalScope = "URL", {name: "UserDataHandler", xbl: true}, "UserProximityEvent", + {name: "USSDReceivedEvent", b2g: true}, "ValidityState", "VideoStreamTrack", "WaveShaperNode", @@ -572,7 +603,8 @@ function createInterfaceMap(isXBLScope) { var version = SpecialPowers.Cc["@mozilla.org/xre/app-info;1"].getService(SpecialPowers.Ci.nsIXULAppInfo).version; var isNightly = version.endsWith("a1"); var isRelease = !version.contains("a"); - var isAndroid = navigator.userAgent.indexOf("Android") >= 0; + var isDesktop = !/Mobile|Tablet/.test(navigator.userAgent); + var isB2G = !isDesktop && !navigator.userAgent.contains("Android"); var interfaceMap = {}; for (var entry of ecmaGlobals) { if (typeof(entry) === "string") { @@ -587,12 +619,13 @@ function createInterfaceMap(isXBLScope) { for (var entry of interfaceNamesInGlobalScope) { if (typeof(entry) === "string") { interfaceMap[entry] = true; - } else if (entry.xbl === isXBLScope || - entry.android === isAndroid || - entry.release === isRelease) { - interfaceMap[entry.name] = true; - } else { + } else if (entry.xbl === !isXBLScope || + entry.desktop === !isDesktop || + entry.b2g === !isB2G || + entry.release === !isRelease) { interfaceMap[entry.name] = false; + } else { + interfaceMap[entry.name] = true; } } return interfaceMap; diff --git a/dom/webidl/TreeColumns.webidl b/dom/webidl/TreeColumns.webidl index 48511fe5d18f..5a0e7117a6ea 100644 --- a/dom/webidl/TreeColumns.webidl +++ b/dom/webidl/TreeColumns.webidl @@ -44,7 +44,7 @@ interface TreeColumns { /** * Parametric column getters. */ - getter MozTreeColumn? getNamedColumn(DOMString id); + getter MozTreeColumn? getNamedColumn(DOMString name); getter MozTreeColumn? getColumnAt(unsigned long index); /** diff --git a/dom/workers/test/Makefile.in b/dom/workers/test/Makefile.in index 741d7048f1c4..f62f30d1b9be 100644 --- a/dom/workers/test/Makefile.in +++ b/dom/workers/test/Makefile.in @@ -108,8 +108,12 @@ MOCHITEST_FILES = \ url_worker.js \ $(NULL) -# Disabled for frequent failures (bug 841505, bug 842344, etc) -# test_xhr_timeout.html \ +# Bug 842386 - Disabled on OSX due to intermittent failures. +ifneq ($(OS_ARCH), Darwin) +MOCHITEST_FILES += \ + test_xhr_timeout.html \ + $(NULL) +endif MOCHITEST_CHROME_FILES = \ test_chromeWorker.xul \ diff --git a/embedding/components/windowwatcher/src/nsWindowWatcher.h b/embedding/components/windowwatcher/src/nsWindowWatcher.h index 78ee962dce86..205afbe94f6d 100644 --- a/embedding/components/windowwatcher/src/nsWindowWatcher.h +++ b/embedding/components/windowwatcher/src/nsWindowWatcher.h @@ -17,6 +17,7 @@ #include "nsIPromptFactory.h" #include "nsPIWindowWatcher.h" #include "nsTArray.h" +#include "js/TypeDecls.h" class nsIURI; class nsIDocShellTreeItem; @@ -26,8 +27,6 @@ class nsString; class nsWatcherWindowEnumerator; class nsIScriptContext; class nsPromptService; -struct JSContext; -class JSObject; struct nsWatcherWindowEntry; struct SizeSpec; diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index fdba9778dd59..7f1ca633b424 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -712,6 +712,121 @@ ContainerLayer::ContainerLayer(LayerManager* aManager, void* aImplData) ContainerLayer::~ContainerLayer() {} +void +ContainerLayer::InsertAfter(Layer* aChild, Layer* aAfter) +{ + NS_ASSERTION(aChild->Manager() == Manager(), + "Child has wrong manager"); + NS_ASSERTION(!aChild->GetParent(), + "aChild already in the tree"); + NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(), + "aChild already has siblings?"); + NS_ASSERTION(!aAfter || + (aAfter->Manager() == Manager() && + aAfter->GetParent() == this), + "aAfter is not our child"); + + aChild->SetParent(this); + if (aAfter == mLastChild) { + mLastChild = aChild; + } + if (!aAfter) { + aChild->SetNextSibling(mFirstChild); + if (mFirstChild) { + mFirstChild->SetPrevSibling(aChild); + } + mFirstChild = aChild; + NS_ADDREF(aChild); + DidInsertChild(aChild); + return; + } + + Layer* next = aAfter->GetNextSibling(); + aChild->SetNextSibling(next); + aChild->SetPrevSibling(aAfter); + if (next) { + next->SetPrevSibling(aChild); + } + aAfter->SetNextSibling(aChild); + NS_ADDREF(aChild); + DidInsertChild(aChild); +} + +void +ContainerLayer::RemoveChild(Layer *aChild) +{ + NS_ASSERTION(aChild->Manager() == Manager(), + "Child has wrong manager"); + NS_ASSERTION(aChild->GetParent() == this, + "aChild not our child"); + + Layer* prev = aChild->GetPrevSibling(); + Layer* next = aChild->GetNextSibling(); + if (prev) { + prev->SetNextSibling(next); + } else { + this->mFirstChild = next; + } + if (next) { + next->SetPrevSibling(prev); + } else { + this->mLastChild = prev; + } + + aChild->SetNextSibling(nullptr); + aChild->SetPrevSibling(nullptr); + aChild->SetParent(nullptr); + + this->DidRemoveChild(aChild); + NS_RELEASE(aChild); +} + + +void +ContainerLayer::RepositionChild(Layer* aChild, Layer* aAfter) +{ + NS_ASSERTION(aChild->Manager() == Manager(), + "Child has wrong manager"); + NS_ASSERTION(aChild->GetParent() == this, + "aChild not our child"); + NS_ASSERTION(!aAfter || + (aAfter->Manager() == Manager() && + aAfter->GetParent() == this), + "aAfter is not our child"); + + Layer* prev = aChild->GetPrevSibling(); + Layer* next = aChild->GetNextSibling(); + if (prev == aAfter) { + // aChild is already in the correct position, nothing to do. + return; + } + if (prev) { + prev->SetNextSibling(next); + } + if (next) { + next->SetPrevSibling(prev); + } + if (!aAfter) { + aChild->SetPrevSibling(nullptr); + aChild->SetNextSibling(mFirstChild); + if (mFirstChild) { + mFirstChild->SetPrevSibling(aChild); + } + mFirstChild = aChild; + return; + } + + Layer* afterNext = aAfter->GetNextSibling(); + if (afterNext) { + afterNext->SetPrevSibling(aChild); + } else { + mLastChild = aChild; + } + aAfter->SetNextSibling(aChild); + aChild->SetPrevSibling(aAfter); + aChild->SetNextSibling(afterNext); +} + void ContainerLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs) { @@ -827,6 +942,16 @@ ContainerLayer::ComputeEffectiveTransformsForChildren(const gfx3DMatrix& aTransf } } +/* static */ bool +ContainerLayer::HasOpaqueAncestorLayer(Layer* aLayer) +{ + for (Layer* l = aLayer->GetParent(); l; l = l->GetParent()) { + if (l->GetContentFlags() & Layer::CONTENT_OPAQUE) + return true; + } + return false; +} + void ContainerLayer::DidRemoveChild(Layer* aLayer) { diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 002055d1fd2b..fa29819997a4 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -1411,13 +1411,13 @@ public: * If aAfter is non-null, it must be a child of this container and * we insert after that layer. If it's null we insert at the start. */ - virtual void InsertAfter(Layer* aChild, Layer* aAfter) = 0; + virtual void InsertAfter(Layer* aChild, Layer* aAfter); /** * CONSTRUCTION PHASE ONLY * Remove aChild from the child list of this container. aChild must * be a child of this container. */ - virtual void RemoveChild(Layer* aChild) = 0; + virtual void RemoveChild(Layer* aChild); /** * CONSTRUCTION PHASE ONLY * Reposition aChild from the child list of this container. aChild must @@ -1425,7 +1425,7 @@ public: * If aAfter is non-null, it must be a child of this container and we * reposition after that layer. If it's null, we reposition at the start. */ - virtual void RepositionChild(Layer* aChild, Layer* aAfter) = 0; + virtual void RepositionChild(Layer* aChild, Layer* aAfter); /** * CONSTRUCTION PHASE ONLY @@ -1530,6 +1530,8 @@ public: protected: friend class ReadbackProcessor; + static bool HasOpaqueAncestorLayer(Layer* aLayer); + void DidInsertChild(Layer* aLayer); void DidRemoveChild(Layer* aLayer); diff --git a/gfx/layers/basic/BasicContainerLayer.cpp b/gfx/layers/basic/BasicContainerLayer.cpp index 9b9fbd9af083..6973aad37f03 100644 --- a/gfx/layers/basic/BasicContainerLayer.cpp +++ b/gfx/layers/basic/BasicContainerLayer.cpp @@ -15,6 +15,9 @@ #include "nsISupportsImpl.h" // for Layer::AddRef, etc #include "nsPoint.h" // for nsIntPoint #include "nsRect.h" // for nsIntRect +#include "gfx3DMatrix.h" // for gfx3DMatrix +#include "gfxMatrix.h" // for gfxMatrix +#include "nsRegion.h" // for nsIntRegion using namespace mozilla::gfx; @@ -24,12 +27,48 @@ namespace layers { BasicContainerLayer::~BasicContainerLayer() { while (mFirstChild) { - ContainerRemoveChild(mFirstChild, this); + ContainerLayer::RemoveChild(mFirstChild); } MOZ_COUNT_DTOR(BasicContainerLayer); } +void +BasicContainerLayer::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface) +{ + // We push groups for container layers if we need to, which always + // are aligned in device space, so it doesn't really matter how we snap + // containers. + gfxMatrix residual; + gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface; + idealTransform.ProjectTo2D(); + + if (!idealTransform.CanDraw2D()) { + mEffectiveTransform = idealTransform; + ComputeEffectiveTransformsForChildren(gfx3DMatrix()); + ComputeEffectiveTransformForMaskLayer(gfx3DMatrix()); + mUseIntermediateSurface = true; + return; + } + + mEffectiveTransform = SnapTransformTranslation(idealTransform, &residual); + // We always pass the ideal matrix down to our children, so there is no + // need to apply any compensation using the residual from SnapTransformTranslation. + ComputeEffectiveTransformsForChildren(idealTransform); + + ComputeEffectiveTransformForMaskLayer(aTransformToSurface); + + /* If we have a single child, it can just inherit our opacity, + * otherwise we need a PushGroup and we need to mark ourselves as using + * an intermediate surface so our children don't inherit our opacity + * via GetEffectiveOpacity. + * Having a mask layer always forces our own push group + */ + mUseIntermediateSurface = + GetMaskLayer() || (GetEffectiveOpacity() != 1.0 && + HasMultipleChildren()); +} + bool BasicContainerLayer::ChildrenPartitionVisibleRegion(const nsIntRect& aInRect) { diff --git a/gfx/layers/basic/BasicContainerLayer.h b/gfx/layers/basic/BasicContainerLayer.h index d444b30b5332..7673e28253a4 100644 --- a/gfx/layers/basic/BasicContainerLayer.h +++ b/gfx/layers/basic/BasicContainerLayer.h @@ -9,181 +9,15 @@ #include "BasicImplData.h" // for BasicImplData #include "BasicLayers.h" // for BasicLayerManager #include "Layers.h" // for Layer, ContainerLayer -#include "gfx3DMatrix.h" // for gfx3DMatrix -#include "gfxMatrix.h" // for gfxMatrix #include "nsDebug.h" // for NS_ASSERTION #include "nsISupportsUtils.h" // for NS_ADDREF, NS_RELEASE -#include "nsRegion.h" // for nsIntRegion #include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR struct nsIntRect; namespace mozilla { namespace layers { -template void -ContainerInsertAfter(Layer* aChild, Layer* aAfter, Container* aContainer) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(!aChild->GetParent(), - "aChild already in the tree"); - NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(), - "aChild already has siblings?"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - aChild->SetParent(aContainer); - if (aAfter == aContainer->mLastChild) { - aContainer->mLastChild = aChild; - } - if (!aAfter) { - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); - return; - } - - Layer* next = aAfter->GetNextSibling(); - aChild->SetNextSibling(next); - aChild->SetPrevSibling(aAfter); - if (next) { - next->SetPrevSibling(aChild); - } - aAfter->SetNextSibling(aChild); - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); -} - -template void -ContainerRemoveChild(Layer* aChild, Container* aContainer) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev) { - prev->SetNextSibling(next); - } else { - aContainer->mFirstChild = next; - } - if (next) { - next->SetPrevSibling(prev); - } else { - aContainer->mLastChild = prev; - } - - aChild->SetNextSibling(nullptr); - aChild->SetPrevSibling(nullptr); - aChild->SetParent(nullptr); - - aContainer->DidRemoveChild(aChild); - NS_RELEASE(aChild); -} - -template void -ContainerRepositionChild(Layer* aChild, Layer* aAfter, Container* aContainer) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev == aAfter) { - // aChild is already in the correct position, nothing to do. - return; - } - if (prev) { - prev->SetNextSibling(next); - } - if (next) { - next->SetPrevSibling(prev); - } - if (!aAfter) { - aChild->SetPrevSibling(nullptr); - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - return; - } - - Layer* afterNext = aAfter->GetNextSibling(); - if (afterNext) { - afterNext->SetPrevSibling(aChild); - } else { - aContainer->mLastChild = aChild; - } - aAfter->SetNextSibling(aChild); - aChild->SetPrevSibling(aAfter); - aChild->SetNextSibling(afterNext); -} - -template -static void -ContainerComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface, - Container* aContainer) -{ - // We push groups for container layers if we need to, which always - // are aligned in device space, so it doesn't really matter how we snap - // containers. - gfxMatrix residual; - gfx3DMatrix idealTransform = aContainer->GetLocalTransform()*aTransformToSurface; - idealTransform.ProjectTo2D(); - - if (!idealTransform.CanDraw2D()) { - aContainer->mEffectiveTransform = idealTransform; - aContainer->ComputeEffectiveTransformsForChildren(gfx3DMatrix()); - aContainer->ComputeEffectiveTransformForMaskLayer(gfx3DMatrix()); - aContainer->mUseIntermediateSurface = true; - return; - } - - aContainer->mEffectiveTransform = - aContainer->SnapTransformTranslation(idealTransform, &residual); - // We always pass the ideal matrix down to our children, so there is no - // need to apply any compensation using the residual from SnapTransformTranslation. - aContainer->ComputeEffectiveTransformsForChildren(idealTransform); - - aContainer->ComputeEffectiveTransformForMaskLayer(aTransformToSurface); - - /* If we have a single child, it can just inherit our opacity, - * otherwise we need a PushGroup and we need to mark ourselves as using - * an intermediate surface so our children don't inherit our opacity - * via GetEffectiveOpacity. - * Having a mask layer always forces our own push group - */ - aContainer->mUseIntermediateSurface = - aContainer->GetMaskLayer() || (aContainer->GetEffectiveOpacity() != 1.0 && - aContainer->HasMultipleChildren()); -} - class BasicContainerLayer : public ContainerLayer, public BasicImplData { - template - friend void ContainerInsertAfter(Layer* aChild, Layer* aAfter, Container* aContainer); - template - friend void ContainerRemoveChild(Layer* aChild, Container* aContainer); - template - friend void ContainerRepositionChild(Layer* aChild, Layer* aAfter, Container* aContainer); - template - friend void ContainerComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface, - Container* aContainer); - public: BasicContainerLayer(BasicLayerManager* aManager) : ContainerLayer(aManager, @@ -204,27 +38,24 @@ public: { NS_ASSERTION(BasicManager()->InConstruction(), "Can only set properties in construction phase"); - ContainerInsertAfter(aChild, aAfter, this); + ContainerLayer::InsertAfter(aChild, aAfter); } virtual void RemoveChild(Layer* aChild) { NS_ASSERTION(BasicManager()->InConstruction(), "Can only set properties in construction phase"); - ContainerRemoveChild(aChild, this); + ContainerLayer::RemoveChild(aChild); } virtual void RepositionChild(Layer* aChild, Layer* aAfter) { NS_ASSERTION(BasicManager()->InConstruction(), "Can only set properties in construction phase"); - ContainerRepositionChild(aChild, aAfter, this); + ContainerLayer::RepositionChild(aChild, aAfter); } - virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface) - { - ContainerComputeEffectiveTransforms(aTransformToSurface, this); - } + virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface); /** * Returns true when: diff --git a/gfx/layers/client/ClientContainerLayer.h b/gfx/layers/client/ClientContainerLayer.h index cecfa628de3d..20df9320f5fe 100644 --- a/gfx/layers/client/ClientContainerLayer.h +++ b/gfx/layers/client/ClientContainerLayer.h @@ -23,140 +23,9 @@ namespace layers { class ShadowableLayer; -template void -ContainerInsertAfter(Layer* aChild, Layer* aAfter, Container* aContainer) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(!aChild->GetParent(), - "aChild already in the tree"); - NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(), - "aChild already has siblings?"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - aChild->SetParent(aContainer); - if (aAfter == aContainer->mLastChild) { - aContainer->mLastChild = aChild; - } - if (!aAfter) { - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); - return; - } - - Layer* next = aAfter->GetNextSibling(); - aChild->SetNextSibling(next); - aChild->SetPrevSibling(aAfter); - if (next) { - next->SetPrevSibling(aChild); - } - aAfter->SetNextSibling(aChild); - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); -} - -template void -ContainerRemoveChild(Layer* aChild, Container* aContainer) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev) { - prev->SetNextSibling(next); - } else { - aContainer->mFirstChild = next; - } - if (next) { - next->SetPrevSibling(prev); - } else { - aContainer->mLastChild = prev; - } - - aChild->SetNextSibling(nullptr); - aChild->SetPrevSibling(nullptr); - aChild->SetParent(nullptr); - - aContainer->DidRemoveChild(aChild); - NS_RELEASE(aChild); -} - -template void -ContainerRepositionChild(Layer* aChild, Layer* aAfter, Container* aContainer) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev == aAfter) { - // aChild is already in the correct position, nothing to do. - return; - } - if (prev) { - prev->SetNextSibling(next); - } - if (next) { - next->SetPrevSibling(prev); - } - if (!aAfter) { - aChild->SetPrevSibling(nullptr); - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - return; - } - - Layer* afterNext = aAfter->GetNextSibling(); - if (afterNext) { - afterNext->SetPrevSibling(aChild); - } else { - aContainer->mLastChild = aChild; - } - aAfter->SetNextSibling(aChild); - aChild->SetPrevSibling(aAfter); - aChild->SetNextSibling(afterNext); -} - -static bool -HasOpaqueAncestorLayer(Layer* aLayer) -{ - for (Layer* l = aLayer->GetParent(); l; l = l->GetParent()) { - if (l->GetContentFlags() & Layer::CONTENT_OPAQUE) - return true; - } - return false; -} - class ClientContainerLayer : public ContainerLayer, public ClientLayer { - template - friend void ContainerInsertAfter(Layer* aChild, Layer* aAfter, Container* aContainer); - template - friend void ContainerRemoveChild(Layer* aChild, Container* aContainer); - template - friend void ContainerRepositionChild(Layer* aChild, Layer* aAfter, Container* aContainer); - public: ClientContainerLayer(ClientLayerManager* aManager) : ContainerLayer(aManager, @@ -168,7 +37,7 @@ public: virtual ~ClientContainerLayer() { while (mFirstChild) { - ContainerRemoveChild(mFirstChild, this); + ContainerLayer::RemoveChild(mFirstChild); } MOZ_COUNT_DTOR(ClientContainerLayer); @@ -219,33 +88,33 @@ public: "Can only set properties in construction phase"); ContainerLayer::SetVisibleRegion(aRegion); } - virtual void InsertAfter(Layer* aChild, Layer* aAfter) + virtual void InsertAfter(Layer* aChild, Layer* aAfter) MOZ_OVERRIDE { NS_ASSERTION(ClientManager()->InConstruction(), "Can only set properties in construction phase"); ClientManager()->InsertAfter(ClientManager()->Hold(this), ClientManager()->Hold(aChild), aAfter ? ClientManager()->Hold(aAfter) : nullptr); - ContainerInsertAfter(aChild, aAfter, this); + ContainerLayer::InsertAfter(aChild, aAfter); } - virtual void RemoveChild(Layer* aChild) + virtual void RemoveChild(Layer* aChild) MOZ_OVERRIDE { NS_ASSERTION(ClientManager()->InConstruction(), "Can only set properties in construction phase"); ClientManager()->RemoveChild(ClientManager()->Hold(this), ClientManager()->Hold(aChild)); - ContainerRemoveChild(aChild, this); + ContainerLayer::RemoveChild(aChild); } - virtual void RepositionChild(Layer* aChild, Layer* aAfter) + virtual void RepositionChild(Layer* aChild, Layer* aAfter) MOZ_OVERRIDE { NS_ASSERTION(ClientManager()->InConstruction(), "Can only set properties in construction phase"); ClientManager()->RepositionChild(ClientManager()->Hold(this), ClientManager()->Hold(aChild), aAfter ? ClientManager()->Hold(aAfter) : nullptr); - ContainerRepositionChild(aChild, aAfter, this); + ContainerLayer::RepositionChild(aChild, aAfter); } virtual Layer* AsLayer() { return this; } diff --git a/gfx/layers/composite/ContainerLayerComposite.cpp b/gfx/layers/composite/ContainerLayerComposite.cpp index 3ffa7d15835b..b1de280e951a 100644 --- a/gfx/layers/composite/ContainerLayerComposite.cpp +++ b/gfx/layers/composite/ContainerLayerComposite.cpp @@ -116,6 +116,11 @@ ContainerRender(ContainerT* aContainer, } else { surface = compositor->CreateRenderTarget(surfaceRect, mode); } + + if (!surface) { + return; + } + compositor->SetRenderTarget(surface); childOffset.x = visibleRect.x; childOffset.y = visibleRect.y; @@ -216,75 +221,6 @@ ContainerLayerComposite::~ContainerLayerComposite() } } -void -ContainerLayerComposite::InsertAfter(Layer* aChild, Layer* aAfter) -{ - NS_ASSERTION(aChild->Manager() == Manager(), - "Child has wrong manager"); - NS_ASSERTION(!aChild->GetParent(), - "aChild already in the tree"); - NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(), - "aChild already has siblings?"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == Manager() && - aAfter->GetParent() == this), - "aAfter is not our child"); - - aChild->SetParent(this); - if (aAfter == mLastChild) { - mLastChild = aChild; - } - if (!aAfter) { - aChild->SetNextSibling(mFirstChild); - if (mFirstChild) { - mFirstChild->SetPrevSibling(aChild); - } - mFirstChild = aChild; - NS_ADDREF(aChild); - DidInsertChild(aChild); - return; - } - - Layer* next = aAfter->GetNextSibling(); - aChild->SetNextSibling(next); - aChild->SetPrevSibling(aAfter); - if (next) { - next->SetPrevSibling(aChild); - } - aAfter->SetNextSibling(aChild); - NS_ADDREF(aChild); - DidInsertChild(aChild); -} - -void -ContainerLayerComposite::RemoveChild(Layer *aChild) -{ - NS_ASSERTION(aChild->Manager() == Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == this, - "aChild not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev) { - prev->SetNextSibling(next); - } else { - this->mFirstChild = next; - } - if (next) { - next->SetPrevSibling(prev); - } else { - this->mLastChild = prev; - } - - aChild->SetNextSibling(nullptr); - aChild->SetPrevSibling(nullptr); - aChild->SetParent(nullptr); - - this->DidRemoveChild(aChild); - NS_RELEASE(aChild); -} - void ContainerLayerComposite::Destroy() { @@ -306,51 +242,6 @@ ContainerLayerComposite::GetFirstChildComposite() return static_cast(mFirstChild->ImplData()); } -void -ContainerLayerComposite::RepositionChild(Layer* aChild, Layer* aAfter) -{ - NS_ASSERTION(aChild->Manager() == Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == this, - "aChild not our child"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == Manager() && - aAfter->GetParent() == this), - "aAfter is not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev == aAfter) { - // aChild is already in the correct position, nothing to do. - return; - } - if (prev) { - prev->SetNextSibling(next); - } - if (next) { - next->SetPrevSibling(prev); - } - if (!aAfter) { - aChild->SetPrevSibling(nullptr); - aChild->SetNextSibling(mFirstChild); - if (mFirstChild) { - mFirstChild->SetPrevSibling(aChild); - } - mFirstChild = aChild; - return; - } - - Layer* afterNext = aAfter->GetNextSibling(); - if (afterNext) { - afterNext->SetPrevSibling(aChild); - } else { - mLastChild = aChild; - } - aAfter->SetNextSibling(aChild); - aChild->SetPrevSibling(aAfter); - aChild->SetNextSibling(afterNext); -} - void ContainerLayerComposite::RenderLayer(const nsIntPoint& aOffset, const nsIntRect& aClipRect) diff --git a/gfx/layers/composite/ContainerLayerComposite.h b/gfx/layers/composite/ContainerLayerComposite.h index 1b587a4e2ec0..8b7f7dfc1bed 100644 --- a/gfx/layers/composite/ContainerLayerComposite.h +++ b/gfx/layers/composite/ContainerLayerComposite.h @@ -33,12 +33,6 @@ public: ~ContainerLayerComposite(); - void InsertAfter(Layer* aChild, Layer* aAfter); - - void RemoveChild(Layer* aChild); - - void RepositionChild(Layer* aChild, Layer* aAfter); - // LayerComposite Implementation virtual Layer* GetLayer() MOZ_OVERRIDE { return this; } diff --git a/gfx/layers/d3d10/ContainerLayerD3D10.cpp b/gfx/layers/d3d10/ContainerLayerD3D10.cpp index a8af6dda593c..dfd913581e19 100644 --- a/gfx/layers/d3d10/ContainerLayerD3D10.cpp +++ b/gfx/layers/d3d10/ContainerLayerD3D10.cpp @@ -28,140 +28,6 @@ ContainerLayerD3D10::~ContainerLayerD3D10() RemoveChild(mFirstChild); } } -template -static void -ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(!aChild->GetParent(), - "aChild already in the tree"); - NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(), - "aChild already has siblings?"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - aChild->SetParent(aContainer); - if (aAfter == aContainer->mLastChild) { - aContainer->mLastChild = aChild; - } - if (!aAfter) { - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); - return; - } - - Layer* next = aAfter->GetNextSibling(); - aChild->SetNextSibling(next); - aChild->SetPrevSibling(aAfter); - if (next) { - next->SetPrevSibling(aChild); - } - aAfter->SetNextSibling(aChild); - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); -} - -template -static void -ContainerRemoveChild(Container* aContainer, Layer* aChild) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev) { - prev->SetNextSibling(next); - } else { - aContainer->mFirstChild = next; - } - if (next) { - next->SetPrevSibling(prev); - } else { - aContainer->mLastChild = prev; - } - - aChild->SetNextSibling(nullptr); - aChild->SetPrevSibling(nullptr); - aChild->SetParent(nullptr); - - aContainer->DidRemoveChild(aChild); - NS_RELEASE(aChild); -} - -template -static void -ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev == aAfter) { - // aChild is already in the correct position, nothing to do. - return; - } - if (prev) { - prev->SetNextSibling(next); - } - if (next) { - next->SetPrevSibling(prev); - } - if (!aAfter) { - aChild->SetPrevSibling(nullptr); - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - return; - } - - Layer* afterNext = aAfter->GetNextSibling(); - if (afterNext) { - afterNext->SetPrevSibling(aChild); - } else { - aContainer->mLastChild = aChild; - } - aAfter->SetNextSibling(aChild); - aChild->SetPrevSibling(aAfter); - aChild->SetNextSibling(afterNext); -} - -void -ContainerLayerD3D10::InsertAfter(Layer* aChild, Layer* aAfter) -{ - ContainerInsertAfter(this, aChild, aAfter); -} - -void -ContainerLayerD3D10::RemoveChild(Layer *aChild) -{ - ContainerRemoveChild(this, aChild); -} - -void -ContainerLayerD3D10::RepositionChild(Layer* aChild, Layer* aAfter) -{ - ContainerRepositionChild(this, aChild, aAfter); -} Layer* ContainerLayerD3D10::GetLayer() diff --git a/gfx/layers/d3d10/ContainerLayerD3D10.h b/gfx/layers/d3d10/ContainerLayerD3D10.h index 40d3948a251b..2a136afb0ce6 100644 --- a/gfx/layers/d3d10/ContainerLayerD3D10.h +++ b/gfx/layers/d3d10/ContainerLayerD3D10.h @@ -11,35 +11,15 @@ namespace mozilla { namespace layers { -template -static void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter); -template -static void ContainerRemoveChild(Container* aContainer, Layer* aChild); -template -static void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter); - class ContainerLayerD3D10 : public ContainerLayer, public LayerD3D10 { - template - friend void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter); - template - friend void ContainerRemoveChild(Container* aContainer, Layer* aChild); - template - friend void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter); public: ContainerLayerD3D10(LayerManagerD3D10 *aManager); ~ContainerLayerD3D10(); nsIntRect GetVisibleRect() { return mVisibleRegion.GetBounds(); } - /* ContainerLayer implementation */ - virtual void InsertAfter(Layer* aChild, Layer* aAfter); - - virtual void RemoveChild(Layer* aChild); - - virtual void RepositionChild(Layer* aChild, Layer* aAfter); - /* LayerD3D10 implementation */ virtual Layer* GetLayer(); diff --git a/gfx/layers/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index d973ee8365f4..eb8a03ed4ec0 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -371,6 +371,10 @@ CompositorD3D11::CreateRenderTarget(const gfx::IntRect& aRect, RefPtr texture; mDevice->CreateTexture2D(&desc, nullptr, byRef(texture)); + NS_ASSERTION(texture, "Could not create texture"); + if (!texture) { + return nullptr; + } RefPtr rt = new CompositingRenderTargetD3D11(texture); rt->SetSize(IntSize(aRect.width, aRect.height)); @@ -393,6 +397,10 @@ CompositorD3D11::CreateRenderTargetFromSource(const gfx::IntRect &aRect, RefPtr texture; mDevice->CreateTexture2D(&desc, nullptr, byRef(texture)); + NS_ASSERTION(texture, "Could not create texture"); + if (!texture) { + return nullptr; + } if (aSource) { const CompositingRenderTargetD3D11* sourceD3D11 = diff --git a/gfx/layers/d3d9/ContainerLayerD3D9.cpp b/gfx/layers/d3d9/ContainerLayerD3D9.cpp index c00a87e1055e..8c654b843c3f 100644 --- a/gfx/layers/d3d9/ContainerLayerD3D9.cpp +++ b/gfx/layers/d3d9/ContainerLayerD3D9.cpp @@ -12,155 +12,37 @@ namespace mozilla { namespace layers { -template -static void -ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter) +ContainerLayerD3D9::ContainerLayerD3D9(LayerManagerD3D9 *aManager) + : ContainerLayer(aManager, nullptr) + , LayerD3D9(aManager) { - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(!aChild->GetParent(), - "aChild already in the tree"); - NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(), - "aChild already has siblings?"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - aChild->SetParent(aContainer); - if (aAfter == aContainer->mLastChild) { - aContainer->mLastChild = aChild; - } - if (!aAfter) { - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); - return; - } - - Layer* next = aAfter->GetNextSibling(); - aChild->SetNextSibling(next); - aChild->SetPrevSibling(aAfter); - if (next) { - next->SetPrevSibling(aChild); - } - aAfter->SetNextSibling(aChild); - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); + mImplData = static_cast(this); } -template -static void -ContainerRemoveChild(Container* aContainer, Layer* aChild) +ContainerLayerD3D9::~ContainerLayerD3D9() { - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev) { - prev->SetNextSibling(next); - } else { - aContainer->mFirstChild = next; + while (mFirstChild) { + RemoveChild(mFirstChild); } - if (next) { - next->SetPrevSibling(prev); - } else { - aContainer->mLastChild = prev; - } - - aChild->SetNextSibling(nullptr); - aChild->SetPrevSibling(nullptr); - aChild->SetParent(nullptr); - - aContainer->DidRemoveChild(aChild); - NS_RELEASE(aChild); } -template -static void -ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter) +Layer* +ContainerLayerD3D9::GetLayer() { - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev == aAfter) { - // aChild is already in the correct position, nothing to do. - return; - } - if (prev) { - prev->SetNextSibling(next); - } - if (next) { - next->SetPrevSibling(prev); - } - if (!aAfter) { - aChild->SetPrevSibling(nullptr); - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - return; - } - - Layer* afterNext = aAfter->GetNextSibling(); - if (afterNext) { - afterNext->SetPrevSibling(aChild); - } else { - aContainer->mLastChild = aChild; - } - aAfter->SetNextSibling(aChild); - aChild->SetPrevSibling(aAfter); - aChild->SetNextSibling(afterNext); + return this; } -static inline LayerD3D9* -GetNextSibling(LayerD3D9* aLayer) +LayerD3D9* +ContainerLayerD3D9::GetFirstChildD3D9() { - Layer* layer = aLayer->GetLayer()->GetNextSibling(); - return layer ? static_cast(layer-> - ImplData()) - : nullptr; -} - -static bool -HasOpaqueAncestorLayer(Layer* aLayer) -{ - for (Layer* l = aLayer->GetParent(); l; l = l->GetParent()) { - if (l->GetContentFlags() & Layer::CONTENT_OPAQUE) - return true; + if (!mFirstChild) { + return nullptr; } - return false; + return static_cast(mFirstChild->ImplData()); } -static inline LayerD3D9* -GetNextSiblingD3D9(LayerD3D9* aLayer) -{ - Layer* layer = aLayer->GetLayer()->GetNextSibling(); - return layer ? static_cast(layer-> - ImplData()) - : nullptr; -} - -template -static void -ContainerRender(Container* aContainer, - LayerManagerD3D9* aManager) +void +ContainerLayerD3D9::RenderLayer() { nsRefPtr previousRenderTarget; nsRefPtr renderTexture; @@ -169,7 +51,7 @@ ContainerRender(Container* aContainer, float oldViewMatrix[4][4]; RECT containerD3D9ClipRect; - aManager->device()->GetScissorRect(&containerD3D9ClipRect); + device()->GetScissorRect(&containerD3D9ClipRect); // Convert scissor to an nsIntRect. RECT's are exclusive on the bottom and // right values. nsIntRect oldScissor(containerD3D9ClipRect.left, @@ -178,44 +60,44 @@ ContainerRender(Container* aContainer, containerD3D9ClipRect.bottom - containerD3D9ClipRect.top); ReadbackProcessor readback; - readback.BuildUpdates(aContainer); + readback.BuildUpdates(this); - nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); - bool useIntermediate = aContainer->UseIntermediateSurface(); + nsIntRect visibleRect = GetEffectiveVisibleRegion().GetBounds(); + bool useIntermediate = UseIntermediateSurface(); - aContainer->mSupportsComponentAlphaChildren = false; + mSupportsComponentAlphaChildren = false; if (useIntermediate) { nsRefPtr renderSurface; - if (!aManager->CompositingDisabled()) { - aManager->device()->GetRenderTarget(0, getter_AddRefs(previousRenderTarget)); - HRESULT hr = aManager->device()->CreateTexture(visibleRect.width, visibleRect.height, 1, - D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, - D3DPOOL_DEFAULT, getter_AddRefs(renderTexture), - nullptr); + if (!mD3DManager->CompositingDisabled()) { + device()->GetRenderTarget(0, getter_AddRefs(previousRenderTarget)); + HRESULT hr = device()->CreateTexture(visibleRect.width, visibleRect.height, 1, + D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, + D3DPOOL_DEFAULT, getter_AddRefs(renderTexture), + nullptr); if (FAILED(hr)) { - aManager->ReportFailure(NS_LITERAL_CSTRING("ContainerLayerD3D9::ContainerRender(): Failed to create texture"), + ReportFailure(NS_LITERAL_CSTRING("ContainerLayerD3D9::ContainerRender(): Failed to create texture"), hr); return; } nsRefPtr renderSurface; renderTexture->GetSurfaceLevel(0, getter_AddRefs(renderSurface)); - aManager->device()->SetRenderTarget(0, renderSurface); + device()->SetRenderTarget(0, renderSurface); } - if (aContainer->mVisibleRegion.GetNumRects() == 1 && - (aContainer->GetContentFlags() & aContainer->CONTENT_OPAQUE)) { + if (mVisibleRegion.GetNumRects() == 1 && + (GetContentFlags() & CONTENT_OPAQUE)) { // don't need a background, we're going to paint all opaque stuff - aContainer->mSupportsComponentAlphaChildren = true; + mSupportsComponentAlphaChildren = true; } else { - const gfx3DMatrix& transform3D = aContainer->GetEffectiveTransform(); + const gfx3DMatrix& transform3D = GetEffectiveTransform(); gfxMatrix transform; // If we have an opaque ancestor layer, then we can be sure that // all the pixels we draw into are either opaque already or will be // covered by something opaque. Otherwise copying up the background is // not safe. HRESULT hr = E_FAIL; - if (HasOpaqueAncestorLayer(aContainer) && + if (HasOpaqueAncestorLayer(this) && transform3D.Is2D(&transform) && !transform.HasNonIntegerTranslation()) { // Copy background up from below RECT dest = { 0, 0, visibleRect.width, visibleRect.height }; @@ -223,24 +105,24 @@ ContainerRender(Container* aContainer, ::OffsetRect(&src, visibleRect.x + int32_t(transform.x0), visibleRect.y + int32_t(transform.y0)); - if (!aManager->CompositingDisabled()) { - hr = aManager->device()-> + if (!mD3DManager->CompositingDisabled()) { + hr = device()-> StretchRect(previousRenderTarget, &src, renderSurface, &dest, D3DTEXF_NONE); } } if (hr == S_OK) { - aContainer->mSupportsComponentAlphaChildren = true; - } else if (!aManager->CompositingDisabled()) { - aManager->device()-> + mSupportsComponentAlphaChildren = true; + } else if (!mD3DManager->CompositingDisabled()) { + device()-> Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 0), 0, 0); } } - aManager->device()-> + device()-> GetVertexShaderConstantF(CBvRenderTargetOffset, previousRenderTargetOffset, 1); renderTargetOffset[0] = (float)visibleRect.x; renderTargetOffset[1] = (float)visibleRect.y; - aManager->device()-> + device()-> SetVertexShaderConstantF(CBvRenderTargetOffset, renderTargetOffset, 1); gfx3DMatrix viewMatrix; @@ -253,19 +135,19 @@ ContainerRender(Container* aContainer, viewMatrix._41 = -1.0f; viewMatrix._42 = 1.0f; - aManager->device()-> + device()-> GetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4); - aManager->device()-> + device()-> SetVertexShaderConstantF(CBmProjection, &viewMatrix._11, 4); } else { - aContainer->mSupportsComponentAlphaChildren = - (aContainer->GetContentFlags() & aContainer->CONTENT_OPAQUE) || - (aContainer->mParent && - aContainer->mParent->SupportsComponentAlphaChildren()); + mSupportsComponentAlphaChildren = + (GetContentFlags() & CONTENT_OPAQUE) || + (mParent && + mParent->SupportsComponentAlphaChildren()); } nsAutoTArray children; - aContainer->SortChildrenBy3DZOrder(children); + SortChildrenBy3DZOrder(children); /* * Render this container's contents. @@ -288,94 +170,40 @@ ContainerRender(Container* aContainer, d3drect.top = scissorRect.y; d3drect.right = scissorRect.x + scissorRect.width; d3drect.bottom = scissorRect.y + scissorRect.height; - aManager->device()->SetScissorRect(&d3drect); + device()->SetScissorRect(&d3drect); - if (layerToRender->GetLayer()->GetType() == aContainer->TYPE_THEBES) { + if (layerToRender->GetLayer()->GetType() == TYPE_THEBES) { static_cast(layerToRender)->RenderThebesLayer(&readback); } else { layerToRender->RenderLayer(); } } - if (useIntermediate && !aManager->CompositingDisabled()) { - aManager->device()->SetRenderTarget(0, previousRenderTarget); - aManager->device()->SetVertexShaderConstantF(CBvRenderTargetOffset, previousRenderTargetOffset, 1); - aManager->device()->SetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4); + if (useIntermediate && !mD3DManager->CompositingDisabled()) { + device()->SetRenderTarget(0, previousRenderTarget); + device()->SetVertexShaderConstantF(CBvRenderTargetOffset, previousRenderTargetOffset, 1); + device()->SetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4); - aManager->device()->SetVertexShaderConstantF(CBvLayerQuad, + device()->SetVertexShaderConstantF(CBvLayerQuad, ShaderConstantRect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height), 1); - aContainer->SetShaderTransformAndOpacity(); - aManager->SetShaderMode(DeviceManagerD3D9::RGBALAYER, - aContainer->GetMaskLayer(), - aContainer->GetTransform().CanDraw2D()); + SetShaderTransformAndOpacity(); + mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBALAYER, + GetMaskLayer(), + GetTransform().CanDraw2D()); - aManager->device()->SetTexture(0, renderTexture); - aManager->device()->SetScissorRect(&containerD3D9ClipRect); - aManager->device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + device()->SetTexture(0, renderTexture); + device()->SetScissorRect(&containerD3D9ClipRect); + device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); } else { - aManager->device()->SetScissorRect(&containerD3D9ClipRect); + device()->SetScissorRect(&containerD3D9ClipRect); } } - -ContainerLayerD3D9::ContainerLayerD3D9(LayerManagerD3D9 *aManager) - : ContainerLayer(aManager, nullptr) - , LayerD3D9(aManager) -{ - mImplData = static_cast(this); -} - -ContainerLayerD3D9::~ContainerLayerD3D9() -{ - while (mFirstChild) { - RemoveChild(mFirstChild); - } -} - -void -ContainerLayerD3D9::InsertAfter(Layer* aChild, Layer* aAfter) -{ - ContainerInsertAfter(this, aChild, aAfter); -} - -void -ContainerLayerD3D9::RemoveChild(Layer *aChild) -{ - ContainerRemoveChild(this, aChild); -} - -void -ContainerLayerD3D9::RepositionChild(Layer* aChild, Layer* aAfter) -{ - ContainerRepositionChild(this, aChild, aAfter); -} - -Layer* -ContainerLayerD3D9::GetLayer() -{ - return this; -} - -LayerD3D9* -ContainerLayerD3D9::GetFirstChildD3D9() -{ - if (!mFirstChild) { - return nullptr; - } - return static_cast(mFirstChild->ImplData()); -} - -void -ContainerLayerD3D9::RenderLayer() -{ - ContainerRender(this, mD3DManager); -} - void ContainerLayerD3D9::LayerManagerDestroyed() { diff --git a/gfx/layers/d3d9/ContainerLayerD3D9.h b/gfx/layers/d3d9/ContainerLayerD3D9.h index 099e69f30d8a..b7d94829b387 100644 --- a/gfx/layers/d3d9/ContainerLayerD3D9.h +++ b/gfx/layers/d3d9/ContainerLayerD3D9.h @@ -12,40 +12,15 @@ namespace mozilla { namespace layers { -template -static void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter); -template -static void ContainerRemoveChild(Container* aContainer, Layer* aChild); -template -static void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter); -template -static void ContainerRender(Container* aContainer, LayerManagerD3D9* aManager); - class ContainerLayerD3D9 : public ContainerLayer, public LayerD3D9 { - template - friend void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter); - template - friend void ContainerRemoveChild(Container* aContainer, Layer* aChild); - template - friend void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter); - template - friend void ContainerRender(Container* aContainer, LayerManagerD3D9* aManager); - public: ContainerLayerD3D9(LayerManagerD3D9 *aManager); ~ContainerLayerD3D9(); nsIntRect GetVisibleRect() { return mVisibleRegion.GetBounds(); } - /* ContainerLayer implementation */ - virtual void InsertAfter(Layer* aChild, Layer* aAfter); - - virtual void RemoveChild(Layer* aChild); - - virtual void RepositionChild(Layer* aChild, Layer* aAfter); - /* LayerD3D9 implementation */ Layer* GetLayer(); diff --git a/gfx/layers/opengl/ContainerLayerOGL.cpp b/gfx/layers/opengl/ContainerLayerOGL.cpp index 0e0cbcf407a7..6b02dead09b5 100644 --- a/gfx/layers/opengl/ContainerLayerOGL.cpp +++ b/gfx/layers/opengl/ContainerLayerOGL.cpp @@ -28,146 +28,6 @@ class gfxImageSurface; namespace mozilla { namespace layers { -template -static void -ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(!aChild->GetParent(), - "aChild already in the tree"); - NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(), - "aChild already has siblings?"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - aChild->SetParent(aContainer); - if (aAfter == aContainer->mLastChild) { - aContainer->mLastChild = aChild; - } - if (!aAfter) { - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); - return; - } - - Layer* next = aAfter->GetNextSibling(); - aChild->SetNextSibling(next); - aChild->SetPrevSibling(aAfter); - if (next) { - next->SetPrevSibling(aChild); - } - aAfter->SetNextSibling(aChild); - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); -} - -template -static void -ContainerRemoveChild(Container* aContainer, Layer* aChild) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev) { - prev->SetNextSibling(next); - } else { - aContainer->mFirstChild = next; - } - if (next) { - next->SetPrevSibling(prev); - } else { - aContainer->mLastChild = prev; - } - - aChild->SetNextSibling(nullptr); - aChild->SetPrevSibling(nullptr); - aChild->SetParent(nullptr); - - aContainer->DidRemoveChild(aChild); - NS_RELEASE(aChild); -} - -template -static void -ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev == aAfter) { - // aChild is already in the correct position, nothing to do. - return; - } - if (prev) { - prev->SetNextSibling(next); - } - if (next) { - next->SetPrevSibling(prev); - } - if (!aAfter) { - aChild->SetPrevSibling(nullptr); - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - return; - } - - Layer* afterNext = aAfter->GetNextSibling(); - if (afterNext) { - afterNext->SetPrevSibling(aChild); - } else { - aContainer->mLastChild = aChild; - } - aAfter->SetNextSibling(aChild); - aChild->SetPrevSibling(aAfter); - aChild->SetNextSibling(afterNext); -} - -template -static void -ContainerDestroy(Container* aContainer) - { - if (!aContainer->mDestroyed) { - while (aContainer->mFirstChild) { - aContainer->GetFirstChildOGL()->Destroy(); - aContainer->RemoveChild(aContainer->mFirstChild); - } - aContainer->mDestroyed = true; - } -} - -template -static void -ContainerCleanupResources(Container* aContainer) -{ - for (Layer* l = aContainer->GetFirstChild(); l; l = l->GetNextSibling()) { - LayerOGL* layerToRender = static_cast(l->ImplData()); - layerToRender->CleanupResources(); - } -} - static inline LayerOGL* GetNextSibling(LayerOGL* aLayer) { @@ -177,195 +37,9 @@ GetNextSibling(LayerOGL* aLayer) : nullptr; } -static bool -HasOpaqueAncestorLayer(Layer* aLayer) -{ - for (Layer* l = aLayer->GetParent(); l; l = l->GetParent()) { - if (l->GetContentFlags() & Layer::CONTENT_OPAQUE) - return true; - } - return false; -} - -template -static void -ContainerRender(Container* aContainer, - int aPreviousFrameBuffer, - const nsIntPoint& aOffset, - LayerManagerOGL* aManager) -{ - /** - * Setup our temporary texture for rendering the contents of this container. - */ - GLuint containerSurface; - GLuint frameBuffer; - - nsIntPoint childOffset(aOffset); - nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); - - nsIntRect cachedScissor = aContainer->gl()->ScissorRect(); - aContainer->gl()->PushScissorRect(); - aContainer->mSupportsComponentAlphaChildren = false; - - float opacity = aContainer->GetEffectiveOpacity(); - const gfx3DMatrix& transform = aContainer->GetEffectiveTransform(); - bool needsFramebuffer = aContainer->UseIntermediateSurface(); - if (needsFramebuffer) { - nsIntRect framebufferRect = visibleRect; - // we're about to create a framebuffer backed by textures to use as an intermediate - // surface. What to do if its size (as given by framebufferRect) would exceed the - // maximum texture size supported by the GL? The present code chooses the compromise - // of just clamping the framebuffer's size to the max supported size. - // This gives us a lower resolution rendering of the intermediate surface (children layers). - // See bug 827170 for a discussion. - GLint maxTexSize; - aContainer->gl()->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &maxTexSize); - framebufferRect.width = std::min(framebufferRect.width, maxTexSize); - framebufferRect.height = std::min(framebufferRect.height, maxTexSize); - - LayerManagerOGL::InitMode mode = LayerManagerOGL::InitModeClear; - if (aContainer->GetEffectiveVisibleRegion().GetNumRects() == 1 && - (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE)) - { - // don't need a background, we're going to paint all opaque stuff - aContainer->mSupportsComponentAlphaChildren = true; - mode = LayerManagerOGL::InitModeNone; - } else { - const gfx3DMatrix& transform3D = aContainer->GetEffectiveTransform(); - gfxMatrix transform; - // If we have an opaque ancestor layer, then we can be sure that - // all the pixels we draw into are either opaque already or will be - // covered by something opaque. Otherwise copying up the background is - // not safe. - if (HasOpaqueAncestorLayer(aContainer) && - transform3D.Is2D(&transform) && !transform.HasNonIntegerTranslation()) { - mode = gfxPlatform::ComponentAlphaEnabled() ? - LayerManagerOGL::InitModeCopy : - LayerManagerOGL::InitModeClear; - framebufferRect.x += transform.x0; - framebufferRect.y += transform.y0; - aContainer->mSupportsComponentAlphaChildren = gfxPlatform::ComponentAlphaEnabled(); - } - } - - aContainer->gl()->PushViewportRect(); - framebufferRect -= childOffset; - if (!aManager->CompositingDisabled()) { - if (!aManager->CreateFBOWithTexture(framebufferRect, - mode, - aPreviousFrameBuffer, - &frameBuffer, - &containerSurface)) { - aContainer->gl()->PopViewportRect(); - aContainer->gl()->PopScissorRect(); - aContainer->gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer); - return; - } - } - childOffset.x = visibleRect.x; - childOffset.y = visibleRect.y; - } else { - frameBuffer = aPreviousFrameBuffer; - aContainer->mSupportsComponentAlphaChildren = (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE) || - (aContainer->GetParent() && aContainer->GetParent()->SupportsComponentAlphaChildren()); - } - - nsAutoTArray children; - aContainer->SortChildrenBy3DZOrder(children); - - /** - * Render this container's contents. - */ - for (uint32_t i = 0; i < children.Length(); i++) { - LayerOGL* layerToRender = static_cast(children.ElementAt(i)->ImplData()); - - if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) { - continue; - } - - nsIntRect scissorRect = layerToRender->GetLayer()-> - CalculateScissorRect(cachedScissor, &aManager->GetWorldTransform()); - if (scissorRect.IsEmpty()) { - continue; - } - - aContainer->gl()->fScissor(scissorRect.x, - scissorRect.y, - scissorRect.width, - scissorRect.height); - - layerToRender->RenderLayer(frameBuffer, childOffset); - aContainer->gl()->MakeCurrent(); - } - - - if (needsFramebuffer) { - // Unbind the current framebuffer and rebind the previous one. -#ifdef MOZ_DUMP_PAINTING - if (gfxUtils::sDumpPainting) { - nsRefPtr surf = - aContainer->gl()->GetTexImage(containerSurface, true, aManager->GetFBOTextureFormat()); - - WriteSnapshotToDumpFile(aContainer, surf); - } -#endif - - // Restore the viewport - aContainer->gl()->PopViewportRect(); - nsIntRect viewport = aContainer->gl()->ViewportRect(); - aManager->SetupPipeline(viewport.width, viewport.height, - LayerManagerOGL::ApplyWorldTransform); - aContainer->gl()->PopScissorRect(); - - if (!aManager->CompositingDisabled()) { - aContainer->gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer); - aContainer->gl()->fDeleteFramebuffers(1, &frameBuffer); - - aContainer->gl()->fActiveTexture(LOCAL_GL_TEXTURE0); - - aContainer->gl()->fBindTexture(aManager->FBOTextureTarget(), containerSurface); - - MaskType maskType = MaskNone; - if (aContainer->GetMaskLayer()) { - if (!aContainer->GetTransform().CanDraw2D()) { - maskType = Mask3d; - } else { - maskType = Mask2d; - } - } - ShaderProgramOGL *rgb = - aManager->GetFBOLayerProgram(maskType); - - rgb->Activate(); - rgb->SetLayerQuadRect(visibleRect); - rgb->SetLayerTransform(transform); - rgb->SetTextureTransform(gfx3DMatrix()); - rgb->SetLayerOpacity(opacity); - rgb->SetRenderOffset(aOffset); - rgb->SetTextureUnit(0); - rgb->LoadMask(aContainer->GetMaskLayer()); - - if (rgb->GetTexCoordMultiplierUniformLocation() != -1) { - // 2DRect case, get the multiplier right for a sampler2DRect - rgb->SetTexCoordMultiplier(visibleRect.width, visibleRect.height); - } - - // Drawing is always flipped, but when copying between surfaces we want to avoid - // this. Pass true for the flip parameter to introduce a second flip - // that cancels the other one out. - aManager->BindAndDrawQuad(rgb, true); - - // Clean up resources. This also unbinds the texture. - aContainer->gl()->fDeleteTextures(1, &containerSurface); - } - } else { - aContainer->gl()->PopScissorRect(); - } -} - -ContainerLayerOGL::ContainerLayerOGL(LayerManagerOGL *aManager) - : ContainerLayer(aManager, nullptr) - , LayerOGL(aManager) +ContainerLayerOGL::ContainerLayerOGL(LayerManagerOGL *mOGLManager) + : ContainerLayer(mOGLManager, nullptr) + , LayerOGL(mOGLManager) { mImplData = static_cast(this); } @@ -375,28 +49,16 @@ ContainerLayerOGL::~ContainerLayerOGL() Destroy(); } -void -ContainerLayerOGL::InsertAfter(Layer* aChild, Layer* aAfter) -{ - ContainerInsertAfter(this, aChild, aAfter); -} - -void -ContainerLayerOGL::RemoveChild(Layer *aChild) -{ - ContainerRemoveChild(this, aChild); -} - -void -ContainerLayerOGL::RepositionChild(Layer* aChild, Layer* aAfter) -{ - ContainerRepositionChild(this, aChild, aAfter); -} - void ContainerLayerOGL::Destroy() { - ContainerDestroy(this); + if (!mDestroyed) { + while (mFirstChild) { + GetFirstChildOGL()->Destroy(); + RemoveChild(mFirstChild); + } + mDestroyed = true; + } } LayerOGL* @@ -412,13 +74,182 @@ void ContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOffset) { - ContainerRender(this, aPreviousFrameBuffer, aOffset, mOGLManager); + /** + * Setup our temporary texture for rendering the contents of this container. + */ + GLuint containerSurface; + GLuint frameBuffer; + + nsIntPoint childOffset(aOffset); + nsIntRect visibleRect = GetEffectiveVisibleRegion().GetBounds(); + + nsIntRect cachedScissor = gl()->ScissorRect(); + gl()->PushScissorRect(); + mSupportsComponentAlphaChildren = false; + + float opacity = GetEffectiveOpacity(); + const gfx3DMatrix& transform = GetEffectiveTransform(); + bool needsFramebuffer = UseIntermediateSurface(); + if (needsFramebuffer) { + nsIntRect framebufferRect = visibleRect; + // we're about to create a framebuffer backed by textures to use as an intermediate + // surface. What to do if its size (as given by framebufferRect) would exceed the + // maximum texture size supported by the GL? The present code chooses the compromise + // of just clamping the framebuffer's size to the max supported size. + // This gives us a lower resolution rendering of the intermediate surface (children layers). + // See bug 827170 for a discussion. + GLint maxTexSize; + gl()->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &maxTexSize); + framebufferRect.width = std::min(framebufferRect.width, maxTexSize); + framebufferRect.height = std::min(framebufferRect.height, maxTexSize); + + LayerManagerOGL::InitMode mode = LayerManagerOGL::InitModeClear; + if (GetEffectiveVisibleRegion().GetNumRects() == 1 && + (GetContentFlags() & Layer::CONTENT_OPAQUE)) + { + // don't need a background, we're going to paint all opaque stuff + mSupportsComponentAlphaChildren = true; + mode = LayerManagerOGL::InitModeNone; + } else { + const gfx3DMatrix& transform3D = GetEffectiveTransform(); + gfxMatrix transform; + // If we have an opaque ancestor layer, then we can be sure that + // all the pixels we draw into are either opaque already or will be + // covered by something opaque. Otherwise copying up the background is + // not safe. + if (HasOpaqueAncestorLayer(this) && + transform3D.Is2D(&transform) && !transform.HasNonIntegerTranslation()) { + mode = gfxPlatform::ComponentAlphaEnabled() ? + LayerManagerOGL::InitModeCopy : + LayerManagerOGL::InitModeClear; + framebufferRect.x += transform.x0; + framebufferRect.y += transform.y0; + mSupportsComponentAlphaChildren = gfxPlatform::ComponentAlphaEnabled(); + } + } + + gl()->PushViewportRect(); + framebufferRect -= childOffset; + if (!mOGLManager->CompositingDisabled()) { + if (!mOGLManager->CreateFBOWithTexture(framebufferRect, + mode, + aPreviousFrameBuffer, + &frameBuffer, + &containerSurface)) { + gl()->PopViewportRect(); + gl()->PopScissorRect(); + gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer); + return; + } + } + childOffset.x = visibleRect.x; + childOffset.y = visibleRect.y; + } else { + frameBuffer = aPreviousFrameBuffer; + mSupportsComponentAlphaChildren = (GetContentFlags() & Layer::CONTENT_OPAQUE) || + (GetParent() && GetParent()->SupportsComponentAlphaChildren()); + } + + nsAutoTArray children; + SortChildrenBy3DZOrder(children); + + /** + * Render this container's contents. + */ + for (uint32_t i = 0; i < children.Length(); i++) { + LayerOGL* layerToRender = static_cast(children.ElementAt(i)->ImplData()); + + if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) { + continue; + } + + nsIntRect scissorRect = layerToRender->GetLayer()-> + CalculateScissorRect(cachedScissor, &mOGLManager->GetWorldTransform()); + if (scissorRect.IsEmpty()) { + continue; + } + + gl()->fScissor(scissorRect.x, + scissorRect.y, + scissorRect.width, + scissorRect.height); + + layerToRender->RenderLayer(frameBuffer, childOffset); + gl()->MakeCurrent(); + } + + + if (needsFramebuffer) { + // Unbind the current framebuffer and rebind the previous one. +#ifdef MOZ_DUMP_PAINTING + if (gfxUtils::sDumpPainting) { + nsRefPtr surf = + gl()->GetTexImage(containerSurface, true, mOGLManager->GetFBOTextureFormat()); + + WriteSnapshotToDumpFile(this, surf); + } +#endif + + // Restore the viewport + gl()->PopViewportRect(); + nsIntRect viewport = gl()->ViewportRect(); + mOGLManager->SetupPipeline(viewport.width, viewport.height, + LayerManagerOGL::ApplyWorldTransform); + gl()->PopScissorRect(); + + if (!mOGLManager->CompositingDisabled()) { + gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer); + gl()->fDeleteFramebuffers(1, &frameBuffer); + + gl()->fActiveTexture(LOCAL_GL_TEXTURE0); + + gl()->fBindTexture(mOGLManager->FBOTextureTarget(), containerSurface); + + MaskType maskType = MaskNone; + if (GetMaskLayer()) { + if (!GetTransform().CanDraw2D()) { + maskType = Mask3d; + } else { + maskType = Mask2d; + } + } + ShaderProgramOGL *rgb = + mOGLManager->GetFBOLayerProgram(maskType); + + rgb->Activate(); + rgb->SetLayerQuadRect(visibleRect); + rgb->SetLayerTransform(transform); + rgb->SetTextureTransform(gfx3DMatrix()); + rgb->SetLayerOpacity(opacity); + rgb->SetRenderOffset(aOffset); + rgb->SetTextureUnit(0); + rgb->LoadMask(GetMaskLayer()); + + if (rgb->GetTexCoordMultiplierUniformLocation() != -1) { + // 2DRect case, get the multiplier right for a sampler2DRect + rgb->SetTexCoordMultiplier(visibleRect.width, visibleRect.height); + } + + // Drawing is always flipped, but when copying between surfaces we want to avoid + // this. Pass true for the flip parameter to introduce a second flip + // that cancels the other one out. + mOGLManager->BindAndDrawQuad(rgb, true); + + // Clean up resources. This also unbinds the texture. + gl()->fDeleteTextures(1, &containerSurface); + } + } else { + gl()->PopScissorRect(); + } } void ContainerLayerOGL::CleanupResources() { - ContainerCleanupResources(this); + for (Layer* l = GetFirstChild(); l; l = l->GetNextSibling()) { + LayerOGL* layerToRender = static_cast(l->ImplData()); + layerToRender->CleanupResources(); + } } } /* layers */ diff --git a/gfx/layers/opengl/ContainerLayerOGL.h b/gfx/layers/opengl/ContainerLayerOGL.h index 84d1bbf32aaf..1e80d23d58dc 100644 --- a/gfx/layers/opengl/ContainerLayerOGL.h +++ b/gfx/layers/opengl/ContainerLayerOGL.h @@ -14,47 +14,13 @@ struct nsIntPoint; namespace mozilla { namespace layers { -template -static void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter); -template -static void ContainerRemoveChild(Container* aContainer, Layer* aChild); -template -static void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter); -template -static void ContainerDestroy(Container* aContainer); -template -static void ContainerRender(Container* aContainer, - int aPreviousFrameBuffer, - const nsIntPoint& aOffset, - LayerManagerOGL* aManager); - class ContainerLayerOGL : public ContainerLayer, public LayerOGL { - template - friend void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter); - template - friend void ContainerRemoveChild(Container* aContainer, Layer* aChild); - template - friend void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter); - template - friend void ContainerDestroy(Container* aContainer); - template - friend void ContainerRender(Container* aContainer, - int aPreviousFrameBuffer, - const nsIntPoint& aOffset, - LayerManagerOGL* aManager); - public: ContainerLayerOGL(LayerManagerOGL *aManager); ~ContainerLayerOGL(); - void InsertAfter(Layer* aChild, Layer* aAfter); - - void RemoveChild(Layer* aChild); - - void RepositionChild(Layer* aChild, Layer* aAfter); - /** LayerOGL implementation */ Layer* GetLayer() { return this; } diff --git a/gfx/src/X11Util.cpp b/gfx/src/X11Util.cpp index 912f269f90ea..ac9c25958248 100644 --- a/gfx/src/X11Util.cpp +++ b/gfx/src/X11Util.cpp @@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "X11Util.h" +#include "nsDebug.h" // for NS_ASSERTION, etc namespace mozilla { diff --git a/gfx/src/X11Util.h b/gfx/src/X11Util.h index 9659a0004b22..a4501fba2f62 100644 --- a/gfx/src/X11Util.h +++ b/gfx/src/X11Util.h @@ -21,10 +21,9 @@ # error Unknown toolkit #endif -#include "mozilla/Scoped.h" - -#include "gfxCore.h" -#include "nsDebug.h" +#include // for memset +#include "gfxCore.h" // for NS_GFX +#include "mozilla/Scoped.h" // for SCOPED_TEMPLATE namespace mozilla { diff --git a/gfx/src/gfxCrashReporterUtils.cpp b/gfx/src/gfxCrashReporterUtils.cpp index e04f8c93a817..d5658c062c17 100644 --- a/gfx/src/gfxCrashReporterUtils.cpp +++ b/gfx/src/gfxCrashReporterUtils.cpp @@ -10,15 +10,25 @@ #endif #ifdef MOZ_GFXFEATUREREPORTER -#include "nsExceptionHandler.h" -#include "nsString.h" -#include "nsTArray.h" -#include "nsIObserverService.h" -#include "nsIObserver.h" -#include "nsAutoPtr.h" -#include "nsServiceManagerUtils.h" -#include "mozilla/Services.h" -#include "nsThreadUtils.h" +#include "gfxCrashReporterUtils.h" +#include // for strcmp +#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 +#include "mozilla/Services.h" // for GetObserverService +#include "mozilla/mozalloc.h" // for operator new, etc +#include "nsAutoPtr.h" // for nsRefPtr +#include "nsCOMPtr.h" // for nsCOMPtr +#include "nsError.h" // for NS_OK, NS_FAILED, nsresult +#include "nsExceptionHandler.h" // for AppendAppNotesToCrashReport +#include "nsID.h" +#include "nsIEventTarget.h" // for NS_DISPATCH_NORMAL +#include "nsIObserver.h" // for nsIObserver, etc +#include "nsIObserverService.h" // for nsIObserverService +#include "nsIRunnable.h" // for nsIRunnable +#include "nsISupports.h" +#include "nsStringGlue.h" // for nsAutoCString, nsCString, etc +#include "nsTArray.h" // for nsTArray +#include "nsThreadUtils.h" // for NS_DispatchToMainThread, etc +#include "nscore.h" // for NS_IMETHOD, NS_IMETHODIMP, etc namespace mozilla { diff --git a/gfx/src/nsColor.cpp b/gfx/src/nsColor.cpp index 2881f52fe646..4f0b009655be 100644 --- a/gfx/src/nsColor.cpp +++ b/gfx/src/nsColor.cpp @@ -5,17 +5,15 @@ #include "mozilla/Util.h" -#include "plstr.h" #include "nsColor.h" -#include "nsColorNames.h" -#include "nsString.h" -#include "nscore.h" -#include "nsCoord.h" -#include "nsCOMPtr.h" -#include "nsIServiceManager.h" -#include -#include "prprf.h" +#include // for int32_t +#include "mozilla/Util.h" // for ArrayLength +#include "mozilla/mozalloc.h" // for operator delete, etc +#include "nsColorNames.h" // for nsColorNames +#include "nsDebug.h" // for NS_ASSERTION, etc #include "nsStaticNameTable.h" +#include "nsStringGlue.h" // for nsAutoCString, nsString, etc +#include "nscore.h" // for nsAString, etc using namespace mozilla; diff --git a/gfx/src/nsColor.h b/gfx/src/nsColor.h index 0ac5feefdab5..bcae9761f1a0 100644 --- a/gfx/src/nsColor.h +++ b/gfx/src/nsColor.h @@ -6,8 +6,11 @@ #ifndef nsColor_h___ #define nsColor_h___ -#include "gfxCore.h" -#include "nscore.h" +#include // for size_t +#include // for uint8_t, uint32_t +#include "gfxCore.h" // for NS_GFX_ +#include "nscore.h" // for nsAString +#include "prtypes.h" // for PR_BEGIN_MACRO, etc class nsAString; class nsString; diff --git a/gfx/src/nsDeviceContext.cpp b/gfx/src/nsDeviceContext.cpp index 4aae268beea6..ba51a6773107 100644 --- a/gfx/src/nsDeviceContext.cpp +++ b/gfx/src/nsDeviceContext.cpp @@ -4,24 +4,36 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsDeviceContext.h" - -#include - -#include "gfxImageSurface.h" -#include "mozilla/Attributes.h" -#include "mozilla/Preferences.h" -#include "mozilla/Services.h" -#include "nsCRT.h" -#include "nsFontMetrics.h" -#include "nsIDeviceContextSpec.h" -#include "nsILanguageAtomService.h" -#include "nsIObserver.h" -#include "nsIObserverService.h" -#include "nsIScreen.h" -#include "nsIScreenManager.h" -#include "nsIServiceManager.h" -#include "nsIWidget.h" -#include "nsRenderingContext.h" +#include // for max +#include "gfxASurface.h" // for gfxASurface, etc +#include "gfxFont.h" // for gfxFontGroup +#include "gfxImageSurface.h" // for gfxImageSurface +#include "gfxPoint.h" // for gfxSize +#include "mozilla/Attributes.h" // for MOZ_FINAL +#include "mozilla/Preferences.h" // for Preferences +#include "mozilla/Services.h" // for GetObserverService +#include "mozilla/mozalloc.h" // for operator new +#include "nsCRT.h" // for nsCRT +#include "nsDebug.h" // for NS_NOTREACHED, NS_ASSERTION, etc +#include "nsFont.h" // for nsFont +#include "nsFontMetrics.h" // for nsFontMetrics +#include "nsIAtom.h" // for nsIAtom, do_GetAtom +#include "nsID.h" +#include "nsIDeviceContextSpec.h" // for nsIDeviceContextSpec +#include "nsILanguageAtomService.h" // for nsILanguageAtomService, etc +#include "nsIObserver.h" // for nsIObserver, etc +#include "nsIObserverService.h" // for nsIObserverService +#include "nsIScreen.h" // for nsIScreen +#include "nsIScreenManager.h" // for nsIScreenManager +#include "nsISupportsUtils.h" // for NS_ADDREF, NS_RELEASE +#include "nsIWidget.h" // for nsIWidget, NS_NATIVE_WINDOW +#include "nsRect.h" // for nsRect +#include "nsRenderingContext.h" // for nsRenderingContext +#include "nsServiceManagerUtils.h" // for do_GetService +#include "nsStringGlue.h" // for nsDependentString +#include "nsTArray.h" // for nsTArray, nsTArray_Impl +#include "nsThreadUtils.h" // for NS_IsMainThread +#include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc #if !XP_MACOSX #include "gfxPDFSurface.h" diff --git a/gfx/src/nsDeviceContext.h b/gfx/src/nsDeviceContext.h index 6eb3e57d98d8..e07e33698b83 100644 --- a/gfx/src/nsDeviceContext.h +++ b/gfx/src/nsDeviceContext.h @@ -6,11 +6,17 @@ #ifndef _NS_DEVICECONTEXT_H_ #define _NS_DEVICECONTEXT_H_ -#include "gfxTypes.h" -#include "nsAutoPtr.h" -#include "nsCOMPtr.h" -#include "nsCoord.h" -#include "nsMathUtils.h" +#include // for uint32_t +#include // for int32_t +#include "gfxTypes.h" // for gfxFloat +#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 +#include "nsAutoPtr.h" // for nsRefPtr +#include "nsCOMPtr.h" // for nsCOMPtr +#include "nsCoord.h" // for nscoord +#include "nsError.h" // for nsresult +#include "nsISupports.h" // for NS_INLINE_DECL_REFCOUNTING +#include "nsMathUtils.h" // for NS_round +#include "nscore.h" // for PRUnichar, nsAString class gfxASurface; class gfxUserFontSet; diff --git a/gfx/src/nsFont.cpp b/gfx/src/nsFont.cpp index 985e3080e413..9f187f8398b2 100644 --- a/gfx/src/nsFont.cpp +++ b/gfx/src/nsFont.cpp @@ -4,10 +4,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsFont.h" -#include "nsString.h" +#include "gfxFont.h" // for gfxFontStyle +#include "gfxFontConstants.h" // for NS_FONT_KERNING_AUTO, etc +#include "gfxFontFeatures.h" // for gfxFontFeature, etc +#include "gfxFontUtils.h" // for TRUETYPE_TAG +#include "nsCRT.h" // for nsCRT +#include "nsDebug.h" // for NS_ASSERTION +#include "nsISupports.h" +#include "nsMemory.h" // for NS_ARRAY_LENGTH #include "nsUnicharUtils.h" -#include "nsCRT.h" -#include "gfxFont.h" +#include "nscore.h" // for PRUnichar +#include "prtypes.h" // for PR_STATIC_ASSERT nsFont::nsFont(const char* aName, uint8_t aStyle, uint8_t aVariant, uint16_t aWeight, int16_t aStretch, uint8_t aDecoration, diff --git a/gfx/src/nsFont.h b/gfx/src/nsFont.h index 6667d4a8eb98..9459dcc64983 100644 --- a/gfx/src/nsFont.h +++ b/gfx/src/nsFont.h @@ -6,13 +6,17 @@ #ifndef nsFont_h___ #define nsFont_h___ -#include "gfxCore.h" -#include "nsCoord.h" -#include "nsStringGlue.h" -#include "nsTArray.h" -#include "gfxFontConstants.h" +#include // for uint8_t, uint16_t +#include // for int16_t +#include "gfxCore.h" // for NS_GFX #include "gfxFontFeatures.h" -#include "nsAutoPtr.h" +#include "nsAutoPtr.h" // for nsRefPtr +#include "nsCoord.h" // for nscoord +#include "nsStringFwd.h" // for nsSubstring +#include "nsStringGlue.h" // for nsString +#include "nsTArray.h" // for nsTArray + +struct gfxFontStyle; // XXX we need a method to enumerate all of the possible fonts on the // system across family, weight, style, size, etc. But not here! @@ -34,8 +38,6 @@ const uint8_t kGenericFont_monospace = 0x08; const uint8_t kGenericFont_cursive = 0x10; const uint8_t kGenericFont_fantasy = 0x20; -struct gfxFontStyle; - // Font structure. struct NS_GFX nsFont { // The family name of the font diff --git a/gfx/src/nsFontMetrics.cpp b/gfx/src/nsFontMetrics.cpp index fbbcdabd7ad0..479e7849e477 100644 --- a/gfx/src/nsFontMetrics.cpp +++ b/gfx/src/nsFontMetrics.cpp @@ -4,11 +4,22 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsFontMetrics.h" -#include "nsBoundingMetrics.h" -#include "nsRenderingContext.h" -#include "nsDeviceContext.h" -#include "nsStyleConsts.h" -#include +#include // for floor, ceil +#include // for max +#include "gfxPlatform.h" // for gfxPlatform +#include "gfxPoint.h" // for gfxPoint +#include "gfxRect.h" // for gfxRect +#include "gfxTypes.h" // for gfxFloat +#include "nsBoundingMetrics.h" // for nsBoundingMetrics +#include "nsDebug.h" // for NS_ERROR, NS_ABORT_IF_FALSE +#include "nsDeviceContext.h" // for nsDeviceContext +#include "nsIAtom.h" // for nsIAtom +#include "nsMathUtils.h" // for NS_round +#include "nsRenderingContext.h" // for nsRenderingContext +#include "nsStringGlue.h" // for nsString +#include "nsStyleConsts.h" // for NS_STYLE_HYPHENS_NONE + +class gfxUserFontSet; namespace { diff --git a/gfx/src/nsFontMetrics.h b/gfx/src/nsFontMetrics.h index 628f6e40bf25..c4bdc72032e1 100644 --- a/gfx/src/nsFontMetrics.h +++ b/gfx/src/nsFontMetrics.h @@ -6,13 +6,21 @@ #ifndef NSFONTMETRICS__H__ #define NSFONTMETRICS__H__ -#include "nsCOMPtr.h" -#include "nsCoord.h" -#include "nsFont.h" -#include "gfxFont.h" +#include // for uint32_t +#include // for int32_t +#include "gfxFont.h" // for gfxFont, gfxFontGroup +#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 +#include "nsAutoPtr.h" // for nsRefPtr +#include "nsCOMPtr.h" // for nsCOMPtr +#include "nsCoord.h" // for nscoord +#include "nsError.h" // for nsresult +#include "nsFont.h" // for nsFont +#include "nsISupports.h" // for NS_INLINE_DECL_REFCOUNTING +#include "nscore.h" // for PRUnichar -class nsIAtom; +class gfxUserFontSet; class nsDeviceContext; +class nsIAtom; class nsRenderingContext; struct nsBoundingMetrics; diff --git a/gfx/src/nsRect.cpp b/gfx/src/nsRect.cpp index 6b1ab2cb994b..ffbb70013856 100644 --- a/gfx/src/nsRect.cpp +++ b/gfx/src/nsRect.cpp @@ -4,9 +4,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsRect.h" -#include "nsString.h" -#include "nsDeviceContext.h" -#include "prlog.h" +#include "mozilla/gfx/Types.h" // for NS_SIDE_BOTTOM, etc +#include "nsDeviceContext.h" // for nsDeviceContext +#include "nsStringGlue.h" // for nsAutoString, etc +#include "prtypes.h" // for PR_STATIC_ASSERT // the mozilla::css::Side sequence must match the nsMargin nscoord sequence PR_STATIC_ASSERT((NS_SIDE_TOP == 0) && (NS_SIDE_RIGHT == 1) && (NS_SIDE_BOTTOM == 2) && (NS_SIDE_LEFT == 3)); diff --git a/gfx/src/nsRect.h b/gfx/src/nsRect.h index 0609f64c877f..244ee127238b 100644 --- a/gfx/src/nsRect.h +++ b/gfx/src/nsRect.h @@ -7,17 +7,20 @@ #ifndef NSRECT_H #define NSRECT_H -#include -#include "nsCoord.h" -#include "nsPoint.h" -#include "nsSize.h" -#include "nsMargin.h" -#include "gfxCore.h" -#include "nsTraceRefcnt.h" -#include "mozilla/gfx/BaseRect.h" -#include "mozilla/Likely.h" -#include -#include +#include // for FILE +#include // for int32_t, int64_t +#include // for max, min +#include // for INT_MAX +#include "gfxCore.h" // for NS_GFX +#include "mozilla/Likely.h" // for MOZ_UNLIKELY +#include "mozilla/gfx/BaseRect.h" // for BaseRect +#include "nsCoord.h" // for nscoord, etc +#include "nsDebug.h" // for NS_WARNING +#include "nsMargin.h" // for nsMargin, etc +#include "nsPoint.h" // for nsIntPoint, nsPoint +#include "nsSize.h" // for nsIntSize, nsSize +#include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc +#include "nscore.h" // for NS_BUILD_REFCNT_LOGGING struct nsIntRect; diff --git a/gfx/src/nsRegion.cpp b/gfx/src/nsRegion.cpp index 5e8e3ec2b2a2..c984de9e9088 100644 --- a/gfx/src/nsRegion.cpp +++ b/gfx/src/nsRegion.cpp @@ -3,11 +3,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsRegion.h" -#include "nsISupportsImpl.h" -#include "nsTArray.h" -#include "mozilla/ThreadLocal.h" -#include "nsPrintfCString.h" -#include +#include // for max, min +#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2, etc +#include "mozilla/ThreadLocal.h" // for ThreadLocal +#include "mozilla/mozalloc.h" // for operator delete, etc +#include "nsDebug.h" // for NS_ASSERTION, NS_ERROR +#include "nsISupports.h" // for NS_ASSERT_OWNINGTHREAD, etc +#include "nsPrintfCString.h" // for nsPrintfCString +#include "nsTArray.h" // for nsTArray, nsTArray_Impl, etc /* * The SENTINEL values below guaranties that a < or > diff --git a/gfx/src/nsRegion.h b/gfx/src/nsRegion.h index 8c811d6a0748..a6b9354e76af 100644 --- a/gfx/src/nsRegion.h +++ b/gfx/src/nsRegion.h @@ -6,9 +6,16 @@ #ifndef nsRegion_h__ #define nsRegion_h__ -#include "nsRect.h" -#include "nsPoint.h" -#include "nsString.h" +#include // for size_t +#include // for uint32_t, uint64_t +#include // for int32_t +#include "gfxCore.h" // for NS_GFX +#include "nsCoord.h" // for nscoord +#include "nsError.h" // for nsresult +#include "nsPoint.h" // for nsIntPoint, nsPoint +#include "nsRect.h" // for nsIntRect, nsRect +#include "nsStringGlue.h" // for nsCString +#include "xpcom-config.h" // for CPP_THROW_NEW class nsIntRegion; diff --git a/gfx/src/nsRenderingContext.cpp b/gfx/src/nsRenderingContext.cpp index 4aa5ecc09c39..4f47b3bb1d05 100644 --- a/gfx/src/nsRenderingContext.cpp +++ b/gfx/src/nsRenderingContext.cpp @@ -4,9 +4,23 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsRenderingContext.h" -#include "nsBoundingMetrics.h" -#include "nsRegion.h" -#include +#include // for strlen +#include // for min +#include "gfxColor.h" // for gfxRGBA +#include "gfxMatrix.h" // for gfxMatrix +#include "gfxPoint.h" // for gfxPoint, gfxSize +#include "gfxRect.h" // for gfxRect +#include "gfxTypes.h" // for gfxFloat +#include "mozilla/gfx/BasePoint.h" // for BasePoint +#include "mozilla/mozalloc.h" // for operator delete[], etc +#include "nsBoundingMetrics.h" // for nsBoundingMetrics +#include "nsCharTraits.h" // for NS_IS_LOW_SURROGATE +#include "nsDebug.h" // for NS_ERROR +#include "nsPoint.h" // for nsPoint +#include "nsRect.h" // for nsRect, nsIntRect +#include "nsRegion.h" // for nsIntRegionRectIterator, etc + +class gfxASurface; // XXXTodo: rename FORM_TWIPS to FROM_APPUNITS #define FROM_TWIPS(_x) ((gfxFloat)((_x)/(mP2A))) diff --git a/gfx/src/nsRenderingContext.h b/gfx/src/nsRenderingContext.h index 1127e91f0e68..0545abcd2fa2 100644 --- a/gfx/src/nsRenderingContext.h +++ b/gfx/src/nsRenderingContext.h @@ -6,16 +6,25 @@ #ifndef NSRENDERINGCONTEXT__H__ #define NSRENDERINGCONTEXT__H__ -#include "nsAutoPtr.h" -#include "nsDeviceContext.h" -#include "nsFontMetrics.h" -#include "nsColor.h" -#include "nsCoord.h" -#include "gfxContext.h" -#include "mozilla/gfx/UserData.h" +#include // for uint32_t +#include // for int32_t +#include "gfxContext.h" // for gfxContext +#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 +#include "mozilla/gfx/UserData.h" // for UserData, UserDataKey +#include "nsAutoPtr.h" // for nsRefPtr +#include "nsBoundingMetrics.h" // for nsBoundingMetrics +#include "nsColor.h" // for nscolor +#include "nsCoord.h" // for nscoord, NSToIntRound +#include "nsDeviceContext.h" // for nsDeviceContext +#include "nsFontMetrics.h" // for nsFontMetrics +#include "nsISupports.h" // for NS_INLINE_DECL_REFCOUNTING, etc +#include "nsStringGlue.h" // for nsString +#include "nscore.h" // for PRUnichar -struct nsPoint; +class gfxASurface; class nsIntRegion; +struct nsPoint; +struct nsRect; typedef enum { nsLineStyle_kNone = 0, diff --git a/gfx/src/nsScriptableRegion.cpp b/gfx/src/nsScriptableRegion.cpp index 889f652204f8..f88ae4eb227a 100644 --- a/gfx/src/nsScriptableRegion.cpp +++ b/gfx/src/nsScriptableRegion.cpp @@ -5,10 +5,19 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsScriptableRegion.h" -#include "nsCOMPtr.h" -#include "nsIXPConnect.h" -#include "nsServiceManagerUtils.h" -#include "jsapi.h" +#include // for uint32_t +#include // for int32_t +#include "js/RootingAPI.h" // for Rooted +#include "js/Value.h" // for INT_TO_JSVAL, etc +#include "jsapi.h" // for JS_DefineElement, etc +#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 +#include "nsError.h" // for NS_OK, NS_ERROR_FAILURE, etc +#include "nsID.h" +#include "nsRect.h" // for nsIntRect +#include "nscore.h" // for NS_IMETHODIMP + +class JSObject; +struct JSContext; nsScriptableRegion::nsScriptableRegion() { diff --git a/gfx/src/nsThebesFontEnumerator.cpp b/gfx/src/nsThebesFontEnumerator.cpp index f81e1e2e711d..eff36fc61975 100644 --- a/gfx/src/nsThebesFontEnumerator.cpp +++ b/gfx/src/nsThebesFontEnumerator.cpp @@ -4,12 +4,18 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsThebesFontEnumerator.h" - -#include "nsMemory.h" - -#include "gfxPlatform.h" -#include "nsTArray.h" -#include "nsIAtom.h" +#include // for uint32_t +#include "gfxPlatform.h" // for gfxPlatform +#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 +#include "nsCOMPtr.h" // for nsCOMPtr +#include "nsDebug.h" // for NS_ENSURE_ARG_POINTER +#include "nsError.h" // for NS_OK, NS_FAILED, nsresult +#include "nsIAtom.h" // for nsIAtom, do_GetAtom +#include "nsID.h" +#include "nsMemory.h" // for nsMemory +#include "nsStringGlue.h" // for nsAutoCString, nsAutoString, etc +#include "nsTArray.h" // for nsTArray, nsTArray_Impl, etc +#include "nscore.h" // for PRUnichar, NS_IMETHODIMP NS_IMPL_ISUPPORTS1(nsThebesFontEnumerator, nsIFontEnumerator) diff --git a/gfx/src/nsThebesFontEnumerator.h b/gfx/src/nsThebesFontEnumerator.h index f1808fcd02f4..664f6e9d7e52 100644 --- a/gfx/src/nsThebesFontEnumerator.h +++ b/gfx/src/nsThebesFontEnumerator.h @@ -6,8 +6,9 @@ #ifndef _NSTHEBESFONTENUMERATOR_H_ #define _NSTHEBESFONTENUMERATOR_H_ -#include "nsIFontEnumerator.h" -#include "mozilla/Attributes.h" +#include "mozilla/Attributes.h" // for MOZ_FINAL +#include "nsIFontEnumerator.h" // for NS_DECL_NSIFONTENUMERATOR, etc +#include "nsISupports.h" // for NS_DECL_ISUPPORTS class nsThebesFontEnumerator MOZ_FINAL : public nsIFontEnumerator { diff --git a/gfx/src/nsThebesGfxFactory.cpp b/gfx/src/nsThebesGfxFactory.cpp index bf1bcd767452..13720f9a5cd4 100644 --- a/gfx/src/nsThebesGfxFactory.cpp +++ b/gfx/src/nsThebesGfxFactory.cpp @@ -3,15 +3,20 @@ * 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 "gfxPlatform.h" // for gfxPlatform +#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 +#include "mozilla/Attributes.h" // for MOZ_FINAL +#include "mozilla/Module.h" // for Module, Module::CIDEntry, etc #include "mozilla/ModuleUtils.h" -#include "mozilla/Attributes.h" -#include "nsCOMPtr.h" -#include "nsGfxCIID.h" - -#include "nsThebesFontEnumerator.h" -#include "nsScriptableRegion.h" - -#include "gfxPlatform.h" +#include "mozilla/mozalloc.h" // for operator new +#include "nsCOMPtr.h" // for nsCOMPtr +#include "nsError.h" // for NS_ERROR_NO_AGGREGATION, etc +#include "nsGfxCIID.h" // for NS_FONT_ENUMERATOR_CID, etc +#include "nsID.h" // for NS_DEFINE_NAMED_CID, etc +#include "nsIScriptableRegion.h" // for nsIScriptableRegion +#include "nsISupports.h" // for NS_DECL_ISUPPORTS, etc +#include "nsScriptableRegion.h" // for nsScriptableRegion +#include "nsThebesFontEnumerator.h" // for nsThebesFontEnumerator // This class doesn't do anything; its only purpose is to give // gfxPlatform::Init a way to force this component to be registered, diff --git a/gfx/thebes/gfxASurface.cpp b/gfx/thebes/gfxASurface.cpp index 37fa78aba4f8..539bf86249f5 100644 --- a/gfx/thebes/gfxASurface.cpp +++ b/gfx/thebes/gfxASurface.cpp @@ -523,7 +523,7 @@ gfxASurface::MovePixels(const nsIntRect& aSourceRect, // CreateSimilarSurface can return nullptr if the current surface is // in an error state. This isn't good, but its better to carry // on with the error surface instead of crashing. - NS_ASSERTION(tmp, "Must have temporary surface to move pixels!"); + NS_WARN_IF_FALSE(tmp, "Must have temporary surface to move pixels!"); if (!tmp) { return; } diff --git a/ipc/chromium/src/base/dir_reader_bsd.h b/ipc/chromium/src/base/dir_reader_bsd.h index f579af969919..f8962c36cee1 100644 --- a/ipc/chromium/src/base/dir_reader_bsd.h +++ b/ipc/chromium/src/base/dir_reader_bsd.h @@ -59,19 +59,11 @@ class DirReaderBSD { if (offset_ != size_) return true; -#ifdef OS_OPENBSD - const int r = getdirentries(fd_, buf_, sizeof(buf_), basep_); -#else const int r = getdents(fd_, buf_, sizeof(buf_)); -#endif if (r == 0) return false; if (r == -1) { -#ifdef OS_OPENBSD - DLOG(ERROR) << "getdirentries returned an error: " << errno; -#else DLOG(ERROR) << "getdents returned an error: " << errno; -#endif return false; } size_ = r; @@ -99,9 +91,6 @@ class DirReaderBSD { private: const int fd_; char buf_[512]; -#ifdef OS_OPENBSD - off_t *basep_; -#endif size_t offset_, size_; DISALLOW_COPY_AND_ASSIGN(DirReaderBSD); diff --git a/ipc/testshell/TestShellParent.h b/ipc/testshell/TestShellParent.h index 77d66284ba2d..2fad6f731b32 100644 --- a/ipc/testshell/TestShellParent.h +++ b/ipc/testshell/TestShellParent.h @@ -11,12 +11,10 @@ #include "mozilla/ipc/PTestShellParent.h" #include "mozilla/ipc/PTestShellCommandParent.h" +#include "js/TypeDecls.h" #include "nsAutoJSValHolder.h" #include "nsStringGlue.h" -struct JSContext; -class JSObject; - namespace mozilla { namespace ipc { diff --git a/ipc/testshell/XPCShellEnvironment.h b/ipc/testshell/XPCShellEnvironment.h index 8c4aaf73d14b..3abe42d72a8e 100644 --- a/ipc/testshell/XPCShellEnvironment.h +++ b/ipc/testshell/XPCShellEnvironment.h @@ -16,9 +16,8 @@ #include "nsStringGlue.h" #include "nsJSPrincipals.h" #include "nsContentUtils.h" +#include "js/TypeDecls.h" -struct JSContext; -class JSObject; struct JSPrincipals; namespace mozilla { diff --git a/js/public/Anchor.h b/js/public/Anchor.h index 0d458e6fb6cb..c2324fb2e912 100644 --- a/js/public/Anchor.h +++ b/js/public/Anchor.h @@ -11,12 +11,7 @@ #include "mozilla/Attributes.h" -class JSFunction; -class JSObject; -class JSScript; -class JSString; - -namespace JS { class Value; } +#include "js/TypeDecls.h" namespace JS { diff --git a/js/public/CallArgs.h b/js/public/CallArgs.h index 315579056335..ad5c9b6d2de8 100644 --- a/js/public/CallArgs.h +++ b/js/public/CallArgs.h @@ -38,9 +38,6 @@ #include "js/RootingAPI.h" #include "js/Value.h" -struct JSContext; -class JSObject; - /* Typedef for native functions called by the JS VM. */ typedef bool (* JSNative)(JSContext *cx, unsigned argc, JS::Value *vp); diff --git a/js/public/Class.h b/js/public/Class.h index e17a46c9ec4c..08f72b0a3f80 100644 --- a/js/public/Class.h +++ b/js/public/Class.h @@ -9,11 +9,11 @@ #ifndef js_Class_h #define js_Class_h -#include "jspubtd.h" #include "jstypes.h" #include "js/CallArgs.h" #include "js/Id.h" +#include "js/TypeDecls.h" /* * A JSClass acts as a vtable for JS objects that allows JSAPI clients to @@ -24,18 +24,6 @@ class JSFreeOp; -namespace JS { -template class Handle; -template class MutableHandle; -class Value; - -typedef JS::Handle HandleObject; -typedef JS::Handle HandleId; -typedef JS::Handle HandleValue; -typedef JS::MutableHandle MutableHandleObject; -typedef JS::MutableHandle MutableHandleValue; -} - namespace js { class Class; diff --git a/js/public/Id.h b/js/public/Id.h index 0ba3e1c5b769..b4bacbf0aa79 100644 --- a/js/public/Id.h +++ b/js/public/Id.h @@ -7,14 +7,24 @@ #ifndef js_Id_h #define js_Id_h +// A jsid is an identifier for a property or method of an object which is +// either a 31-bit signed integer, interned string or object. +// +// Also, there is an additional jsid value, JSID_VOID, which does not occur in +// JS scripts but may be used to indicate the absence of a valid jsid. A void +// jsid is not a valid id and only arises as an exceptional API return value, +// such as in JS_NextProperty. Embeddings must not pass JSID_VOID into JSAPI +// entry points expecting a jsid and do not need to handle JSID_VOID in hooks +// receiving a jsid except when explicitly noted in the API contract. +// +// A jsid is not implicitly convertible to or from a jsval; JS_ValueToId or +// JS_IdToValue must be used instead. + #include "jstypes.h" -#include "js/IdForward.h" +#include "js/TypeDecls.h" #include "js/Utility.h" -class JSObject; -class JSString; - #ifdef JS_USE_JSID_STRUCT_TYPES struct jsid { diff --git a/js/public/IdForward.h b/js/public/IdForward.h deleted file mode 100644 index f300406c9b54..000000000000 --- a/js/public/IdForward.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_IdForward_h -#define js_IdForward_h - -#include - -// A jsid is an identifier for a property or method of an object which is -// either a 31-bit signed integer, interned string or object. -// -// Also, there is an additional jsid value, JSID_VOID, which does not occur in -// JS scripts but may be used to indicate the absence of a valid jsid. A void -// jsid is not a valid id and only arises as an exceptional API return value, -// such as in JS_NextProperty. Embeddings must not pass JSID_VOID into JSAPI -// entry points expecting a jsid and do not need to handle JSID_VOID in hooks -// receiving a jsid except when explicitly noted in the API contract. -// -// A jsid is not implicitly convertible to or from a jsval; JS_ValueToId or -// JS_IdToValue must be used instead. -// -// In release builds, jsid is defined to be an integral type. This -// prevents many bugs from being caught at compile time. E.g.: -// -// jsid id = ... -// if (id) // error -// ... -// -// size_t n = id; // error -// -// To catch more errors, jsid is given a struct type in C++ debug builds. -// Struct assignment and (in C++) operator== allow correct code to be mostly -// oblivious to the change. This feature can be explicitly disabled in debug -// builds by defining JS_NO_JSVAL_JSID_STRUCT_TYPES. -// -// Note: if jsid was always a struct, we could just forward declare it in -// places where its declaration is needed. But the fact that it's a typedef in -// non-debug builds prevents that. So we have this file, which is morally -// equivalent to a forward declaration, and should be included by any file that -// uses jsid but doesn't need its definition. - -#if defined(DEBUG) && !defined(JS_NO_JSVAL_JSID_STRUCT_TYPES) -# define JS_USE_JSID_STRUCT_TYPES -#endif - -#ifdef JS_USE_JSID_STRUCT_TYPES -struct jsid; -#else -typedef ptrdiff_t jsid; -#endif - -#endif /* js_IdForward_h */ diff --git a/js/public/OldDebugAPI.h b/js/public/OldDebugAPI.h index 0835274ef5ac..911428194070 100644 --- a/js/public/OldDebugAPI.h +++ b/js/public/OldDebugAPI.h @@ -14,7 +14,7 @@ #include "jsbytecode.h" #include "js/CallArgs.h" -#include "js/IdForward.h" +#include "js/TypeDecls.h" class JSAtom; class JSFreeOp; diff --git a/js/public/ProfilingStack.h b/js/public/ProfilingStack.h index 36af5969034d..49b0ce995cc0 100644 --- a/js/public/ProfilingStack.h +++ b/js/public/ProfilingStack.h @@ -13,7 +13,6 @@ #include "js/Utility.h" struct JSRuntime; -class JSScript; namespace js { diff --git a/js/public/PropertyKey.h b/js/public/PropertyKey.h index 24640e143a17..1f90653b4027 100644 --- a/js/public/PropertyKey.h +++ b/js/public/PropertyKey.h @@ -9,10 +9,9 @@ #ifndef js_PropertyKey_h #define js_PropertyKey_h +#include "js/TypeDecls.h" #include "js/Value.h" -struct JSContext; - namespace JS { class PropertyKey; diff --git a/js/public/RootingAPI.h b/js/public/RootingAPI.h index 31948d28e3b3..82d4961ab691 100644 --- a/js/public/RootingAPI.h +++ b/js/public/RootingAPI.h @@ -12,7 +12,7 @@ #include "jspubtd.h" -#include "js/IdForward.h" +#include "js/TypeDecls.h" #include "js/Utility.h" /* @@ -98,7 +98,6 @@ namespace js { -class Module; class ScriptSourceObject; template @@ -144,9 +143,6 @@ namespace JS { template class Rooted; -template class Handle; -template class MutableHandle; - /* This is exposing internal state of the GC for inlining purposes. */ JS_FRIEND_API(bool) isGCEnabled(); @@ -467,15 +463,6 @@ class MOZ_NONHEAP_CLASS Handle : public js::HandleBase void operator=(S v) MOZ_DELETE; }; -typedef Handle HandleObject; -typedef Handle HandleModule; -typedef Handle HandleScriptSource; -typedef Handle HandleFunction; -typedef Handle HandleScript; -typedef Handle HandleString; -typedef Handle HandleId; -typedef Handle HandleValue; - /* * Similar to a handle, but the underlying storage can be changed. This is * useful for outparams. @@ -527,13 +514,6 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase void operator=(MutableHandle other) MOZ_DELETE; }; -typedef MutableHandle MutableHandleObject; -typedef MutableHandle MutableHandleFunction; -typedef MutableHandle MutableHandleScript; -typedef MutableHandle MutableHandleString; -typedef MutableHandle MutableHandleId; -typedef MutableHandle MutableHandleValue; - #ifdef JSGC_GENERATIONAL JS_PUBLIC_API(void) HeapCellPostBarrier(js::gc::Cell **cellp); JS_PUBLIC_API(void) HeapCellRelocate(js::gc::Cell **cellp); @@ -803,8 +783,6 @@ class Rooted; #endif typedef Rooted RootedObject; -typedef Rooted RootedModule; -typedef Rooted RootedScriptSource; typedef Rooted RootedFunction; typedef Rooted RootedScript; typedef Rooted RootedString; diff --git a/js/public/StructuredClone.h b/js/public/StructuredClone.h index 22084596e732..fa7d91d53c16 100644 --- a/js/public/StructuredClone.h +++ b/js/public/StructuredClone.h @@ -11,17 +11,12 @@ #include "jstypes.h" -struct JSContext; -class JSObject; +#include "js/TypeDecls.h" + struct JSRuntime; struct JSStructuredCloneReader; struct JSStructuredCloneWriter; -namespace JS { -template class Handle; -class Value; -} - // API for the HTML5 internal structured cloning algorithm. // Read structured data from the reader r. This hook is used to read a value diff --git a/js/public/TypeDecls.h b/js/public/TypeDecls.h new file mode 100644 index 000000000000..7274be8bc786 --- /dev/null +++ b/js/public/TypeDecls.h @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// This file contains public type declarations that are used *frequently*. If +// it doesn't occur at least 10 times in Gecko, it probably shouldn't be in +// here. +// +// It includes only: +// - forward declarations of structs and classes; +// - typedefs; +// - enums (maybe). +// It does *not* contain any struct or class definitions. + +#ifndef js_TypeDecls_h +#define js_TypeDecls_h + +#include +#include + +struct JSContext; +class JSFunction; +class JSObject; +class JSScript; +class JSString; + +// In release builds, jsid is defined to be an integral type. This +// prevents many bugs from being caught at compile time. E.g.: +// +// jsid id = ... +// if (id) // error +// ... +// +// size_t n = id; // error +// +// To catch more errors, jsid is given a struct type in C++ debug builds. +// Struct assignment and (in C++) operator== allow correct code to be mostly +// oblivious to the change. This feature can be explicitly disabled in debug +// builds by defining JS_NO_JSVAL_JSID_STRUCT_TYPES. +// +#if defined(DEBUG) && !defined(JS_NO_JSVAL_JSID_STRUCT_TYPES) +# define JS_USE_JSID_STRUCT_TYPES +#endif + +#ifdef JS_USE_JSID_STRUCT_TYPES +struct jsid; +#else +typedef ptrdiff_t jsid; +#endif + +#ifdef WIN32 +typedef wchar_t jschar; +#else +typedef uint16_t jschar; +#endif + +namespace JS { + +class Value; +template class Handle; +template class MutableHandle; + +typedef Handle HandleFunction; +typedef Handle HandleId; +typedef Handle HandleObject; +typedef Handle HandleScript; +typedef Handle HandleString; +typedef Handle HandleValue; + +typedef MutableHandle MutableHandleFunction; +typedef MutableHandle MutableHandleId; +typedef MutableHandle MutableHandleObject; +typedef MutableHandle MutableHandleScript; +typedef MutableHandle MutableHandleString; +typedef MutableHandle MutableHandleValue; + +} // namespace JS + +#endif /* js_TypeDecls_h */ diff --git a/js/src/TraceLogging.h b/js/src/TraceLogging.h index 6b79fcff1bba..64ae5a8df23c 100644 --- a/js/src/TraceLogging.h +++ b/js/src/TraceLogging.h @@ -10,8 +10,6 @@ #include #include -class JSScript; - namespace JS { class CompileOptions; } diff --git a/js/src/builtin/Intl.h b/js/src/builtin/Intl.h index 68c6e67913f2..149fd6660820 100644 --- a/js/src/builtin/Intl.h +++ b/js/src/builtin/Intl.h @@ -11,9 +11,6 @@ #include "js/RootingAPI.h" -struct JSContext; -class JSObject; - /* * The Intl module specified by standard ECMA-402, * ECMAScript Internationalization API Specification. @@ -26,7 +23,6 @@ class JSObject; extern JSObject * js_InitIntlClass(JSContext *cx, js::HandleObject obj); - namespace js { /* diff --git a/js/src/builtin/Module.cpp b/js/src/builtin/Module.cpp index 561deec8525d..157440e60cec 100644 --- a/js/src/builtin/Module.cpp +++ b/js/src/builtin/Module.cpp @@ -10,6 +10,10 @@ using namespace js; +namespace js { +typedef Rooted RootedModule; +} + Class Module::class_ = { "Module", JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_IS_ANONYMOUS, diff --git a/js/src/builtin/Profilers.cpp b/js/src/builtin/Profilers.cpp index 1f2b0fcce63d..c2eddfcaa412 100644 --- a/js/src/builtin/Profilers.cpp +++ b/js/src/builtin/Profilers.cpp @@ -213,8 +213,7 @@ struct RequiredStringArg { return (void*) mBytes; } ~RequiredStringArg() { - if (mBytes) - js_free(mBytes); + js_free(mBytes); } }; diff --git a/js/src/config/makefiles/mozconfig.mk b/js/src/config/makefiles/mozconfig.mk new file mode 100644 index 000000000000..21408c46af48 --- /dev/null +++ b/js/src/config/makefiles/mozconfig.mk @@ -0,0 +1,33 @@ +# -*- makefile -*- +# vim:set ts=8 sw=8 sts=8 noet: +# +# 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/. +# + +INCLUDED_MOZCONFIG_MK = 1 + +# We are pulling in the mozconfig exports, so we only need to run once for the +# whole make process tree (not for each sub-make). Export this so the sub-makes +# don't read mozconfig multiple times. +export INCLUDED_MOZCONFIG_MK + +MOZCONFIG_LOADER := build/autoconf/mozconfig2client-mk + +define CR + + +endef + +# topsrcdir is used by rules.mk (set from the generated Makefile), while +# TOPSRCDIR is used by client.mk +ifneq (,$(topsrcdir)) +top := $(topsrcdir) +else +top := $(TOPSRCDIR) +endif +# As $(shell) doesn't preserve newlines, use sed to replace them with an +# unlikely sequence (||), which is then replaced back to newlines by make +# before evaluation. +$(eval $(subst ||,$(CR),$(shell _PYMAKE=$(.PYMAKE) $(top)/$(MOZCONFIG_LOADER) $(top) 2> $(top)/.mozconfig.out | sed 's/$$/||/'))) diff --git a/js/src/config/rules.mk b/js/src/config/rules.mk index 1642368e71da..45ca4ea68a55 100644 --- a/js/src/config/rules.mk +++ b/js/src/config/rules.mk @@ -10,6 +10,10 @@ ifndef topsrcdir $(error topsrcdir was not set)) endif +ifndef INCLUDED_MOZCONFIG_MK +include $(topsrcdir)/config/makefiles/mozconfig.mk +endif + # Integrate with mozbuild-generated make files. We first verify that no # variables provided by the automatically generated .mk files are # present. If they are, this is a violation of the separation of diff --git a/js/src/ctypes/CTypes.h b/js/src/ctypes/CTypes.h index c120dcc5be9f..fa753c28fa99 100644 --- a/js/src/ctypes/CTypes.h +++ b/js/src/ctypes/CTypes.h @@ -298,8 +298,7 @@ struct ClosureInfo ~ClosureInfo() { if (closure) ffi_closure_free(closure); - if (errResult) - js_free(errResult); + js_free(errResult); } }; diff --git a/js/src/ds/LifoAlloc.cpp b/js/src/ds/LifoAlloc.cpp index 5a759cef1db7..2a785019d1fc 100644 --- a/js/src/ds/LifoAlloc.cpp +++ b/js/src/ds/LifoAlloc.cpp @@ -124,14 +124,16 @@ void LifoAlloc::transferFrom(LifoAlloc *other) { JS_ASSERT(!markCount); - JS_ASSERT(latest == first); JS_ASSERT(!other->markCount); if (!other->first) return; incrementCurSize(other->curSize_); - append(other->first, other->last); + if (other->isEmpty()) + appendUnused(other->first, other->last); + else + appendUsed(other->first, other->latest, other->last); other->first = other->last = other->latest = NULL; other->curSize_ = 0; } @@ -161,7 +163,7 @@ LifoAlloc::transferUnusedFrom(LifoAlloc *other) } } - append(other->latest->next(), other->last); + appendUnused(other->latest->next(), other->last); other->latest->setNext(NULL); other->last = other->latest; } diff --git a/js/src/ds/LifoAlloc.h b/js/src/ds/LifoAlloc.h index d8da17e85a30..48e3a16a80cc 100644 --- a/js/src/ds/LifoAlloc.h +++ b/js/src/ds/LifoAlloc.h @@ -187,7 +187,8 @@ class LifoAlloc curSize_ = 0; } - void append(BumpChunk *start, BumpChunk *end) { + // Append unused chunks to the end of this LifoAlloc. + void appendUnused(BumpChunk *start, BumpChunk *end) { JS_ASSERT(start && end); if (last) last->setNext(start); @@ -196,6 +197,18 @@ class LifoAlloc last = end; } + // Append used chunks to the end of this LifoAlloc. We act as if all the + // chunks in |this| are used, even if they're not, so memory may be wasted. + void appendUsed(BumpChunk *start, BumpChunk *latest, BumpChunk *end) { + JS_ASSERT(start && latest && end); + if (last) + last->setNext(start); + else + first = latest = start; + last = end; + this->latest = latest; + } + void incrementCurSize(size_t size) { curSize_ += size; if (curSize_ > peakSize_) diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index a60046bc1831..f6767646ba97 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -188,7 +188,7 @@ frontend::CompileScript(ExclusiveContext *cx, LifoAlloc *alloc, HandleObject sco if (options.filename && !ss->setFilename(cx, options.filename)) return NULL; - JS::RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, ss)); + RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, ss)); if (!sourceObject) return NULL; @@ -416,7 +416,7 @@ frontend::CompileLazyFunction(JSContext *cx, LazyScript *lazy, const jschar *cha return false; RootedObject enclosingScope(cx, lazy->enclosingScope()); - JS::RootedScriptSource sourceObject(cx, lazy->sourceObject()); + RootedScriptSource sourceObject(cx, lazy->sourceObject()); JS_ASSERT(sourceObject); Rooted script(cx, JSScript::Create(cx, enclosingScope, false, @@ -468,7 +468,7 @@ CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileOptions opt return false; if (options.filename && !ss->setFilename(cx, options.filename)) return false; - JS::RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, ss)); + RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, ss)); if (!sourceObject) return false; SourceCompressionTask sct(cx); diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index ae1e6db268a2..bf3109cd9d0d 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -3621,6 +3621,8 @@ EmitSingletonInitialiser(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode * JS_STATIC_ASSERT(JSOP_NOP_LENGTH == 1); JS_STATIC_ASSERT(JSOP_POP_LENGTH == 1); +namespace { + class EmitLevelManager { BytecodeEmitter *bce; @@ -3629,6 +3631,8 @@ class EmitLevelManager ~EmitLevelManager() { bce->emitLevel--; } }; +} /* anonymous namespace */ + static bool EmitCatch(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn) { diff --git a/js/src/frontend/NameFunctions.cpp b/js/src/frontend/NameFunctions.cpp index 100c774fac99..1258651e9ac2 100644 --- a/js/src/frontend/NameFunctions.cpp +++ b/js/src/frontend/NameFunctions.cpp @@ -20,6 +20,8 @@ using namespace js; using namespace js::frontend; +namespace { + class NameResolver { static const size_t MaxParents = 100; @@ -325,6 +327,8 @@ class NameResolver } }; +} /* anonymous namespace */ + bool frontend::NameFunctions(JSContext *cx, ParseNode *pn) { diff --git a/js/src/frontend/NameFunctions.h b/js/src/frontend/NameFunctions.h index bfefd4cf27c9..c6845c4cbfad 100644 --- a/js/src/frontend/NameFunctions.h +++ b/js/src/frontend/NameFunctions.h @@ -7,7 +7,7 @@ #ifndef frontend_NameFunctions_h #define frontend_NameFunctions_h -struct JSContext; +#include "js/TypeDecls.h" namespace js { namespace frontend { diff --git a/js/src/frontend/ParseNode.cpp b/js/src/frontend/ParseNode.cpp index 55a2c172aa78..1536a66268ad 100644 --- a/js/src/frontend/ParseNode.cpp +++ b/js/src/frontend/ParseNode.cpp @@ -70,6 +70,8 @@ ParseNodeAllocator::freeNode(ParseNode *pn) freelist = pn; } +namespace { + /* * A work pool of ParseNodes. The work pool is a stack, chained together * by nodes' pn_next fields. We use this to avoid creating deep C++ stacks @@ -104,6 +106,8 @@ class NodeStack { ParseNode *top; }; +} /* anonymous namespace */ + /* * Push the children of |pn| on |stack|. Return true if |pn| itself could be * safely recycled, or false if it must be cleaned later (pn_used and pn_defn diff --git a/js/src/frontend/TokenStream.cpp b/js/src/frontend/TokenStream.cpp index 2e1973b61558..ae7b719ef294 100644 --- a/js/src/frontend/TokenStream.cpp +++ b/js/src/frontend/TokenStream.cpp @@ -333,8 +333,7 @@ TokenStream::TokenStream(ExclusiveContext *cx, const CompileOptions &options, TokenStream::~TokenStream() { - if (sourceMap) - js_free(sourceMap); + js_free(sourceMap); JS_ASSERT_IF(originPrincipals, originPrincipals->refcount); } @@ -847,8 +846,7 @@ TokenStream::getSourceMappingURL(bool isMultiline, bool shouldWarnDeprecated) size_t sourceMapLength = tokenbuf.length(); - if (sourceMap) - js_free(sourceMap); + js_free(sourceMap); sourceMap = cx->pod_malloc(sourceMapLength + 1); if (!sourceMap) return false; diff --git a/js/src/gc/Marking.h b/js/src/gc/Marking.h index 51835dbe7ab0..c8f190e180f2 100644 --- a/js/src/gc/Marking.h +++ b/js/src/gc/Marking.h @@ -9,13 +9,7 @@ #include "gc/Barrier.h" #include "jit/IonCode.h" - -extern "C" { -struct JSContext; -class JSFunction; -class JSObject; -class JSScript; -} +#include "js/TypeDecls.h" class JSAtom; class JSLinearString; diff --git a/js/src/gc/Rooting.h b/js/src/gc/Rooting.h index 6c45e82b9a4d..bf94a6591cfc 100644 --- a/js/src/gc/Rooting.h +++ b/js/src/gc/Rooting.h @@ -24,6 +24,7 @@ typedef JS::Handle HandleShape; typedef JS::Handle HandleTypeObject; typedef JS::Handle HandleAtom; typedef JS::Handle HandlePropertyName; +typedef JS::Handle HandleScriptSource; typedef JS::MutableHandle MutableHandleShape; typedef JS::MutableHandle MutableHandleAtom; @@ -32,6 +33,7 @@ typedef JS::Rooted RootedShape; typedef JS::Rooted RootedTypeObject; typedef JS::Rooted RootedAtom; typedef JS::Rooted RootedPropertyName; +typedef Rooted RootedScriptSource; } /* namespace js */ diff --git a/js/src/jit/AsmJS.cpp b/js/src/jit/AsmJS.cpp index 33cd89ade4c5..09a072487645 100644 --- a/js/src/jit/AsmJS.cpp +++ b/js/src/jit/AsmJS.cpp @@ -623,6 +623,8 @@ operator<=(Type lhs, VarType rhs) static inline MIRType ToMIRType(MIRType t) { return t; } static inline MIRType ToMIRType(VarType t) { return t.toMIRType(); } +namespace { + template class ABIArgIter { @@ -683,6 +685,8 @@ class Signature RetType retType() const { return retType_; } }; +} /* namespace anonymous */ + static bool operator==(const Signature &lhs, const Signature &rhs) { @@ -907,11 +911,11 @@ TypedArrayStoreType(ArrayBufferView::ViewType viewType) /*****************************************************************************/ +namespace { + typedef Vector LabelVector; typedef Vector BlockVector; -namespace { - // ModuleCompiler encapsulates the compilation of an entire asm.js module. Over // the course of an ModuleCompiler object's lifetime, many FunctionCompiler // objects will be created and destroyed in sequence, one for each function in diff --git a/js/src/jit/BaselineBailouts.cpp b/js/src/jit/BaselineBailouts.cpp index e73ce08313d4..4936d3707c9d 100644 --- a/js/src/jit/BaselineBailouts.cpp +++ b/js/src/jit/BaselineBailouts.cpp @@ -96,8 +96,7 @@ struct BaselineStackBuilder } ~BaselineStackBuilder() { - if (buffer_) - js_free(buffer_); + js_free(buffer_); } bool init() { diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index baefb11338bf..7e77fa9a8a67 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -422,8 +422,8 @@ BaselineCompiler::emitStackCheck() { Label skipCall; uintptr_t *limitAddr = &cx->runtime()->mainThread.ionStackLimit; - masm.loadPtr(AbsoluteAddress(limitAddr), R0.scratchReg()); - masm.branchPtr(Assembler::AboveOrEqual, BaselineStackReg, R0.scratchReg(), &skipCall); + masm.branchPtr(Assembler::BelowOrEqual, AbsoluteAddress(limitAddr), BaselineStackReg, + &skipCall); prepareVMCall(); if (!callVM(CheckOverRecursedInfo)) diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 6c777a0b0bcb..eba68b7ae438 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -6187,7 +6187,8 @@ CodeGenerator::visitSetPropertyCacheV(LSetPropertyCacheV *ins) Register objReg = ToRegister(ins->getOperand(0)); ConstantOrRegister value = TypedOrValueRegister(ToValue(ins, LSetPropertyCacheV::Value)); - SetPropertyIC cache(liveRegs, objReg, ins->mir()->name(), value, ins->mir()->strict()); + SetPropertyIC cache(liveRegs, objReg, ins->mir()->name(), value, ins->mir()->strict(), + ins->mir()->needsTypeBarrier()); return addCache(ins, allocateCache(cache)); } @@ -6203,7 +6204,8 @@ CodeGenerator::visitSetPropertyCacheT(LSetPropertyCacheT *ins) else value = TypedOrValueRegister(ins->valueType(), ToAnyRegister(ins->getOperand(1))); - SetPropertyIC cache(liveRegs, objReg, ins->mir()->name(), value, ins->mir()->strict()); + SetPropertyIC cache(liveRegs, objReg, ins->mir()->name(), value, ins->mir()->strict(), + ins->mir()->needsTypeBarrier()); return addCache(ins, allocateCache(cache)); } diff --git a/js/src/jit/EffectiveAddressAnalysis.cpp b/js/src/jit/EffectiveAddressAnalysis.cpp index e329c2d81750..9d39fe12a397 100644 --- a/js/src/jit/EffectiveAddressAnalysis.cpp +++ b/js/src/jit/EffectiveAddressAnalysis.cpp @@ -32,7 +32,7 @@ AnalyzeLsh(MBasicBlock *block, MLsh *lsh) MInstruction *last = lsh; MDefinition *base = NULL; while (true) { - if (last->useCount() != 1) + if (!last->hasOneUse()) break; MUseIterator use = last->usesBegin(); @@ -61,7 +61,7 @@ AnalyzeLsh(MBasicBlock *block, MLsh *lsh) if (displacement % elemSize != 0) return; - if (last->useCount() != 1) + if (!last->hasOneUse()) return; MUseIterator use = last->usesBegin(); diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index 9d84cc6a5fba..f6be53e54e53 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -478,8 +478,7 @@ IonCompartment::IonCompartment(IonRuntime *rt) IonCompartment::~IonCompartment() { - if (stubCodes_) - js_delete(stubCodes_); + js_delete(stubCodes_); } bool diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 34f092a6621f..105eaf574eff 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -1141,7 +1141,7 @@ IonBuilder::traverseBytecode() #ifdef DEBUG for (size_t i = 0; i < popped.length(); i++) { // Call instructions can discard PassArg instructions. Ignore them. - if (popped[i]->isPassArg() && popped[i]->useCount() == 0) + if (popped[i]->isPassArg() && !popped[i]->hasUses()) continue; switch (op) { @@ -4038,13 +4038,14 @@ IonBuilder::getInlineableGetPropertyCache(CallInfo &callInfo) return NULL; MTypeBarrier *barrier = unbox->input()->toTypeBarrier(); - if (barrier->useCount() != 1) + // Test if usecount() > 1 + if (!barrier->hasOneUse()) return NULL; if (!barrier->input()->isGetPropertyCache()) return NULL; MGetPropertyCache *cache = barrier->input()->toGetPropertyCache(); - if (cache->useCount() > 1) + if (cache->hasUses() && !cache->hasOneUse()) return NULL; if (!CanInlineGetPropertyCache(cache, thisDef)) return NULL; @@ -4161,7 +4162,7 @@ IonBuilder::inlineTypeObjectFallback(CallInfo &callInfo, MBasicBlock *dispatchBl // 3. The MGetPropertyCache (and, if applicable, MTypeBarrier and MUnbox) only // have at most a single use. JS_ASSERT_IF(callInfo.fun()->isGetPropertyCache(), !cache->hasUses()); - JS_ASSERT_IF(callInfo.fun()->isUnbox(), cache->useCount() == 1); + JS_ASSERT_IF(callInfo.fun()->isUnbox(), cache->hasOneUse()); // This means that no resume points yet capture the MGetPropertyCache, // so everything from the MGetPropertyCache up until the call is movable. @@ -8612,11 +8613,8 @@ IonBuilder::setPropTryCache(bool *emitted, MDefinition *obj, { JS_ASSERT(*emitted == false); - if (barrier) - return true; - // Emit SetPropertyCache. - MSetPropertyCache *ins = MSetPropertyCache::New(obj, value, name, script()->strict); + MSetPropertyCache *ins = MSetPropertyCache::New(obj, value, name, script()->strict, barrier); RootedId id(cx, NameToId(name)); if (!objTypes || objTypes->propertyNeedsBarrier(cx, id)) diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 564ce745b04c..2bd3297a49dc 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -854,8 +854,6 @@ EmitGetterCall(JSContext *cx, MacroAssembler &masm, // TODO: ensure stack is aligned? DebugOnly initialStack = masm.framePushed(); - attacher.pushStubCodePointer(masm); - if (callNative) { JS_ASSERT(shape->hasGetterValue() && shape->getterValue().isObject() && shape->getterValue().toObject().is()); @@ -880,9 +878,13 @@ EmitGetterCall(JSContext *cx, MacroAssembler &masm, masm.move32(Imm32(0), argUintNReg); masm.movePtr(StackPointer, argVpReg); + // Push marking data for later use. + masm.Push(argUintNReg); + attacher.pushStubCodePointer(masm); + if (!masm.buildOOLFakeExitFrame(returnAddr)) return false; - masm.enterFakeExitFrame(ION_FRAME_OOL_NATIVE_GETTER); + masm.enterFakeExitFrame(ION_FRAME_OOL_NATIVE); // Construct and execute call. masm.setupUnalignedABICall(3, scratchReg); @@ -896,7 +898,7 @@ EmitGetterCall(JSContext *cx, MacroAssembler &masm, // Load the outparam vp[0] into output register(s). masm.loadValue( - Address(StackPointer, IonOOLNativeGetterExitFrameLayout::offsetOfResult()), + Address(StackPointer, IonOOLNativeExitFrameLayout::offsetOfResult()), JSReturnOperand); } else { Register argObjReg = argUintNReg; @@ -904,6 +906,10 @@ EmitGetterCall(JSContext *cx, MacroAssembler &masm, PropertyOp target = shape->getterOp(); JS_ASSERT(target); + + // Push stubCode for marking. + attacher.pushStubCodePointer(masm); + // JSPropertyOp: bool fn(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue vp) // Push args on stack first so we can take pointers to make handles. @@ -952,7 +958,7 @@ EmitGetterCall(JSContext *cx, MacroAssembler &masm, // Move the StackPointer back to its original location, unwinding the native exit frame. if (callNative) - masm.adjustStack(IonOOLNativeGetterExitFrameLayout::Size()); + masm.adjustStack(IonOOLNativeExitFrameLayout::Size(0)); else masm.adjustStack(IonOOLPropertyOpExitFrameLayout::Size()); JS_ASSERT(masm.framePushed() == initialStack); @@ -1319,7 +1325,7 @@ EmitCallProxyGet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at if (!masm.buildOOLFakeExitFrame(returnAddr)) return false; - masm.enterFakeExitFrame(ION_FRAME_OOL_PROXY_GET); + masm.enterFakeExitFrame(ION_FRAME_OOL_PROXY); // Make the call. masm.setupUnalignedABICall(5, scratch); @@ -1335,7 +1341,7 @@ EmitCallProxyGet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at // Load the outparam vp[0] into output register(s). masm.loadValue( - Address(StackPointer, IonOOLProxyGetExitFrameLayout::offsetOfResult()), + Address(StackPointer, IonOOLProxyExitFrameLayout::offsetOfResult()), JSReturnOperand); masm.storeCallResultValue(output); @@ -1344,7 +1350,7 @@ EmitCallProxyGet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at // is no need for leaveFakeExitFrame. // Move the StackPointer back to its original location, unwinding the exit frame. - masm.adjustStack(IonOOLProxyGetExitFrameLayout::Size()); + masm.adjustStack(IonOOLProxyExitFrameLayout::Size()); JS_ASSERT(masm.framePushed() == initialStack); // restoreLive() @@ -1521,6 +1527,21 @@ GetPropertyIC::tryAttachProxy(JSContext *cx, IonScript *ion, HandleObject obj, return tryAttachGenericProxy(cx, ion, obj, name, returnAddr, emitted); } +static void +GenerateProxyClassGuards(MacroAssembler &masm, Register object, Register scratchReg, + Label *failures, Label *success) +{ + // Ensure that the incoming object has one of the magic class pointers, i.e, + // that it is one of an ObjectProxy, FunctionProxy, or OuterWindowProxy. + // This is equivalent to obj->is(). + masm.branchTestObjClass(Assembler::Equal, object, scratchReg, + ObjectProxyClassPtr, success); + masm.branchTestObjClass(Assembler::Equal, object, scratchReg, + FunctionProxyClassPtr, success); + masm.branchTestObjClass(Assembler::NotEqual, object, scratchReg, + OuterWindowProxyClassPtr, failures); +} + bool GetPropertyIC::tryAttachGenericProxy(JSContext *cx, IonScript *ion, HandleObject obj, HandlePropertyName name, void *returnAddr, @@ -1536,7 +1557,6 @@ GetPropertyIC::tryAttachGenericProxy(JSContext *cx, IonScript *ion, HandleObject *emitted = true; Label failures; - Label classPass; MacroAssembler masm(cx); RepatchStubAppender attacher(*this); @@ -1544,25 +1564,14 @@ GetPropertyIC::tryAttachGenericProxy(JSContext *cx, IonScript *ion, HandleObject masm.setFramePushed(ion->frameSize()); - // The branching around here is a little kludgy. It seems mostly unavoidable. + Label proxySuccess; + GenerateProxyClassGuards(masm, object(), scratchReg, &failures, &proxySuccess); + masm.bind(&proxySuccess); - // Ensure that the incoming object has one of the magic class pointers, i.e, - // that it is one of an ObjectProxy, FunctionProxy, or OuterWindowProxy. - masm.branchTestObjClass(Assembler::Equal, object(), scratchReg, - ObjectProxyClassPtr, &classPass); - masm.branchTestObjClass(Assembler::Equal, object(), scratchReg, - FunctionProxyClassPtr, &classPass); - masm.branchTestObjClass(Assembler::NotEqual, object(), scratchReg, - OuterWindowProxyClassPtr, &failures); - - masm.bind(&classPass); // Ensure that the incoming object is not a DOM proxy, so that we can get to // the specialized stubs - Address handlerAddr(object(), ProxyObject::offsetOfHandler()); - masm.loadPrivate(handlerAddr, scratchReg); - Address familyAddr(scratchReg, BaseProxyHandler::offsetOfFamily()); - masm.branchPtr(Assembler::Equal, familyAddr, ImmWord(GetDOMProxyHandlerFamily()), - &failures); + masm.branchTestProxyHandlerFamily(Assembler::Equal, object(), scratchReg, + GetDOMProxyHandlerFamily(), &failures); if (!EmitCallProxyGet(cx, masm, attacher, name, liveRegs_, object(), output(), returnAddr)) return false; @@ -1798,8 +1807,7 @@ void ParallelIonCache::destroy() { DispatchIonCache::destroy(); - if (stubbedShapes_) - js_delete(stubbedShapes_); + js_delete(stubbedShapes_); } void @@ -1936,12 +1944,53 @@ bool SetPropertyIC::attachNativeExisting(JSContext *cx, IonScript *ion, HandleObject obj, HandleShape shape) { + JS_ASSERT(obj->isNative()); + MacroAssembler masm(cx); RepatchStubAppender attacher(*this); - attacher.branchNextStub(masm, Assembler::NotEqual, - Address(object(), JSObject::offsetOfShape()), - ImmGCPtr(obj->lastProperty())); + Label failures; + masm.branchPtr(Assembler::NotEqual, + Address(object(), JSObject::offsetOfShape()), + ImmGCPtr(obj->lastProperty()), &failures); + + // Guard that the incoming value is in the type set for the property + // if a type barrier is required. + if (needsTypeBarrier() && !value().constant()) { + // We can't do anything that would change the HeapTypeSet, so + // just guard that it's already there. + + // Obtain and guard on the TypeObject of the object. + types::TypeObject *type = obj->getType(cx); + masm.branchPtr(Assembler::NotEqual, + Address(object(), JSObject::offsetOfType()), + ImmGCPtr(type), &failures); + + if (!type->unknownProperties()) { + TypedOrValueRegister valReg = value().reg(); + RootedId id(cx, types::IdToTypeId(AtomToId(name()))); + types::HeapTypeSet *propTypes = type->maybeGetProperty(cx, id); + JS_ASSERT(propTypes); + + if (!propTypes->unknown()) { + Label barrierSuccess; + Label barrierFailure; + + Register scratchReg = object(); + masm.push(scratchReg); + + masm.guardTypeSet(valReg, propTypes, scratchReg, + &barrierSuccess, &barrierFailure); + + masm.bind(&barrierFailure); + masm.pop(object()); + masm.jump(&failures); + + masm.bind(&barrierSuccess); + masm.pop(object()); + } + } + } if (obj->isFixedSlot(shape->slot())) { Address addr(object(), JSObject::getFixedSlotOffset(shape->slot())); @@ -1964,14 +2013,484 @@ SetPropertyIC::attachNativeExisting(JSContext *cx, IonScript *ion, attacher.jumpRejoin(masm); + masm.bind(&failures); + attacher.jumpNextStub(masm); + return linkAndAttachStub(cx, masm, attacher, ion, "setting"); } +static bool +IsCacheableSetPropCallNative(HandleObject obj, HandleObject holder, HandleShape shape) +{ + if (!obj->isNative()) + return false; + + if (!shape || !IsCacheableProtoChain(obj, holder)) + return false; + + return shape->hasSetterValue() && shape->setterObject()->is() && + shape->setterObject()->as().isNative(); +} + +static bool +IsCacheableSetPropCallPropertyOp(HandleObject obj, HandleObject holder, + HandleShape shape) +{ + if (!obj->isNative()) + return false; + + if (!shape) + return false; + + if (!IsCacheableProtoChain(obj, holder)) + return false; + + if (shape->hasSlot()) + return false; + + if (shape->hasDefaultSetter()) + return false; + + if (shape->hasSetterValue()) + return false; + + return true; +} + +static bool +EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher, + HandleId propId, RegisterSet liveRegs, Register object, + ConstantOrRegister value, void *returnAddr, bool strict) +{ + // saveLive() + masm.PushRegsInMask(liveRegs); + + // Remaining registers should be free, but we need to use |object| still + // so leave it alone. + RegisterSet regSet(RegisterSet::All()); + regSet.take(AnyRegister(object)); + + // Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, + // bool strict, MutableHandleValue vp) + Register argJSContextReg = regSet.takeGeneral(); + Register argProxyReg = regSet.takeGeneral(); + Register argIdReg = regSet.takeGeneral(); + Register argVpReg = regSet.takeGeneral(); + Register argStrictReg = regSet.takeGeneral(); + + Register scratch = regSet.takeGeneral(); + + DebugOnly initialStack = masm.framePushed(); + + // Push stubCode for marking. + attacher.pushStubCodePointer(masm); + + // Push args on stack first so we can take pointers to make handles. + masm.Push(value); + masm.movePtr(StackPointer, argVpReg); + + masm.Push(propId, scratch); + masm.movePtr(StackPointer, argIdReg); + + // Pushing object and receiver. Both are the same, so Handle to one is equivalent to + // handle to other. + masm.Push(object); + masm.Push(object); + masm.movePtr(StackPointer, argProxyReg); + + masm.loadJSContext(argJSContextReg); + masm.move32(Imm32(strict? 1 : 0), argStrictReg); + + if (!masm.buildOOLFakeExitFrame(returnAddr)) + return false; + masm.enterFakeExitFrame(ION_FRAME_OOL_PROXY); + + // Make the call. + masm.setupUnalignedABICall(6, scratch); + masm.passABIArg(argJSContextReg); + masm.passABIArg(argProxyReg); + masm.passABIArg(argProxyReg); + masm.passABIArg(argIdReg); + masm.passABIArg(argStrictReg); + masm.passABIArg(argVpReg); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, Proxy::set)); + + // Test for failure. + masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel()); + + // The next instruction is removing the footer of the exit frame, so there + // is no need for leaveFakeExitFrame. + + // Move the StackPointer back to its original location, unwinding the exit frame. + masm.adjustStack(IonOOLProxyExitFrameLayout::Size()); + JS_ASSERT(masm.framePushed() == initialStack); + + // restoreLive() + masm.PopRegsInMask(liveRegs); + + return true; +} + +bool +SetPropertyIC::attachGenericProxy(JSContext *cx, IonScript *ion, void *returnAddr) +{ + JS_ASSERT(!hasGenericProxyStub()); + + MacroAssembler masm(cx); + RepatchStubAppender attacher(*this); + + masm.setFramePushed(ion->frameSize()); + + Label failures; + { + Label proxyFailures; + Label proxySuccess; + + RegisterSet regSet(RegisterSet::All()); + regSet.take(AnyRegister(object())); + if (!value().constant()) + regSet.maybeTake(value().reg()); + + Register scratch = regSet.takeGeneral(); + masm.push(scratch); + + GenerateProxyClassGuards(masm, object(), scratch, &proxyFailures, &proxySuccess); + + // Remove the DOM proxies. They'll take care of themselves so this stub doesn't + // catch too much. + masm.branchTestProxyHandlerFamily(Assembler::Equal, object(), scratch, + GetDOMProxyHandlerFamily(), &proxyFailures); + + masm.bind(&proxyFailures); + masm.pop(scratch); + // Unify the point of failure to allow for later DOM proxy handling. + masm.jump(&failures); + + masm.bind(&proxySuccess); + masm.pop(scratch); + } + + RootedId propId(cx, AtomToId(name())); + if (!EmitCallProxySet(cx, masm, attacher, propId, liveRegs_, object(), value(), + returnAddr, strict())) + { + return false; + } + + attacher.jumpRejoin(masm); + + masm.bind(&failures); + attacher.jumpNextStub(masm); + + JS_ASSERT(!hasGenericProxyStub_); + hasGenericProxyStub_ = true; + + return linkAndAttachStub(cx, masm, attacher, ion, "generic proxy set"); +} + +bool +SetPropertyIC::attachDOMProxyShadowed(JSContext *cx, IonScript *ion, HandleObject obj, + void *returnAddr) +{ + JS_ASSERT(IsCacheableDOMProxy(obj)); + + Label failures; + MacroAssembler masm(cx); + RepatchStubAppender attacher(*this); + + masm.setFramePushed(ion->frameSize()); + + // Guard on the shape of the object. + masm.branchPtr(Assembler::NotEqual, + Address(object(), JSObject::offsetOfShape()), + ImmGCPtr(obj->lastProperty()), &failures); + + // Make sure object is a DOMProxy + GenerateDOMProxyChecks(cx, masm, obj, name(), object(), &failures, + /*skipExpandoCheck=*/true); + + RootedId propId(cx, AtomToId(name())); + if (!EmitCallProxySet(cx, masm, attacher, propId, liveRegs_, object(), + value(), returnAddr, strict())) + { + return false; + } + + // Success. + attacher.jumpRejoin(masm); + + // Failure. + masm.bind(&failures); + attacher.jumpNextStub(masm); + + return linkAndAttachStub(cx, masm, attacher, ion, "DOM proxy shadowed set"); +} + +static bool +GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler &masm, + IonCache::StubAttacher &attacher, HandleObject obj, + HandleObject holder, HandleShape shape, bool strict, Register object, + ConstantOrRegister value, Label *failure, RegisterSet liveRegs, + void *returnAddr) +{ + // Generate prototype guards if needed. + // Take a scratch register for use, save on stack. + { + RegisterSet regSet(RegisterSet::All()); + regSet.take(AnyRegister(object)); + if (!value.constant()) + regSet.maybeTake(value.reg()); + Register scratchReg = regSet.takeGeneral(); + masm.push(scratchReg); + + Label protoFailure; + Label protoSuccess; + + // Generate prototype/shape guards. + if (obj != holder) + GeneratePrototypeGuards(cx, ion, masm, obj, holder, object, scratchReg, &protoFailure); + + masm.moveNurseryPtr(ImmMaybeNurseryPtr(holder), scratchReg); + masm.branchPtr(Assembler::NotEqual, + Address(scratchReg, JSObject::offsetOfShape()), + ImmGCPtr(holder->lastProperty()), + &protoFailure); + + masm.jump(&protoSuccess); + + masm.bind(&protoFailure); + masm.pop(scratchReg); + masm.jump(failure); + + masm.bind(&protoSuccess); + masm.pop(scratchReg); + } + + // Good to go for invoking setter. + + // saveLive() + masm.PushRegsInMask(liveRegs); + + // Remaining registers should basically be free, but we need to use |object| still + // so leave it alone. + RegisterSet regSet(RegisterSet::All()); + regSet.take(AnyRegister(object)); + + // This is a slower stub path, and we're going to be doing a call anyway. Don't need + // to try so hard to not use the stack. Scratch regs are just taken from the register + // set not including the input, current value saved on the stack, and restored when + // we're done with it. + // + // Be very careful not to use any of these before value is pushed, since they + // might shadow. + Register scratchReg = regSet.takeGeneral(); + Register argJSContextReg = regSet.takeGeneral(); + Register argVpReg = regSet.takeGeneral(); + + bool callNative = IsCacheableSetPropCallNative(obj, holder, shape); + JS_ASSERT_IF(!callNative, IsCacheableSetPropCallPropertyOp(obj, holder, shape)); + + // Ensure stack is aligned. + DebugOnly initialStack = masm.framePushed(); + + if (callNative) { + JS_ASSERT(shape->hasSetterValue() && shape->setterObject() && + shape->setterObject()->is()); + JSFunction *target = &shape->setterObject()->as(); + + JS_ASSERT(target->isNative()); + + Register argUintNReg = regSet.takeGeneral(); + + // Set up the call: + // bool (*)(JSContext *, unsigned, Value *vp) + // vp[0] is callee/outparam + // vp[1] is |this| + // vp[2] is the value + + // Build vp and move the base into argVpReg. + masm.Push(value); + masm.Push(TypedOrValueRegister(MIRType_Object, AnyRegister(object))); + masm.Push(ObjectValue(*target)); + masm.movePtr(StackPointer, argVpReg); + + // Preload other regs + masm.loadJSContext(argJSContextReg); + masm.move32(Imm32(1), argUintNReg); + + // Push data for GC marking + masm.Push(argUintNReg); + attacher.pushStubCodePointer(masm); + + if (!masm.buildOOLFakeExitFrame(returnAddr)) + return false; + masm.enterFakeExitFrame(ION_FRAME_OOL_NATIVE); + + // Make the call + masm.setupUnalignedABICall(3, scratchReg); + masm.passABIArg(argJSContextReg); + masm.passABIArg(argUintNReg); + masm.passABIArg(argVpReg); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, target->native())); + } else { + Register argObjReg = regSet.takeGeneral(); + Register argIdReg = regSet.takeGeneral(); + Register argStrictReg = regSet.takeGeneral(); + + attacher.pushStubCodePointer(masm); + + StrictPropertyOp target = shape->setterOp(); + JS_ASSERT(target); + // JSStrictPropertyOp: bool fn(JSContext *cx, HandleObject obj, + // HandleId id, bool strict, MutableHandleValue vp); + + // Push args on stack first so we can take pointers to make handles. + if (value.constant()) + masm.Push(value.value()); + else + masm.Push(value.reg()); + masm.movePtr(StackPointer, argVpReg); + + masm.move32(Imm32(strict ? 1 : 0), argStrictReg); + + // push canonical jsid from shape instead of propertyname. + RootedId propId(cx); + if (!shape->getUserId(cx, &propId)) + return false; + masm.Push(propId, argIdReg); + masm.movePtr(StackPointer, argIdReg); + + masm.Push(object); + masm.movePtr(StackPointer, argObjReg); + + masm.loadJSContext(argJSContextReg); + + if (!masm.buildOOLFakeExitFrame(returnAddr)) + return false; + masm.enterFakeExitFrame(ION_FRAME_OOL_PROPERTY_OP); + + // Make the call. + masm.setupUnalignedABICall(5, scratchReg); + masm.passABIArg(argJSContextReg); + masm.passABIArg(argObjReg); + masm.passABIArg(argIdReg); + masm.passABIArg(argStrictReg); + masm.passABIArg(argVpReg); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, target)); + } + + // Test for failure. + masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel()); + + // The next instruction is removing the footer of the exit frame, so there + // is no need for leaveFakeExitFrame. + + // Move the StackPointer back to its original location, unwinding the exit frame. + if (callNative) + masm.adjustStack(IonOOLNativeExitFrameLayout::Size(1)); + else + masm.adjustStack(IonOOLPropertyOpExitFrameLayout::Size()); + JS_ASSERT(masm.framePushed() == initialStack); + + // restoreLive() + masm.PopRegsInMask(liveRegs); + + return true; +} + +bool +IsCacheableDOMProxyUnshadowedSetterCall(JSContext *cx, HandleObject obj, HandlePropertyName name, + MutableHandleObject holder, MutableHandleShape shape, + bool *isSetter) +{ + JS_ASSERT(IsCacheableDOMProxy(obj)); + + *isSetter = false; + + RootedObject checkObj(cx, obj->getTaggedProto().toObjectOrNull()); + if (!checkObj) + return true; + + if (!JSObject::lookupProperty(cx, obj, name, holder, shape)) + return false; + + if (!holder) + return true; + + if (!IsCacheableSetPropCallNative(checkObj, holder, shape) && + !IsCacheableSetPropCallPropertyOp(checkObj, holder, shape)) + { + return true; + } + + *isSetter = true; + return true; +} + +bool +SetPropertyIC::attachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, HandleObject obj, + void *returnAddr) +{ + JS_ASSERT(IsCacheableDOMProxy(obj)); + + Label failures; + MacroAssembler masm(cx); + RepatchStubAppender attacher(*this); + + masm.setFramePushed(ion->frameSize()); + + // Guard on the shape of the object. + masm.branchPtr(Assembler::NotEqual, + Address(object(), JSObject::offsetOfShape()), + ImmGCPtr(obj->lastProperty()), &failures); + + // Make sure object is a DOMProxy + GenerateDOMProxyChecks(cx, masm, obj, name(), object(), &failures); + + RootedPropertyName propName(cx, name()); + RootedObject holder(cx); + RootedShape shape(cx); + bool isSetter; + if (!IsCacheableDOMProxyUnshadowedSetterCall(cx, obj, propName, &holder, + &shape, &isSetter)) + { + return false; + } + + if (isSetter) { + if (!GenerateCallSetter(cx, ion, masm, attacher, obj, holder, shape, strict(), + object(), value(), &failures, liveRegs_, returnAddr)) + { + return false; + } + } else { + // Either there was no proto, or the property wasn't appropriately found on it. + // Drop back to just a call to Proxy::set(). + RootedId propId(cx, AtomToId(name())); + if (!EmitCallProxySet(cx, masm, attacher, propId, liveRegs_, object(), + value(), returnAddr, strict())) + { + return false; + } + } + + // Success. + attacher.jumpRejoin(masm); + + // Failure. + masm.bind(&failures); + attacher.jumpNextStub(masm); + + return linkAndAttachStub(cx, masm, attacher, ion, "DOM proxy unshadowed set"); +} + bool SetPropertyIC::attachSetterCall(JSContext *cx, IonScript *ion, HandleObject obj, HandleObject holder, HandleShape shape, void *returnAddr) { + JS_ASSERT(obj->isNative()); + MacroAssembler masm(cx); RepatchStubAppender attacher(*this); @@ -1985,117 +2504,12 @@ SetPropertyIC::attachSetterCall(JSContext *cx, IonScript *ion, ImmGCPtr(obj->lastProperty()), &failure); - // Generate prototype guards if needed. - // Take a scratch register for use, save on stack. + if (!GenerateCallSetter(cx, ion, masm, attacher, obj, holder, shape, strict(), + object(), value(), &failure, liveRegs_, returnAddr)) { - RegisterSet regSet(RegisterSet::All()); - regSet.take(AnyRegister(object())); - if (!value().constant()) - regSet.maybeTake(value().reg()); - Register scratchReg = regSet.takeGeneral(); - masm.push(scratchReg); - - Label protoFailure; - Label protoSuccess; - - // Generate prototype/shape guards. - if (obj != holder) - GeneratePrototypeGuards(cx, ion, masm, obj, holder, object(), scratchReg, &protoFailure); - - masm.moveNurseryPtr(ImmMaybeNurseryPtr(holder), scratchReg); - masm.branchPtr(Assembler::NotEqual, - Address(scratchReg, JSObject::offsetOfShape()), - ImmGCPtr(holder->lastProperty()), - &protoFailure); - - masm.jump(&protoSuccess); - - masm.bind(&protoFailure); - masm.pop(scratchReg); - masm.jump(&failure); - - masm.bind(&protoSuccess); - masm.pop(scratchReg); + return false; } - // Good to go for invoking setter. - - // saveLive() - masm.PushRegsInMask(liveRegs_); - - // Remaining registers should basically be free, but we need to use |object| still - // so leave it alone. - RegisterSet regSet(RegisterSet::All()); - regSet.take(AnyRegister(object())); - - // This is a slower stub path, and we're going to be doing a call anyway. Don't need - // to try so hard to not use the stack. Scratch regs are just taken from the register - // set not including the input, current value saved on the stack, and restored when - // we're done with it. - Register scratchReg = regSet.takeGeneral(); - Register argJSContextReg = regSet.takeGeneral(); - Register argObjReg = regSet.takeGeneral(); - Register argIdReg = regSet.takeGeneral(); - Register argStrictReg = regSet.takeGeneral(); - Register argVpReg = regSet.takeGeneral(); - - // Ensure stack is aligned. - DebugOnly initialStack = masm.framePushed(); - - attacher.pushStubCodePointer(masm); - - StrictPropertyOp target = shape->setterOp(); - JS_ASSERT(target); - // JSStrictPropertyOp: bool fn(JSContext *cx, HandleObject obj, - // HandleId id, bool strict, MutableHandleValue vp); - - // Push args on stack first so we can take pointers to make handles. - if (value().constant()) - masm.Push(value().value()); - else - masm.Push(value().reg()); - masm.movePtr(StackPointer, argVpReg); - - masm.move32(Imm32(strict() ? 1 : 0), argStrictReg); - - // push canonical jsid from shape instead of propertyname. - RootedId propId(cx); - if (!shape->getUserId(cx, &propId)) - return false; - masm.Push(propId, argIdReg); - masm.movePtr(StackPointer, argIdReg); - - masm.Push(object()); - masm.movePtr(StackPointer, argObjReg); - - masm.loadJSContext(argJSContextReg); - - if (!masm.buildOOLFakeExitFrame(returnAddr)) - return false; - masm.enterFakeExitFrame(ION_FRAME_OOL_PROPERTY_OP); - - // Make the call. - masm.setupUnalignedABICall(5, scratchReg); - masm.passABIArg(argJSContextReg); - masm.passABIArg(argObjReg); - masm.passABIArg(argIdReg); - masm.passABIArg(argStrictReg); - masm.passABIArg(argVpReg); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, target)); - - // Test for failure. - masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel()); - - // The next instruction is removing the footer of the exit frame, so there - // is no need for leaveFakeExitFrame. - - // Move the StackPointer back to its original location, unwinding the exit frame. - masm.adjustStack(IonOOLPropertyOpExitFrameLayout::Size()); - JS_ASSERT(masm.framePushed() == initialStack); - - // restoreLive() - masm.PopRegsInMask(liveRegs_); - // Rejoin jump. attacher.jumpRejoin(masm); @@ -2103,7 +2517,7 @@ SetPropertyIC::attachSetterCall(JSContext *cx, IonScript *ion, masm.bind(&failure); attacher.jumpNextStub(masm); - return linkAndAttachStub(cx, masm, attacher, ion, "calling"); + return linkAndAttachStub(cx, masm, attacher, ion, "setter call"); } bool @@ -2111,6 +2525,8 @@ SetPropertyIC::attachNativeAdding(JSContext *cx, IonScript *ion, JSObject *obj, HandleShape oldShape, HandleShape newShape, HandleShape propShape) { + JS_ASSERT(obj->isNative()); + MacroAssembler masm(cx); RepatchStubAppender attacher(*this); @@ -2176,20 +2592,12 @@ SetPropertyIC::attachNativeAdding(JSContext *cx, IonScript *ion, JSObject *obj, } static bool -IsPropertyInlineable(JSObject *obj) +IsPropertySetInlineable(JSContext *cx, const SetPropertyIC &cache, HandleObject obj, + HandleId id, MutableHandleShape pshape) { if (!obj->isNative()) return false; - if (obj->watched()) - return false; - - return true; -} - -static bool -IsPropertySetInlineable(JSContext *cx, HandleObject obj, HandleId id, MutableHandleShape pshape) -{ Shape *shape = obj->nativeLookup(cx, id); if (!shape) @@ -2204,42 +2612,31 @@ IsPropertySetInlineable(JSContext *cx, HandleObject obj, HandleId id, MutableHan if (!shape->writable()) return false; + types::TypeObject *type = obj->getType(cx); + if (cache.needsTypeBarrier() && !type->unknownProperties()) { + RootedId typeId(cx, types::IdToTypeId(id)); + types::HeapTypeSet *propTypes = type->maybeGetProperty(cx, typeId); + if (!propTypes) + return false; + if (cache.value().constant() && !propTypes->unknown()) { + // If the input is a constant, then don't bother if the barrier will always fail. + if (!propTypes->hasType(types::GetValueType(cache.value().value()))) + return false; + } + } + pshape.set(shape); return true; } -static bool -IsPropertySetterCallInlineable(JSContext *cx, HandleObject obj, HandleObject holder, - HandleShape shape) -{ - if (!shape) - return false; - - if (!holder->isNative()) - return false; - - if (shape->hasSlot()) - return false; - - if (shape->hasDefaultSetter()) - return false; - - if (!shape->writable()) - return false; - - // We only handle propertyOps for now, so fail if we have SetterValue - // (which implies JSNative setter). - if (shape->hasSetterValue()) - return false; - - return true; -} - static bool IsPropertyAddInlineable(JSContext *cx, HandleObject obj, HandleId id, uint32_t oldSlots, MutableHandleShape pShape) { + if (!obj->isNative()) + return false; + // This is not a Add, the property exists. if (pShape.get()) return false; @@ -2306,20 +2703,47 @@ SetPropertyIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj, // Stop generating new stubs once we hit the stub count limit, see // GetPropertyCache. - bool inlinable = cache.canAttachStub() && IsPropertyInlineable(obj); + bool inlinable = cache.canAttachStub() && !obj->watched(); bool addedSetterStub = false; if (inlinable) { + if (!addedSetterStub && obj->is()) { + if (IsCacheableDOMProxy(obj)) { + DOMProxyShadowsResult shadows = GetDOMProxyShadowsCheck()(cx, obj, id); + if (shadows == ShadowCheckFailed) + return false; + if (shadows == Shadows) { + if (!cache.attachDOMProxyShadowed(cx, ion, obj, returnAddr)) + return false; + addedSetterStub = true; + } else { + JS_ASSERT(shadows == DoesntShadow || shadows == DoesntShadowUnique); + if (shadows == DoesntShadowUnique) + cache.reset(); + if (!cache.attachDOMProxyUnshadowed(cx, ion, obj, returnAddr)) + return false; + addedSetterStub = true; + } + } + + if (!addedSetterStub && !cache.hasGenericProxyStub()) { + if (!cache.attachGenericProxy(cx, ion, returnAddr)) + return false; + addedSetterStub = true; + } + } RootedShape shape(cx); - if (IsPropertySetInlineable(cx, obj, id, &shape)) { + if (!addedSetterStub && IsPropertySetInlineable(cx, cache, obj, id, &shape)) { if (!cache.attachNativeExisting(cx, ion, obj, shape)) return false; addedSetterStub = true; - } else { + } else if (!addedSetterStub) { RootedObject holder(cx); if (!JSObject::lookupProperty(cx, obj, name, &holder, &shape)) return false; - if (IsPropertySetterCallInlineable(cx, obj, holder, shape)) { + if (IsCacheableSetPropCallPropertyOp(obj, holder, shape) || + IsCacheableSetPropCallNative(obj, holder, shape)) + { if (!cache.attachSetterCall(cx, ion, obj, holder, shape, returnAddr)) return false; addedSetterStub = true; @@ -2335,7 +2759,8 @@ SetPropertyIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj, return false; // The property did not exist before, now we can try to inline the property add. - if (inlinable && !addedSetterStub && obj->lastProperty() != oldShape && + if (inlinable && !addedSetterStub && !cache.needsTypeBarrier() && + obj->lastProperty() != oldShape && IsPropertyAddInlineable(cx, obj, id, oldSlots, &shape)) { RootedShape newShape(cx, obj->lastProperty()); @@ -2346,6 +2771,13 @@ SetPropertyIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj, return true; } +void +SetPropertyIC::reset() +{ + RepatchIonCache::reset(); + hasGenericProxyStub_ = false; +} + const size_t GetElementIC::MAX_FAILED_UPDATES = 16; /* static */ bool diff --git a/js/src/jit/IonCaches.h b/js/src/jit/IonCaches.h index b9c1da271094..885f7fc0214f 100644 --- a/js/src/jit/IonCaches.h +++ b/js/src/jit/IonCaches.h @@ -14,9 +14,6 @@ #include "jit/Registers.h" #include "jit/shared/Assembler-shared.h" -class JSFunction; -class JSScript; - namespace js { class LockedJSContext; @@ -650,20 +647,27 @@ class SetPropertyIC : public RepatchIonCache PropertyName *name_; ConstantOrRegister value_; bool strict_; + bool needsTypeBarrier_; + + bool hasGenericProxyStub_; public: SetPropertyIC(RegisterSet liveRegs, Register object, PropertyName *name, - ConstantOrRegister value, bool strict) + ConstantOrRegister value, bool strict, bool needsTypeBarrier) : liveRegs_(liveRegs), object_(object), name_(name), value_(value), - strict_(strict) + strict_(strict), + needsTypeBarrier_(needsTypeBarrier), + hasGenericProxyStub_(false) { } CACHE_HEADER(SetProperty) + void reset(); + Register object() const { return object_; } @@ -676,12 +680,23 @@ class SetPropertyIC : public RepatchIonCache bool strict() const { return strict_; } + bool needsTypeBarrier() const { + return needsTypeBarrier_; + } + bool hasGenericProxyStub() const { + return hasGenericProxyStub_; + } bool attachNativeExisting(JSContext *cx, IonScript *ion, HandleObject obj, HandleShape shape); bool attachSetterCall(JSContext *cx, IonScript *ion, HandleObject obj, HandleObject holder, HandleShape shape, void *returnAddr); bool attachNativeAdding(JSContext *cx, IonScript *ion, JSObject *obj, HandleShape oldshape, HandleShape newshape, HandleShape propshape); + bool attachGenericProxy(JSContext *cx, IonScript *ion, void *returnAddr); + bool attachDOMProxyShadowed(JSContext *cx, IonScript *ion, HandleObject obj, + void *returnAddr); + bool attachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, HandleObject obj, + void *returnAddr); static bool update(JSContext *cx, size_t cacheIndex, HandleObject obj, HandleValue value); diff --git a/js/src/jit/IonCode.h b/js/src/jit/IonCode.h index a5def78f9454..8c7d3efca5c4 100644 --- a/js/src/jit/IonCode.h +++ b/js/src/jit/IonCode.h @@ -19,8 +19,6 @@ namespace JSC { class ExecutablePool; } -class JSScript; - namespace js { class AsmJSModule; @@ -586,10 +584,8 @@ struct IonBlockCounts } void destroy() { - if (successors_) - js_free(successors_); - if (code_) - js_free(code_); + js_free(successors_); + js_free(code_); } uint32_t id() const { @@ -673,8 +669,7 @@ struct IonScriptCounts for (size_t i = 0; i < numBlocks_; i++) blocks_[i].destroy(); js_free(blocks_); - if (previous_) - js_delete(previous_); + js_delete(previous_); } bool init(size_t numBlocks) { diff --git a/js/src/jit/IonFrameIterator.h b/js/src/jit/IonFrameIterator.h index 45e3c484a012..736d5d2f9f2a 100644 --- a/js/src/jit/IonFrameIterator.h +++ b/js/src/jit/IonFrameIterator.h @@ -143,9 +143,9 @@ class IonFrameIterator return type_ == IonFrame_BaselineStub; } bool isNative() const; - bool isOOLNativeGetter() const; + bool isOOLNative() const; bool isOOLPropertyOp() const; - bool isOOLProxyGet() const; + bool isOOLProxy() const; bool isDOMExit() const; bool isEntry() const { return type_ == IonFrame_Entry; diff --git a/js/src/jit/IonFrames.cpp b/js/src/jit/IonFrames.cpp index e70dc391393d..178c09c1a006 100644 --- a/js/src/jit/IonFrames.cpp +++ b/js/src/jit/IonFrames.cpp @@ -117,11 +117,11 @@ IonFrameIterator::isNative() const } bool -IonFrameIterator::isOOLNativeGetter() const +IonFrameIterator::isOOLNative() const { if (type_ != IonFrame_Exit) return false; - return exitFrame()->footer()->ionCode() == ION_FRAME_OOL_NATIVE_GETTER; + return exitFrame()->footer()->ionCode() == ION_FRAME_OOL_NATIVE; } bool @@ -133,11 +133,11 @@ IonFrameIterator::isOOLPropertyOp() const } bool -IonFrameIterator::isOOLProxyGet() const +IonFrameIterator::isOOLProxy() const { if (type_ != IonFrame_Exit) return false; - return exitFrame()->footer()->ionCode() == ION_FRAME_OOL_PROXY_GET; + return exitFrame()->footer()->ionCode() == ION_FRAME_OOL_PROXY; } bool @@ -906,11 +906,12 @@ MarkIonExitFrame(JSTracer *trc, const IonFrameIterator &frame) return; } - if (frame.isOOLNativeGetter()) { - IonOOLNativeGetterExitFrameLayout *oolgetter = frame.exitFrame()->oolNativeGetterExit(); - gc::MarkIonCodeRoot(trc, oolgetter->stubCode(), "ion-ool-getter-code"); - gc::MarkValueRoot(trc, oolgetter->vp(), "ion-ool-getter-callee"); - gc::MarkValueRoot(trc, oolgetter->thisp(), "ion-ool-getter-this"); + if (frame.isOOLNative()) { + IonOOLNativeExitFrameLayout *oolnative = frame.exitFrame()->oolNativeExit(); + gc::MarkIonCodeRoot(trc, oolnative->stubCode(), "ion-ool-native-code"); + gc::MarkValueRoot(trc, oolnative->vp(), "iol-ool-native-vp"); + size_t len = oolnative->argc() + 1; + gc::MarkValueRootRange(trc, len, oolnative->thisp(), "ion-ool-native-thisargs"); return; } @@ -923,13 +924,13 @@ MarkIonExitFrame(JSTracer *trc, const IonFrameIterator &frame) return; } - if (frame.isOOLProxyGet()) { - IonOOLProxyGetExitFrameLayout *oolproxyget = frame.exitFrame()->oolProxyGetExit(); - gc::MarkIonCodeRoot(trc, oolproxyget->stubCode(), "ion-ool-proxy-get-code"); - gc::MarkValueRoot(trc, oolproxyget->vp(), "ion-ool-proxy-get-vp"); - gc::MarkIdRoot(trc, oolproxyget->id(), "ion-ool-proxy-get-id"); - gc::MarkObjectRoot(trc, oolproxyget->proxy(), "ion-ool-proxy-get-proxy"); - gc::MarkObjectRoot(trc, oolproxyget->receiver(), "ion-ool-proxy-get-receiver"); + if (frame.isOOLProxy()) { + IonOOLProxyExitFrameLayout *oolproxy = frame.exitFrame()->oolProxyExit(); + gc::MarkIonCodeRoot(trc, oolproxy->stubCode(), "ion-ool-proxy-code"); + gc::MarkValueRoot(trc, oolproxy->vp(), "ion-ool-proxy-vp"); + gc::MarkIdRoot(trc, oolproxy->id(), "ion-ool-proxy-id"); + gc::MarkObjectRoot(trc, oolproxy->proxy(), "ion-ool-proxy-proxy"); + gc::MarkObjectRoot(trc, oolproxy->receiver(), "ion-ool-proxy-receiver"); return; } diff --git a/js/src/jit/IonFrames.h b/js/src/jit/IonFrames.h index 87d3417cdd2d..c0be812a7ff9 100644 --- a/js/src/jit/IonFrames.h +++ b/js/src/jit/IonFrames.h @@ -20,9 +20,6 @@ #include "jit/IonFrameIterator.h" #include "jit/Registers.h" -class JSFunction; -class JSScript; - namespace js { namespace jit { diff --git a/js/src/jit/IonMacroAssembler.cpp b/js/src/jit/IonMacroAssembler.cpp index 08f0e120b73c..cf19857fabd5 100644 --- a/js/src/jit/IonMacroAssembler.cpp +++ b/js/src/jit/IonMacroAssembler.cpp @@ -125,6 +125,13 @@ template void MacroAssembler::guardTypeSet(const Address &address, const types:: template void MacroAssembler::guardTypeSet(const ValueOperand &value, const types::StackTypeSet *types, Register scratch, Label *matched, Label *miss); +template void MacroAssembler::guardTypeSet(const Address &address, const types::HeapTypeSet *types, + Register scratch, Label *matched, Label *miss); +template void MacroAssembler::guardTypeSet(const ValueOperand &value, const types::HeapTypeSet *types, + Register scratch, Label *matched, Label *miss); +template void MacroAssembler::guardTypeSet(const TypedOrValueRegister ®, const types::HeapTypeSet *types, + Register scratch, Label *matched, Label *miss); + template void MacroAssembler::guardTypeSet(const Address &address, const types::TypeSet *types, Register scratch, Label *matched, Label *miss); template void MacroAssembler::guardTypeSet(const ValueOperand &value, const types::TypeSet *types, @@ -1005,7 +1012,8 @@ MacroAssembler::loadBaselineOrIonNoArgCheck(Register script, Register dest, Exec void MacroAssembler::loadBaselineFramePtr(Register framePtr, Register dest) { - movePtr(framePtr, dest); + if (framePtr != dest) + movePtr(framePtr, dest); subPtr(Imm32(BaselineFrame::Size()), dest); } diff --git a/js/src/jit/IonMacroAssembler.h b/js/src/jit/IonMacroAssembler.h index e5b3d0404d07..c656ec470e6e 100644 --- a/js/src/jit/IonMacroAssembler.h +++ b/js/src/jit/IonMacroAssembler.h @@ -189,6 +189,13 @@ class MacroAssembler : public MacroAssemblerSpecific void branchTestObjShape(Condition cond, Register obj, Register shape, Label *label) { branchPtr(cond, Address(obj, JSObject::offsetOfShape()), shape, label); } + void branchTestProxyHandlerFamily(Condition cond, Register proxy, Register scratch, + void *handlerp, Label *label) { + Address handlerAddr(proxy, ProxyObject::offsetOfHandler()); + loadPrivate(handlerAddr, scratch); + Address familyAddr(scratch, BaseProxyHandler::offsetOfFamily()); + branchPtr(cond, familyAddr, ImmWord(handlerp), label); + } template Condition testMIRType(Condition cond, const Value &val, MIRType type) { @@ -605,6 +612,22 @@ class MacroAssembler : public MacroAssemblerSpecific return extractObject(value, scratch); } + using MacroAssemblerSpecific::extractTag; + Register extractTag(const TypedOrValueRegister ®, Register scratch) { + if (reg.hasValue()) { + return extractTag(reg.valueReg(), scratch); + } + mov(ImmWord(ValueTypeFromMIRType(reg.type())), scratch); + return scratch; + } + + using MacroAssemblerSpecific::extractObject; + Register extractObject(const TypedOrValueRegister ®, Register scratch) { + if (reg.hasValue()) + return extractObject(reg.valueReg(), scratch); + return reg.typedReg().gpr(); + } + // Inline version of js_TypedArray_uint8_clamp_double. // This function clobbers the input register. void clampDoubleToUint8(FloatRegister input, Register output); diff --git a/js/src/jit/IonSpewer.cpp b/js/src/jit/IonSpewer.cpp index 3118a0e810ac..30b92427f92c 100644 --- a/js/src/jit/IonSpewer.cpp +++ b/js/src/jit/IonSpewer.cpp @@ -259,6 +259,7 @@ jit::CheckLogging() " safepoints Safepoints\n" " pools Literal Pools (ARM only for now)\n" " cacheflush Instruction Cache flushes (ARM only for now)\n" + " range Range Analysis\n" " logs C1 and JSON visualization logging\n" " trace Generate calls to js::jit::Trace() for effectful instructions\n" " all Everything\n" diff --git a/js/src/jit/JSONSpewer.h b/js/src/jit/JSONSpewer.h index fa00562fab4c..486bf7945c7e 100644 --- a/js/src/jit/JSONSpewer.h +++ b/js/src/jit/JSONSpewer.h @@ -9,7 +9,7 @@ #include -class JSScript; +#include "js/TypeDecls.h" namespace js { namespace jit { diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 6a0cb5fb2397..5198d546558a 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -559,9 +559,14 @@ ReorderCommutative(MDefinition **lhsp, MDefinition **rhsp) if (rhs->isConstant()) return; - if (lhs->isConstant() || - (rhs->defUseCount() == 1 && lhs->defUseCount() > 1)) - { + // lhs and rhs are used by the commutative operator. If they have any + // *other* uses besides, try to reorder to avoid clobbering them. To + // be fully precise, we should check whether this is the *last* use, + // but checking hasOneDefUse() is a decent approximation which doesn't + // require any extra analysis. + JS_ASSERT(lhs->defUseCount() > 0); + JS_ASSERT(rhs->defUseCount() > 0); + if (lhs->isConstant() || (rhs->hasOneDefUse() && !lhs->hasOneDefUse())) { *rhsp = lhs; *lhsp = rhs; } @@ -1118,7 +1123,7 @@ LIRGenerator::visitSqrt(MSqrt *ins) MDefinition *num = ins->num(); JS_ASSERT(num->type() == MIRType_Double); LSqrtD *lir = new LSqrtD(useRegisterAtStart(num)); - return defineReuseInput(lir, ins, 0); + return define(lir, ins); } bool diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 7a7a506fba8e..38c2919f475a 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -273,6 +273,35 @@ MDefinition::defUseCount() const return count; } +bool +MDefinition::hasOneUse() const +{ + MUseIterator i(uses_.begin()); + if (i == uses_.end()) + return false; + i++; + return i == uses_.end(); +} + +bool +MDefinition::hasOneDefUse() const +{ + bool hasOneDefUse = false; + for (MUseIterator i(uses_.begin()); i != uses_.end(); i++) { + if (!(*i)->consumer()->isDefinition()) + continue; + + // We already have a definition use. So 1+ + if (hasOneDefUse) + return false; + + // We saw one definition. Loop to test if there is another. + hasOneDefUse = true; + } + + return hasOneDefUse; +} + MUseIterator MDefinition::removeUse(MUseIterator use) { @@ -856,7 +885,7 @@ MPhi::addInputSlow(MDefinition *ins, bool *ptypeChange) uint32_t MPrepareCall::argc() const { - JS_ASSERT(useCount() == 1); + JS_ASSERT(hasOneUse()); MCall *call = usesBegin()->consumer()->toDefinition()->toCall(); return call->numStackArgs(); } diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index b6e6a2e258cd..9c957e37cbc2 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -480,6 +480,13 @@ class MDefinition : public MNode // (only counting MDefinitions, ignoring MResumePoints) size_t defUseCount() const; + // Test whether this MDefinition has exactly one use. + bool hasOneUse() const; + + // Test whether this MDefinition has exactly one use. + // (only counting MDefinitions, ignoring MResumePoints) + bool hasOneDefUse() const; + bool hasUses() const { return !uses_.empty(); } @@ -3946,11 +3953,9 @@ class MBeta : public MUnaryInstruction { private: const Range *comparison_; - MDefinition *val_; MBeta(MDefinition *val, const Range *comp) : MUnaryInstruction(val), - comparison_(comp), - val_(val) + comparison_(comp) { setResultType(val->type()); setResultTypeSet(val->resultTypeSet()); @@ -6674,21 +6679,30 @@ class MSetPropertyCache : public MSetPropertyInstruction, public SingleObjectPolicy { - MSetPropertyCache(MDefinition *obj, MDefinition *value, HandlePropertyName name, bool strict) - : MSetPropertyInstruction(obj, value, name, strict) + bool needsTypeBarrier_; + + MSetPropertyCache(MDefinition *obj, MDefinition *value, HandlePropertyName name, bool strict, + bool typeBarrier) + : MSetPropertyInstruction(obj, value, name, strict), + needsTypeBarrier_(typeBarrier) { } public: INSTRUCTION_HEADER(SetPropertyCache) - static MSetPropertyCache *New(MDefinition *obj, MDefinition *value, HandlePropertyName name, bool strict) { - return new MSetPropertyCache(obj, value, name, strict); + static MSetPropertyCache *New(MDefinition *obj, MDefinition *value, HandlePropertyName name, + bool strict, bool typeBarrier) { + return new MSetPropertyCache(obj, value, name, strict, typeBarrier); } TypePolicy *typePolicy() { return this; } + + bool needsTypeBarrier() const { + return needsTypeBarrier_; + } }; class MSetElementCache diff --git a/js/src/jit/PerfSpewer.h b/js/src/jit/PerfSpewer.h index e5a9845ef39d..aa747a029047 100644 --- a/js/src/jit/PerfSpewer.h +++ b/js/src/jit/PerfSpewer.h @@ -11,8 +11,6 @@ #include "jit/IonMacroAssembler.h" -class JSScript; - namespace js { namespace jit { diff --git a/js/src/jit/RangeAnalysis.cpp b/js/src/jit/RangeAnalysis.cpp index ea00ac42a941..87715381a2e2 100644 --- a/js/src/jit/RangeAnalysis.cpp +++ b/js/src/jit/RangeAnalysis.cpp @@ -358,12 +358,12 @@ Range::unionWith(const Range *other) if (lower_infinite_ || other->lower_infinite_) makeLowerInfinite(); else - setLower(Min(lower_, other->lower_)); + setLowerInit(Min(lower_, other->lower_)); if (upper_infinite_ || other->upper_infinite_) makeUpperInfinite(); else - setUpper(Max(upper_, other->upper_)); + setUpperInit(Max(upper_, other->upper_)); decimal_ = decimal; max_exponent_ = max_exponent; @@ -800,7 +800,7 @@ MBeta::computeRange() { bool emptyRange = false; - Range *range = Range::intersect(val_->range(), comparison_, &emptyRange); + Range *range = Range::intersect(getOperand(0)->range(), comparison_, &emptyRange); if (emptyRange) { IonSpew(IonSpew_Range, "Marking block for inst %d unexitable", id()); block()->setEarlyAbort(); diff --git a/js/src/jit/RegisterSets.h b/js/src/jit/RegisterSets.h index 8449ae92d357..b19d422c3fcc 100644 --- a/js/src/jit/RegisterSets.h +++ b/js/src/jit/RegisterSets.h @@ -163,6 +163,15 @@ class TypedOrValueRegister return *data.value.addr(); } + const AnyRegister &dataTyped() const { + JS_ASSERT(hasTyped()); + return *data.typed.addr(); + } + const ValueOperand &dataValue() const { + JS_ASSERT(hasValue()); + return *data.value.addr(); + } + public: TypedOrValueRegister() @@ -193,11 +202,11 @@ class TypedOrValueRegister return type() == MIRType_Value; } - AnyRegister typedReg() { + AnyRegister typedReg() const { return dataTyped(); } - ValueOperand valueReg() { + ValueOperand valueReg() const { return dataValue(); } diff --git a/js/src/jit/UnreachableCodeElimination.cpp b/js/src/jit/UnreachableCodeElimination.cpp index 23d8d3ee3e14..4862d580b803 100644 --- a/js/src/jit/UnreachableCodeElimination.cpp +++ b/js/src/jit/UnreachableCodeElimination.cpp @@ -297,7 +297,7 @@ UnreachableCodeElimination::removeUnmarkedBlocksAndClearDominators() MCall *call = iter->toCall(); for (size_t i = 0; i < call->numStackArgs(); i++) { JS_ASSERT(call->getArg(i)->isPassArg()); - JS_ASSERT(call->getArg(i)->defUseCount() == 1); + JS_ASSERT(call->getArg(i)->hasOneDefUse()); MPassArg *arg = call->getArg(i)->toPassArg(); arg->replaceAllUsesWith(arg->getArgument()); } diff --git a/js/src/jit/arm/CodeGenerator-arm.cpp b/js/src/jit/arm/CodeGenerator-arm.cpp index 178ad659b698..14e0ca494b10 100644 --- a/js/src/jit/arm/CodeGenerator-arm.cpp +++ b/js/src/jit/arm/CodeGenerator-arm.cpp @@ -343,8 +343,8 @@ bool CodeGeneratorARM::visitSqrtD(LSqrtD *ins) { FloatRegister input = ToFloatRegister(ins->input()); - JS_ASSERT(input == ToFloatRegister(ins->output())); - masm.ma_vsqrt(input, input); + FloatRegister output = ToFloatRegister(ins->output()); + masm.ma_vsqrt(input, output); return true; } diff --git a/js/src/jit/arm/IonFrames-arm.h b/js/src/jit/arm/IonFrames-arm.h index 68c500adf03a..9400b28e9c82 100644 --- a/js/src/jit/arm/IonFrames-arm.h +++ b/js/src/jit/arm/IonFrames-arm.h @@ -190,9 +190,9 @@ class IonBaselineStubFrameLayout : public IonCommonFrameLayout }; class IonNativeExitFrameLayout; -class IonOOLNativeGetterExitFrameLayout; +class IonOOLNativeExitFrameLayout; class IonOOLPropertyOpExitFrameLayout; -class IonOOLProxyGetExitFrameLayout; +class IonOOLProxyExitFrameLayout; class IonDOMExitFrameLayout; // this is the frame layout when we are exiting ion code, and about to enter EABI code @@ -229,14 +229,14 @@ class IonExitFrameLayout : public IonCommonFrameLayout inline bool isNativeExit() { return footer()->ionCode() == NULL; } - inline bool isOOLNativeGetterExit() { - return footer()->ionCode() == ION_FRAME_OOL_NATIVE_GETTER; + inline bool isOOLNativeExit() { + return footer()->ionCode() == ION_FRAME_OOL_NATIVE; } inline bool isOOLPropertyOpExit() { return footer()->ionCode() == ION_FRAME_OOL_PROPERTY_OP; } - inline bool isOOLProxyGetExit() { - return footer()->ionCode() == ION_FRAME_OOL_PROXY_GET; + inline bool isOOLProxyExit() { + return footer()->ionCode() == ION_FRAME_OOL_PROXY; } inline bool isDomExit() { IonCode *code = footer()->ionCode(); @@ -251,17 +251,17 @@ class IonExitFrameLayout : public IonCommonFrameLayout JS_ASSERT(isNativeExit()); return reinterpret_cast(footer()); } - inline IonOOLNativeGetterExitFrameLayout *oolNativeGetterExit() { - JS_ASSERT(isOOLNativeGetterExit()); - return reinterpret_cast(footer()); + inline IonOOLNativeExitFrameLayout *oolNativeExit() { + JS_ASSERT(isOOLNativeExit()); + return reinterpret_cast(footer()); } inline IonOOLPropertyOpExitFrameLayout *oolPropertyOpExit() { JS_ASSERT(isOOLPropertyOpExit()); return reinterpret_cast(footer()); } - inline IonOOLProxyGetExitFrameLayout *oolProxyGetExit() { - JS_ASSERT(isOOLProxyGetExit()); - return reinterpret_cast(footer()); + inline IonOOLProxyExitFrameLayout *oolProxyExit() { + JS_ASSERT(isOOLProxyExit()); + return reinterpret_cast(footer()); } inline IonDOMExitFrameLayout *DOMExit() { JS_ASSERT(isDomExit()); @@ -298,30 +298,33 @@ class IonNativeExitFrameLayout } }; -class IonOOLNativeGetterExitFrameLayout +class IonOOLNativeExitFrameLayout { IonExitFooterFrame footer_; IonExitFrameLayout exit_; + // pointer to root the stub's IonCode + IonCode *stubCode_; + + uintptr_t argc_; + // We need to split the Value into 2 fields of 32 bits, otherwise the C++ // compiler may add some padding between the fields. uint32_t loCalleeResult_; uint32_t hiCalleeResult_; - // The frame includes the object argument. + // Split Value for |this| and args above. uint32_t loThis_; uint32_t hiThis_; - // pointer to root the stub's IonCode - IonCode *stubCode_; - public: - static inline size_t Size() { - return sizeof(IonOOLNativeGetterExitFrameLayout); + static inline size_t Size(size_t argc) { + // The frame accounts for the callee/result and |this|, so we only need args. + return sizeof(IonOOLNativeExitFrameLayout) + (argc * sizeof(Value)); } static size_t offsetOfResult() { - return offsetof(IonOOLNativeGetterExitFrameLayout, loCalleeResult_); + return offsetof(IonOOLNativeExitFrameLayout, loCalleeResult_); } inline IonCode **stubCode() { @@ -334,7 +337,7 @@ class IonOOLNativeGetterExitFrameLayout return reinterpret_cast(&loThis_); } inline uintptr_t argc() const { - return 0; + return argc_; } }; @@ -382,7 +385,9 @@ class IonOOLPropertyOpExitFrameLayout // Proxy::get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, // MutableHandleValue vp) -class IonOOLProxyGetExitFrameLayout +// Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, +// bool strict, MutableHandleValue vp) +class IonOOLProxyExitFrameLayout { protected: // only to silence a clang warning about unused private fields IonExitFooterFrame footer_; @@ -407,11 +412,11 @@ class IonOOLProxyGetExitFrameLayout public: static inline size_t Size() { - return sizeof(IonOOLProxyGetExitFrameLayout); + return sizeof(IonOOLProxyExitFrameLayout); } static size_t offsetOfResult() { - return offsetof(IonOOLProxyGetExitFrameLayout, vp0_); + return offsetof(IonOOLProxyExitFrameLayout, vp0_); } inline IonCode **stubCode() { diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.cpp b/js/src/jit/shared/CodeGenerator-x86-shared.cpp index 21150ee3d2af..629ecc1290de 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp @@ -19,7 +19,10 @@ using namespace js; using namespace js::jit; +using mozilla::DoubleSignificandBits; using mozilla::FloorLog2; +using mozilla::NegativeInfinity; +using mozilla::SpecificNaN; namespace js { namespace jit { @@ -420,9 +423,9 @@ CodeGeneratorX86Shared::visitAbsD(LAbsD *ins) { FloatRegister input = ToFloatRegister(ins->input()); JS_ASSERT(input == ToFloatRegister(ins->output())); - masm.xorpd(ScratchFloatReg, ScratchFloatReg); - masm.subsd(input, ScratchFloatReg); // negate the sign bit. - masm.andpd(ScratchFloatReg, input); // s & ~s + // Load a value which is all ones except for the sign bit. + masm.loadConstantDouble(SpecificNaN(0, DoubleSignificandBits), ScratchFloatReg); + masm.andpd(ScratchFloatReg, input); return true; } @@ -430,8 +433,8 @@ bool CodeGeneratorX86Shared::visitSqrtD(LSqrtD *ins) { FloatRegister input = ToFloatRegister(ins->input()); - JS_ASSERT(input == ToFloatRegister(ins->output())); - masm.sqrtsd(input, input); + FloatRegister output = ToFloatRegister(ins->output()); + masm.sqrtsd(input, output); return true; } @@ -439,15 +442,12 @@ bool CodeGeneratorX86Shared::visitPowHalfD(LPowHalfD *ins) { FloatRegister input = ToFloatRegister(ins->input()); - Register scratch = ToRegister(ins->temp()); JS_ASSERT(input == ToFloatRegister(ins->output())); - const uint32_t NegInfinityFloatBits = 0xFF800000; Label done, sqrt; // Branch if not -Infinity. - masm.move32(Imm32(NegInfinityFloatBits), scratch); - masm.loadFloatAsDouble(scratch, ScratchFloatReg); + masm.loadConstantDouble(NegativeInfinity(), ScratchFloatReg); masm.branchDouble(Assembler::DoubleNotEqualOrUnordered, input, ScratchFloatReg, &sqrt); // Math.pow(-Infinity, 0.5) == Infinity. diff --git a/js/src/jit/shared/IonFrames-shared.h b/js/src/jit/shared/IonFrames-shared.h index 0f5eb17690d2..c06df6dc6a5c 100644 --- a/js/src/jit/shared/IonFrames-shared.h +++ b/js/src/jit/shared/IonFrames-shared.h @@ -10,8 +10,8 @@ #define ION_FRAME_DOMGETTER ((IonCode *)0x1) #define ION_FRAME_DOMSETTER ((IonCode *)0x2) #define ION_FRAME_DOMMETHOD ((IonCode *)0x3) -#define ION_FRAME_OOL_NATIVE_GETTER ((IonCode *)0x4) +#define ION_FRAME_OOL_NATIVE ((IonCode *)0x4) #define ION_FRAME_OOL_PROPERTY_OP ((IonCode *)0x5) -#define ION_FRAME_OOL_PROXY_GET ((IonCode *)0x6) +#define ION_FRAME_OOL_PROXY ((IonCode *)0x6) #endif /* jit_shared_IonFrames_shared_h */ diff --git a/js/src/jit/shared/IonFrames-x86-shared.h b/js/src/jit/shared/IonFrames-x86-shared.h index 7309d9101feb..744a699a4df3 100644 --- a/js/src/jit/shared/IonFrames-x86-shared.h +++ b/js/src/jit/shared/IonFrames-x86-shared.h @@ -156,9 +156,9 @@ class IonExitFooterFrame }; class IonNativeExitFrameLayout; -class IonOOLNativeGetterExitFrameLayout; +class IonOOLNativeExitFrameLayout; class IonOOLPropertyOpExitFrameLayout; -class IonOOLProxyGetExitFrameLayout; +class IonOOLProxyExitFrameLayout; class IonDOMExitFrameLayout; class IonExitFrameLayout : public IonCommonFrameLayout @@ -194,14 +194,14 @@ class IonExitFrameLayout : public IonCommonFrameLayout inline bool isNativeExit() { return footer()->ionCode() == NULL; } - inline bool isOOLNativeGetterExit() { - return footer()->ionCode() == ION_FRAME_OOL_NATIVE_GETTER; + inline bool isOOLNativeExit() { + return footer()->ionCode() == ION_FRAME_OOL_NATIVE; } inline bool isOOLPropertyOpExit() { return footer()->ionCode() == ION_FRAME_OOL_PROPERTY_OP; } - inline bool isOOLProxyGetExit() { - return footer()->ionCode() == ION_FRAME_OOL_PROXY_GET; + inline bool isOOLProxyExit() { + return footer()->ionCode() == ION_FRAME_OOL_PROXY; } inline bool isDomExit() { IonCode *code = footer()->ionCode(); @@ -216,17 +216,17 @@ class IonExitFrameLayout : public IonCommonFrameLayout JS_ASSERT(isNativeExit()); return reinterpret_cast(footer()); } - inline IonOOLNativeGetterExitFrameLayout *oolNativeGetterExit() { - JS_ASSERT(isOOLNativeGetterExit()); - return reinterpret_cast(footer()); + inline IonOOLNativeExitFrameLayout *oolNativeExit() { + JS_ASSERT(isOOLNativeExit()); + return reinterpret_cast(footer()); } inline IonOOLPropertyOpExitFrameLayout *oolPropertyOpExit() { JS_ASSERT(isOOLPropertyOpExit()); return reinterpret_cast(footer()); } - inline IonOOLProxyGetExitFrameLayout *oolProxyGetExit() { - JS_ASSERT(isOOLProxyGetExit()); - return reinterpret_cast(footer()); + inline IonOOLProxyExitFrameLayout *oolProxyExit() { + JS_ASSERT(isOOLProxyExit()); + return reinterpret_cast(footer()); } inline IonDOMExitFrameLayout *DOMExit() { JS_ASSERT(isDomExit()); @@ -262,31 +262,34 @@ class IonNativeExitFrameLayout } }; -class IonOOLNativeGetterExitFrameLayout +class IonOOLNativeExitFrameLayout { protected: // only to silence a clang warning about unused private fields IonExitFooterFrame footer_; IonExitFrameLayout exit_; + // pointer to root the stub's IonCode + IonCode *stubCode_; + + uintptr_t argc_; + // We need to split the Value into 2 fields of 32 bits, otherwise the C++ // compiler may add some padding between the fields. uint32_t loCalleeResult_; uint32_t hiCalleeResult_; - // The frame includes the object argument. + // Split Value for |this| and args above. uint32_t loThis_; uint32_t hiThis_; - // pointer to root the stub's IonCode - IonCode *stubCode_; - public: - static inline size_t Size() { - return sizeof(IonOOLNativeGetterExitFrameLayout); + static inline size_t Size(size_t argc) { + // The Frame accounts for the callee/result and |this|, so we only needs args. + return sizeof(IonOOLNativeExitFrameLayout) + (argc * sizeof(Value)); } static size_t offsetOfResult() { - return offsetof(IonOOLNativeGetterExitFrameLayout, loCalleeResult_); + return offsetof(IonOOLNativeExitFrameLayout, loCalleeResult_); } inline IonCode **stubCode() { @@ -298,9 +301,8 @@ class IonOOLNativeGetterExitFrameLayout inline Value *thisp() { return reinterpret_cast(&loThis_); } - inline uintptr_t argc() const { - return 0; + return argc_; } }; @@ -349,7 +351,9 @@ class IonOOLPropertyOpExitFrameLayout // Proxy::get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, // MutableHandleValue vp) -class IonOOLProxyGetExitFrameLayout +// Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, +// bool strict, MutableHandleValue vp) +class IonOOLProxyExitFrameLayout { protected: // only to silence a clang warning about unused private fields IonExitFooterFrame footer_; @@ -374,11 +378,11 @@ class IonOOLProxyGetExitFrameLayout public: static inline size_t Size() { - return sizeof(IonOOLProxyGetExitFrameLayout); + return sizeof(IonOOLProxyExitFrameLayout); } static size_t offsetOfResult() { - return offsetof(IonOOLProxyGetExitFrameLayout, vp0_); + return offsetof(IonOOLProxyExitFrameLayout, vp0_); } inline IonCode **stubCode() { diff --git a/js/src/jit/shared/LIR-x86-shared.h b/js/src/jit/shared/LIR-x86-shared.h index 0fedf8600447..1842e8bf1b0a 100644 --- a/js/src/jit/shared/LIR-x86-shared.h +++ b/js/src/jit/shared/LIR-x86-shared.h @@ -157,21 +157,17 @@ class LModPowTwoI : public LInstructionHelper<1,1,0> }; // Double raised to a half power. -class LPowHalfD : public LInstructionHelper<1, 1, 1> +class LPowHalfD : public LInstructionHelper<1, 1, 0> { public: LIR_HEADER(PowHalfD) - LPowHalfD(const LAllocation &input, const LDefinition &temp) { + LPowHalfD(const LAllocation &input) { setOperand(0, input); - setTemp(0, temp); } const LAllocation *input() { return getOperand(0); } - const LDefinition *temp() { - return getTemp(0); - } const LDefinition *output() { return getDef(0); } diff --git a/js/src/jit/shared/Lowering-x86-shared.cpp b/js/src/jit/shared/Lowering-x86-shared.cpp index 9bdb12f72f29..31e6e01e0e74 100644 --- a/js/src/jit/shared/Lowering-x86-shared.cpp +++ b/js/src/jit/shared/Lowering-x86-shared.cpp @@ -62,7 +62,7 @@ LIRGeneratorX86Shared::visitPowHalf(MPowHalf *ins) { MDefinition *input = ins->input(); JS_ASSERT(input->type() == MIRType_Double); - LPowHalfD *lir = new LPowHalfD(useRegisterAtStart(input), temp()); + LPowHalfD *lir = new LPowHalfD(useRegisterAtStart(input)); return defineReuseInput(lir, ins, 0); } diff --git a/js/src/jit/x64/BaselineIC-x64.cpp b/js/src/jit/x64/BaselineIC-x64.cpp index 31546a26610d..a418de5cddd9 100644 --- a/js/src/jit/x64/BaselineIC-x64.cpp +++ b/js/src/jit/x64/BaselineIC-x64.cpp @@ -28,9 +28,9 @@ ICCompare_Int32::Compiler::generateStubCode(MacroAssembler &masm) // Directly compare the int32 payload of R0 and R1. Assembler::Condition cond = JSOpToCondition(op, /* signed = */true); + masm.xorl(ScratchReg, ScratchReg); masm.cmpl(R0.valueReg(), R1.valueReg()); masm.setCC(cond, ScratchReg); - masm.movzxbl(ScratchReg, ScratchReg); // Box the result and return masm.boxValue(JSVAL_TYPE_BOOLEAN, ScratchReg, R0.valueReg()); diff --git a/js/src/jit/x64/MacroAssembler-x64.cpp b/js/src/jit/x64/MacroAssembler-x64.cpp index a453153abbdc..2689021c4799 100644 --- a/js/src/jit/x64/MacroAssembler-x64.cpp +++ b/js/src/jit/x64/MacroAssembler-x64.cpp @@ -314,6 +314,6 @@ Assembler::Condition MacroAssemblerX64::testNegativeZero(const FloatRegister ®, const Register &scratch) { movq(reg, scratch); - subq(Imm32(1), scratch); + cmpq(scratch, Imm32(1)); return Overflow; } diff --git a/js/src/jit/x64/Trampoline-x64.cpp b/js/src/jit/x64/Trampoline-x64.cpp index 7685ded2595a..340abf8b62e5 100644 --- a/js/src/jit/x64/Trampoline-x64.cpp +++ b/js/src/jit/x64/Trampoline-x64.cpp @@ -348,8 +348,6 @@ IonRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void * masm.push(r10); masm.subl(Imm32(1), rcx); - - masm.testl(rcx, rcx); masm.j(Assembler::NonZero, &undefLoopTop); } @@ -358,19 +356,14 @@ IonRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void * masm.lea(Operand(b), rcx); // Push arguments, |nargs| + 1 times (to include |this|). + masm.addl(Imm32(1), r8); { - Label copyLoopTop, initialSkip; - - masm.jump(&initialSkip); + Label copyLoopTop; masm.bind(©LoopTop); + masm.push(Operand(rcx, 0x0)); masm.subq(Imm32(sizeof(Value)), rcx); masm.subl(Imm32(1), r8); - masm.bind(&initialSkip); - - masm.push(Operand(rcx, 0x0)); - - masm.testl(r8, r8); masm.j(Assembler::NonZero, ©LoopTop); } diff --git a/js/src/jit/x86/Trampoline-x86.cpp b/js/src/jit/x86/Trampoline-x86.cpp index f0a04684d5eb..5bbcf1c33f08 100644 --- a/js/src/jit/x86/Trampoline-x86.cpp +++ b/js/src/jit/x86/Trampoline-x86.cpp @@ -342,8 +342,6 @@ IonRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void * masm.push(ebx); // type(undefined); masm.push(edi); // payload(undefined); masm.subl(Imm32(1), ecx); - - masm.testl(ecx, ecx); masm.j(Assembler::NonZero, &undefLoopTop); } @@ -354,20 +352,15 @@ IonRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void * masm.lea(Operand(b), ecx); // Push arguments, |nargs| + 1 times (to include |this|). + masm.addl(Imm32(1), esi); { - Label copyLoopTop, initialSkip; - - masm.jump(&initialSkip); + Label copyLoopTop; masm.bind(©LoopTop); - masm.subl(Imm32(sizeof(Value)), ecx); - masm.subl(Imm32(1), esi); - masm.bind(&initialSkip); - masm.push(Operand(ecx, sizeof(Value)/2)); masm.push(Operand(ecx, 0x0)); - - masm.testl(esi, esi); + masm.subl(Imm32(sizeof(Value)), ecx); + masm.subl(Imm32(1), esi); masm.j(Assembler::NonZero, ©LoopTop); } diff --git a/js/src/jsalloc.h b/js/src/jsalloc.h index 17c6c52253fb..451ee3e745ef 100644 --- a/js/src/jsalloc.h +++ b/js/src/jsalloc.h @@ -9,10 +9,9 @@ #ifndef jsalloc_h #define jsalloc_h +#include "js/TypeDecls.h" #include "js/Utility.h" -struct JSContext; - namespace js { class ContextFriendFields; diff --git a/js/src/jsanalyze.h b/js/src/jsanalyze.h index de1c78650e8a..5e127e5fa265 100644 --- a/js/src/jsanalyze.h +++ b/js/src/jsanalyze.h @@ -11,8 +11,6 @@ #include "jscompartment.h" -class JSScript; - namespace js { namespace analyze { diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 631e6b44b87d..88b5aa9ad21d 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -2875,6 +2875,8 @@ JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp) return true; } +namespace { + class AutoHoldZone { public: @@ -2895,6 +2897,8 @@ class AutoHoldZone MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; +} /* anonymous namespace */ + JS_PUBLIC_API(JSObject *) JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals, JS::OnNewGlobalHookOption hookOption, @@ -4713,6 +4717,8 @@ ReadCompleteFile(JSContext *cx, FILE *fp, FileContents &buffer) return true; } +namespace { + class AutoFile { FILE *fp_; @@ -4734,6 +4740,8 @@ class AutoFile } }; +} /* anonymous namespace */ + /* * Open a source file for reading. Supports "-" and NULL to mean stdin. The * return value must be fclosed unless it is stdin. diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 1206314a769c..7e805fcca889 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -4637,7 +4637,6 @@ using JS::CallNonGenericMethod; using JS::Rooted; using JS::RootedObject; -using JS::RootedModule; using JS::RootedFunction; using JS::RootedScript; using JS::RootedString; @@ -4646,7 +4645,6 @@ using JS::RootedValue; using JS::Handle; using JS::HandleObject; -using JS::HandleModule; using JS::HandleFunction; using JS::HandleScript; using JS::HandleString; diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index 349ff266542b..7f8783fd2f26 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -831,8 +831,7 @@ js_ReportErrorNumberVA(JSContext *cx, unsigned flags, JSErrorCallback callback, ReportError(cx, message, &report, callback, userRef); - if (message) - js_free(message); + js_free(message); if (report.messageArgs) { /* * js_ExpandErrorArguments owns its messageArgs only if it had to @@ -845,8 +844,7 @@ js_ReportErrorNumberVA(JSContext *cx, unsigned flags, JSErrorCallback callback, } js_free((void *)report.messageArgs); } - if (report.ucmessage) - js_free((void *)report.ucmessage); + js_free((void *)report.ucmessage); return warning; } @@ -876,10 +874,8 @@ js_ReportErrorNumberUCArray(JSContext *cx, unsigned flags, JSErrorCallback callb ReportError(cx, message, &report, callback, userRef); - if (message) - js_free(message); - if (report.ucmessage) - js_free((void *)report.ucmessage); + js_free(message); + js_free((void *)report.ucmessage); return warning; } diff --git a/js/src/jsdate.h b/js/src/jsdate.h index 819869db2956..028e64794e4a 100644 --- a/js/src/jsdate.h +++ b/js/src/jsdate.h @@ -14,15 +14,7 @@ #include "jstypes.h" #include "js/RootingAPI.h" - -extern "C" { -class JSObject; -struct JSContext; -} - -namespace JS { -class Value; -} +#include "js/TypeDecls.h" extern JSObject * js_InitDateClass(JSContext *cx, JS::HandleObject obj); diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 049185716f41..0f60b2a48342 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -342,6 +342,14 @@ js::IsAtomsCompartment(JSCompartment *comp) return comp->runtimeFromAnyThread()->isAtomsCompartment(comp); } +JS_FRIEND_API(bool) +js::IsInNonStrictPropertySet(JSContext *cx) +{ + jsbytecode *pc; + JSScript *script = cx->currentScript(&pc, JSContext::ALLOW_CROSS_COMPARTMENT); + return script && !script->strict && (js_CodeSpec[*pc].format & JOF_SET); +} + JS_FRIEND_API(bool) js::IsFunctionObject(JSObject *obj) { diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 45e9b16b0e69..763adebd77a9 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -266,6 +266,15 @@ IsAtomsCompartment(JSCompartment *comp); extern JS_FRIEND_API(bool) ReportIfUndeclaredVarAssignment(JSContext *cx, JS::HandleString propname); +/* + * Returns whether we're in a non-strict property set (in that we're in a + * non-strict script and the bytecode we're on is a property set). The return + * value does NOT indicate any sort of exception was thrown: it's just a + * boolean. + */ +extern JS_FRIEND_API(bool) +IsInNonStrictPropertySet(JSContext *cx); + struct WeakMapTracer; /* diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 1ce34ca7e465..2f1161d6097e 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -4023,6 +4023,8 @@ EndSweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, bool lastGC) rt->gcLastGCTime = PRMJ_Now(); } +namespace { + /* ...while this class is to be used only for garbage collection. */ class AutoGCSession : AutoTraceSession { public: @@ -4030,6 +4032,8 @@ class AutoGCSession : AutoTraceSession { ~AutoGCSession(); }; +} /* anonymous namespace */ + /* Start a new heap session. */ AutoTraceSession::AutoTraceSession(JSRuntime *rt, js::HeapState heapState) : runtime(rt), @@ -4173,6 +4177,8 @@ ResetIncrementalGC(JSRuntime *rt, const char *reason) #endif } +namespace { + class AutoGCSlice { public: AutoGCSlice(JSRuntime *rt); @@ -4182,6 +4188,8 @@ class AutoGCSlice { JSRuntime *runtime; }; +} /* anonymous namespace */ + AutoGCSlice::AutoGCSlice(JSRuntime *rt) : runtime(rt) { @@ -4505,6 +4513,8 @@ ShouldCleanUpEverything(JSRuntime *rt, JS::gcreason::Reason reason, JSGCInvocati gckind == GC_SHRINK; } +namespace { + #ifdef JSGC_GENERATIONAL class AutoDisableStoreBuffer { @@ -4528,6 +4538,8 @@ struct AutoDisableStoreBuffer }; #endif +} /* anonymous namespace */ + static void Collect(JSRuntime *rt, bool incremental, int64_t budget, JSGCInvocationKind gckind, JS::gcreason::Reason reason) diff --git a/js/src/jsgc.h b/js/src/jsgc.h index ca977a802205..08c32263e776 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -21,7 +21,6 @@ class JSAtom; struct JSCompartment; -class JSFunction; class JSFlatString; class JSLinearString; diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 58f1f138b598..4bc823750a28 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -568,6 +568,8 @@ TypeSet::unionSets(TypeSet *a, TypeSet *b, LifoAlloc *alloc) // TypeSet constraints ///////////////////////////////////////////////////////////////////// +namespace { + /* Standard subset constraint, propagate all types from one set to another. */ class TypeConstraintSubset : public TypeConstraint { @@ -589,6 +591,8 @@ class TypeConstraintSubset : public TypeConstraint } }; +} /* anonymous namespace */ + void StackTypeSet::addSubset(JSContext *cx, TypeSet *target) { @@ -602,6 +606,8 @@ HeapTypeSet::addSubset(JSContext *cx, TypeSet *target) add(cx, cx->typeLifoAlloc().new_(target)); } +namespace { + enum PropertyAccessKind { PROPERTY_WRITE, PROPERTY_READ, @@ -641,6 +647,8 @@ typedef TypeConstraintProp TypeConstraintSetProperty; typedef TypeConstraintProp TypeConstraintGetProperty; typedef TypeConstraintProp TypeConstraintGetPropertyExisting; +} /* anonymous namespace */ + void StackTypeSet::addGetProperty(JSContext *cx, JSScript *script, jsbytecode *pc, StackTypeSet *target, jsid id) @@ -669,6 +677,8 @@ HeapTypeSet::addGetProperty(JSContext *cx, JSScript *script, jsbytecode *pc, add(cx, cx->typeLifoAlloc().new_(script, pc, target, id)); } +namespace { + /* * Constraints for updating the 'this' types of callees on CALLPROP/CALLELEM. * These are derived from the types on the properties themselves, rather than @@ -701,6 +711,8 @@ class TypeConstraintCallProp : public TypeConstraint typedef TypeConstraintCallProp TypeConstraintCallProperty; typedef TypeConstraintCallProp TypeConstraintCallPropertyExisting; +} /* anonymous namespace */ + void HeapTypeSet::addCallProperty(JSContext *cx, JSScript *script, jsbytecode *pc, jsid id) { @@ -716,6 +728,8 @@ HeapTypeSet::addCallProperty(JSContext *cx, JSScript *script, jsbytecode *pc, js add(cx, cx->typeLifoAlloc().new_(script, callpc, id)); } +namespace { + /* * Constraints for generating 'set' property constraints on a SETELEM only if * the element type may be a number. For SETELEM we only account for integer @@ -745,6 +759,8 @@ class TypeConstraintSetElement : public TypeConstraint void newType(JSContext *cx, TypeSet *source, Type type); }; +} /* anonymous namespace */ + void StackTypeSet::addSetElement(JSContext *cx, JSScript *script, jsbytecode *pc, StackTypeSet *objectTypes, StackTypeSet *valueTypes) @@ -753,6 +769,8 @@ StackTypeSet::addSetElement(JSContext *cx, JSScript *script, jsbytecode *pc, valueTypes)); } +namespace { + /* * Constraints for watching call edges as they are discovered and invoking native * function handlers, adding constraints for arguments, receiver objects and the @@ -773,12 +791,16 @@ class TypeConstraintCall : public TypeConstraint void newType(JSContext *cx, TypeSet *source, Type type); }; +} /* anonymous namespace */ + void StackTypeSet::addCall(JSContext *cx, TypeCallsite *site) { add(cx, cx->analysisLifoAlloc().new_(site)); } +namespace { + /* Constraints for arithmetic operations. */ class TypeConstraintArith : public TypeConstraint { @@ -804,6 +826,8 @@ class TypeConstraintArith : public TypeConstraint void newType(JSContext *cx, TypeSet *source, Type type); }; +} /* anonymous namespace */ + void StackTypeSet::addArith(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet *target, TypeSet *other) @@ -811,6 +835,8 @@ StackTypeSet::addArith(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet add(cx, cx->analysisLifoAlloc().new_(script, pc, target, other)); } +namespace { + /* Subset constraint which transforms primitive values into appropriate objects. */ class TypeConstraintTransformThis : public TypeConstraint { @@ -828,12 +854,16 @@ class TypeConstraintTransformThis : public TypeConstraint void newType(JSContext *cx, TypeSet *source, Type type); }; +} /* anonymous namespace */ + void StackTypeSet::addTransformThis(JSContext *cx, JSScript *script, TypeSet *target) { add(cx, cx->analysisLifoAlloc().new_(script, target)); } +namespace { + /* * Constraint which adds a particular type to the 'this' types of all * discovered scripted functions. @@ -856,6 +886,8 @@ class TypeConstraintPropagateThis : public TypeConstraint void newType(JSContext *cx, TypeSet *source, Type type); }; +} /* anonymous namespace */ + void StackTypeSet::addPropagateThis(JSContext *cx, JSScript *script, jsbytecode *pc, Type type, StackTypeSet *types) @@ -863,6 +895,8 @@ StackTypeSet::addPropagateThis(JSContext *cx, JSScript *script, jsbytecode *pc, add(cx, cx->analysisLifoAlloc().new_(script, pc, type, types)); } +namespace { + /* Subset constraint which filters out primitive types. */ class TypeConstraintFilterPrimitive : public TypeConstraint { @@ -884,6 +918,8 @@ class TypeConstraintFilterPrimitive : public TypeConstraint } }; +} /* anonymous namespace */ + void HeapTypeSet::addFilterPrimitives(JSContext *cx, TypeSet *target) { @@ -994,6 +1030,8 @@ void ScriptAnalysis::breakTypeBarriersSSA(JSContext *cx, const SSAValue &v) breakTypeBarriers(cx, offset, true); } +namespace { + /* * Subset constraint for property reads and argument passing which can add type * barriers on the read instead of passing types along. @@ -1021,6 +1059,8 @@ class TypeConstraintSubsetBarrier : public TypeConstraint } }; +} /* anonymous namespace */ + void StackTypeSet::addSubsetBarrier(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet *target) { @@ -1634,6 +1674,8 @@ TypeConstraintTransformThis::newType(JSContext *cx, TypeSet *source, Type type) // Freeze constraints ///////////////////////////////////////////////////////////////////// +namespace { + /* Constraint which triggers recompilation of a script if any type is added to a type set. */ class TypeConstraintFreeze : public TypeConstraint { @@ -1659,6 +1701,8 @@ class TypeConstraintFreeze : public TypeConstraint } }; +} /* anonymous namespace */ + void HeapTypeSet::addFreeze(JSContext *cx) { @@ -1754,6 +1798,8 @@ StackTypeSet::mightBeType(JSValueType type) return baseFlags() & PrimitiveTypeFlag(type); } +namespace { + /* Constraint which triggers recompilation if an object acquires particular flags. */ class TypeConstraintFreezeObjectFlags : public TypeConstraint { @@ -1784,6 +1830,8 @@ class TypeConstraintFreezeObjectFlags : public TypeConstraint } }; +} /* anonymous namespace */ + bool StackTypeSet::hasObjectFlags(JSContext *cx, TypeObjectFlags flags) { @@ -1881,6 +1929,8 @@ HeapTypeSet::WatchObjectStateChange(JSContext *cx, TypeObject *obj) 0)); } +namespace { + class TypeConstraintFreezeOwnProperty : public TypeConstraint { public: @@ -1908,6 +1958,8 @@ class TypeConstraintFreezeOwnProperty : public TypeConstraint } }; +} /* anonymous namespace */ + static void CheckNewScriptProperties(JSContext *cx, HandleTypeObject type, HandleFunction fun); @@ -2217,6 +2269,8 @@ AddPendingRecompile(JSContext *cx, JSScript *script) cx->compartment()->types.addPendingRecompile(cx, script); } +namespace { + /* * As for TypeConstraintFreeze, but describes an implicit freeze constraint * added for stack types within a script. Applies to all compilations of the @@ -2243,6 +2297,8 @@ class TypeConstraintFreezeStack : public TypeConstraint } }; +} /* anonymous namespace */ + ///////////////////////////////////////////////////////////////////// // TypeCompartment ///////////////////////////////////////////////////////////////////// @@ -4745,6 +4801,8 @@ ScriptAnalysis::analyzeTypes(JSContext *cx) TypeScript::AddFreezeConstraints(cx, script_); } +namespace { + /* * Persistent constraint clearing out newScript and definite properties from * an object should a property on another object get a getter or setter. @@ -4777,6 +4835,8 @@ class TypeConstraintClearDefiniteGetterSetter : public TypeConstraint void newType(JSContext *cx, TypeSet *source, Type type) {} }; +} /* anonymous namespace */ + static bool AddClearDefiniteGetterSetterForPrototypeChain(JSContext *cx, TypeObject *type, jsid id) { @@ -4799,6 +4859,8 @@ AddClearDefiniteGetterSetterForPrototypeChain(JSContext *cx, TypeObject *type, j return true; } +namespace { + /* * Constraint which clears definite properties on an object should a type set * contain any types other than a single object. @@ -4835,6 +4897,8 @@ struct NewScriptPropertiesState {} }; +} /* anonymous namespace */ + static bool AnalyzePoppedThis(JSContext *cx, SSAUseChain *use, TypeObject *type, JSFunction *fun, NewScriptPropertiesState &state); @@ -6386,17 +6450,10 @@ JSCompartment::sweepNewTypeObjectTable(TypeObjectSet &table) TypeCompartment::~TypeCompartment() { - if (pendingArray) - js_free(pendingArray); - - if (arrayTypeTable) - js_delete(arrayTypeTable); - - if (objectTypeTable) - js_delete(objectTypeTable); - - if (allocationSiteTable) - js_delete(allocationSiteTable); + js_free(pendingArray); + js_delete(arrayTypeTable); + js_delete(objectTypeTable); + js_delete(allocationSiteTable); } /* static */ void diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index fd84125d409b..884e2d38c04d 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -18,8 +18,6 @@ #include "gc/Barrier.h" #include "js/Utility.h" -class JSScript; - namespace js { class TypeRepresentation; diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index fa7eeeb711ea..1ead377f523f 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -1166,6 +1166,8 @@ SuppressDeletedPropertyHelper(JSContext *cx, HandleObject obj, StringPredicate p return true; } +namespace { + class SingleStringPredicate { Handle str; public: @@ -1175,6 +1177,8 @@ public: bool matchesAtMostOne() { return true; } }; +} /* anonymous namespace */ + bool js_SuppressDeletedProperty(JSContext *cx, HandleObject obj, jsid id) { @@ -1193,6 +1197,8 @@ js_SuppressDeletedElement(JSContext *cx, HandleObject obj, uint32_t index) return js_SuppressDeletedProperty(cx, obj, id); } +namespace { + class IndexRangePredicate { uint32_t begin, end; @@ -1207,6 +1213,8 @@ class IndexRangePredicate { bool matchesAtMostOne() { return false; } }; +} /* anonymous namespace */ + bool js_SuppressDeletedElements(JSContext *cx, HandleObject obj, uint32_t begin, uint32_t end) { diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp index ebdf773683ec..61a3dcb4d920 100644 --- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -85,6 +85,8 @@ ComputeAccurateDecimalInteger(ThreadSafeContext *cx, return true; } +namespace { + class BinaryDigitReader { const int base; /* Base of number; must be a power of 2 */ @@ -122,6 +124,8 @@ class BinaryDigitReader } }; +} /* anonymous namespace */ + /* * The fast result might also have been inaccurate for power-of-two bases. This * happens if the addition in value * 2 + digit causes a round-down to an even @@ -532,8 +536,7 @@ ToCStringBuf::ToCStringBuf() :dbuf(NULL) ToCStringBuf::~ToCStringBuf() { - if (dbuf) - js_free(dbuf); + js_free(dbuf); } template diff --git a/js/src/jsnum.h b/js/src/jsnum.h index 693770471c01..20fabea50d13 100644 --- a/js/src/jsnum.h +++ b/js/src/jsnum.h @@ -42,8 +42,6 @@ extern const char js_isFinite_str[]; extern const char js_parseFloat_str[]; extern const char js_parseInt_str[]; -class JSString; - /* * When base == 10, this function implements ToString() as specified by * ECMA-262-5 section 9.8.1; but note that it handles integers specially for diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 867b1dc13272..a94c7862f371 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -1868,10 +1868,8 @@ struct JSObject::TradeGutsReserved { ~TradeGutsReserved() { - if (newaslots) - js_free(newaslots); - if (newbslots) - js_free(newbslots); + js_free(newaslots); + js_free(newbslots); } }; diff --git a/js/src/json.cpp b/js/src/json.cpp index 176adc415b09..e5c4112a1b9a 100644 --- a/js/src/json.cpp +++ b/js/src/json.cpp @@ -115,6 +115,8 @@ Quote(JSContext *cx, StringBuffer &sb, JSString *str) return sb.append('"'); } +namespace { + class StringifyContext { public: @@ -134,6 +136,8 @@ class StringifyContext uint32_t depth; }; +} /* anonymous namespace */ + static bool Str(JSContext *cx, const Value &v, StringifyContext *scx); static bool @@ -151,6 +155,8 @@ WriteIndent(JSContext *cx, StringifyContext *scx, uint32_t limit) return true; } +namespace { + template class KeyStringifier { }; @@ -171,6 +177,8 @@ class KeyStringifier { } }; +} /* anonymous namespace */ + /* * ES5 15.12.3 Str, steps 2-4, extracted to enable preprocessing of property * values when stringifying objects in JO. diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp index 8873c60741fc..be06e685a478 100644 --- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -1087,6 +1087,8 @@ GetBlockChainAtPC(JSContext *cx, JSScript *script, jsbytecode *pc) return blockChain; } +namespace { + class PCStack { jsbytecode **stack; @@ -1100,6 +1102,8 @@ class PCStack jsbytecode *operator[](int i) const; }; +} /* anonymous namespace */ + PCStack::~PCStack() { js_free(stack); diff --git a/js/src/jsprf.cpp b/js/src/jsprf.cpp index a4b3c49f5623..92cf56f3394b 100644 --- a/js/src/jsprf.cpp +++ b/js/src/jsprf.cpp @@ -1053,11 +1053,7 @@ static int GrowStuff(SprintfState *ss, const char *sp, uint32_t len) if (off + len >= ss->maxlen) { /* Grow the buffer */ newlen = ss->maxlen + ((len > 32) ? len : 32); - if (ss->base) { - newbase = (char*) js_realloc(ss->base, newlen); - } else { - newbase = (char*) js_malloc(newlen); - } + newbase = (char*) js_realloc(ss->base, newlen); if (!newbase) { /* Ran out of memory */ return -1; @@ -1109,9 +1105,7 @@ JS_PUBLIC_API(char *) JS_vsmprintf(const char *fmt, va_list ap) ss.maxlen = 0; rv = dosprintf(&ss, fmt, ap); if (rv < 0) { - if (ss.base) { - js_free(ss.base); - } + js_free(ss.base); return 0; } return ss.base; @@ -1208,9 +1202,7 @@ JS_PUBLIC_API(char *) JS_vsprintf_append(char *last, const char *fmt, va_list ap } rv = dosprintf(&ss, fmt, ap); if (rv < 0) { - if (ss.base) { - js_free(ss.base); - } + js_free(ss.base); return 0; } return ss.base; diff --git a/js/src/jsproxy.cpp b/js/src/jsproxy.cpp index 7a76debdfc36..f0a9df0d2d51 100644 --- a/js/src/jsproxy.cpp +++ b/js/src/jsproxy.cpp @@ -746,6 +746,8 @@ FunctionProxyObject::constructOrUndefined() const return getSlot(CONSTRUCT_SLOT); } +namespace { + /* Derived class for all scripted indirect proxy handlers. */ class ScriptedIndirectProxyHandler : public BaseProxyHandler { @@ -791,6 +793,8 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler static ScriptedIndirectProxyHandler singleton; }; +} /* anonymous namespace */ + static int sScriptedIndirectProxyHandlerFamily = 0; ScriptedIndirectProxyHandler::ScriptedIndirectProxyHandler() diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index fba410c24b39..1d5d7277d088 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -15,9 +15,8 @@ #include "jsprototypes.h" #include "jstypes.h" -#include "jsversion.h" // #include here so it's seen everywhere -#include "js/IdForward.h" +#include "js/TypeDecls.h" #if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) || defined(DEBUG) # define JSGC_TRACK_EXACT_ROOTS @@ -25,12 +24,6 @@ namespace JS { -/* - * Allow headers to reference JS::Value without #including the whole jsapi.h. - * Unfortunately, typedefs (hence jsval) cannot be declared. - */ -class Value; - class AutoIdVector; class CallArgs; @@ -46,12 +39,6 @@ struct Zone; } /* namespace JS */ -#ifdef WIN32 -typedef wchar_t jschar; -#else -typedef uint16_t jschar; -#endif - /* * Run-time version enumeration. For compile-time version checking, please use * the JS_HAS_* macros in jsversion.h, or use MOZJS_MAJOR_VERSION, @@ -150,7 +137,6 @@ typedef enum { typedef struct JSClass JSClass; typedef struct JSCompartment JSCompartment; typedef struct JSConstDoubleSpec JSConstDoubleSpec; -typedef struct JSContext JSContext; typedef struct JSCrossCompartmentCall JSCrossCompartmentCall; typedef struct JSErrorReport JSErrorReport; typedef struct JSExceptionState JSExceptionState; @@ -170,11 +156,7 @@ typedef struct JSStructuredCloneWriter JSStructuredCloneWriter; typedef struct JSTracer JSTracer; class JSFlatString; -class JSFunction; -class JSObject; -class JSScript; class JSStableString; // long story -class JSString; #ifdef JS_THREADSAFE typedef struct PRCallOnceType JSCallOnceType; diff --git a/js/src/jsreflect.cpp b/js/src/jsreflect.cpp index dc33ff76f842..f69a039f4f28 100644 --- a/js/src/jsreflect.cpp +++ b/js/src/jsreflect.cpp @@ -120,6 +120,8 @@ typedef AutoValueVector NodeVector; return false; \ JS_END_MACRO +namespace { + /* * Builder class that constructs JavaScript AST node objects. See: * @@ -615,6 +617,8 @@ class NodeBuilder bool propertyPattern(HandleValue key, HandleValue patt, TokenPos *pos, MutableHandleValue dst); }; +} /* anonymous namespace */ + bool NodeBuilder::newNode(ASTType type, TokenPos *pos, MutableHandleObject dst) { diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 04a612ac6fb0..7ebffce2cde9 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -546,7 +546,7 @@ js::XDRScript(XDRState *xdr, HandleObject enclosingScope, HandleScript enc options.setVersion(version_) .setNoScriptRval(!!(scriptBits & (1 << NoScriptRval))) .setSelfHostingMode(!!(scriptBits & (1 << SelfHosted))); - JS::RootedScriptSource sourceObject(cx); + RootedScriptSource sourceObject(cx); if (scriptBits & (1 << OwnSource)) { ScriptSource *ss = cx->new_(xdr->originPrincipals()); if (!ss) @@ -962,7 +962,7 @@ ScriptSourceObject::create(ExclusiveContext *cx, ScriptSource *source) RootedObject object(cx, NewObjectWithGivenProto(cx, &class_, NULL, cx->global())); if (!object) return NULL; - JS::RootedScriptSource sourceObject(cx, &object->as()); + RootedScriptSource sourceObject(cx, &object->as()); sourceObject->setSlot(SOURCE_SLOT, PrivateValue(source)); source->incref(); return sourceObject; @@ -1610,7 +1610,7 @@ JSScript::initCompartment(ExclusiveContext *cx) JSScript * JSScript::Create(ExclusiveContext *cx, HandleObject enclosingScope, bool savedCallerFun, const CompileOptions &options, unsigned staticLevel, - JS::HandleScriptSource sourceObject, uint32_t bufStart, uint32_t bufEnd) + HandleScriptSource sourceObject, uint32_t bufStart, uint32_t bufEnd) { JS_ASSERT(bufStart <= bufEnd); @@ -2291,7 +2291,7 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, .setVersion(src->getVersion()); /* Make sure we clone the script source object with the script */ - JS::RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, src->scriptSource())); + RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, src->scriptSource())); if (!sourceObject) return NULL; diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 5ec61a9ae552..eb3d5d555330 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -20,6 +20,7 @@ #include "jsopcode.h" #include "gc/Barrier.h" +#include "gc/Rooting.h" #include "vm/Shape.h" namespace js { @@ -630,7 +631,7 @@ class JSScript : public js::gc::Cell static JSScript *Create(js::ExclusiveContext *cx, js::HandleObject enclosingScope, bool savedCallerFun, const JS::CompileOptions &options, unsigned staticLevel, - JS::HandleScriptSource sourceObject, uint32_t sourceStart, + js::HandleScriptSource sourceObject, uint32_t sourceStart, uint32_t sourceEnd); void initCompartment(js::ExclusiveContext *cx); diff --git a/js/src/jsutil.h b/js/src/jsutil.h index 6f14f8b5f4cd..77e867da7644 100644 --- a/js/src/jsutil.h +++ b/js/src/jsutil.h @@ -20,9 +20,6 @@ #include "js/Utility.h" -/* Forward declarations. */ -struct JSContext; - static JS_ALWAYS_INLINE void * js_memcpy(void *dst_, const void *src_, size_t len) { diff --git a/js/src/moz.build b/js/src/moz.build index 00275cb77a19..850f778eb49a 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -16,11 +16,7 @@ if CONFIG['JS_NATIVE_EDITLINE']: if not CONFIG['JS_DISABLE_SHELL']: DIRS += ['shell'] -# FIXME: bug 530688 covers getting these working on Android -if CONFIG['OS_ARCH'] != 'ANDROID': - TEST_DIRS += ['jsapi-tests'] - -TEST_DIRS += ['tests', 'gdb'] +TEST_DIRS += ['jsapi-tests', 'tests', 'gdb'] MODULE = 'js' @@ -72,7 +68,6 @@ EXPORTS.js += [ '../public/HashTable.h', '../public/HeapAPI.h', '../public/Id.h', - '../public/IdForward.h', '../public/LegacyIntTypes.h', '../public/MemoryMetrics.h', '../public/OldDebugAPI.h', @@ -81,6 +76,7 @@ EXPORTS.js += [ '../public/RequiredDefines.h', '../public/RootingAPI.h', '../public/StructuredClone.h', + '../public/TypeDecls.h', '../public/Utility.h', '../public/Value.h', '../public/Vector.h', diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index 62ad8986be79..cd28205957c4 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -2859,7 +2859,7 @@ DebuggerScript_getSource(JSContext *cx, unsigned argc, Value *vp) THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "(get source)", args, obj, script); Debugger *dbg = Debugger::fromChildJSObject(obj); - JS::RootedScriptSource source(cx, script->sourceObject()); + RootedScriptSource source(cx, script->sourceObject()); RootedObject sourceObject(cx, dbg->wrapSource(cx, source)); if (!sourceObject) return false; @@ -2979,6 +2979,8 @@ DebuggerScript_getOffsetLine(JSContext *cx, unsigned argc, Value *vp) return true; } +namespace { + class BytecodeRangeWithPosition : private BytecodeRange { public: @@ -3207,6 +3209,8 @@ class FlowGraphSummary { Vector entries_; }; +} /* anonymous namespace */ + static bool DebuggerScript_getAllOffsets(JSContext *cx, unsigned argc, Value *vp) { @@ -3620,7 +3624,7 @@ Class DebuggerSource_class = { }; JSObject * -Debugger::newDebuggerSource(JSContext *cx, JS::HandleScriptSource source) +Debugger::newDebuggerSource(JSContext *cx, HandleScriptSource source) { assertSameCompartment(cx, object.get()); @@ -3636,7 +3640,7 @@ Debugger::newDebuggerSource(JSContext *cx, JS::HandleScriptSource source) } JSObject * -Debugger::wrapSource(JSContext *cx, JS::HandleScriptSource source) +Debugger::wrapSource(JSContext *cx, HandleScriptSource source) { assertSameCompartment(cx, object.get()); JS_ASSERT(cx->compartment() != source->compartment()); @@ -3700,7 +3704,7 @@ DebuggerSource_checkThis(JSContext *cx, const CallArgs &args, const char *fnname RootedObject obj(cx, DebuggerSource_checkThis(cx, args, fnname)); \ if (!obj) \ return false; \ - JS::RootedScriptSource sourceObject(cx, GetSourceReferent(obj)); \ + RootedScriptSource sourceObject(cx, GetSourceReferent(obj)); \ if (!sourceObject) \ return false; diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h index 4e36ddfd72f2..4c9c1abb691d 100644 --- a/js/src/vm/Debugger.h +++ b/js/src/vm/Debugger.h @@ -365,7 +365,7 @@ class Debugger : private mozilla::LinkedListElement * Allocate and initialize a Debugger.Source instance whose referent is * |source|. */ - JSObject *newDebuggerSource(JSContext *cx, JS::HandleScriptSource source); + JSObject *newDebuggerSource(JSContext *cx, js::HandleScriptSource source); /* * Receive a "new script" event from the engine. A new script was compiled @@ -528,7 +528,7 @@ class Debugger : private mozilla::LinkedListElement * needed. The context |cx| must be in the debugger compartment; |source| * must be a script source object in a debuggee compartment. */ - JSObject *wrapSource(JSContext *cx, JS::HandleScriptSource source); + JSObject *wrapSource(JSContext *cx, js::HandleScriptSource source); private: Debugger(const Debugger &) MOZ_DELETE; diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp index 9e9ec9f1132d..a15c64b21ca8 100644 --- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -232,7 +232,7 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx) js_free(source); return NULL; } - JS::RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, ss)); + RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, ss)); if (!sourceObject) return NULL; ss->setSource(source, sourceLen); diff --git a/js/src/vm/OldDebugAPI.cpp b/js/src/vm/OldDebugAPI.cpp index 60c48d919799..b0fc2afbc93f 100644 --- a/js/src/vm/OldDebugAPI.cpp +++ b/js/src/vm/OldDebugAPI.cpp @@ -1004,6 +1004,8 @@ JS::FreeStackDescription(JSContext *cx, JS::StackDescription *desc) js_delete(desc); } +namespace { + class AutoPropertyDescArray { JSContext *cx_; @@ -1032,6 +1034,8 @@ class AutoPropertyDescArray } }; +} /* anonymous namespace */ + static const char * FormatValue(JSContext *cx, const Value &vArg, JSAutoByteString &bytes) { diff --git a/js/src/vm/RegExpObject.cpp b/js/src/vm/RegExpObject.cpp index 11d6874724d5..4b356094fb2c 100644 --- a/js/src/vm/RegExpObject.cpp +++ b/js/src/vm/RegExpObject.cpp @@ -393,8 +393,7 @@ RegExpShared::~RegExpShared() #if ENABLE_YARR_JIT codeBlock.release(); #endif - if (bytecode) - js_delete(bytecode); + js_delete(bytecode); } void diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp index a56a73d26254..f7c587502185 100644 --- a/js/src/vm/Runtime.cpp +++ b/js/src/vm/Runtime.cpp @@ -390,8 +390,7 @@ JSRuntime::~JSRuntime() mainThread.removeFromThreadList(); #ifdef JS_WORKER_THREADS - if (workerThreadState) - js_delete(workerThreadState); + js_delete(workerThreadState); JS_ASSERT(!exclusiveAccessOwner); if (exclusiveAccessLock) @@ -451,8 +450,7 @@ JSRuntime::~JSRuntime() #endif js_delete(execAlloc_); /* Delete after ionRuntime_. */ - if (ionPcScriptCache) - js_delete(ionPcScriptCache); + js_delete(ionPcScriptCache); #ifdef JSGC_GENERATIONAL gcStoreBuffer.disable(); diff --git a/js/src/vm/SPSProfiler.h b/js/src/vm/SPSProfiler.h index 224cd558da3a..37322e6c8736 100644 --- a/js/src/vm/SPSProfiler.h +++ b/js/src/vm/SPSProfiler.h @@ -103,8 +103,6 @@ * from a signal handler when the JIT code is executing. */ -class JSFunction; - namespace js { class ProfileEntry; diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index 0d5f6f5d1bc4..bfcc5160d9a2 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -1138,6 +1138,8 @@ ScopeIterKey::match(ScopeIterKey si1, ScopeIterKey si2) /*****************************************************************************/ +namespace { + /* * DebugScopeProxy is the handler for DebugScopeObject proxy objects. Having a * custom handler (rather than trying to reuse js::Wrapper) gives us several @@ -1532,6 +1534,8 @@ class DebugScopeProxy : public BaseProxyHandler } }; +} /* anonymous namespace */ + int DebugScopeProxy::family = 0; DebugScopeProxy DebugScopeProxy::singleton; diff --git a/js/src/vm/Shape.h b/js/src/vm/Shape.h index a23e0ee8d833..6a1564fe1faf 100644 --- a/js/src/vm/Shape.h +++ b/js/src/vm/Shape.h @@ -93,8 +93,6 @@ * a single BaseShape. */ -class JSObject; - namespace js { class Bindings; diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h index 0dd6c530b11b..59ea0b47824b 100644 --- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -18,7 +18,6 @@ #endif #include "js/OldDebugAPI.h" -struct JSContext; struct JSCompartment; struct JSGenerator; diff --git a/js/src/vm/String.h b/js/src/vm/String.h index 1ad659ffd0f3..83dbd7ca0297 100644 --- a/js/src/vm/String.h +++ b/js/src/vm/String.h @@ -25,7 +25,6 @@ class JSExtensibleString; class JSExternalString; class JSInlineString; class JSStableString; -class JSString; class JSRope; namespace js { diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp index 42dbbfcd3294..76d48610f38e 100644 --- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -966,12 +966,14 @@ JSStructuredCloneReader::checkDouble(double d) return true; } +namespace { + class Chars { JSContext *cx; jschar *p; public: Chars(JSContext *cx) : cx(cx), p(NULL) {} - ~Chars() { if (p) js_free(p); } + ~Chars() { js_free(p); } bool allocate(size_t len) { JS_ASSERT(!p); @@ -987,6 +989,8 @@ class Chars { void forget() { p = NULL; } }; +} /* anonymous namespace */ + JSString * JSStructuredCloneReader::readString(uint32_t nchars) { diff --git a/js/src/vm/ThreadPool.cpp b/js/src/vm/ThreadPool.cpp index 15fa806a5fe0..07d4a5c3b4e2 100644 --- a/js/src/vm/ThreadPool.cpp +++ b/js/src/vm/ThreadPool.cpp @@ -24,7 +24,7 @@ using namespace js; // Once the worker's state is set to |TERMINATING|, the worker will // exit as soon as its queue is empty. -const size_t WORKER_THREAD_STACK_SIZE = 1*1024*1024; +static const size_t WORKER_THREAD_STACK_SIZE = 1*1024*1024; class js::ThreadPoolWorker : public Monitor { diff --git a/js/src/vm/ThreadPool.h b/js/src/vm/ThreadPool.h index 66f34e034da8..8af87545f040 100644 --- a/js/src/vm/ThreadPool.h +++ b/js/src/vm/ThreadPool.h @@ -20,10 +20,8 @@ #include "js/Vector.h" -struct JSContext; struct JSRuntime; struct JSCompartment; -class JSScript; namespace js { diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index 85d804480979..7067d2268ec2 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -1407,8 +1407,6 @@ template<> inline const bool ElementTypeMayBeDouble() { return true; } template<> inline const bool ElementTypeMayBeDouble() { return true; } template<> inline const bool ElementTypeMayBeDouble() { return true; } -template class TypedArrayObjectTemplate; - template static inline JSObject * NewArray(JSContext *cx, uint32_t nelements); @@ -1425,6 +1423,8 @@ InitArrayBufferViewDataPointer(JSObject *obj, ArrayBufferObject *buffer, size_t PostBarrierTypedArrayObject(obj); } +namespace { + template class TypedArrayObjectTemplate : public TypedArrayObject { @@ -2619,6 +2619,8 @@ class Uint8ClampedArrayObject : public TypedArrayObjectTemplate { static const JSFunctionSpec jsfuncs[]; }; +} /* anonymous namespace */ + template bool ArrayBufferObject::createTypedArrayFromBufferImpl(JSContext *cx, CallArgs args) @@ -2682,6 +2684,8 @@ TypedArrayObjectTemplate::copyIndexToValue(JSObject *tarray, uint32_ vp.setInt32(getIndex(tarray, index)); } +namespace { + // and we need to specialize for 32-bit integers and floats template<> void @@ -2739,6 +2743,8 @@ TypedArrayObjectTemplate::copyIndexToValue(JSObject *tarray, uint32_t in vp.setDouble(JS_CANONICALIZE_NAN(val)); } +} /* anonymous namespace */ + static NewObjectKind DataViewNewObjectKind(JSContext *cx, uint32_t byteLength, JSObject *proto) { diff --git a/js/src/yarr/wtfbridge.h b/js/src/yarr/wtfbridge.h index ae9f535a9cd9..7ef80920aeae 100644 --- a/js/src/yarr/wtfbridge.h +++ b/js/src/yarr/wtfbridge.h @@ -82,8 +82,7 @@ class OwnPtr { OwnPtr(PassOwnPtr p) : ptr(p.get()) { } ~OwnPtr() { - if (ptr) - js_delete(ptr); + js_delete(ptr); } OwnPtr &operator=(PassOwnPtr p) { diff --git a/js/xpconnect/idl/nsIXPConnect.idl b/js/xpconnect/idl/nsIXPConnect.idl index aef0342600ac..85dd06151f36 100644 --- a/js/xpconnect/idl/nsIXPConnect.idl +++ b/js/xpconnect/idl/nsIXPConnect.idl @@ -20,16 +20,12 @@ %{ C++ #include "jspubtd.h" +#include "js/TypeDecls.h" #include "xptinfo.h" #include "nsAXPCNativeCallContext.h" struct JSFreeOp; -namespace JS { -template class Handle; -template class MutableHandle; -} - class nsWrapperCache; %} diff --git a/js/xpconnect/idl/xpcIJSModuleLoader.idl b/js/xpconnect/idl/xpcIJSModuleLoader.idl index 9d7f2ebeea39..02d820b4e365 100644 --- a/js/xpconnect/idl/xpcIJSModuleLoader.idl +++ b/js/xpconnect/idl/xpcIJSModuleLoader.idl @@ -8,7 +8,7 @@ [ptr] native nsAXPCNativeCallContextPtr(nsAXPCNativeCallContext); %{C++ -class JSObject; +#include "js/TypeDecls.h" %} [ptr] native JSObjectPtr(JSObject); diff --git a/js/xpconnect/idl/xpcexception.idl b/js/xpconnect/idl/xpcexception.idl index 4806f18d39ee..6c31e424b83c 100644 --- a/js/xpconnect/idl/xpcexception.idl +++ b/js/xpconnect/idl/xpcexception.idl @@ -8,10 +8,7 @@ #include "nsIException.idl" %{ C++ -struct JSContext; -namespace JS { -class Value; -} +#include "js/TypeDecls.h" %} [ptr] native xpcexJSContextPtr(JSContext); diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h index 3c3b6d8a679e..98be9767240a 100644 --- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -16,6 +16,7 @@ #include "nsRect.h" #include "nsDeviceContext.h" #include "nsFont.h" +#include "gfxFontConstants.h" #include "nsIAtom.h" #include "nsIObserver.h" #include "nsITimer.h" diff --git a/media/mtransport/nricectx.cpp b/media/mtransport/nricectx.cpp index 953e09eab448..d300ec6f5a9f 100644 --- a/media/mtransport/nricectx.cpp +++ b/media/mtransport/nricectx.cpp @@ -318,12 +318,12 @@ RefPtr NrIceCtx::Create(const std::string& name, nr_crypto_vtbl = &nr_ice_crypto_nss_vtbl; initialized = true; - // Set the priorites for candidate type preferences - NR_reg_set_uchar((char *)"ice.pref.type.srv_rflx",100); - NR_reg_set_uchar((char *)"ice.pref.type.peer_rflx",105); - NR_reg_set_uchar((char *)"ice.pref.type.prflx",99); - NR_reg_set_uchar((char *)"ice.pref.type.host",125); - NR_reg_set_uchar((char *)"ice.pref.type.relayed",126); + // Set the priorites for candidate type preferences. + // These numbers come from RFC 5245 S. 4.1.2.2 + NR_reg_set_uchar((char *)"ice.pref.type.srv_rflx", 100); + NR_reg_set_uchar((char *)"ice.pref.type.peer_rflx", 110); + NR_reg_set_uchar((char *)"ice.pref.type.host", 126); + NR_reg_set_uchar((char *)"ice.pref.type.relayed", 0); if (set_interface_priorities) { NR_reg_set_uchar((char *)"ice.pref.interface.rl0", 255); diff --git a/media/mtransport/nricemediastream.cpp b/media/mtransport/nricemediastream.cpp index 747de3ce3ea5..25a7b3c51803 100644 --- a/media/mtransport/nricemediastream.cpp +++ b/media/mtransport/nricemediastream.cpp @@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "logging.h" #include "nsError.h" +#include "mozilla/Scoped.h" // nICEr includes extern "C" { @@ -72,6 +73,52 @@ namespace mozilla { MOZ_MTLOG_MODULE("mtransport") +// Make an NrIceCandidate from the candidate |cand|. +// This is not a member fxn because we want to hide the +// defn of nr_ice_candidate but we pass by reference. +static NrIceCandidate* MakeNrIceCandidate(const nr_ice_candidate& candc) { + ScopedDeletePtr out(new NrIceCandidate()); + + int r; + // Const-cast because the internal nICEr code isn't const-correct. + nr_ice_candidate *cand = const_cast(&candc); + char addr[INET6_ADDRSTRLEN + 1]; + + r = nr_transport_addr_get_addrstring(&cand->addr, addr, sizeof(addr)); + if (r) + return nullptr; + + int port; + r=nr_transport_addr_get_port(&cand->addr, &port); + if (r) + return nullptr; + + NrIceCandidate::Type type; + + switch(cand->type) { + case HOST: + type = NrIceCandidate::ICE_HOST; + break; + case SERVER_REFLEXIVE: + type = NrIceCandidate::ICE_SERVER_REFLEXIVE; + break; + case PEER_REFLEXIVE: + type = NrIceCandidate::ICE_PEER_REFLEXIVE; + break; + case RELAYED: + type = NrIceCandidate::ICE_RELAYED; + break; + default: + return nullptr; + } + + out->host = addr; + out->port = port; + out->type = type; + + return out.forget(); +} + // NrIceMediaStream RefPtr NrIceMediaStream::Create(NrIceCtx *ctx, @@ -150,6 +197,38 @@ nsresult NrIceMediaStream::ParseTrickleCandidate(const std::string& candidate) { return NS_OK; } +nsresult NrIceMediaStream::GetActivePair(int component, + NrIceCandidate **localp, + NrIceCandidate **remotep) { + int r; + nr_ice_candidate *local_int; + nr_ice_candidate *remote_int; + + r = nr_ice_media_stream_get_active(ctx_->peer(), + stream_, + component, + &local_int, &remote_int); + if (r) + return NS_ERROR_FAILURE; + + ScopedDeletePtr local( + MakeNrIceCandidate(*local_int)); + if (!local) + return NS_ERROR_FAILURE; + + ScopedDeletePtr remote( + MakeNrIceCandidate(*remote_int)); + if (!remote) + return NS_ERROR_FAILURE; + + if (localp) + *localp = local.forget(); + if (remotep) + *remotep = remote.forget(); + + return NS_OK; +} + void NrIceMediaStream::EmitAllCandidates() { char **attrs = 0; @@ -248,9 +327,16 @@ nsresult NrIceMediaStream::SendPacket(int component_id, void NrIceMediaStream::Ready() { - MOZ_MTLOG(ML_DEBUG, "Marking stream ready '" << name_ << "'"); - state_ = ICE_OPEN; - SignalReady(this); + // This function is called whenever a stream becomes ready, but it + // gets fired multiple times when a stream gets nominated repeatedly. + if (state_ != ICE_OPEN) { + MOZ_MTLOG(ML_DEBUG, "Marking stream ready '" << name_ << "'"); + state_ = ICE_OPEN; + SignalReady(this); + } + else { + MOZ_MTLOG(ML_DEBUG, "Stream ready callback fired again for '" << name_ << "'"); + } } void NrIceMediaStream::Close() { diff --git a/media/mtransport/nricemediastream.h b/media/mtransport/nricemediastream.h index 57082fa627f4..f23df86d7760 100644 --- a/media/mtransport/nricemediastream.h +++ b/media/mtransport/nricemediastream.h @@ -63,6 +63,21 @@ typedef struct nr_ice_media_stream_ nr_ice_media_stream; class NrIceCtx; +/* A summary of a candidate, for use in asking which candidate + pair is active */ +struct NrIceCandidate { + enum Type { + ICE_HOST, + ICE_SERVER_REFLEXIVE, + ICE_PEER_REFLEXIVE, + ICE_RELAYED + }; + + std::string host; + uint16_t port; + Type type; +}; + class NrIceMediaStream { public: static RefPtr Create(NrIceCtx *ctx, @@ -89,6 +104,14 @@ class NrIceMediaStream { // Parse trickle ICE candidate nsresult ParseTrickleCandidate(const std::string& candidate); + // Get the candidate pair currently active. It's the + // caller's responsibility to free these. + nsresult GetActivePair(int component, + NrIceCandidate** local, NrIceCandidate** remote); + + // The number of components + int components() const { return components_; } + // The underlying nICEr stream nr_ice_media_stream *stream() { return stream_; } // Signals to indicate events. API users can (and should) @@ -126,11 +149,7 @@ class NrIceMediaStream { ctx_(ctx), name_(name), components_(components), - stream_(nullptr) - { - // XXX: components_ will be used eventually; placate clang in the meantime. - (void)components_; - } + stream_(nullptr) {} DISALLOW_COPY_ASSIGN(NrIceMediaStream); diff --git a/media/mtransport/test/ice_unittest.cpp b/media/mtransport/test/ice_unittest.cpp index 39ed64af37d8..243414a58258 100644 --- a/media/mtransport/test/ice_unittest.cpp +++ b/media/mtransport/test/ice_unittest.cpp @@ -77,7 +77,9 @@ class IceTestPeer : public sigslot::has_slots<> { fake_resolver_(), dns_resolver_(new NrIceResolver()), remote_(nullptr), - candidate_filter_(nullptr) { + candidate_filter_(nullptr), + expected_local_type_(NrIceCandidate::ICE_HOST), + expected_remote_type_(NrIceCandidate::ICE_HOST) { ice_ctx_->SignalGatheringCompleted.connect(this, &IceTestPeer::GatheringComplete); ice_ctx_->SignalCompleted.connect(this, &IceTestPeer::IceCompleted); @@ -180,6 +182,11 @@ class IceTestPeer : public sigslot::has_slots<> { return candidates; } + void SetExpectedTypes(NrIceCandidate::Type local, NrIceCandidate::Type remote) { + expected_local_type_ = local; + expected_remote_type_ = remote; + } + bool gathering_complete() { return gathering_complete_; } int ready_ct() { return ready_ct_; } bool is_ready(size_t stream) { @@ -255,6 +262,57 @@ class IceTestPeer : public sigslot::has_slots<> { } } + void DumpCandidate(std::string which, const NrIceCandidate& cand) { + std::string type; + + switch(cand.type) { + case NrIceCandidate::ICE_HOST: + type = "host"; + break; + case NrIceCandidate::ICE_SERVER_REFLEXIVE: + type = "srflx"; + break; + case NrIceCandidate::ICE_PEER_REFLEXIVE: + type = "prflx"; + break; + case NrIceCandidate::ICE_RELAYED: + type = "relay"; + break; + default: + FAIL(); + }; + + std::cerr << which + << " --> " + << type + << " " + << cand.host + << ":" + << cand.port + << std::endl; + } + + void DumpAndCheckActiveCandidates() { + std::cerr << "Active candidates:" << std::endl; + for (size_t i=0; i < streams_.size(); ++i) { + for (int j=0; j < streams_[i]->components(); ++j) { + std::cerr << "Stream " << i << " component " << j+1 << std::endl; + + NrIceCandidate *local; + NrIceCandidate *remote; + + nsresult res = streams_[i]->GetActivePair(j+1, &local, &remote); + ASSERT_TRUE(NS_SUCCEEDED(res)); + DumpCandidate("Local ", *local); + ASSERT_EQ(expected_local_type_, local->type); + DumpCandidate("Remote ", *remote); + ASSERT_EQ(expected_remote_type_, remote->type); + delete local; + delete remote; + } + } + } + void Close() { test_utils->sts_target()->Dispatch( WrapRunnable(ice_ctx_, &NrIceCtx::destroy_peer_ctx), @@ -286,8 +344,8 @@ class IceTestPeer : public sigslot::has_slots<> { } void StreamReady(NrIceMediaStream *stream) { - std::cerr << "Stream ready " << stream->name() << std::endl; ++ready_ct_; + std::cerr << "Stream ready " << stream->name() << " ct=" << ready_ct_ << std::endl; } void IceCompleted(NrIceCtx *ctx) { @@ -335,6 +393,8 @@ class IceTestPeer : public sigslot::has_slots<> { nsRefPtr dns_resolver_; IceTestPeer *remote_; CandidateFilter candidate_filter_; + NrIceCandidate::Type expected_local_type_; + NrIceCandidate::Type expected_remote_type_; }; class IceGatherTest : public ::testing::Test { @@ -401,9 +461,11 @@ class IceConnectTest : public ::testing::Test { p2_->SetTurnServer(addr, port, username, password); } - void SetCandidateFilter(CandidateFilter filter) { + void SetCandidateFilter(CandidateFilter filter, bool both=true) { p1_->SetCandidateFilter(filter); - p2_->SetCandidateFilter(filter); + if (both) { + p2_->SetCandidateFilter(filter); + } } void Connect() { @@ -412,8 +474,21 @@ class IceConnectTest : public ::testing::Test { ASSERT_TRUE_WAIT(p1_->ready_ct() == 1 && p2_->ready_ct() == 1, 5000); ASSERT_TRUE_WAIT(p1_->ice_complete() && p2_->ice_complete(), 5000); + + p1_->DumpAndCheckActiveCandidates(); + p2_->DumpAndCheckActiveCandidates(); } + void SetExpectedTypes(NrIceCandidate::Type local, NrIceCandidate::Type remote) { + p1_->SetExpectedTypes(local, remote); + p2_->SetExpectedTypes(local, remote); + } + + void SetExpectedTypes(NrIceCandidate::Type local1, NrIceCandidate::Type remote1, + NrIceCandidate::Type local2, NrIceCandidate::Type remote2) { + p1_->SetExpectedTypes(local1, remote1); + p2_->SetExpectedTypes(local2, remote2); + } void ConnectP1(TrickleMode mode = TRICKLE_NONE) { p1_->Connect(p2_, mode); @@ -700,6 +775,8 @@ TEST_F(IceConnectTest, TestConnectTurnOnly) { g_turn_user, g_turn_password); ASSERT_TRUE(Gather(true)); SetCandidateFilter(IsRelayCandidate); + SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED, + NrIceCandidate::Type::ICE_RELAYED); Connect(); } @@ -712,6 +789,8 @@ TEST_F(IceConnectTest, TestSendReceiveTurnOnly) { g_turn_user, g_turn_password); ASSERT_TRUE(Gather(true)); SetCandidateFilter(IsRelayCandidate); + SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED, + NrIceCandidate::Type::ICE_RELAYED); Connect(); SendReceive(); } diff --git a/media/mtransport/test/turn_unittest.cpp b/media/mtransport/test/turn_unittest.cpp index 89c54c6a352c..d5e6c3f5024c 100644 --- a/media/mtransport/test/turn_unittest.cpp +++ b/media/mtransport/test/turn_unittest.cpp @@ -315,6 +315,10 @@ TEST_F(TurnClient, SendToSelf) { Allocate(); SendTo(relay_addr_); ASSERT_TRUE_WAIT(received() == 100, 1000); + PR_Sleep(10000); // Wait 10 seconds to make sure the + // CreatePermission has time to complete/fail. + SendTo(relay_addr_); + ASSERT_TRUE_WAIT(received() == 200, 1000); } TEST_F(TurnClient, AllocateDummyServer) { diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_component.c b/media/mtransport/third_party/nICEr/src/ice/ice_component.c index 95aa1b76ff56..1492729c7d11 100644 --- a/media/mtransport/third_party/nICEr/src/ice/ice_component.c +++ b/media/mtransport/third_party/nICEr/src/ice/ice_component.c @@ -799,10 +799,13 @@ int nr_ice_component_nominated_pair(nr_ice_component *comp, nr_ice_cand_pair *pa r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s)/comp(%d): cancelling all pairs but %s (0x%p)",comp->stream->pctx->label,comp->stream->label,comp->component_id,pair->as_string,pair); - /* OK, we need to cancel off everything on this component */ + /* Cancel checks in WAITING and FROZEN per ICE S 8.1.2 */ p2=TAILQ_FIRST(&comp->stream->check_list); while(p2){ - if((p2 != pair) && (p2->remote->component->component_id == comp->component_id)){ + if((p2 != pair) && + (p2->remote->component->component_id == comp->component_id) && + ((p2->state == NR_ICE_PAIR_STATE_FROZEN) || + (p2->state == NR_ICE_PAIR_STATE_WAITING))) { r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s)/comp(%d): cancelling pair %s (0x%p)",comp->stream->pctx->label,comp->stream->label,comp->component_id,p2->as_string,p2); if(r=nr_ice_candidate_pair_cancel(pair->pctx,p2)) diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c b/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c index 1804b5196e6e..af88d9821d16 100644 --- a/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c +++ b/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c @@ -295,7 +295,6 @@ int nr_ice_media_stream_service_pre_answer_requests(nr_ice_peer_ctx *pctx, nr_ic nr_ice_component *pcomp; int r,_status; char *user = 0; - char *lufrag, *rufrag; if (serviced) *serviced = 0; @@ -698,7 +697,6 @@ int nr_ice_media_stream_find_component(nr_ice_media_stream *str, int comp_id, nr return(_status); } - int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, UCHAR *data, int len) { int r,_status; @@ -710,7 +708,7 @@ int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, in /* Do we have an active pair yet? We should... */ if(!comp->active) - ABORT(R_BAD_ARGS); + ABORT(R_NOT_FOUND); /* OK, write to that pair, which means: 1. Use the socket on our local side. @@ -718,7 +716,7 @@ int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, in */ comp->keepalive_needed=0; /* Suppress keepalives */ if(r=nr_socket_sendto(comp->active->local->osock,data,len,0, - &comp->active->remote->addr)) + &comp->active->remote->addr)) ABORT(r); _status=0; @@ -726,6 +724,25 @@ int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, in return(_status); } +int nr_ice_media_stream_get_active(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_ice_candidate **local, nr_ice_candidate **remote) + { + int r,_status; + nr_ice_component *comp; + + /* First find the peer component */ + if(r=nr_ice_peer_ctx_find_component(pctx, str, component, &comp)) + ABORT(r); + + if(!comp->active) + ABORT(R_NOT_FOUND); + + if (local) *local = comp->active->local; + if (remote) *remote = comp->active->remote; + + _status=0; + abort: + return(_status); + } int nr_ice_media_stream_addrs(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_transport_addr *local, nr_transport_addr *remote) { diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.h b/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.h index eeabce63a8ae..a71d07bc43c5 100644 --- a/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.h +++ b/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.h @@ -88,7 +88,8 @@ int nr_ice_media_stream_component_nominated(nr_ice_media_stream *stream,nr_ice_c int nr_ice_media_stream_component_failed(nr_ice_media_stream *stream,nr_ice_component *component); int nr_ice_media_stream_set_state(nr_ice_media_stream *str, int state); int nr_ice_media_stream_get_best_candidate(nr_ice_media_stream *str, int component, nr_ice_candidate **candp); -int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx,nr_ice_media_stream *str, int component, UCHAR *data, int len); +int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, UCHAR *data, int len); +int nr_ice_media_stream_get_active(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_ice_candidate **local, nr_ice_candidate **remote); int nr_ice_media_stream_find_component(nr_ice_media_stream *str, int comp_id, nr_ice_component **compp); int nr_ice_media_stream_addrs(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_transport_addr *local, nr_transport_addr *remote); int diff --git a/media/mtransport/third_party/nICEr/src/stun/stun_proc.c b/media/mtransport/third_party/nICEr/src/stun/stun_proc.c index 03888bb964ac..d925553fc284 100644 --- a/media/mtransport/third_party/nICEr/src/stun/stun_proc.c +++ b/media/mtransport/third_party/nICEr/src/stun/stun_proc.c @@ -89,7 +89,7 @@ nr_stun_receive_message(nr_stun_message *req, nr_stun_message *msg) } if (NR_STUN_GET_TYPE_METHOD(req->header.type) != NR_STUN_GET_TYPE_METHOD(msg->header.type)) { - r_log(NR_LOG_STUN,LOG_NOTICE,"Inconsistent message method: %03x", msg->header.type); + r_log(NR_LOG_STUN,LOG_NOTICE,"Inconsistent message method: %03x expected %03x", msg->header.type, req->header.type); ABORT(R_REJECTED); } diff --git a/media/mtransport/third_party/nICEr/src/stun/turn_client_ctx.c b/media/mtransport/third_party/nICEr/src/stun/turn_client_ctx.c index fcdf06f85146..3c8135b0060b 100644 --- a/media/mtransport/third_party/nICEr/src/stun/turn_client_ctx.c +++ b/media/mtransport/third_party/nICEr/src/stun/turn_client_ctx.c @@ -176,6 +176,11 @@ static int nr_turn_stun_set_auth_params(nr_turn_stun_ctx *ctx, if (!ctx->nonce) ABORT(R_NO_MEMORY); + RFREE(ctx->stun->realm); + ctx->stun->realm = r_strdup(ctx->realm); + if (!ctx->stun->realm) + ABORT(R_NO_MEMORY); + ctx->stun->auth_params.realm = ctx->realm; ctx->stun->auth_params.nonce = ctx->nonce; ctx->stun->auth_params.authenticate = 1; /* May already be 1 */ diff --git a/netwerk/base/src/ProxyAutoConfig.h b/netwerk/base/src/ProxyAutoConfig.h index 92e0c66099d3..2e322c73358d 100644 --- a/netwerk/base/src/ProxyAutoConfig.h +++ b/netwerk/base/src/ProxyAutoConfig.h @@ -12,10 +12,7 @@ #include "nsITimer.h" #include "nsAutoPtr.h" #include "mozilla/net/DNS.h" - -namespace JS { -class Value; -} +#include "js/TypeDecls.h" namespace mozilla { namespace net { diff --git a/netwerk/base/src/nsSocketTransportService2.cpp b/netwerk/base/src/nsSocketTransportService2.cpp index 9aa2e5331419..d2eff6f4d6a6 100644 --- a/netwerk/base/src/nsSocketTransportService2.cpp +++ b/netwerk/base/src/nsSocketTransportService2.cpp @@ -1051,10 +1051,14 @@ nsSocketTransportService::DiscoverMaxCount() return PR_SUCCESS; } + +// Used to return connection info to Dashboard.cpp void nsSocketTransportService::AnalyzeConnection(nsTArray *data, struct SocketContext *context, bool aActive) { + if (context->mHandler->mIsPrivate) + return; PRFileDesc *aFD = context->mFD; bool tcp = (PR_GetDescType(aFD) == PR_DESC_SOCKET_TCP); diff --git a/netwerk/dns/nsDNSService2.cpp b/netwerk/dns/nsDNSService2.cpp index 1250af9df5b3..1f792fae6de9 100644 --- a/netwerk/dns/nsDNSService2.cpp +++ b/netwerk/dns/nsDNSService2.cpp @@ -29,6 +29,7 @@ #include "nsCharSeparatedTokenizer.h" #include "nsNetAddr.h" #include "nsProxyRelease.h" +#include "nsIObserverService.h" #include "mozilla/Attributes.h" #include "mozilla/VisualEventTracer.h" @@ -433,6 +434,13 @@ nsDNSService::Init() // If a manual proxy is in use, disable prefetch implicitly prefs->AddObserver("network.proxy.type", this, false); } + + nsresult rv; + nsCOMPtr observerService = + do_GetService("@mozilla.org/observer-service;1", &rv); + if (NS_SUCCEEDED(rv)) { + observerService->AddObserver(this, "last-pb-context-exited", false); + } } nsDNSPrefetch::Initialize(this); @@ -782,7 +790,8 @@ NS_IMETHODIMP nsDNSService::Observe(nsISupports *subject, const char *topic, const PRUnichar *data) { // we are only getting called if a preference has changed. - NS_ASSERTION(strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0, + NS_ASSERTION(strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0 || + strcmp(topic, "last-pb-context-exited") == 0, "unexpected observe call"); // diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index c2f2865ac1cf..ae69f4f8f4d2 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -3343,6 +3343,9 @@ nsHttpConnectionMgr::ReadConnectionEntry(const nsACString &key, nsAutoPtr &ent, void *aArg) { + if (ent->mConnInfo->GetPrivate()) + return PL_DHASH_NEXT; + nsTArray *args = static_cast *> (aArg); HttpRetParams data; data.host = ent->mConnInfo->Host(); diff --git a/netwerk/protocol/websocket/WebSocketChannel.cpp b/netwerk/protocol/websocket/WebSocketChannel.cpp index a8050b2553d6..0003e2cd82db 100644 --- a/netwerk/protocol/websocket/WebSocketChannel.cpp +++ b/netwerk/protocol/websocket/WebSocketChannel.cpp @@ -952,6 +952,7 @@ WebSocketChannel::WebSocketChannel() : mCompressor(nullptr), mDynamicOutputSize(0), mDynamicOutput(nullptr), + mPrivateBrowsing(false), mConnectionLogService(nullptr) { NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread"); @@ -1328,7 +1329,7 @@ WebSocketChannel::ProcessInput(uint8_t *buffer, uint32_t count) NS_DispatchToMainThread(new CallOnMessageAvailable(this, utf8Data, -1)); nsresult rv; - if (mConnectionLogService) { + if (mConnectionLogService && !mPrivateBrowsing) { nsAutoCString host; rv = mURI->GetHostPort(host); if (NS_SUCCEEDED(rv)) { @@ -1419,7 +1420,7 @@ WebSocketChannel::ProcessInput(uint8_t *buffer, uint32_t count) payloadLength)); // To add the header to 'Networking Dashboard' log nsresult rv; - if (mConnectionLogService) { + if (mConnectionLogService && !mPrivateBrowsing) { nsAutoCString host; rv = mURI->GetHostPort(host); if (NS_SUCCEEDED(rv)) { @@ -1844,7 +1845,7 @@ WebSocketChannel::CleanupConnection() } nsresult rv; - if (mConnectionLogService) { + if (mConnectionLogService && !mPrivateBrowsing) { nsAutoCString host; rv = mURI->GetHostPort(host); if (NS_SUCCEEDED(rv)) @@ -2678,7 +2679,9 @@ WebSocketChannel::AsyncOpen(nsIURI *aURI, if (NS_FAILED(rv)) return rv; - if (mConnectionLogService) { + mPrivateBrowsing = NS_UsePrivateBrowsing(localChannel); + + if (mConnectionLogService && !mPrivateBrowsing) { nsAutoCString host; rv = mURI->GetHostPort(host); if (NS_SUCCEEDED(rv)) { @@ -2783,7 +2786,7 @@ WebSocketChannel::SendMsgCommon(const nsACString *aMsg, bool aIsBinary, } nsresult rv; - if (mConnectionLogService) { + if (mConnectionLogService && !mPrivateBrowsing) { nsAutoCString host; rv = mURI->GetHostPort(host); if (NS_SUCCEEDED(rv)) { diff --git a/netwerk/protocol/websocket/WebSocketChannel.h b/netwerk/protocol/websocket/WebSocketChannel.h index 0bf902957efd..1af942b7944c 100644 --- a/netwerk/protocol/websocket/WebSocketChannel.h +++ b/netwerk/protocol/websocket/WebSocketChannel.h @@ -247,6 +247,7 @@ private: nsWSCompression *mCompressor; uint32_t mDynamicOutputSize; uint8_t *mDynamicOutput; + bool mPrivateBrowsing; nsCOMPtr mConnectionLogService; uint32_t mSerial; diff --git a/netwerk/test/unit/test_cache_jar.js b/netwerk/test/unit/test_cache_jar.js index fe6d1f628aaf..de4a354fecf3 100644 --- a/netwerk/test/unit/test_cache_jar.js +++ b/netwerk/test/unit/test_cache_jar.js @@ -48,7 +48,7 @@ function run_all_tests() { handlers_called = 0; var chan = makeChan(URL, test[0], test[1]); chan.asyncOpen(new ChannelListener(doneFirstLoad, test[2]), null); - yield; + yield undefined; } // We can't easily cause webapp data to be cleared from the child process, so skip @@ -68,7 +68,7 @@ function run_all_tests() { handlers_called = 0; var chan = makeChan(URL, test[0], test[1]); chan.asyncOpen(new ChannelListener(doneFirstLoad, test[2]), null); - yield; + yield undefined; } subject = { @@ -82,7 +82,7 @@ function run_all_tests() { handlers_called = 0; var chan = makeChan(URL, test[0], test[1]); chan.asyncOpen(new ChannelListener(doneFirstLoad, test[2]), null); - yield; + yield undefined; } } diff --git a/python/mozbuild/mozbuild/base.py b/python/mozbuild/mozbuild/base.py index 6acf2a589a33..40399cb33fbb 100644 --- a/python/mozbuild/mozbuild/base.py +++ b/python/mozbuild/mozbuild/base.py @@ -164,11 +164,12 @@ class MozbuildObject(ProcessExecutionMixin): # not another one. This prevents accidental usage of the wrong objdir # when the current objdir is ambiguous. if topobjdir and config_topobjdir \ - and not samepath(topobjdir, config_topobjdir): + and not samepath(topobjdir, config_topobjdir) \ + and not samepath(topobjdir, os.path.join(config_topobjdir, "mozilla")): raise ObjdirMismatchException(topobjdir, config_topobjdir) - topobjdir = config_topobjdir or topobjdir + topobjdir = topobjdir or config_topobjdir if topobjdir: topobjdir = os.path.normpath(topobjdir) diff --git a/security/manager/boot/src/nsSTSPreloadList.errors b/security/manager/boot/src/nsSTSPreloadList.errors index 2f378c5b9a71..62aff5175df4 100644 --- a/security/manager/boot/src/nsSTSPreloadList.errors +++ b/security/manager/boot/src/nsSTSPreloadList.errors @@ -5,6 +5,7 @@ api.recurly.com: did not receive HSTS header api.simple.com: did not receive HSTS header apis.google.com: did not receive HSTS header appengine.google.com: did not receive HSTS header +bcrook.com: max-age too low: 86400 betnet.fr: could not connect to host bigshinylock.minazo.net: could not connect to host blueseed.co: did not receive HSTS header @@ -18,7 +19,6 @@ chrome-devtools-frontend.appspot.com: did not receive HSTS header chrome.google.com: did not receive HSTS header code.google.com: did not receive HSTS header codereview.chromium.org: did not receive HSTS header -crypto.cat: could not connect to host crypto.is: did not receive HSTS header csawctf.poly.edu: did not receive HSTS header dl.google.com: did not receive HSTS header @@ -35,7 +35,7 @@ gmail.com: did not receive HSTS header gocardless.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-hsts-000000000000000/getHSTSPreloadList.js :: processStsHeader :: line 124" data: no] googlemail.com: did not receive HSTS header googleplex.com: could not connect to host -greplin.com: did not receive HSTS header +greplin.com: could not connect to host grepular.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-hsts-000000000000000/getHSTSPreloadList.js :: processStsHeader :: line 124" data: no] groups.google.com: did not receive HSTS header health.google.com: did not receive HSTS header @@ -57,7 +57,6 @@ neonisi.com: could not connect to host openshift.redhat.com: did not receive HSTS header ottospora.nl: could not connect to host packagist.org: max-age too low: 2592000 -passwd.io: could not connect to host paypal.com: max-age too low: 14400 piratenlogin.de: could not connect to host plus.google.com: did not receive HSTS header @@ -91,7 +90,7 @@ www.elanex.biz: did not receive HSTS header www.gmail.com: did not receive HSTS header www.googlemail.com: did not receive HSTS header www.gov.uk: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-hsts-000000000000000/getHSTSPreloadList.js :: processStsHeader :: line 124" data: no] -www.greplin.com: did not receive HSTS header +www.greplin.com: could not connect to host www.jitsi.org: did not receive HSTS header www.lastpass.com: did not receive HSTS header www.ledgerscope.net: max-age too low: 86400 diff --git a/security/manager/boot/src/nsSTSPreloadList.inc b/security/manager/boot/src/nsSTSPreloadList.inc index 8cadfb0bb5e5..43236bf51a79 100644 --- a/security/manager/boot/src/nsSTSPreloadList.inc +++ b/security/manager/boot/src/nsSTSPreloadList.inc @@ -8,7 +8,7 @@ /*****************************************************************************/ #include -const PRTime gPreloadListExpirationTime = INT64_C(1388225223906000); +const PRTime gPreloadListExpirationTime = INT64_C(1388829945161000); class nsSTSPreload { @@ -34,6 +34,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "carezone.com", false }, { "check.torproject.org", false }, { "chromiumcodereview.appspot.com", false }, + { "cloudns.com.au", true }, { "cloudsecurityalliance.org", true }, { "codereview.appspot.com", false }, { "conformal.com", true }, @@ -70,6 +71,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "login.persona.org", true }, { "login.sapo.pt", true }, { "logotype.se", true }, + { "lolicore.ch", true }, { "lookout.com", false }, { "luneta.nearbuysystems.com", false }, { "makeyourlaws.org", true }, @@ -83,6 +85,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "my.onlime.ch", false }, { "mylookout.com", false }, { "neg9.org", false }, + { "oplop.appspot.com", true }, { "p.linode.com", false }, { "passwd.io", true }, { "paste.linode.com", false }, diff --git a/storage/src/mozStoragePrivateHelpers.h b/storage/src/mozStoragePrivateHelpers.h index a82a5c4d8f49..2f8253b4c0dd 100644 --- a/storage/src/mozStoragePrivateHelpers.h +++ b/storage/src/mozStoragePrivateHelpers.h @@ -15,16 +15,13 @@ #include "nsIVariant.h" #include "nsError.h" #include "nsAutoPtr.h" +#include "js/TypeDecls.h" class mozIStorageCompletionCallback; class mozIStorageBaseStatement; class mozIStorageBindingParams; class nsIRunnable; -namespace JS { -class Value; -} - namespace mozilla { namespace storage { diff --git a/testing/mochitest/android.json b/testing/mochitest/android.json index cfdefb9351bb..7f944f1ccc8b 100644 --- a/testing/mochitest/android.json +++ b/testing/mochitest/android.json @@ -108,7 +108,6 @@ "content/xul/content/test/test_bug486990.xul": "TIMED_OUT", "docshell/test/navigation/test_bug13871.html": "RANDOM", "docshell/test/navigation/test_bug430723.html": "TIMED_OUT", - "docshell/test/navigation/test_popup-navigates-children.html": "bug 783589", "docshell/test/navigation/test_sessionhistory.html": "RANDOM", "docshell/test/navigation/test_bug344861.html": "", "docshell/test/test_bug413310.html": "", diff --git a/testing/mochitest/androidx86.json b/testing/mochitest/androidx86.json index 0ce6874c926a..3e2324b70122 100644 --- a/testing/mochitest/androidx86.json +++ b/testing/mochitest/androidx86.json @@ -112,7 +112,6 @@ "docshell/test/navigation/test_bug13871.html": "RANDOM", "docshell/test/navigation/test_bug430723.html": "TIMED_OUT", "docshell/test/navigation/test_not-opener.html": "x86 only", - "docshell/test/navigation/test_popup-navigates-children.html": "bug 783589", "docshell/test/navigation/test_sessionhistory.html": "RANDOM", "docshell/test/navigation/test_bug344861.html": "", "docshell/test/test_bug413310.html": "", diff --git a/testing/mochitest/b2g.json b/testing/mochitest/b2g.json index b465be7b247c..e695c57d37cc 100644 --- a/testing/mochitest/b2g.json +++ b/testing/mochitest/b2g.json @@ -332,7 +332,6 @@ "content/base/test/test_bug166235.html":"clipboard undefined", "dom/tests/mochitest/general/test_idleapi_permissions.html":"", - "dom/tests/mochitest/general/test_interfaces.html":"", "dom/tests/mochitest/general/test_paste_selection.html":"No clipboard", "dom/tests/mochitest/geolocation/test_allowCurrent.html":"Bug 910235 - Error: no message manager set when calling method: [nsIObserver::observe]", diff --git a/testing/xpcshell/runxpcshelltests.py b/testing/xpcshell/runxpcshelltests.py index fb95b44765fa..3f4b68693ff6 100644 --- a/testing/xpcshell/runxpcshelltests.py +++ b/testing/xpcshell/runxpcshelltests.py @@ -483,6 +483,14 @@ class XPCShellTestThread(Thread): for part in output: # For multi-line output, such as a stack trace for line in part.splitlines(): + try: + line = line.decode('utf-8') + except UnicodeDecodeError: + self.log.info("TEST-INFO | %s | Detected non UTF-8 output."\ + " Please modify the test to only print UTF-8." % + self.test_object['name']) + # add '?' instead of funky bytes + line = line.decode('utf-8', 'replace') self.log.info(line) self.log.info("<<<<<<<") diff --git a/toolkit/mozapps/update/test/unit/test_0202_app_launch_apply_update_dirlocked.js b/toolkit/mozapps/update/test/unit/test_0202_app_launch_apply_update_dirlocked.js index 500b9003aed3..f464ec8fc369 100644 --- a/toolkit/mozapps/update/test/unit/test_0202_app_launch_apply_update_dirlocked.js +++ b/toolkit/mozapps/update/test/unit/test_0202_app_launch_apply_update_dirlocked.js @@ -104,6 +104,17 @@ function run_test() { return; } + if (IS_WIN) { + var version = AUS_Cc["@mozilla.org/system-info;1"] + .getService(AUS_Ci.nsIPropertyBag2) + .getProperty("version"); + var isVistaOrHigher = (parseFloat(version) >= 6.0); + if (!isVistaOrHigher) { + logTestInfo("Disabled on Windows XP due to bug 909489"); + return; + } + } + do_test_pending(); do_register_cleanup(end_test); diff --git a/tools/profiler/GeckoProfiler.h b/tools/profiler/GeckoProfiler.h index 9dbc43253d07..8cc8594621f7 100644 --- a/tools/profiler/GeckoProfiler.h +++ b/tools/profiler/GeckoProfiler.h @@ -50,6 +50,7 @@ #define SAMPLER_H #include "mozilla/NullPtr.h" +#include "js/TypeDecls.h" namespace mozilla { class TimeStamp; @@ -59,9 +60,6 @@ class TimeStamp; #include -struct JSContext; -class JSObject; - // Insert a RAII in this scope to active a pseudo label. Any samples collected // in this scope will contain this annotation. For dynamic strings use // PROFILER_LABEL_PRINTF. Arguments must be string literals. diff --git a/tools/profiler/GeckoProfilerFunc.h b/tools/profiler/GeckoProfilerFunc.h index 56e1410cfeb2..d145169db189 100644 --- a/tools/profiler/GeckoProfilerFunc.h +++ b/tools/profiler/GeckoProfilerFunc.h @@ -7,6 +7,7 @@ #define PROFILER_FUNCS_H #include "mozilla/NullPtr.h" +#include "js/TypeDecls.h" #include namespace mozilla { @@ -17,9 +18,6 @@ class TimeStamp; using mozilla::TimeStamp; using mozilla::TimeDuration; -struct JSContext; -class JSObject; - // Returns a handle to pass on exit. This can check that we are popping the // correct callstack. inline void* mozilla_sampler_call_enter(const char *aInfo, void *aFrameAddress = NULL, diff --git a/tools/profiler/JSObjectBuilder.h b/tools/profiler/JSObjectBuilder.h index 3f597d742c7d..6be8da1a98d9 100644 --- a/tools/profiler/JSObjectBuilder.h +++ b/tools/profiler/JSObjectBuilder.h @@ -7,11 +7,10 @@ #define JSOBJECTBUILDER_H #include "JSAObjectBuilder.h" +#include "js/TypeDecls.h" class JSCustomObject; class JSCustomObjectBuilder; -struct JSContext; -class JSObject; class nsAString; /* this is handy wrapper around JSAPI to make it more pleasant to use. diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 8fb77d115aae..389861765c69 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -37,7 +37,6 @@ using mozilla::unused; #include "gfxContext.h" #include "Layers.h" -#include "BasicLayers.h" #include "LayerManagerOGL.h" #include "mozilla/layers/LayerManagerComposite.h" #include "mozilla/layers/AsyncCompositionManager.h" diff --git a/widget/gtk2/nsWindow.cpp b/widget/gtk2/nsWindow.cpp index 7aef5ad26bee..d944c5f00704 100644 --- a/widget/gtk2/nsWindow.cpp +++ b/widget/gtk2/nsWindow.cpp @@ -90,7 +90,6 @@ using namespace mozilla::widget; #include "nsImageToPixbuf.h" #include "nsIInterfaceRequestorUtils.h" #include "nsAutoPtr.h" -#include "BasicLayers.h" #include "ClientLayerManager.h" extern "C" { @@ -6128,8 +6127,7 @@ nsWindow::ClearCachedResources() { if (mLayerManager && mLayerManager->GetBackendType() == mozilla::layers::LAYERS_BASIC) { - static_cast (mLayerManager.get())-> - ClearCachedResources(); + mLayerManager->ClearCachedResources(); } GList* children = gdk_window_peek_children(mGdkWindow); diff --git a/widget/qt/nsWindow.cpp b/widget/qt/nsWindow.cpp index 02d57ea8d770..1791e343abcb 100644 --- a/widget/qt/nsWindow.cpp +++ b/widget/qt/nsWindow.cpp @@ -95,7 +95,6 @@ using namespace QtMobility; #include "gfxUtils.h" #include "Layers.h" #include "GLContextProvider.h" -#include "BasicLayers.h" #include "LayerManagerOGL.h" #include "nsFastStartupQt.h" @@ -441,8 +440,7 @@ nsWindow::ClearCachedResources() { if (mLayerManager && mLayerManager->GetBackendType() == mozilla::layers::LAYERS_BASIC) { - static_cast (mLayerManager.get())-> - ClearCachedResources(); + statimLayerManager->ClearCachedResources(); } for (nsIWidget* kid = mFirstChild; kid; ) { nsIWidget* next = kid->GetNextSibling(); diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 751b95d42c52..8c1bbbbfb2eb 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -134,7 +134,6 @@ #include "LayerManagerOGL.h" #include "nsIGfxInfo.h" -#include "BasicLayers.h" #include "nsUXThemeConstants.h" #include "KeyboardLayout.h" #include "nsNativeDragTarget.h" @@ -7176,8 +7175,7 @@ nsWindow::ClearCachedResources() #endif if (mLayerManager && mLayerManager->GetBackendType() == LAYERS_BASIC) { - static_cast(mLayerManager.get())-> - ClearCachedResources(); + mLayerManager->ClearCachedResources(); } ::EnumChildWindows(mWnd, nsWindow::ClearResourcesCallback, 0); } diff --git a/widget/windows/nsWindowGfx.cpp b/widget/windows/nsWindowGfx.cpp index 8095475f57e5..1c6535bc4c5d 100644 --- a/widget/windows/nsWindowGfx.cpp +++ b/widget/windows/nsWindowGfx.cpp @@ -38,7 +38,6 @@ using mozilla::plugins::PluginInstanceParent; #include "mozilla/unused.h" #include "LayerManagerOGL.h" -#include "BasicLayers.h" #ifdef MOZ_ENABLE_D3D9_LAYER #include "LayerManagerD3D9.h" #endif diff --git a/widget/xpwidgets/nsBaseWidget.cpp b/widget/xpwidgets/nsBaseWidget.cpp index ee2d3b6ca828..ccab14b55520 100644 --- a/widget/xpwidgets/nsBaseWidget.cpp +++ b/widget/xpwidgets/nsBaseWidget.cpp @@ -1050,7 +1050,7 @@ LayerManager* nsBaseWidget::GetLayerManager(PLayerTransactionChild* aShadowManag return usedLayerManager; } -BasicLayerManager* nsBaseWidget::CreateBasicLayerManager() +LayerManager* nsBaseWidget::CreateBasicLayerManager() { return new BasicLayerManager(this); } diff --git a/widget/xpwidgets/nsBaseWidget.h b/widget/xpwidgets/nsBaseWidget.h index 292a10cb6c24..354874152e0d 100644 --- a/widget/xpwidgets/nsBaseWidget.h +++ b/widget/xpwidgets/nsBaseWidget.h @@ -332,7 +332,7 @@ protected: return widget.forget(); } - BasicLayerManager* CreateBasicLayerManager(); + LayerManager* CreateBasicLayerManager(); nsPopupType PopupType() const { return mPopupType; } diff --git a/xpcom/build/nsXULAppAPI.h b/xpcom/build/nsXULAppAPI.h index 590a5738080e..783ff2026529 100644 --- a/xpcom/build/nsXULAppAPI.h +++ b/xpcom/build/nsXULAppAPI.h @@ -12,6 +12,7 @@ #include "nsISupports.h" #include "prlog.h" #include "nsXREAppData.h" +#include "js/TypeDecls.h" #include "mozilla/Assertions.h" @@ -426,15 +427,10 @@ XRE_API(void, XRE_API(MessageLoop*, XRE_GetIOMessageLoop, ()) -struct JSContext; -class JSString; - XRE_API(bool, XRE_SendTestShellCommand, (JSContext* aCx, JSString* aCommand, void* aCallback)) -class JSObject; - XRE_API(bool, XRE_ShutdownTestShell, ()) diff --git a/xpcom/ds/nsStaticNameTable.h b/xpcom/ds/nsStaticNameTable.h index 379b7712cb75..6616c770e6be 100644 --- a/xpcom/ds/nsStaticNameTable.h +++ b/xpcom/ds/nsStaticNameTable.h @@ -10,6 +10,8 @@ #define nsStaticNameTable_h___ #include "pldhash.h" +#include "nsString.h" + /* This class supports case insensitive lookup. * * It differs from atom tables: diff --git a/xpfe/appshell/public/nsIAppShellService.idl b/xpfe/appshell/public/nsIAppShellService.idl index c29483c2cc2a..7a2fa8c67495 100644 --- a/xpfe/appshell/public/nsIAppShellService.idl +++ b/xpfe/appshell/public/nsIAppShellService.idl @@ -14,7 +14,7 @@ interface nsIAppShell; [ptr] native JSContext(JSContext); %{C++ -struct JSContext; +#include "js/TypeDecls.h" %} [scriptable, uuid(5c19ab54-67bf-46d0-ac5b-21abd9050c3b)]