Merge mozilla-central and inbound

This commit is contained in:
Ed Morley 2013-09-19 18:43:55 +01:00
commit 9e1f94393c
158 changed files with 2181 additions and 754 deletions

View File

@ -2,11 +2,13 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
# Disabled for too many intermittent failures (bug 895390)
# browser_privatebrowsing_cache.js \
MOCHITEST_BROWSER_FILES = \ MOCHITEST_BROWSER_FILES = \
head.js \ head.js \
browser_privatebrowsing_aboutHomeButtonAfterWindowClose.js \ browser_privatebrowsing_aboutHomeButtonAfterWindowClose.js \
browser_privatebrowsing_aboutSessionRestore.js \ browser_privatebrowsing_aboutSessionRestore.js \
browser_privatebrowsing_cache.js \
browser_privatebrowsing_certexceptionsui.js \ browser_privatebrowsing_certexceptionsui.js \
browser_privatebrowsing_concurrent.js \ browser_privatebrowsing_concurrent.js \
browser_privatebrowsing_concurrent_page.html \ browser_privatebrowsing_concurrent_page.html \

View File

@ -8,10 +8,13 @@ MOCHITEST_BROWSER_FILES := \
browser_bug400731.js \ browser_bug400731.js \
$(NULL) $(NULL)
# The browser chrome test for bug 415846 doesn't run on Mac because of its
# bizarre special-and-unique snowflake of a help menu. # browser_bug415846.js disabled for too many intermittent failures (bug 546169)
ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT)) #
MOCHITEST_BROWSER_FILES += \ # # The browser chrome test for bug 415846 doesn't run on Mac because of its
browser_bug415846.js \ # # bizarre special-and-unique snowflake of a help menu.
$(NULL) # ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
endif # MOCHITEST_BROWSER_FILES += \
# browser_bug415846.js \
# $(NULL)
# endif

View File

@ -1,18 +1,25 @@
if [ -d "/c/Program Files (x86)/Microsoft Visual Studio 10.0" ]; then
_VSPATH="/c/Program Files (x86)/Microsoft Visual Studio 10.0"
else
_VSPATH="/c/tools/msvs10"
fi
## SDK redist ## ## SDK redist ##
export WIN32_REDIST_DIR=/c/tools/msvs10/VC/redist/x86/Microsoft.VC100.CRT export WIN32_REDIST_DIR=${_VSPATH}/VC/redist/x86/Microsoft.VC100.CRT
## moz tools location for 64-bit builders ## ## moz tools location for 64-bit builders ##
export MOZ_TOOLS=C:/mozilla-build/moztools export MOZ_TOOLS=C:/mozilla-build/moztools
## includes: win8 sdk includes, winrt headers for metro, msvc 10 std library, directx sdk for d3d9 ## ## includes: win8 sdk includes, winrt headers for metro, msvc 10 std library, directx sdk for d3d9 ##
export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl/wrappers:/c/tools/msvs10/vc/include:/c/tools/msvs10/vc/atlmfc/include:/c/tools/sdks/dx10/include export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl/wrappers:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include
## libs: win8 sdk x86 (32-bit) libs, msvc 10 (32-bit) std library, msvc 10 atl libs, directx sdk (32-bit) for d3d9 ## ## libs: win8 sdk x86 (32-bit) libs, msvc 10 (32-bit) std library, msvc 10 atl libs, directx sdk (32-bit) for d3d9 ##
export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x86:/c/tools/msvs10/vc/lib:/c/tools/msvs10/vc/atlmfc/lib:/c/tools/sdks/dx10/lib export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x86:${_VSPATH}/vc/lib:${_VSPATH}/vc/atlmfc/lib:/c/tools/sdks/dx10/lib
export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x86:/c/tools/msvs10/vc/lib:/c/tools/msvs10/vc/atlmfc/lib:/c/tools/sdks/dx10/lib export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x86:${_VSPATH}/vc/lib:${_VSPATH}/vc/atlmfc/lib:/c/tools/sdks/dx10/lib
## paths: win8 sdk x86 (32-bit) tools, msvc 10 (32-bit) build toolchain, moz tools ## ## paths: win8 sdk x86 (32-bit) tools, msvc 10 (32-bit) build toolchain, moz tools ##
export PATH="/c/Program Files (x86)/Windows Kits/8.0/bin/x86:/c/tools/msvs10/Common7/IDE:/c/tools/msvs10/VC/BIN:/c/tools/msvs10/Common7/Tools:/c/tools/msvs10/VC/VCPackages:/c/mozilla-build/moztools:${PATH}" export PATH="/c/Program Files (x86)/Windows Kits/8.0/bin/x86:${_VSPATH}/Common7/IDE:${_VSPATH}/VC/BIN:${_VSPATH}/Common7/Tools:${_VSPATH}/VC/VCPackages:/c/mozilla-build/moztools:${PATH}"
. $topsrcdir/build/mozconfig.vs2010-common . $topsrcdir/build/mozconfig.vs2010-common

View File

@ -1,15 +1,22 @@
if [ -d "/c/Program Files (x86)/Microsoft Visual Studio 10.0" ]; then
_VSPATH="/c/Program Files (x86)/Microsoft Visual Studio 10.0"
else
_VSPATH="/c/tools/msvs10"
fi
## SDK redist ## ## SDK redist ##
export WIN32_REDIST_DIR=/c/tools/msvs10/VC/redist/x64/Microsoft.VC100.CRT export WIN32_REDIST_DIR=${_VSPATH}/VC/redist/x64/Microsoft.VC100.CRT
## includes: win8 sdk includes, winrt headers for metro, msvc 10 std library, directx sdk for d3d9 ## ## includes: win8 sdk includes, winrt headers for metro, msvc 10 std library, directx sdk for d3d9 ##
export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl/wrappers:/c/tools/msvs10/vc/include:/c/tools/msvs10/vc/atlmfc/include:/c/tools/sdks/dx10/include export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl/wrappers:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include
## libs: win8 sdk x64 (64-bit) libs, msvc 10 (64-bit) std library, msvc 10 atl libs, directx sdk (64-bit) for d3d9 ## ## libs: win8 sdk x64 (64-bit) libs, msvc 10 (64-bit) std library, msvc 10 atl libs, directx sdk (64-bit) for d3d9 ##
export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x64:/c/tools/msvs10/vc/lib/amd64:/c/tools/msvs10/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64 export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x64:${_VSPATH}/vc/lib/amd64:${_VSPATH}/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64
export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x64:/c/tools/msvs10/vc/lib/amd64:/c/tools/msvs10/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64 export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x64:${_VSPATH}/vc/lib/amd64:${_VSPATH}/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64
## paths: win8 sdk x64 (64-bit) tools, msvc 10 (64-bit) build toolchain, moz tools ## ## paths: win8 sdk x64 (64-bit) tools, msvc 10 (64-bit) build toolchain, moz tools ##
export PATH="/c/Program Files (x86)/Windows Kits/8.0/bin/x64:/c/tools/msvs10/Common7/IDE:/c/tools/msvs10/VC/BIN/amd64:/c/tools/msvs10/VC/BIN/x86_amd64:/c/tools/msvs10/VC/BIN:/c/tools/msvs10/Common7/Tools:/c/tools/msvs10/VC/VCPackages:${PATH}" export PATH="/c/Program Files (x86)/Windows Kits/8.0/bin/x64:${_VSPATH}/Common7/IDE:${_VSPATH}/VC/BIN/amd64:${_VSPATH}/VC/BIN/x86_amd64:${_VSPATH}/VC/BIN:${_VSPATH}/Common7/Tools:${_VSPATH}/VC/VCPackages:${PATH}"
# Use 32bit linker for PGO crash bug. # Use 32bit linker for PGO crash bug.
# https://connect.microsoft.com/VisualStudio/feedback/details/686117/ # https://connect.microsoft.com/VisualStudio/feedback/details/686117/

View File

@ -16,6 +16,7 @@
#include "nsJSPrincipals.h" #include "nsJSPrincipals.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsPrincipal.h" #include "nsPrincipal.h"
#include "nsIContentSecurityPolicy.h"
class nsIURI; class nsIURI;
@ -53,6 +54,7 @@ public:
virtual ~nsNullPrincipal(); virtual ~nsNullPrincipal();
nsCOMPtr<nsIURI> mURI; nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
}; };
#endif // nsNullPrincipal_h__ #endif // nsNullPrincipal_h__

View File

@ -149,8 +149,7 @@ nsNullPrincipal::GetHashValue(uint32_t *aResult)
NS_IMETHODIMP NS_IMETHODIMP
nsNullPrincipal::GetSecurityPolicy(void** aSecurityPolicy) nsNullPrincipal::GetSecurityPolicy(void** aSecurityPolicy)
{ {
// We don't actually do security policy caching. And it's not like anyone // We don't actually do security policy caching.
// can set a security policy for us anyway.
*aSecurityPolicy = nullptr; *aSecurityPolicy = nullptr;
return NS_OK; return NS_OK;
} }
@ -158,8 +157,7 @@ nsNullPrincipal::GetSecurityPolicy(void** aSecurityPolicy)
NS_IMETHODIMP NS_IMETHODIMP
nsNullPrincipal::SetSecurityPolicy(void* aSecurityPolicy) nsNullPrincipal::SetSecurityPolicy(void* aSecurityPolicy)
{ {
// We don't actually do security policy caching. And it's not like anyone // We don't actually do security policy caching.
// can set a security policy for us anyway.
return NS_OK; return NS_OK;
} }
@ -172,16 +170,20 @@ nsNullPrincipal::GetURI(nsIURI** aURI)
NS_IMETHODIMP NS_IMETHODIMP
nsNullPrincipal::GetCsp(nsIContentSecurityPolicy** aCsp) nsNullPrincipal::GetCsp(nsIContentSecurityPolicy** aCsp)
{ {
// CSP on a null principal makes no sense NS_IF_ADDREF(*aCsp = mCSP);
*aCsp = nullptr;
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsNullPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp) nsNullPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
{ {
// CSP on a null principal makes no sense // If CSP was already set, it should not be destroyed! Instead, it should
return NS_ERROR_NOT_AVAILABLE; // get set anew when a new principal is created.
if (mCSP)
return NS_ERROR_ALREADY_INITIALIZED;
mCSP = aCsp;
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP

View File

@ -49,9 +49,9 @@ function ContentSecurityPolicy() {
this._request = ""; this._request = "";
this._requestOrigin = ""; this._requestOrigin = "";
this._requestPrincipal = ""; this._weakRequestPrincipal = null;
this._referrer = ""; this._referrer = "";
this._docRequest = null; this._weakDocRequest = { get : function() { return null; } };
CSPdebug("CSP object initialized, no policies to enforce yet"); CSPdebug("CSP object initialized, no policies to enforce yet");
this._cache = { }; this._cache = { };
@ -249,7 +249,7 @@ ContentSecurityPolicy.prototype = {
return; return;
// Save the docRequest for fetching a policy-uri // Save the docRequest for fetching a policy-uri
this._docRequest = aChannel; this._weakDocRequest = Cu.getWeakReference(aChannel);
// save the document URI (minus <fragment>) and referrer for reporting // save the document URI (minus <fragment>) and referrer for reporting
let uri = aChannel.URI.cloneIgnoringRef(); let uri = aChannel.URI.cloneIgnoringRef();
@ -260,8 +260,9 @@ ContentSecurityPolicy.prototype = {
this._requestOrigin = uri; this._requestOrigin = uri;
//store a reference to the principal, that can later be used in shouldLoad //store a reference to the principal, that can later be used in shouldLoad
this._requestPrincipal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]. this._weakRequestPrincipal = Cu.getWeakReference(Cc["@mozilla.org/scriptsecuritymanager;1"]
getService(Components.interfaces.nsIScriptSecurityManager).getChannelPrincipal(aChannel); .getService(Ci.nsIScriptSecurityManager)
.getChannelPrincipal(aChannel));
if (aChannel.referrer) { if (aChannel.referrer) {
let referrer = aChannel.referrer.cloneIgnoringRef(); let referrer = aChannel.referrer.cloneIgnoringRef();
@ -310,13 +311,13 @@ ContentSecurityPolicy.prototype = {
if (aSpecCompliant) { if (aSpecCompliant) {
newpolicy = CSPRep.fromStringSpecCompliant(aPolicy, newpolicy = CSPRep.fromStringSpecCompliant(aPolicy,
selfURI, selfURI,
this._docRequest, this._weakDocRequest.get(),
this, this,
aReportOnly); aReportOnly);
} else { } else {
newpolicy = CSPRep.fromString(aPolicy, newpolicy = CSPRep.fromString(aPolicy,
selfURI, selfURI,
this._docRequest, this._weakDocRequest.get(),
this, this,
aReportOnly); aReportOnly);
} }
@ -434,8 +435,8 @@ ContentSecurityPolicy.prototype = {
// we need to set an nsIChannelEventSink on the channel object // we need to set an nsIChannelEventSink on the channel object
// so we can tell it to not follow redirects when posting the reports // so we can tell it to not follow redirects when posting the reports
chan.notificationCallbacks = new CSPReportRedirectSink(policy); chan.notificationCallbacks = new CSPReportRedirectSink(policy);
if (this._docRequest) { if (this._weakDocRequest.get()) {
chan.loadGroup = this._docRequest.loadGroup; chan.loadGroup = this._weakDocRequest.get().loadGroup;
} }
chan.QueryInterface(Ci.nsIUploadChannel) chan.QueryInterface(Ci.nsIUploadChannel)
@ -454,7 +455,7 @@ ContentSecurityPolicy.prototype = {
.getService(Ci.nsIContentPolicy); .getService(Ci.nsIContentPolicy);
if (contentPolicy.shouldLoad(Ci.nsIContentPolicy.TYPE_CSP_REPORT, if (contentPolicy.shouldLoad(Ci.nsIContentPolicy.TYPE_CSP_REPORT,
chan.URI, this._requestOrigin, chan.URI, this._requestOrigin,
null, null, null, this._requestPrincipal) null, null, null, this._weakRequestPrincipal.get())
!= Ci.nsIContentPolicy.ACCEPT) { != Ci.nsIContentPolicy.ACCEPT) {
continue; // skip unauthorized URIs continue; // skip unauthorized URIs
} }

View File

@ -35,6 +35,7 @@
#include "mozilla/CheckedInt.h" #include "mozilla/CheckedInt.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "nsThreadUtils.h"
#include "mozilla/dom/FileListBinding.h" #include "mozilla/dom/FileListBinding.h"
using namespace mozilla; using namespace mozilla;

View File

@ -2681,7 +2681,8 @@ nsDocument::InitCSP(nsIChannel* aChannel)
if (csp) { if (csp) {
// Copy into principal // Copy into principal
nsIPrincipal* principal = GetPrincipal(); nsIPrincipal* principal = GetPrincipal();
principal->SetCsp(csp); rv = principal->SetCsp(csp);
NS_ENSURE_SUCCESS(rv, rv);
#ifdef PR_LOGGING #ifdef PR_LOGGING
PR_LOG(gCspPRLog, PR_LOG_DEBUG, PR_LOG(gCspPRLog, PR_LOG_DEBUG,
("Inserted CSP into principal %p", principal)); ("Inserted CSP into principal %p", principal));

View File

@ -53,7 +53,6 @@
#include "pldhash.h" #include "pldhash.h"
#include "nsAttrAndChildArray.h" #include "nsAttrAndChildArray.h"
#include "nsDOMAttributeMap.h" #include "nsDOMAttributeMap.h"
#include "nsThreadUtils.h"
#include "nsIContentViewer.h" #include "nsIContentViewer.h"
#include "nsIDOMXPathNSResolver.h" #include "nsIDOMXPathNSResolver.h"
#include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestor.h"

View File

@ -18,7 +18,7 @@
#include "nsIDocShell.h" #include "nsIDocShell.h"
#include "nsIDOMElement.h" #include "nsIDOMElement.h"
#include "nsCOMArray.h" #include "nsCOMArray.h"
#include "nsThreadUtils.h" #include "nsIRunnable.h"
#include "nsIGlobalObject.h" #include "nsIGlobalObject.h"
#include "nsIScriptObjectPrincipal.h" #include "nsIScriptObjectPrincipal.h"
#include "nsWeakReference.h" #include "nsWeakReference.h"

View File

@ -97,6 +97,19 @@ MOCHITEST_FILES := \
file_bug836922_npolicies.html^headers^ \ file_bug836922_npolicies.html^headers^ \
file_bug836922_npolicies_violation.sjs \ file_bug836922_npolicies_violation.sjs \
file_bug836922_npolicies_ro_violation.sjs \ file_bug836922_npolicies_ro_violation.sjs \
test_bug886164.html \
file_bug886164.html \
file_bug886164.html^headers^ \
file_bug886164_2.html \
file_bug886164_2.html^headers^ \
file_bug886164_3.html \
file_bug886164_3.html^headers^ \
file_bug886164_4.html \
file_bug886164_4.html^headers^ \
file_bug886164_5.html \
file_bug886164_5.html^headers^ \
file_bug886164_6.html \
file_bug886164_6.html^headers^ \
$(NULL) $(NULL)
MOCHITEST_CHROME_FILES := \ MOCHITEST_CHROME_FILES := \

View File

@ -0,0 +1,15 @@
<html>
<head> <meta charset="utf-8"> </head>
<body>
<!-- sandbox="allow-same-origin" -->
<!-- Content-Security-Policy: default-src 'self' -->
<!-- these should be stopped by CSP -->
<img src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=img_bad&type=img/png"> </img>
<!-- these should load ok -->
<img src="/tests/content/base/test/csp/file_CSP.sjs?testid=img_good&type=img/png" />
<script src='/tests/content/base/test/csp/file_CSP.sjs?testid=scripta_bad&type=text/javascript'></script>
</body>
</html>

View File

@ -0,0 +1 @@
Content-Security-Policy: default-src 'self'

View File

@ -0,0 +1,14 @@
<html>
<head> <meta charset="utf-8"> </head>
<body>
<!-- sandbox -->
<!-- Content-Security-Policy: default-src 'self' -->
<!-- these should be stopped by CSP -->
<img src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=img2_bad&type=img/png"> </img>
<!-- these should load ok -->
<img src="/tests/content/base/test/csp/file_CSP.sjs?testid=img2a_good&type=img/png" />
</body>
</html>

View File

@ -0,0 +1 @@
Content-Security-Policy: default-src 'self'

View File

@ -0,0 +1,12 @@
<html>
<head> <meta charset="utf-8"> </head>
<body>
<!-- sandbox -->
<!-- Content-Security-Policy: default-src 'none' -->
<!-- these should be stopped by CSP -->
<img src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=img3_bad&type=img/png"> </img>
<img src="/tests/content/base/test/csp/file_CSP.sjs?testid=img3a_bad&type=img/png" />
</body>
</html>

View File

@ -0,0 +1 @@
Content-Security-Policy: default-src 'none'

View File

@ -0,0 +1,12 @@
<html>
<head> <meta charset="utf-8"> </head>
<body>
<!-- sandbox -->
<!-- Content-Security-Policy: default-src 'none' -->
<!-- these should be stopped by CSP -->
<img src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=img4_bad&type=img/png"> </img>
<img src="/tests/content/base/test/csp/file_CSP.sjs?testid=img4a_bad&type=img/png" />
</body>
</html>

View File

@ -0,0 +1 @@
Content-Security-Policy: default-src 'none'

View File

@ -0,0 +1,26 @@
<!DOCTYPE HTML>
<html>
<head> <meta charset="utf-8"> </head>
<script type="text/javascript">
function ok(result, desc) {
window.parent.postMessage({ok: result, desc: desc}, "*");
}
function doStuff() {
ok(true, "documents sandboxed with allow-scripts should be able to run inline scripts");
}
</script>
<script src='file_iframe_sandbox_pass.js'></script>
<body onLoad='ok(true, "documents sandboxed with allow-scripts should be able to run script from event listeners");doStuff();'>
I am sandboxed but with only inline "allow-scripts"
<!-- sandbox="allow-scripts" -->
<!-- Content-Security-Policy: default-src 'none' 'unsafe-inline'-->
<!-- these should be stopped by CSP -->
<img src="/tests/content/base/test/csp/file_CSP.sjs?testid=img5_bad&type=img/png" />
<img src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=img5a_bad&type=img/png"> </img>
<script src='/tests/content/base/test/csp/file_CSP.sjs?testid=script5_bad&type=text/javascript'></script>
<script src='http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=script5a_bad&type=text/javascript'></script>
</body>
</html>

View File

@ -0,0 +1 @@
Content-Security-Policy: default-src 'none' 'unsafe-inline';

View File

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
</head>
<script type="text/javascript">
function ok(result, desc) {
window.parent.postMessage({ok: result, desc: desc}, "*");
}
function doStuff() {
ok(true, "documents sandboxed with allow-scripts should be able to run inline scripts");
document.getElementById('a_form').submit();
// trigger the javascript: url test
sendMouseEvent({type:'click'}, 'a_link');
}
</script>
<script src='file_iframe_sandbox_pass.js'></script>
<body onLoad='ok(true, "documents sandboxed with allow-scripts should be able to run script from event listeners");doStuff();'>
I am sandboxed but with "allow-scripts"
<img src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=img6_bad&type=img/png"> </img>
<script src='http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=script6_bad&type=text/javascript'></script>
<form method="get" action="file_iframe_sandbox_form_fail.html" id="a_form">
First name: <input type="text" name="firstname">
Last name: <input type="text" name="lastname">
<input type="submit" onclick="doSubmit()" id="a_button">
</form>
<a href = 'javascript:ok(true, "documents sandboxed with allow-scripts should be able to run script from javascript: URLs");' id='a_link'>click me</a>
</body>
</html>

View File

@ -0,0 +1 @@
Content-Security-Policy: default-src 'self' 'unsafe-inline';

View File

@ -0,0 +1,185 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Bug 886164 - Enforce CSP in sandboxed iframe</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<iframe style="width:200px;height:200px;" id='cspframe' sandbox="allow-same-origin"></iframe>
<iframe style="width:200px;height:200px;" id='cspframe2' sandbox></iframe>
<iframe style="width:200px;height:200px;" id='cspframe3' sandbox="allow-same-origin"></iframe>
<iframe style="width:200px;height:200px;" id='cspframe4' sandbox></iframe>
<iframe style="width:200px;height:200px;" id='cspframe5' sandbox="allow-scripts"></iframe>
<iframe style="width:200px;height:200px;" id='cspframe6' sandbox="allow-same-origin allow-scripts"></iframe>
<script class="testbody" type="text/javascript">
var path = "/tests/content/base/test/csp/";
// These are test results: -1 means it hasn't run,
// true/false is the pass/fail result.
window.tests = {
// sandbox allow-same-origin; 'self'
img_good: -1, // same origin
img_bad: -1, //example.com
// sandbox; 'self'
img2_bad: -1, //example.com
img2a_good: -1, // same origin & is image
// sandbox allow-same-origin; 'none'
img3_bad: -1,
img3a_bad: -1,
// sandbox; 'none'
img4_bad: -1,
img4a_bad: -1,
// sandbox allow-scripts; 'none' 'unsafe-inline'
img5_bad: -1,
img5a_bad: -1,
script5_bad: -1,
script5a_bad: -1,
// sandbox allow-same-origin allow-scripts; 'self' 'unsafe-inline'
img6_bad: -1,
script6_bad: -1,
};
// a postMessage handler that is used by sandboxed iframes without
// 'allow-same-origin' to communicate pass/fail back to this main page.
// it expects to be called with an object like {ok: true/false, desc:
// <description of the test> which it then forwards to ok()
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{
ok_wrapper(event.data.ok, event.data.desc);
}
var cspTestsDone = false;
var iframeSandboxTestsDone = false;
// iframe related
var completedTests = 0;
var passedTests = 0;
function ok_wrapper(result, desc) {
ok(result, desc);
completedTests++;
if (result) {
passedTests++;
}
if (completedTests === 5) {
iframeSandboxTestsDone = true;
if (cspTestsDone) {
SimpleTest.finish();
}
}
}
//csp related
// This is used to watch the blocked data bounce off CSP and allowed data
// get sent out to the wire.
function examiner() {
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
SpecialPowers.addObserver(this, "http-on-modify-request", false);
}
examiner.prototype = {
observe: function(subject, topic, data) {
// subject should be an nsURI, and should be either allowed or blocked.
if (!SpecialPowers.can_QI(subject))
return;
var testpat = new RegExp("testid=([a-z0-9_]+)");
//_good things better be allowed!
//_bad things better be stopped!
if (topic === "http-on-modify-request") {
//these things were allowed by CSP
var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIHttpChannel"), "URI.asciiSpec");
if (!testpat.test(asciiSpec)) return;
var testid = testpat.exec(asciiSpec)[1];
window.testResult(testid,
/_good/.test(testid),
asciiSpec + " allowed by csp");
}
if(topic === "csp-on-violate-policy") {
//these were blocked... record that they were blocked
var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIURI"), "asciiSpec");
if (!testpat.test(asciiSpec)) return;
var testid = testpat.exec(asciiSpec)[1];
window.testResult(testid,
/_bad/.test(testid),
asciiSpec + " blocked by \"" + data + "\"");
}
},
// must eventually call this to remove the listener,
// or mochitests might get borked.
remove: function() {
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
SpecialPowers.removeObserver(this, "http-on-modify-request");
}
}
window.examiner = new examiner();
window.testResult = function(testname, result, msg) {
//test already complete.... forget it... remember the first result.
if (window.tests[testname] != -1)
return;
window.tests[testname] = result;
is(result, true, testname + ' test: ' + msg);
// if any test is incomplete, keep waiting
for (var v in window.tests)
if(tests[v] == -1) {
console.log(v + " is not complete");
return;
}
// ... otherwise, finish
window.examiner.remove();
cspTestsDone = true;
if (iframeSandboxTestsDone) {
SimpleTest.finish();
}
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{'set':[["security.csp.speccompliant", true]]},
function() {
// save this for last so that our listeners are registered.
// ... this loads the testbed of good and bad requests.
document.getElementById('cspframe').src = 'file_bug886164.html';
document.getElementById('cspframe2').src = 'file_bug886164_2.html';
document.getElementById('cspframe3').src = 'file_bug886164_3.html';
document.getElementById('cspframe4').src = 'file_bug886164_4.html';
document.getElementById('cspframe5').src = 'file_bug886164_5.html';
document.getElementById('cspframe6').src = 'file_bug886164_6.html';
});
</script>
</pre>
</body>
</html>

View File

@ -13,7 +13,7 @@
#include "nsIScriptGlobalObject.h" #include "nsIScriptGlobalObject.h"
#include "nsEventListenerManager.h" #include "nsEventListenerManager.h"
#include "nsIScriptContext.h" #include "nsIScriptContext.h"
#include "nsThreadUtils.h" #include "MainThreadUtils.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/dom/EventTarget.h" #include "mozilla/dom/EventTarget.h"

View File

@ -11,7 +11,6 @@
#include "MediaDecoderOwner.h" #include "MediaDecoderOwner.h"
#include "nsIChannel.h" #include "nsIChannel.h"
#include "nsIHttpChannel.h" #include "nsIHttpChannel.h"
#include "nsThreadUtils.h"
#include "nsIDOMRange.h" #include "nsIDOMRange.h"
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
#include "nsILoadGroup.h" #include "nsILoadGroup.h"
@ -45,6 +44,7 @@ class MediaDecoder;
class nsITimer; class nsITimer;
class nsRange; class nsRange;
class nsIRunnable;
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {

View File

@ -15,6 +15,7 @@ namespace mozilla {
namespace dom { namespace dom {
struct ThreeDPoint; struct ThreeDPoint;
class AudioParamTimeline; class AudioParamTimeline;
class DelayNodeEngine;
} }
class AudioNodeStream; class AudioNodeStream;
@ -206,6 +207,8 @@ public:
MOZ_COUNT_DTOR(AudioNodeEngine); MOZ_COUNT_DTOR(AudioNodeEngine);
} }
virtual dom::DelayNodeEngine* AsDelayNodeEngine() { return nullptr; }
virtual void SetStreamTimeParameter(uint32_t aIndex, TrackTicks aParam) virtual void SetStreamTimeParameter(uint32_t aIndex, TrackTicks aParam)
{ {
NS_ERROR("Invalid SetStreamTimeParameter index"); NS_ERROR("Invalid SetStreamTimeParameter index");

View File

@ -286,6 +286,20 @@ AudioNodeStream::ObtainInputBlock(AudioChunk& aTmpChunk, uint32_t aPortIndex)
a->IsAudioParamStream()) { a->IsAudioParamStream()) {
continue; continue;
} }
// It is possible for mLastChunks to be empty here, because `a` might be a
// AudioNodeStream that has not been scheduled yet, because it is further
// down the graph _but_ as a connection to this node. Because we enforce the
// presence of at least one DelayNode, with at least one block of delay, and
// because the output of a DelayNode when it has been fed less that
// `delayTime` amount of audio is silence, we can simply continue here,
// because this input would not influence the output of this node. Next
// iteration, a->mLastChunks.IsEmpty() will be false, and everthing will
// work as usual.
if (a->mLastChunks.IsEmpty()) {
continue;
}
AudioChunk* chunk = &a->mLastChunks[mInputs[i]->OutputNumber()]; AudioChunk* chunk = &a->mLastChunks[mInputs[i]->OutputNumber()];
MOZ_ASSERT(chunk); MOZ_ASSERT(chunk);
if (chunk->IsNull() || chunk->mChannelData.IsEmpty()) { if (chunk->IsNull() || chunk->mChannelData.IsEmpty()) {
@ -412,8 +426,7 @@ AudioNodeStream::ProduceOutput(GraphTime aFrom, GraphTime aTo)
uint16_t outputCount = std::max(uint16_t(1), mEngine->OutputCount()); uint16_t outputCount = std::max(uint16_t(1), mEngine->OutputCount());
mLastChunks.SetLength(outputCount); mLastChunks.SetLength(outputCount);
if (mInCycle) { if (mMuted) {
// XXX DelayNode not supported yet so just produce silence
for (uint16_t i = 0; i < outputCount; ++i) { for (uint16_t i = 0; i < outputCount; ++i) {
mLastChunks[i].SetNull(WEBAUDIO_BLOCK_SIZE); mLastChunks[i].SetNull(WEBAUDIO_BLOCK_SIZE);
} }

View File

@ -21,6 +21,7 @@ namespace mozilla {
namespace dom { namespace dom {
struct ThreeDPoint; struct ThreeDPoint;
class AudioParamTimeline; class AudioParamTimeline;
class DelayNodeEngine;
} }
class ThreadSharedFloatArrayBufferList; class ThreadSharedFloatArrayBufferList;
@ -54,7 +55,8 @@ public:
mKind(aKind), mKind(aKind),
mNumberOfInputChannels(2), mNumberOfInputChannels(2),
mMarkAsFinishedAfterThisBlock(false), mMarkAsFinishedAfterThisBlock(false),
mAudioParamStream(false) mAudioParamStream(false),
mMuted(false)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
mChannelCountMode = dom::ChannelCountMode::Max; mChannelCountMode = dom::ChannelCountMode::Max;
@ -103,6 +105,14 @@ public:
{ {
return mAudioParamStream; return mAudioParamStream;
} }
void Mute() {
mMuted = true;
}
void Unmute() {
mMuted = false;
}
const OutputChunks& LastChunks() const const OutputChunks& LastChunks() const
{ {
return mLastChunks; return mLastChunks;
@ -153,6 +163,8 @@ protected:
bool mMarkAsFinishedAfterThisBlock; bool mMarkAsFinishedAfterThisBlock;
// Whether the stream is an AudioParamHelper stream. // Whether the stream is an AudioParamHelper stream.
bool mAudioParamStream; bool mAudioParamStream;
// Whether the stream is muted. Access only on the MediaStreamGraph thread.
bool mMuted;
}; };
} }

View File

@ -472,12 +472,39 @@ MediaStreamGraphImpl::UpdateStreamOrderForStream(mozilla::LinkedList<MediaStream
NS_ASSERTION(!stream->mHasBeenOrdered, "stream should not have already been ordered"); NS_ASSERTION(!stream->mHasBeenOrdered, "stream should not have already been ordered");
if (stream->mIsOnOrderingStack) { if (stream->mIsOnOrderingStack) {
MediaStream* iter = aStack->getLast(); MediaStream* iter = aStack->getLast();
AudioNodeStream* ns = stream->AsAudioNodeStream();
bool delayNodePresent = ns ? ns->Engine()->AsDelayNodeEngine() != nullptr : false;
bool cycleFound = false;
if (iter) { if (iter) {
do { do {
cycleFound = true;
iter->AsProcessedStream()->mInCycle = true; iter->AsProcessedStream()->mInCycle = true;
AudioNodeStream* ns = iter->AsAudioNodeStream();
if (ns && ns->Engine()->AsDelayNodeEngine()) {
delayNodePresent = true;
}
iter = iter->getPrevious(); iter = iter->getPrevious();
} while (iter && iter != stream); } while (iter && iter != stream);
} }
if (cycleFound && !delayNodePresent) {
// If we have detected a cycle, the previous loop should exit with stream
// == iter, or the node is connected to itself. Go back in the cycle and
// mute all nodes we find, or just mute the node itself.
if (!iter) {
// The node is connected to itself.
iter = aStack->getLast();
iter->AsAudioNodeStream()->Mute();
} else {
MOZ_ASSERT(iter);
do {
// There can't be non-AudioNodeStream here, MediaStreamAudio{Source,
// Destination}Node are connected to regular MediaStreams, but they can't be
// in a cycle (there is no content API to do so).
MOZ_ASSERT(iter->AsAudioNodeStream());
iter->AsAudioNodeStream()->Mute();
} while((iter = iter->getNext()));
}
}
return; return;
} }
ProcessedMediaStream* ps = stream->AsProcessedStream(); ProcessedMediaStream* ps = stream->AsProcessedStream();
@ -513,6 +540,10 @@ MediaStreamGraphImpl::UpdateStreamOrder()
ProcessedMediaStream* ps = stream->AsProcessedStream(); ProcessedMediaStream* ps = stream->AsProcessedStream();
if (ps) { if (ps) {
ps->mInCycle = false; ps->mInCycle = false;
AudioNodeStream* ns = ps->AsAudioNodeStream();
if (ns) {
ns->Unmute();
}
} }
} }
@ -2293,6 +2324,7 @@ MediaStreamGraphImpl::MediaStreamGraphImpl(bool aRealtime)
, mPostedRunInStableState(false) , mPostedRunInStableState(false)
, mRealtime(aRealtime) , mRealtime(aRealtime)
, mNonRealtimeProcessing(false) , mNonRealtimeProcessing(false)
, mStreamOrderDirty(false)
{ {
#ifdef PR_LOGGING #ifdef PR_LOGGING
if (!gMediaStreamGraphLog) { if (!gMediaStreamGraphLog) {
@ -2446,4 +2478,11 @@ MediaStreamGraph::StartNonRealtimeProcessing(uint32_t aTicksToProcess)
graph->EnsureRunInStableState(); graph->EnsureRunInStableState();
} }
void
ProcessedMediaStream::AddInput(MediaInputPort* aPort)
{
mInputs.AppendElement(aPort);
GraphImpl()->SetStreamOrderDirty();
}
} }

View File

@ -15,7 +15,9 @@
#include "TimeVarying.h" #include "TimeVarying.h"
#include "VideoFrameContainer.h" #include "VideoFrameContainer.h"
#include "VideoSegment.h" #include "VideoSegment.h"
#include "nsThreadUtils.h" #include "MainThreadUtils.h"
class nsIRunnable;
namespace mozilla { namespace mozilla {
@ -917,10 +919,7 @@ public:
friend class MediaStreamGraphImpl; friend class MediaStreamGraphImpl;
// Do not call these from outside MediaStreamGraph.cpp! // Do not call these from outside MediaStreamGraph.cpp!
virtual void AddInput(MediaInputPort* aPort) virtual void AddInput(MediaInputPort* aPort);
{
mInputs.AppendElement(aPort);
}
virtual void RemoveInput(MediaInputPort* aPort) virtual void RemoveInput(MediaInputPort* aPort)
{ {
mInputs.RemoveElement(aPort); mInputs.RemoveElement(aPort);
@ -946,6 +945,9 @@ public:
*/ */
virtual void ForwardTrackEnabled(TrackID aOutputID, bool aEnabled) {}; virtual void ForwardTrackEnabled(TrackID aOutputID, bool aEnabled) {};
bool InCycle() const { return mInCycle; }
protected: protected:
// This state is all accessed only on the media graph thread. // This state is all accessed only on the media graph thread.

View File

@ -365,6 +365,13 @@ public:
* Remove aPort from the graph and release it. * Remove aPort from the graph and release it.
*/ */
void DestroyPort(MediaInputPort* aPort); void DestroyPort(MediaInputPort* aPort);
/**
* Mark the media stream order as dirty.
*/
void SetStreamOrderDirty()
{
mStreamOrderDirty = true;
}
// Data members // Data members
@ -554,6 +561,11 @@ public:
* value is only accessed on the main thread. * value is only accessed on the main thread.
*/ */
bool mNonRealtimeProcessing; bool mNonRealtimeProcessing;
/**
* True when a change has happened which requires us to recompute the stream
* blocking order.
*/
bool mStreamOrderDirty;
}; };
} }

View File

@ -18,7 +18,6 @@
#include "nsTArray.h" #include "nsTArray.h"
#include "nsIURI.h" #include "nsIURI.h"
#include "nsITimer.h" #include "nsITimer.h"
#include "nsThreadUtils.h"
#include "MediaDecoder.h" #include "MediaDecoder.h"
#include "DASHReader.h" #include "DASHReader.h"

View File

@ -25,6 +25,10 @@
# make the test first check canPlayType for the type, and if it's not # make the test first check canPlayType for the type, and if it's not
# supported, just do ok(true, "Type not supported") and stop the test. # supported, just do ok(true, "Type not supported") and stop the test.
# Disabled for too many intermittent failures (bug 897108)
# test_playback_rate_playpause.html \
MOCHITEST_FILES = \ MOCHITEST_FILES = \
allowed.sjs \ allowed.sjs \
can_play_type_ogg.js \ can_play_type_ogg.js \
@ -141,7 +145,6 @@ MOCHITEST_FILES = \
test_VideoPlaybackQuality.html \ test_VideoPlaybackQuality.html \
test_VideoPlaybackQuality_disabled.html \ test_VideoPlaybackQuality_disabled.html \
test_webvtt_disabled.html \ test_webvtt_disabled.html \
test_playback_rate_playpause.html \
test_bug895305.html \ test_bug895305.html \
$(NULL) $(NULL)

View File

@ -130,6 +130,10 @@ public:
return nullptr; return nullptr;
} }
virtual const DelayNode* AsDelayNode() const {
return nullptr;
}
AudioContext* GetParentObject() const AudioContext* GetParentObject() const
{ {
return mContext; return mContext;

View File

@ -44,6 +44,11 @@ public:
{ {
} }
virtual DelayNodeEngine* AsDelayNodeEngine()
{
return this;
}
void SetSourceStream(AudioNodeStream* aSource) void SetSourceStream(AudioNodeStream* aSource)
{ {
mSource = aSource; mSource = aSource;
@ -123,18 +128,28 @@ public:
float* const* outputChannels = reinterpret_cast<float* const*> float* const* outputChannels = reinterpret_cast<float* const*>
(const_cast<void* const*>(aOutput->mChannelData.Elements())); (const_cast<void* const*>(aOutput->mChannelData.Elements()));
bool inCycle = aStream->AsProcessedStream()->InCycle();
double sampleRate = aStream->SampleRate(); double sampleRate = aStream->SampleRate();
if (mDelay.HasSimpleValue()) { if (mDelay.HasSimpleValue()) {
double delayFrames = mDelay.GetValue() * sampleRate; // If this DelayNode is in a cycle, make sure the delay value is at least
mProcessor.Process(delayFrames, inputChannels, outputChannels, // one block.
float delayFrames = mDelay.GetValue() * sampleRate;
float delayFramesClamped = inCycle ? std::max(static_cast<float>(WEBAUDIO_BLOCK_SIZE), delayFrames) :
delayFrames;
mProcessor.Process(delayFramesClamped, inputChannels, outputChannels,
numChannels, WEBAUDIO_BLOCK_SIZE); numChannels, WEBAUDIO_BLOCK_SIZE);
} else { } else {
// Compute the delay values for the duration of the input AudioChunk // Compute the delay values for the duration of the input AudioChunk
// If this DelayNode is in a cycle, make sure the delay value is at least
// one block.
double computedDelay[WEBAUDIO_BLOCK_SIZE]; double computedDelay[WEBAUDIO_BLOCK_SIZE];
TrackTicks tick = aStream->GetCurrentPosition(); TrackTicks tick = aStream->GetCurrentPosition();
for (size_t counter = 0; counter < WEBAUDIO_BLOCK_SIZE; ++counter) { for (size_t counter = 0; counter < WEBAUDIO_BLOCK_SIZE; ++counter) {
computedDelay[counter] = float delayAtTick = mDelay.GetValueAtTime(tick, counter) * sampleRate;
mDelay.GetValueAtTime(tick, counter) * sampleRate; float delayAtTickClamped = inCycle ? std::max(static_cast<float>(WEBAUDIO_BLOCK_SIZE), delayAtTick) :
delayAtTick;
computedDelay[counter] = delayAtTickClamped;
} }
mProcessor.Process(computedDelay, inputChannels, outputChannels, mProcessor.Process(computedDelay, inputChannels, outputChannels,
numChannels, WEBAUDIO_BLOCK_SIZE); numChannels, WEBAUDIO_BLOCK_SIZE);

View File

@ -32,6 +32,11 @@ public:
return mDelay; return mDelay;
} }
virtual const DelayNode* AsDelayNode() const MOZ_OVERRIDE
{
return this;
}
virtual void NotifyInputConnected() MOZ_OVERRIDE virtual void NotifyInputConnected() MOZ_OVERRIDE
{ {
mMediaStreamGraphUpdateIndexAtLastInputConnection = mMediaStreamGraphUpdateIndexAtLastInputConnection =

View File

@ -57,6 +57,7 @@ MOCHITEST_FILES := \
test_delayNodeAtMax.html \ test_delayNodeAtMax.html \
test_delayNodeSmallMaxDelay.html \ test_delayNodeSmallMaxDelay.html \
test_delayNodeWithGain.html \ test_delayNodeWithGain.html \
test_delayNodeCycles.html \
test_dynamicsCompressorNode.html \ test_dynamicsCompressorNode.html \
test_gainNode.html \ test_gainNode.html \
test_gainNodeInLoop.html \ test_gainNodeInLoop.html \

View File

@ -0,0 +1,170 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test the support of cycles.</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script src="webaudio.js" type="text/javascript"></script>
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
function getSineBuffer(ctx) {
var buffer = ctx.createBuffer(1, 2048, ctx.sampleRate);
var b = buffer.getChannelData(0);
for (var i = 0; i < 2048; i++) {
b[i] = Math.sin(440 * 2 * Math.PI * i / ctx.sampleRate);
}
return buffer;
}
function createAndPlayWithCycleAndDelayNode(ctx) {
var source = ctx.createBufferSource();
source.loop = true;
source.buffer = getSineBuffer(ctx);
var gain = ctx.createGain();
var delay = ctx.createDelay();
delay.delayTime = 0.5;
source.connect(gain);
gain.connect(delay);
delay.connect(ctx.destination);
// cycle
delay.connect(gain);
source.start(0);
}
function createAndPlayWithCycleAndDelayNodeButNullDelayTime(ctx) {
var source = ctx.createBufferSource();
source.loop = true;
source.buffer = getSineBuffer(ctx);
var gain = ctx.createGain();
var delay = ctx.createDelay();
delay.delayTime = 0.0;
source.connect(gain);
gain.connect(delay);
delay.connect(ctx.destination);
// cycle
delay.connect(gain);
source.start(0);
}
function createAndPlayWithCycleAndNoDelayNode(ctx) {
var source = ctx.createBufferSource();
source.loop = true;
source.buffer = getSineBuffer(ctx);
var gain = ctx.createGain();
var gain2 = ctx.createGain();
source.connect(gain);
gain.connect(gain2);
// cycle
gain2.connect(gain);
gain2.connect(ctx.destination);
source.start(0);
}
function createAndPlayWithCycleAndNoDelayNodeInCycle(ctx) {
var source = ctx.createBufferSource();
source.loop = true;
source.buffer = getSineBuffer(ctx);
var delay = ctx.createDelay();
var gain = ctx.createGain();
var gain2 = ctx.createGain();
// Their is a cycle, a delay, but the delay is not in the cycle.
source.connect(delay);
delay.connect(gain);
gain.connect(gain2);
// cycle
gain2.connect(gain);
gain2.connect(ctx.destination);
source.start(0);
}
var remainingTests = 0;
function finish() {
if (--remainingTests == 0) {
SimpleTest.finish();
}
}
function getOfflineContext(oncomplete) {
var ctx = new OfflineAudioContext(1, 48000, 48000);
ctx.oncomplete = oncomplete;
return ctx;
}
function checkSilentBuffer(e) {
var buffer = e.renderedBuffer.getChannelData(0);
for (var i = 0; i < buffer.length; i++) {
if (buffer[i] != 0.0) {
ok(false, "buffer should be silent.");
finish();
return;
}
}
ok(true, "buffer should be silent.");
finish();
}
function checkNoisyBuffer(e) {
var buffer = e.renderedBuffer.getChannelData(0);
for (var i = 0; i < buffer.length; i++) {
if (buffer[i] != 0.0) {
ok(true, "buffer should be noisy.");
finish();
return true;
}
}
ok(false, "buffer should be noisy.");
finish();
return false;
}
function expectSilentOutput(f) {
remainingTests++;
var ctx = getOfflineContext(checkSilentBuffer);
f(ctx);
ctx.startRendering();
}
function expectNoisyOutput(f) {
remainingTests++;
var ctx = getOfflineContext(checkNoisyBuffer);
f(ctx);
ctx.startRendering();
}
// This is trying to make a graph with a cycle and no DelayNode in the graph.
// The cycle subgraph should be muted, in this graph the output should be silent.
expectSilentOutput(createAndPlayWithCycleAndNoDelayNode);
// This is trying to make a graph with a cycle and a DelayNode in the graph, but
// not part of the cycle.
// The cycle subgraph should be muted, in this graph the output should be silent.
expectSilentOutput(createAndPlayWithCycleAndNoDelayNodeInCycle);
// Those are making legal graphs, with at least one DelayNode in the cycle.
// There should be some non-silent output.
expectNoisyOutput(createAndPlayWithCycleAndDelayNode);
// DelayNode.delayTime will be clamped to 128/ctx.sampleRate.
// There should be some non-silent output.
expectNoisyOutput(createAndPlayWithCycleAndDelayNodeButNullDelayTime);
});
</script>
</pre>
</body>
</html>

View File

@ -3,6 +3,9 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
# Disabled for too many intermittent failures (bug 719186)
# test_bug413310.html \
MOCHITEST_FILES = \ MOCHITEST_FILES = \
test_bug123696.html \ test_bug123696.html \
bug123696-subframe.html \ bug123696-subframe.html \
@ -13,7 +16,6 @@ MOCHITEST_FILES = \
test_bug387979.html \ test_bug387979.html \
test_bug404548.html \ test_bug404548.html \
bug404548-subframe.html \ bug404548-subframe.html \
test_bug413310.html \
bug413310-subframe.html \ bug413310-subframe.html \
bug413310-post.sjs \ bug413310-post.sjs \
test_bug402210.html \ test_bug402210.html \

View File

@ -23,7 +23,7 @@
#include "mozilla/Util.h" #include "mozilla/Util.h"
#include "nsCycleCollector.h" #include "nsCycleCollector.h"
#include "nsIXPConnect.h" #include "nsIXPConnect.h"
#include "nsThreadUtils.h" // Hacky work around for some bindings needing NS_IsMainThread. #include "MainThreadUtils.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "qsObjectHelper.h" #include "qsObjectHelper.h"
#include "xpcpublic.h" #include "xpcpublic.h"

View File

@ -19,7 +19,6 @@
#define NAN std::numeric_limits<double>::quiet_NaN() #define NAN std::numeric_limits<double>::quiet_NaN()
#endif #endif
#include "nsThreadUtils.h"
#include "nsIDOMCameraManager.h" #include "nsIDOMCameraManager.h"
#include "prlog.h" #include "prlog.h"

View File

@ -15,6 +15,7 @@
#include "FileRequest.h" #include "FileRequest.h"
#include "FileService.h" #include "FileService.h"
#include "nsIRequest.h" #include "nsIRequest.h"
#include "nsThreadUtils.h"
USING_FILE_NAMESPACE USING_FILE_NAMESPACE
@ -209,3 +210,17 @@ FileHelper::Finish()
mRequest), "Subclass didn't call FileHelper::ReleaseObjects!"); mRequest), "Subclass didn't call FileHelper::ReleaseObjects!");
} }
void
FileHelper::OnStreamClose()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
Finish();
}
void
FileHelper::OnStreamDestroy()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
Finish();
}

View File

@ -10,7 +10,6 @@
#include "FileCommon.h" #include "FileCommon.h"
#include "nsIRequestObserver.h" #include "nsIRequestObserver.h"
#include "nsThreadUtils.h"
class nsIFileStorage; class nsIFileStorage;
@ -58,18 +57,10 @@ public:
OnStreamProgress(uint64_t aProgress, uint64_t aProgressMax); OnStreamProgress(uint64_t aProgress, uint64_t aProgressMax);
void void
OnStreamClose() OnStreamClose();
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
Finish();
}
void void
OnStreamDestroy() OnStreamDestroy();
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
Finish();
}
static LockedFile* static LockedFile*
GetCurrentLockedFile(); GetCurrentLockedFile();

View File

@ -1,8 +1,10 @@
# THIS FILE IS AUTOGENERATED BY parseFailures.py - DO NOT EDIT # THIS FILE IS AUTOGENERATED BY parseFailures.py - DO NOT EDIT
# Disabled due to bug 859075
# test_window-named-properties.html.json \
MOCHITEST_FILES := \ MOCHITEST_FILES := \
test_window-indexed-properties-strict.html.json \ test_window-indexed-properties-strict.html.json \
test_window-named-properties.html.json \
test_window-properties.html.json \ test_window-properties.html.json \
test_window-prototype-chain.html.json \ test_window-prototype-chain.html.json \
$(NULL) $(NULL)

View File

@ -1,9 +1,11 @@
# THIS FILE IS AUTOGENERATED BY importTestsuite.py - DO NOT EDIT # THIS FILE IS AUTOGENERATED BY importTestsuite.py - DO NOT EDIT
# Disabled due to bug 859075
# test_window-named-properties.html \
MOCHITEST_FILES := \ MOCHITEST_FILES := \
test_window-indexed-properties.html \ test_window-indexed-properties.html \
test_window-indexed-properties-strict.html \ test_window-indexed-properties-strict.html \
test_window-named-properties.html \
test_window-properties.html \ test_window-properties.html \
test_window-prototype-chain.html \ test_window-prototype-chain.html \
$(NULL) $(NULL)

View File

@ -5,7 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "FileInfo.h" #include "FileInfo.h"
#include "nsThreadUtils.h"
#include "mozilla/dom/quota/QuotaManager.h" #include "mozilla/dom/quota/QuotaManager.h"
USING_INDEXEDDB_NAMESPACE USING_INDEXEDDB_NAMESPACE

View File

@ -9,8 +9,6 @@
#include "IndexedDatabase.h" #include "IndexedDatabase.h"
#include "nsThreadUtils.h"
#include "FileManager.h" #include "FileManager.h"
#include "IndexedDatabaseManager.h" #include "IndexedDatabaseManager.h"

View File

@ -191,10 +191,8 @@ IDBFactory::Create(JSContext* aCx,
nsCString origin; nsCString origin;
StoragePrivilege privilege; StoragePrivilege privilege;
PersistenceType defaultPersistenceType; PersistenceType defaultPersistenceType;
nsresult rv = QuotaManager::GetInfoForChrome(&group, &origin, &privilege,
QuotaManager::GetInfoFromWindow(nullptr, &group, &origin, &privilege, &defaultPersistenceType);
&defaultPersistenceType);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsRefPtr<IDBFactory> factory = new IDBFactory(); nsRefPtr<IDBFactory> factory = new IDBFactory();
factory->mGroup = group; factory->mGroup = group;
@ -231,6 +229,15 @@ IDBFactory::Create(ContentParent* aContentParent,
NS_ASSERTION(!nsContentUtils::GetCurrentJSContext(), "Should be called from C++"); NS_ASSERTION(!nsContentUtils::GetCurrentJSContext(), "Should be called from C++");
// We need to get this information before we push a null principal to avoid
// IsCallerChrome() assertion in quota manager.
nsCString group;
nsCString origin;
StoragePrivilege privilege;
PersistenceType defaultPersistenceType;
QuotaManager::GetInfoForChrome(&group, &origin, &privilege,
&defaultPersistenceType);
nsCOMPtr<nsIPrincipal> principal = nsCOMPtr<nsIPrincipal> principal =
do_CreateInstance("@mozilla.org/nullprincipal;1"); do_CreateInstance("@mozilla.org/nullprincipal;1");
NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE); NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE);
@ -253,9 +260,13 @@ IDBFactory::Create(ContentParent* aContentParent,
JSAutoCompartment ac(cx, global); JSAutoCompartment ac(cx, global);
nsRefPtr<IDBFactory> factory; nsRefPtr<IDBFactory> factory = new IDBFactory();
rv = Create(cx, global, aContentParent, getter_AddRefs(factory)); factory->mGroup = group;
NS_ENSURE_SUCCESS(rv, rv); factory->mASCIIOrigin = origin;
factory->mPrivilege = privilege;
factory->mDefaultPersistenceType = defaultPersistenceType;
factory->mOwningObject = global;
factory->mContentParent = aContentParent;
mozilla::HoldJSObjects(factory.get()); mozilla::HoldJSObjects(factory.get());
factory->mRootedOwningObject = true; factory->mRootedOwningObject = true;
@ -609,12 +620,7 @@ IDBFactory::OpenInternal(const nsAString& aName,
rv = openHelper->WaitForOpenAllowed(); rv = openHelper->WaitForOpenAllowed();
} }
else { else {
StoragePrivilege openerPrivilege; if (mPrivilege != Chrome &&
rv = QuotaManager::GetInfoFromWindow(window, nullptr, nullptr,
&openerPrivilege, nullptr);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (openerPrivilege != Chrome &&
aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) { aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
nsRefPtr<CheckPermissionsHelper> permissionHelper = nsRefPtr<CheckPermissionsHelper> permissionHelper =
new CheckPermissionsHelper(openHelper, window); new CheckPermissionsHelper(openHelper, window);

View File

@ -13,7 +13,7 @@
#include "mozilla/dom/IDBIndexBinding.h" #include "mozilla/dom/IDBIndexBinding.h"
#include "mozilla/dom/IDBObjectStoreBinding.h" #include "mozilla/dom/IDBObjectStoreBinding.h"
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
#include "nsThreadUtils.h" #include "MainThreadUtils.h"
#include "mozilla/dom/indexedDB/IDBRequest.h" #include "mozilla/dom/indexedDB/IDBRequest.h"
#include "mozilla/dom/indexedDB/IDBTransaction.h" #include "mozilla/dom/indexedDB/IDBTransaction.h"

View File

@ -23,6 +23,7 @@
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsPluginInstanceOwner.h" #include "nsPluginInstanceOwner.h"
#include "nsThreadUtils.h"
#include "nsIDOMElement.h" #include "nsIDOMElement.h"
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsIDocShell.h" #include "nsIDocShell.h"

View File

@ -19,7 +19,7 @@
#include "nsWeakPtr.h" #include "nsWeakPtr.h"
#include "nsIPrompt.h" #include "nsIPrompt.h"
#include "nsWeakReference.h" #include "nsWeakReference.h"
#include "nsThreadUtils.h" #include "MainThreadUtils.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "nsTObserverArray.h" #include "nsTObserverArray.h"
#include "nsITimer.h" #include "nsITimer.h"

View File

@ -18,6 +18,7 @@
#include "nsIWindowMediator.h" #include "nsIWindowMediator.h"
#include "nsIWinTaskbar.h" #include "nsIWinTaskbar.h"
#include "nsServiceManagerUtils.h" #include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
#include "WidgetUtils.h" #include "WidgetUtils.h"

View File

@ -20,7 +20,6 @@
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "nsStringGlue.h" #include "nsStringGlue.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "nsThreadUtils.h"
#include "prlog.h" #include "prlog.h"
#include "nsHashKeys.h" #include "nsHashKeys.h"
#ifdef MOZ_CRASHREPORTER #ifdef MOZ_CRASHREPORTER

View File

@ -925,27 +925,6 @@ GetTemporaryStorageLimit(nsIFile* aDirectory, uint64_t aCurrentUsage,
return NS_OK; return NS_OK;
} }
void
GetInfoForChrome(nsACString* aGroup, nsACString* aASCIIOrigin,
StoragePrivilege* aPrivilege,
PersistenceType* aDefaultPersistenceType)
{
static const char kChromeOrigin[] = "chrome";
if (aGroup) {
aGroup->AssignLiteral(kChromeOrigin);
}
if (aASCIIOrigin) {
aASCIIOrigin->AssignLiteral(kChromeOrigin);
}
if (aPrivilege) {
*aPrivilege = Chrome;
}
if (aDefaultPersistenceType) {
*aDefaultPersistenceType = PERSISTENCE_TYPE_PERSISTENT;
}
}
} // anonymous namespace } // anonymous namespace
QuotaManager::QuotaManager() QuotaManager::QuotaManager()
@ -2163,13 +2142,7 @@ QuotaManager::GetInfoFromWindow(nsPIDOMWindow* aWindow,
{ {
NS_ASSERTION(NS_IsMainThread(), NS_ASSERTION(NS_IsMainThread(),
"We're about to touch a window off the main thread!"); "We're about to touch a window off the main thread!");
NS_ASSERTION(aWindow, "Don't hand me a null window!");
if (!aWindow) {
NS_ASSERTION(nsContentUtils::IsCallerChrome(),
"Null window but not chrome!");
GetInfoForChrome(aGroup, aASCIIOrigin, aPrivilege, aDefaultPersistenceType);
return NS_OK;
}
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aWindow); nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aWindow);
NS_ENSURE_TRUE(sop, NS_ERROR_FAILURE); NS_ENSURE_TRUE(sop, NS_ERROR_FAILURE);
@ -2184,6 +2157,31 @@ QuotaManager::GetInfoFromWindow(nsPIDOMWindow* aWindow,
return NS_OK; return NS_OK;
} }
// static
void
QuotaManager::GetInfoForChrome(nsACString* aGroup,
nsACString* aASCIIOrigin,
StoragePrivilege* aPrivilege,
PersistenceType* aDefaultPersistenceType)
{
NS_ASSERTION(nsContentUtils::IsCallerChrome(), "Only for chrome!");
static const char kChromeOrigin[] = "chrome";
if (aGroup) {
aGroup->AssignLiteral(kChromeOrigin);
}
if (aASCIIOrigin) {
aASCIIOrigin->AssignLiteral(kChromeOrigin);
}
if (aPrivilege) {
*aPrivilege = Chrome;
}
if (aDefaultPersistenceType) {
*aDefaultPersistenceType = PERSISTENCE_TYPE_PERSISTENT;
}
}
NS_IMPL_ISUPPORTS2(QuotaManager, nsIQuotaManager, nsIObserver) NS_IMPL_ISUPPORTS2(QuotaManager, nsIQuotaManager, nsIObserver)
NS_IMETHODIMP NS_IMETHODIMP

View File

@ -17,7 +17,6 @@
#include "nsClassHashtable.h" #include "nsClassHashtable.h"
#include "nsRefPtrHashtable.h" #include "nsRefPtrHashtable.h"
#include "nsThreadUtils.h"
#include "ArrayCluster.h" #include "ArrayCluster.h"
#include "Client.h" #include "Client.h"
@ -33,6 +32,7 @@ class nsIThread;
class nsITimer; class nsITimer;
class nsIURI; class nsIURI;
class nsPIDOMWindow; class nsPIDOMWindow;
class nsIRunnable;
BEGIN_QUOTA_NAMESPACE BEGIN_QUOTA_NAMESPACE
@ -314,6 +314,12 @@ public:
StoragePrivilege* aPrivilege, StoragePrivilege* aPrivilege,
PersistenceType* aDefaultPersistenceType); PersistenceType* aDefaultPersistenceType);
static void
GetInfoForChrome(nsACString* aGroup,
nsACString* aASCIIOrigin,
StoragePrivilege* aPrivilege,
PersistenceType* aDefaultPersistenceType);
static void static void
GetOriginPatternString(uint32_t aAppId, bool aBrowserOnly, GetOriginPatternString(uint32_t aAppId, bool aBrowserOnly,
const nsACString& aOrigin, nsAutoCString& _retval) const nsACString& aOrigin, nsAutoCString& _retval)

View File

@ -15,7 +15,6 @@
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
#include "nsIDOMWindow.h" #include "nsIDOMWindow.h"
#include "nsIScriptObjectPrincipal.h" #include "nsIScriptObjectPrincipal.h"
#include "nsThreadUtils.h"
#include "nsDOMEventTargetHelper.h" #include "nsDOMEventTargetHelper.h"
#include "nsIDOMEvent.h" #include "nsIDOMEvent.h"

View File

@ -14,6 +14,7 @@
#include "nsXULAppAPI.h" #include "nsXULAppAPI.h"
#include "mozilla/unused.h" #include "mozilla/unused.h"
#include "nsProxyRelease.h" #include "nsProxyRelease.h"
#include "nsThreadUtils.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {

View File

@ -25,7 +25,6 @@
#include "nsRect.h" // for nsIntRect #include "nsRect.h" // for nsIntRect
#include "nsSize.h" // for nsIntSize #include "nsSize.h" // for nsIntSize
#include "nsTArray.h" // for nsTArray #include "nsTArray.h" // for nsTArray
#include "nsThreadUtils.h" // for NS_IsMainThread
#include "mozilla/Atomics.h" #include "mozilla/Atomics.h"
class nsMainThreadSurfaceRef; class nsMainThreadSurfaceRef;
@ -817,7 +816,6 @@ public:
virtual already_AddRefed<gfxASurface> GetAsSurface() virtual already_AddRefed<gfxASurface> GetAsSurface()
{ {
NS_ASSERTION(NS_IsMainThread(), "Must be main thread");
nsRefPtr<gfxASurface> surface = mSurface.get(); nsRefPtr<gfxASurface> surface = mSurface.get();
return surface.forget(); return surface.forget();
} }

View File

@ -16,8 +16,6 @@
#include "nsITimer.h" #include "nsITimer.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsIRunnable.h"
#include "nsThreadUtils.h"
#include "nsComponentManagerUtils.h" #include "nsComponentManagerUtils.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "nsAutoPtr.h" #include "nsAutoPtr.h"

View File

@ -239,12 +239,6 @@ IsBinaryArray(JSContext *cx, HandleObject obj)
return IsBlockOfKind(cx, obj, TypeRepresentation::Array); return IsBlockOfKind(cx, obj, TypeRepresentation::Array);
} }
static inline bool
IsBinaryStruct(JSContext *cx, HandleObject obj)
{
return IsBlockOfKind(cx, obj, TypeRepresentation::Struct);
}
const Class js::DataClass = { const Class js::DataClass = {
"Data", "Data",
JSCLASS_HAS_CACHED_PROTO(JSProto_Data), JSCLASS_HAS_CACHED_PROTO(JSProto_Data),

View File

@ -605,8 +605,6 @@ EmitNonLocalJumpFixup(ExclusiveContext *cx, BytecodeEmitter *bce, StmtInfoBCE *t
#undef FLUSH_POPS #undef FLUSH_POPS
} }
static const jsatomid INVALID_ATOMID = -1;
static ptrdiff_t static ptrdiff_t
EmitGoto(ExclusiveContext *cx, BytecodeEmitter *bce, StmtInfoBCE *toStmt, ptrdiff_t *lastp, EmitGoto(ExclusiveContext *cx, BytecodeEmitter *bce, StmtInfoBCE *toStmt, ptrdiff_t *lastp,
SrcNoteType noteType = SRC_NULL) SrcNoteType noteType = SRC_NULL)

View File

@ -564,6 +564,9 @@ new Uint8Array(buf)[0xfffff] = 0xAA;
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0); assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0);
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0xfffff),0xAA); assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0xfffff),0xAA);
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x100000),0); assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x100000),0);
var buf = new ArrayBuffer(0x104000);
new Uint8Array(buf)[0x103fff] = 0xAA;
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[0x103fff]|0; } return f'), this, null, buf)(),0xAA);
var buf = new ArrayBuffer(0x3f8000); var buf = new ArrayBuffer(0x3f8000);
new Uint8Array(buf)[0x3f7fff] = 0xAA; new Uint8Array(buf)[0x3f7fff] = 0xAA;
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0); assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0);
@ -576,6 +579,9 @@ assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'functi
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x3fc000),0); assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x3fc000),0);
var buf = new ArrayBuffer(0x3fe000); var buf = new ArrayBuffer(0x3fe000);
assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf); assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
var buf = new ArrayBuffer(0x410000);
new Uint8Array(buf)[0x40ffff] = 0xAA;
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[0x40ffff]|0; } return f'), this, null, buf)(),0xAA);
// The rest are getting too large for regular testing. // The rest are getting too large for regular testing.
//var buf = new ArrayBuffer(0xfe8000); //var buf = new ArrayBuffer(0xfe8000);
//assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf); //assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
@ -604,6 +610,9 @@ assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'funct
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0xff00000),0); //assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0xff00000),0);
//var buf = new ArrayBuffer(0xff80000); //var buf = new ArrayBuffer(0xff80000);
//assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf); //assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
//var buf = new ArrayBuffer(0x10400000);
//new Uint8Array(buf)[0x103fffff] = 0xAA;
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[0x103fffff]|0; } return f'), this, null, buf)(),0xAA);
//var buf = new ArrayBuffer(0x3fa00000); //var buf = new ArrayBuffer(0x3fa00000);
//assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf); //assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
//var buf = new ArrayBuffer(0x3fc00000); // 1020M //var buf = new ArrayBuffer(0x3fc00000); // 1020M

View File

@ -164,13 +164,6 @@ CaseBody(ParseNode *pn)
return BinaryRight(pn); return BinaryRight(pn);
} }
static inline JSAtom *
StringAtom(ParseNode *pn)
{
JS_ASSERT(pn->isKind(PNK_STRING));
return pn->pn_atom;
}
static inline bool static inline bool
IsExpressionStatement(ParseNode *pn) IsExpressionStatement(ParseNode *pn)
{ {
@ -285,19 +278,6 @@ FunctionStatementList(ParseNode *fn)
return last; return last;
} }
static inline ParseNode *
FunctionLastReturnStatementOrNull(ParseNode *fn)
{
ParseNode *listIter = ListHead(FunctionStatementList(fn));
ParseNode *lastReturn = NULL;
while (listIter) {
if (listIter->isKind(PNK_RETURN))
lastReturn = listIter;
listIter = listIter->pn_next;
}
return lastReturn;
}
static inline bool static inline bool
IsNormalObjectField(ExclusiveContext *cx, ParseNode *pn) IsNormalObjectField(ExclusiveContext *cx, ParseNode *pn)
{ {
@ -960,7 +940,7 @@ js::RoundUpToNextValidAsmJSHeapLength(uint32_t length)
return (length + 0x0003ffff) & ~0x0003ffff; return (length + 0x0003ffff) & ~0x0003ffff;
if (length < 0x10000000u) // < 256M quanta 1M if (length < 0x10000000u) // < 256M quanta 1M
return (length + 0x000fffff) & ~0x000fffff; return (length + 0x000fffff) & ~0x000fffff;
if (length < 0x10000000u) // < 1024M quanta 4M if (length < 0x40000000u) // < 1024M quanta 4M
return (length + 0x003fffff) & ~0x003fffff; return (length + 0x003fffff) & ~0x003fffff;
// < 4096M quanta 16M. Note zero is returned if over 0xff000000 but such // < 4096M quanta 16M. Note zero is returned if over 0xff000000 but such
// lengths are not currently valid. // lengths are not currently valid.
@ -1766,15 +1746,28 @@ class MOZ_STACK_CLASS ModuleCompiler
} }
} }
// Global-data-section accesses #if defined(JS_CPU_X86)
#if defined(JS_CPU_X86) || defined(JS_CPU_X64) // Global data accesses in x86 need to be patched with the absolute
// address of the global. Globals are allocated sequentially after the
// code section so we can just use an RelativeLink.
for (unsigned i = 0; i < globalAccesses_.length(); i++) {
AsmJSGlobalAccess a = globalAccesses_[i];
AsmJSStaticLinkData::RelativeLink link;
link.patchAtOffset = masm_.labelOffsetToPatchOffset(a.patchAt.offset());
link.targetOffset = module_->offsetOfGlobalData() + a.globalDataOffset;
if (!linkData->relativeLinks.append(link))
return false;
}
#endif
#if defined(JS_CPU_X64)
// Global data accesses on x64 use rip-relative addressing and thus do
// not need patching after deserialization.
uint8_t *code = module_->codeBase(); uint8_t *code = module_->codeBase();
for (unsigned i = 0; i < globalAccesses_.length(); i++) { for (unsigned i = 0; i < globalAccesses_.length(); i++) {
AsmJSGlobalAccess a = globalAccesses_[i]; AsmJSGlobalAccess a = globalAccesses_[i];
masm_.patchAsmJSGlobalAccess(a.offset, code, module_->globalData(), a.globalDataOffset); masm_.patchAsmJSGlobalAccess(a.patchAt, code, module_->globalData(), a.globalDataOffset);
} }
#else
JS_ASSERT(globalAccesses_.empty());
#endif #endif
*module = module_.forget(); *module = module_.forget();

View File

@ -224,8 +224,10 @@ DynamicallyLinkModule(JSContext *cx, CallArgs args, AsmJSModule &module)
// This check is sufficient without considering the size of the loaded datum because heap // This check is sufficient without considering the size of the loaded datum because heap
// loads and stores start on an aligned boundary and the heap byteLength has larger alignment. // loads and stores start on an aligned boundary and the heap byteLength has larger alignment.
JS_ASSERT((module.minHeapLength() - 1) <= INT32_MAX); JS_ASSERT((module.minHeapLength() - 1) <= INT32_MAX);
if (heap->byteLength() < module.minHeapLength()) if (heap->byteLength() < module.minHeapLength()) {
return LinkFail(cx, "ArrayBuffer byteLength less than the largest source code heap length constraint."); return LinkFail(cx, JS_smprintf("ArrayBuffer byteLength of 0x%x is less than 0x%x (which is the largest constant heap access offset rounded up to the next valid heap size).",
heap->byteLength(), module.minHeapLength()));
}
if (!ArrayBufferObject::prepareForAsmJS(cx, heap)) if (!ArrayBufferObject::prepareForAsmJS(cx, heap))
return LinkFail(cx, "Unable to prepare ArrayBuffer for asm.js use"); return LinkFail(cx, "Unable to prepare ArrayBuffer for asm.js use");

View File

@ -26,6 +26,7 @@
#include "jit/ParallelFunctions.h" #include "jit/ParallelFunctions.h"
#include "jit/ParallelSafetyAnalysis.h" #include "jit/ParallelSafetyAnalysis.h"
#include "jit/PerfSpewer.h" #include "jit/PerfSpewer.h"
#include "jit/RangeAnalysis.h"
#include "vm/ForkJoin.h" #include "vm/ForkJoin.h"
#include "jsboolinlines.h" #include "jsboolinlines.h"

View File

@ -1180,19 +1180,6 @@ jit::BuildPhiReverseMapping(MIRGraph &graph)
return true; return true;
} }
static inline MBasicBlock *
SkipContainedLoop(MBasicBlock *block, MBasicBlock *header)
{
while (block->loopHeader() || block->isLoopHeader()) {
if (block->loopHeader())
block = block->loopHeader();
if (block == header)
break;
block = block->loopPredecessor();
}
return block;
}
#ifdef DEBUG #ifdef DEBUG
static bool static bool
CheckSuccessorImpliesPredecessor(MBasicBlock *A, MBasicBlock *B) CheckSuccessorImpliesPredecessor(MBasicBlock *A, MBasicBlock *B)

View File

@ -695,6 +695,7 @@ MarkCalleeToken(JSTracer *trc, CalleeToken token)
} }
} }
#ifdef JS_NUNBOX32
static inline uintptr_t static inline uintptr_t
ReadAllocation(const IonFrameIterator &frame, const LAllocation *a) ReadAllocation(const IonFrameIterator &frame, const LAllocation *a)
{ {
@ -710,6 +711,7 @@ ReadAllocation(const IonFrameIterator &frame, const LAllocation *a)
uint8_t *argv = reinterpret_cast<uint8_t *>(frame.jsFrame()->argv()); uint8_t *argv = reinterpret_cast<uint8_t *>(frame.jsFrame()->argv());
return *reinterpret_cast<uintptr_t *>(argv + index); return *reinterpret_cast<uintptr_t *>(argv + index);
} }
#endif
static void static void
MarkActualArguments(JSTracer *trc, const IonFrameIterator &frame) MarkActualArguments(JSTracer *trc, const IonFrameIterator &frame)
@ -725,6 +727,7 @@ MarkActualArguments(JSTracer *trc, const IonFrameIterator &frame)
gc::MarkValueRoot(trc, &argv[i], "ion-argv"); gc::MarkValueRoot(trc, &argv[i], "ion-argv");
} }
#ifdef JS_NUNBOX32
static inline void static inline void
WriteAllocation(const IonFrameIterator &frame, const LAllocation *a, uintptr_t value) WriteAllocation(const IonFrameIterator &frame, const LAllocation *a, uintptr_t value)
{ {
@ -742,6 +745,7 @@ WriteAllocation(const IonFrameIterator &frame, const LAllocation *a, uintptr_t v
uint8_t *argv = reinterpret_cast<uint8_t *>(frame.jsFrame()->argv()); uint8_t *argv = reinterpret_cast<uint8_t *>(frame.jsFrame()->argv());
*reinterpret_cast<uintptr_t *>(argv + index) = value; *reinterpret_cast<uintptr_t *>(argv + index) = value;
} }
#endif
static void static void
MarkIonJSFrame(JSTracer *trc, const IonFrameIterator &frame) MarkIonJSFrame(JSTracer *trc, const IonFrameIterator &frame)

View File

@ -54,7 +54,7 @@ FilterContainsLocation(HandleScript function)
const char *filename = function->filename(); const char *filename = function->filename();
const size_t line = function->lineno; const size_t line = function->lineno;
static size_t filelen = strlen(filename); const size_t filelen = strlen(filename);
const char *index = strstr(filter, filename); const char *index = strstr(filter, filename);
while (index) { while (index) {
if (index == filter || index[-1] == ',') { if (index == filter || index[-1] == ',') {

View File

@ -7,7 +7,6 @@
#ifndef jit_LIR_Common_h #ifndef jit_LIR_Common_h
#define jit_LIR_Common_h #define jit_LIR_Common_h
#include "jit/RangeAnalysis.h"
#include "jit/shared/Assembler-shared.h" #include "jit/shared/Assembler-shared.h"
// This file declares LIR instructions that are common to every platform. // This file declares LIR instructions that are common to every platform.
@ -15,6 +14,8 @@
namespace js { namespace js {
namespace jit { namespace jit {
class Range;
template <size_t Temps, size_t ExtraUses = 0> template <size_t Temps, size_t ExtraUses = 0>
class LBinaryMath : public LInstructionHelper<1, 2 + ExtraUses, Temps> class LBinaryMath : public LInstructionHelper<1, 2 + ExtraUses, Temps>
{ {

View File

@ -2663,7 +2663,7 @@ LIRGenerator::visitAssertRange(MAssertRange *ins)
switch (input->type()) { switch (input->type()) {
case MIRType_Int32: case MIRType_Int32:
lir = new LAssertRangeI(useRegisterAtStart(input)); lir = new LAssertRangeI(useRegisterAtStart(input));
break; break;
case MIRType_Double: case MIRType_Double:

View File

@ -1328,14 +1328,6 @@ MMod::canBePowerOfTwoDivisor() const
return true; return true;
} }
static inline MDefinition *
TryFold(MDefinition *original, MDefinition *replacement)
{
if (original->type() == replacement->type())
return replacement;
return original;
}
MDefinition * MDefinition *
MMod::foldsTo(bool useValueNumbers) MMod::foldsTo(bool useValueNumbers)
{ {
@ -2381,24 +2373,15 @@ MNot::foldsTo(bool useValueNumbers)
return this; return this;
} }
bool
MBoundsCheckLower::fallible()
{
return !range() || range()->lower() < minimum_;
}
void void
MBeta::printOpcode(FILE *fp) const MBeta::printOpcode(FILE *fp) const
{ {
PrintOpcodeName(fp, op()); MDefinition::printOpcode(fp);
fprintf(fp, " ");
getOperand(0)->printName(fp);
fprintf(fp, " ");
Sprinter sp(GetIonContext()->cx); Sprinter sp(GetIonContext()->cx);
sp.init(); sp.init();
comparison_->print(sp); comparison_->print(sp);
fprintf(fp, "%s", sp.string()); fprintf(fp, " %s", sp.string());
} }
bool bool

View File

@ -4974,9 +4974,10 @@ class MBoundsCheckLower
: public MUnaryInstruction : public MUnaryInstruction
{ {
int32_t minimum_; int32_t minimum_;
bool fallible_;
MBoundsCheckLower(MDefinition *index) MBoundsCheckLower(MDefinition *index)
: MUnaryInstruction(index), minimum_(0) : MUnaryInstruction(index), minimum_(0), fallible_(true)
{ {
setGuard(); setGuard();
setMovable(); setMovable();
@ -5002,7 +5003,10 @@ class MBoundsCheckLower
AliasSet getAliasSet() const { AliasSet getAliasSet() const {
return AliasSet::None(); return AliasSet::None();
} }
bool fallible(); bool fallible() const {
return fallible_;
}
void collectRangeInfo();
}; };
// Load a value from a dense array's element vector and does a hole check if the // Load a value from a dense array's element vector and does a hole check if the
@ -8455,7 +8459,7 @@ class MAsmJSStoreHeap : public MBinaryInstruction, public MAsmJSHeapAccess
class MAsmJSLoadGlobalVar : public MNullaryInstruction class MAsmJSLoadGlobalVar : public MNullaryInstruction
{ {
MAsmJSLoadGlobalVar(MIRType type, unsigned globalDataOffset, bool isConstant) MAsmJSLoadGlobalVar(MIRType type, unsigned globalDataOffset, bool isConstant)
: globalDataOffset_(globalDataOffset), isConstant_(isConstant) : globalDataOffset_(globalDataOffset)
{ {
JS_ASSERT(type == MIRType_Int32 || type == MIRType_Double); JS_ASSERT(type == MIRType_Int32 || type == MIRType_Double);
setResultType(type); setResultType(type);
@ -8463,7 +8467,6 @@ class MAsmJSLoadGlobalVar : public MNullaryInstruction
} }
unsigned globalDataOffset_; unsigned globalDataOffset_;
bool isConstant_;
public: public:
INSTRUCTION_HEADER(AsmJSLoadGlobalVar); INSTRUCTION_HEADER(AsmJSLoadGlobalVar);

View File

@ -28,18 +28,6 @@ class MBasicBlock;
class MIRGraph; class MIRGraph;
class MStart; class MStart;
struct AsmJSGlobalAccess
{
unsigned offset;
unsigned globalDataOffset;
AsmJSGlobalAccess(unsigned offset, unsigned globalDataOffset)
: offset(offset), globalDataOffset(globalDataOffset)
{}
};
typedef Vector<AsmJSGlobalAccess, 0, IonAllocPolicy> AsmJSGlobalAccessVector;
class MIRGenerator class MIRGenerator
{ {
public: public:

View File

@ -15,7 +15,6 @@
#include "jit/LIR.h" #include "jit/LIR.h"
#include "jit/MIR.h" #include "jit/MIR.h"
#include "jit/MIRGraph.h" #include "jit/MIRGraph.h"
#include "jit/RangeAnalysis.h"
// perf expects its data to be in a file /tmp/perf-PID.map, but for Android // perf expects its data to be in a file /tmp/perf-PID.map, but for Android
// and B2G the map files are written to /data/local/tmp/perf-PID.map // and B2G the map files are written to /data/local/tmp/perf-PID.map

View File

@ -269,11 +269,11 @@ Range::print(Sprinter &sp) const
JS_ASSERT_IF(lower_infinite_, lower_ == JSVAL_INT_MIN); JS_ASSERT_IF(lower_infinite_, lower_ == JSVAL_INT_MIN);
JS_ASSERT_IF(upper_infinite_, upper_ == JSVAL_INT_MAX); JS_ASSERT_IF(upper_infinite_, upper_ == JSVAL_INT_MAX);
// Real or Natural subset. // Floating-point or Integer subset.
if (canHaveFractionalPart_) if (canHaveFractionalPart_)
sp.printf("R"); sp.printf("F");
else else
sp.printf("N"); sp.printf("I");
sp.printf("["); sp.printf("[");
@ -352,21 +352,21 @@ Range::intersect(const Range *lhs, const Range *rhs, bool *emptyRange)
void void
Range::unionWith(const Range *other) Range::unionWith(const Range *other)
{ {
bool canHaveFractionalPart = canHaveFractionalPart_ | other->canHaveFractionalPart_; bool canHaveFractionalPart = canHaveFractionalPart_ | other->canHaveFractionalPart_;
uint16_t max_exponent = Max(max_exponent_, other->max_exponent_); uint16_t max_exponent = Max(max_exponent_, other->max_exponent_);
if (lower_infinite_ || other->lower_infinite_) if (lower_infinite_ || other->lower_infinite_)
makeLowerInfinite(); makeLowerInfinite();
else else
setLowerInit(Min(lower_, other->lower_)); setLowerInit(Min(lower_, other->lower_));
if (upper_infinite_ || other->upper_infinite_) if (upper_infinite_ || other->upper_infinite_)
makeUpperInfinite(); makeUpperInfinite();
else else
setUpperInit(Max(upper_, other->upper_)); setUpperInit(Max(upper_, other->upper_));
canHaveFractionalPart_ = canHaveFractionalPart; canHaveFractionalPart_ = canHaveFractionalPart;
max_exponent_ = max_exponent; max_exponent_ = max_exponent;
} }
static const int64_t RANGE_INF_MAX = int64_t(JSVAL_INT_MAX) + 1; static const int64_t RANGE_INF_MAX = int64_t(JSVAL_INT_MAX) + 1;
@ -824,10 +824,8 @@ MConstant::computeRange()
int exp = Range::MaxDoubleExponent; int exp = Range::MaxDoubleExponent;
// NaN is estimated as a Double which covers everything. // NaN is estimated as a Double which covers everything.
if (IsNaN(d)) { if (IsNaN(d))
setRange(new Range(RANGE_INF_MIN, RANGE_INF_MAX, true, exp));
return; return;
}
// Infinity is used to set both lower and upper to the range boundaries. // Infinity is used to set both lower and upper to the range boundaries.
if (IsInfinite(d)) { if (IsInfinite(d)) {
@ -1540,6 +1538,7 @@ ConvertLinearSum(MBasicBlock *block, const LinearSum &sum)
def = MAdd::New(def, term.term); def = MAdd::New(def, term.term);
def->toAdd()->setInt32(); def->toAdd()->setInt32();
block->insertBefore(block->lastIns(), def->toInstruction()); block->insertBefore(block->lastIns(), def->toInstruction());
def->computeRange();
} else { } else {
def = term.term; def = term.term;
} }
@ -1547,10 +1546,12 @@ ConvertLinearSum(MBasicBlock *block, const LinearSum &sum)
if (!def) { if (!def) {
def = MConstant::New(Int32Value(0)); def = MConstant::New(Int32Value(0));
block->insertBefore(block->lastIns(), def->toInstruction()); block->insertBefore(block->lastIns(), def->toInstruction());
def->computeRange();
} }
def = MSub::New(def, term.term); def = MSub::New(def, term.term);
def->toSub()->setInt32(); def->toSub()->setInt32();
block->insertBefore(block->lastIns(), def->toInstruction()); block->insertBefore(block->lastIns(), def->toInstruction());
def->computeRange();
} else { } else {
JS_ASSERT(term.scale != 0); JS_ASSERT(term.scale != 0);
MConstant *factor = MConstant::New(Int32Value(term.scale)); MConstant *factor = MConstant::New(Int32Value(term.scale));
@ -1558,10 +1559,12 @@ ConvertLinearSum(MBasicBlock *block, const LinearSum &sum)
MMul *mul = MMul::New(term.term, factor); MMul *mul = MMul::New(term.term, factor);
mul->setInt32(); mul->setInt32();
block->insertBefore(block->lastIns(), mul); block->insertBefore(block->lastIns(), mul);
mul->computeRange();
if (def) { if (def) {
def = MAdd::New(def, mul); def = MAdd::New(def, mul);
def->toAdd()->setInt32(); def->toAdd()->setInt32();
block->insertBefore(block->lastIns(), def->toInstruction()); block->insertBefore(block->lastIns(), def->toInstruction());
def->computeRange();
} else { } else {
def = mul; def = mul;
} }
@ -1571,6 +1574,7 @@ ConvertLinearSum(MBasicBlock *block, const LinearSum &sum)
if (!def) { if (!def) {
def = MConstant::New(Int32Value(0)); def = MConstant::New(Int32Value(0));
block->insertBefore(block->lastIns(), def->toInstruction()); block->insertBefore(block->lastIns(), def->toInstruction());
def->computeRange();
} }
return def; return def;
@ -1623,8 +1627,6 @@ RangeAnalysis::tryHoistBoundsCheck(MBasicBlock *header, MBoundsCheck *ins)
return false; return false;
if (!SafeSub(lowerConstant, lower->sum.constant(), &lowerConstant)) if (!SafeSub(lowerConstant, lower->sum.constant(), &lowerConstant))
return false; return false;
MBoundsCheckLower *lowerCheck = MBoundsCheckLower::New(lowerTerm);
lowerCheck->setMinimum(lowerConstant);
// We are checking that index < boundsLength, and know that // We are checking that index < boundsLength, and know that
// index <= upperTerm + upperConstant. Thus, check that: // index <= upperTerm + upperConstant. Thus, check that:
@ -1634,6 +1636,10 @@ RangeAnalysis::tryHoistBoundsCheck(MBasicBlock *header, MBoundsCheck *ins)
int32_t upperConstant = index.constant; int32_t upperConstant = index.constant;
if (!SafeAdd(upper->sum.constant(), upperConstant, &upperConstant)) if (!SafeAdd(upper->sum.constant(), upperConstant, &upperConstant))
return false; return false;
MBoundsCheckLower *lowerCheck = MBoundsCheckLower::New(lowerTerm);
lowerCheck->setMinimum(lowerConstant);
MBoundsCheck *upperCheck = MBoundsCheck::New(upperTerm, ins->length()); MBoundsCheck *upperCheck = MBoundsCheck::New(upperTerm, ins->length());
upperCheck->setMinimum(upperConstant); upperCheck->setMinimum(upperConstant);
upperCheck->setMaximum(upperConstant); upperCheck->setMaximum(upperConstant);
@ -2143,3 +2149,9 @@ MMod::collectRangeInfo()
{ {
canBeNegativeDividend_ = !lhs()->range() || lhs()->range()->lower() < 0; canBeNegativeDividend_ = !lhs()->range() || lhs()->range()->lower() < 0;
} }
void
MBoundsCheckLower::collectRangeInfo()
{
fallible_ = !index()->range() || index()->range()->lower() < minimum_;
}

View File

@ -204,9 +204,6 @@ class Range : public TempObject {
void print(Sprinter &sp) const; void print(Sprinter &sp) const;
bool update(const Range *other); bool update(const Range *other);
bool update(const Range &other) {
return update(&other);
}
// Unlike the other operations, unionWith is an in-place // Unlike the other operations, unionWith is an in-place
// modification. This is to avoid a bunch of useless extra // modification. This is to avoid a bunch of useless extra
@ -233,67 +230,62 @@ class Range : public TempObject {
static bool negativeZeroMul(const Range *lhs, const Range *rhs); static bool negativeZeroMul(const Range *lhs, const Range *rhs);
inline void makeLowerInfinite() { void makeLowerInfinite() {
lower_infinite_ = true; lower_infinite_ = true;
lower_ = JSVAL_INT_MIN; lower_ = JSVAL_INT_MIN;
if (max_exponent_ < MaxInt32Exponent) if (max_exponent_ < MaxInt32Exponent)
max_exponent_ = MaxInt32Exponent; max_exponent_ = MaxInt32Exponent;
} }
inline void makeUpperInfinite() { void makeUpperInfinite() {
upper_infinite_ = true; upper_infinite_ = true;
upper_ = JSVAL_INT_MAX; upper_ = JSVAL_INT_MAX;
if (max_exponent_ < MaxInt32Exponent) if (max_exponent_ < MaxInt32Exponent)
max_exponent_ = MaxInt32Exponent; max_exponent_ = MaxInt32Exponent;
} }
inline void makeRangeInfinite() {
makeLowerInfinite();
makeUpperInfinite();
max_exponent_ = MaxDoubleExponent;
}
inline bool isLowerInfinite() const { bool isLowerInfinite() const {
return lower_infinite_; return lower_infinite_;
} }
inline bool isUpperInfinite() const { bool isUpperInfinite() const {
return upper_infinite_; return upper_infinite_;
} }
inline bool isInt32() const { bool isInt32() const {
return !isLowerInfinite() && !isUpperInfinite(); return !isLowerInfinite() && !isUpperInfinite();
} }
inline bool isBoolean() const { bool isBoolean() const {
return lower() >= 0 && upper() <= 1; return lower() >= 0 && upper() <= 1;
} }
inline bool hasRoundingErrors() const { bool hasRoundingErrors() const {
return canHaveFractionalPart() || exponent() >= MaxTruncatableExponent; return canHaveFractionalPart() || exponent() >= MaxTruncatableExponent;
} }
inline bool isInfinite() const { bool isInfinite() const {
return exponent() >= MaxDoubleExponent; return exponent() >= MaxDoubleExponent;
} }
inline bool canHaveFractionalPart() const { bool canHaveFractionalPart() const {
return canHaveFractionalPart_; return canHaveFractionalPart_;
} }
inline uint16_t exponent() const { uint16_t exponent() const {
return max_exponent_; return max_exponent_;
} }
inline uint16_t numBits() const { uint16_t numBits() const {
return max_exponent_ + 1; // 2^0 -> 1 return max_exponent_ + 1; // 2^0 -> 1
} }
inline int32_t lower() const { int32_t lower() const {
return lower_; return lower_;
} }
inline int32_t upper() const { int32_t upper() const {
return upper_; return upper_;
} }
inline void setLowerInit(int64_t x) { void setLowerInit(int64_t x) {
if (x > JSVAL_INT_MAX) { // c.c if (x > JSVAL_INT_MAX) { // c.c
lower_ = JSVAL_INT_MAX; lower_ = JSVAL_INT_MAX;
lower_infinite_ = false; lower_infinite_ = false;
@ -304,12 +296,12 @@ class Range : public TempObject {
lower_infinite_ = false; lower_infinite_ = false;
} }
} }
inline void setLower(int64_t x) { void setLower(int64_t x) {
setLowerInit(x); setLowerInit(x);
rectifyExponent(); rectifyExponent();
JS_ASSERT_IF(lower_infinite_, lower_ == JSVAL_INT_MIN); JS_ASSERT_IF(lower_infinite_, lower_ == JSVAL_INT_MIN);
} }
inline void setUpperInit(int64_t x) { void setUpperInit(int64_t x) {
if (x > JSVAL_INT_MAX) { if (x > JSVAL_INT_MAX) {
makeUpperInfinite(); makeUpperInfinite();
} else if (x < JSVAL_INT_MIN) { // c.c } else if (x < JSVAL_INT_MIN) { // c.c
@ -320,20 +312,20 @@ class Range : public TempObject {
upper_infinite_ = false; upper_infinite_ = false;
} }
} }
inline void setUpper(int64_t x) { void setUpper(int64_t x) {
setUpperInit(x); setUpperInit(x);
rectifyExponent(); rectifyExponent();
JS_ASSERT_IF(upper_infinite_, upper_ == JSVAL_INT_MAX); JS_ASSERT_IF(upper_infinite_, upper_ == JSVAL_INT_MAX);
} }
inline void setInt32() { void setInt32() {
lower_infinite_ = false; lower_infinite_ = false;
upper_infinite_ = false; upper_infinite_ = false;
canHaveFractionalPart_ = false; canHaveFractionalPart_ = false;
max_exponent_ = MaxInt32Exponent; max_exponent_ = MaxInt32Exponent;
} }
inline void set(int64_t l, int64_t h, bool f = false, uint16_t e = MaxInt32Exponent) { void set(int64_t l, int64_t h, bool f = false, uint16_t e = MaxInt32Exponent) {
max_exponent_ = e; max_exponent_ = e;
setLowerInit(l); setLowerInit(l);
setUpperInit(h); setUpperInit(h);
@ -374,7 +366,7 @@ class Range : public TempObject {
// Note: // Note:
// exponent of JSVAL_INT_MIN == 32 // exponent of JSVAL_INT_MIN == 32
// exponent of JSVAL_INT_MAX == 31 // exponent of JSVAL_INT_MAX == 31
inline void rectifyExponent() { void rectifyExponent() {
if (!isInt32()) { if (!isInt32()) {
JS_ASSERT(max_exponent_ >= MaxInt32Exponent); JS_ASSERT(max_exponent_ >= MaxInt32Exponent);
return; return;
@ -394,10 +386,10 @@ class Range : public TempObject {
return symbolicUpper_; return symbolicUpper_;
} }
inline void setSymbolicLower(SymbolicBound *bound) { void setSymbolicLower(SymbolicBound *bound) {
symbolicLower_ = bound; symbolicLower_ = bound;
} }
inline void setSymbolicUpper(SymbolicBound *bound) { void setSymbolicUpper(SymbolicBound *bound) {
symbolicUpper_ = bound; symbolicUpper_ = bound;
} }
}; };

View File

@ -613,6 +613,18 @@ class CodeLocationLabel
} }
}; };
struct AsmJSGlobalAccess
{
CodeOffsetLabel patchAt;
unsigned globalDataOffset;
AsmJSGlobalAccess(CodeOffsetLabel patchAt, unsigned globalDataOffset)
: patchAt(patchAt), globalDataOffset(globalDataOffset)
{}
};
typedef Vector<AsmJSGlobalAccess, 0, IonAllocPolicy> AsmJSGlobalAccessVector;
} // namespace jit } // namespace jit
} // namespace js } // namespace js

View File

@ -1174,10 +1174,10 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
} }
// See CodeGeneratorX64 calls to noteAsmJSGlobalAccess. // See CodeGeneratorX64 calls to noteAsmJSGlobalAccess.
void patchAsmJSGlobalAccess(unsigned offset, uint8_t *code, uint8_t *globalData, void patchAsmJSGlobalAccess(CodeOffsetLabel patchAt, uint8_t *code, uint8_t *globalData,
unsigned globalDataOffset) unsigned globalDataOffset)
{ {
uint8_t *nextInsn = code + offset; uint8_t *nextInsn = code + patchAt.offset();
JS_ASSERT(nextInsn <= globalData); JS_ASSERT(nextInsn <= globalData);
uint8_t *target = globalData + globalDataOffset; uint8_t *target = globalData + globalDataOffset;
((int32_t *)nextInsn)[-1] = target - nextInsn; ((int32_t *)nextInsn)[-1] = target - nextInsn;

View File

@ -1065,16 +1065,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
call(code); call(code);
addl(Imm32(sizeof(uintptr_t) * 2), esp); addl(Imm32(sizeof(uintptr_t) * 2), esp);
} }
// See CodeGeneratorX86 calls to noteAsmJSGlobalAccess.
void patchAsmJSGlobalAccess(unsigned offset, uint8_t *code, uint8_t *globalData,
unsigned globalDataOffset)
{
uint8_t *nextInsn = code + offset;
JS_ASSERT(nextInsn <= globalData);
uint8_t *target = globalData + globalDataOffset;
((int32_t *)nextInsn)[-1] = uintptr_t(target);
}
}; };
typedef MacroAssemblerX86 MacroAssemblerSpecific; typedef MacroAssemblerX86 MacroAssemblerSpecific;

View File

@ -15,10 +15,10 @@
using namespace js; using namespace js;
using namespace js::crash; using namespace js::crash;
static const int stack_snapshot_max_size = 32768;
#if defined(XP_WIN) #if defined(XP_WIN)
static const int stack_snapshot_max_size = 32768;
#include <windows.h> #include <windows.h>
static bool static bool

View File

@ -52,11 +52,6 @@ id_prototype(JSContext *cx) {
return NameToId(cx->names().classPrototype); return NameToId(cx->names().classPrototype);
} }
static inline jsid
id_length(JSContext *cx) {
return NameToId(cx->names().length);
}
static inline jsid static inline jsid
id___proto__(JSContext *cx) { id___proto__(JSContext *cx) {
return NameToId(cx->names().proto); return NameToId(cx->names().proto);
@ -2737,24 +2732,6 @@ TypeObject::print()
// Type Analysis // Type Analysis
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
static inline TypeObject *
GetInitializerType(JSContext *cx, JSScript *script, jsbytecode *pc)
{
if (!script->compileAndGo)
return NULL;
JSOp op = JSOp(*pc);
JS_ASSERT(op == JSOP_NEWARRAY || op == JSOP_NEWOBJECT || op == JSOP_NEWINIT);
bool isArray = (op == JSOP_NEWARRAY || (op == JSOP_NEWINIT && GET_UINT8(pc) == JSProto_Array));
JSProtoKey key = isArray ? JSProto_Array : JSProto_Object;
if (UseNewTypeForInitializer(cx, script, pc, key))
return NULL;
return TypeScript::InitObject(cx, script, pc, key);
}
/* /*
* Persistent constraint clearing out newScript and definite properties from * Persistent constraint clearing out newScript and definite properties from
* an object should a property on another object get a getter or setter. * an object should a property on another object get a getter or setter.
@ -3200,78 +3177,6 @@ types::UseNewTypeForClone(JSFunction *fun)
// TypeScript // TypeScript
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
/*
* Returns true if we don't expect to compute the correct types for some value
* pushed by the specified bytecode.
*/
static inline bool
IgnorePushed(const jsbytecode *pc, unsigned index)
{
switch (JSOp(*pc)) {
/* We keep track of the scopes pushed by BINDNAME separately. */
case JSOP_BINDNAME:
case JSOP_BINDGNAME:
case JSOP_BINDINTRINSIC:
return true;
/* Stack not consistent in TRY_BRANCH_AFTER_COND. */
case JSOP_IN:
case JSOP_EQ:
case JSOP_NE:
case JSOP_LT:
case JSOP_LE:
case JSOP_GT:
case JSOP_GE:
return (index == 0);
/* Value not determining result is not pushed by OR/AND. */
case JSOP_OR:
case JSOP_AND:
return (index == 0);
/* Holes tracked separately. */
case JSOP_HOLE:
return (index == 0);
/* Storage for 'with' and 'let' blocks not monitored. */
case JSOP_ENTERWITH:
case JSOP_ENTERBLOCK:
case JSOP_ENTERLET0:
case JSOP_ENTERLET1:
return true;
/* We don't keep track of the iteration state for 'for in' or 'for each in' loops. */
case JSOP_ITER:
case JSOP_ITERNEXT:
case JSOP_MOREITER:
case JSOP_ENDITER:
return true;
/* Ops which can manipulate values pushed by opcodes we don't model. */
case JSOP_DUP:
case JSOP_DUP2:
case JSOP_SWAP:
case JSOP_PICK:
return true;
/* We don't keep track of state indicating whether there is a pending exception. */
case JSOP_FINALLY:
return true;
/*
* We don't treat GETLOCAL immediately followed by a pop as a use-before-def,
* and while the type will have been inferred correctly the method JIT
* may not have written the local's initial undefined value to the stack,
* leaving a stale value.
*/
case JSOP_GETLOCAL:
return JSOp(pc[JSOP_GETLOCAL_LENGTH]) == JSOP_POP;
default:
return false;
}
}
bool bool
JSScript::makeTypes(JSContext *cx) JSScript::makeTypes(JSContext *cx)
{ {

View File

@ -1963,7 +1963,6 @@ JSScript::finalize(FreeOp *fop)
} }
static const uint32_t GSN_CACHE_THRESHOLD = 100; static const uint32_t GSN_CACHE_THRESHOLD = 100;
static const uint32_t GSN_CACHE_MAP_INIT_SIZE = 20;
void void
GSNCache::purge() GSNCache::purge()

View File

@ -2718,13 +2718,6 @@ GetScriptReferent(JSObject *obj)
return static_cast<JSScript *>(obj->getPrivate()); return static_cast<JSScript *>(obj->getPrivate());
} }
static inline void
SetScriptReferent(JSObject *obj, JSScript *script)
{
JS_ASSERT(obj->getClass() == &DebuggerScript_class);
obj->setPrivateGCThing(script);
}
static void static void
DebuggerScript_trace(JSTracer *trc, JSObject *obj) DebuggerScript_trace(JSTracer *trc, JSObject *obj)
{ {

View File

@ -60,17 +60,6 @@ using namespace js::types;
using mozilla::DebugOnly; using mozilla::DebugOnly;
using mozilla::PodCopy; using mozilla::PodCopy;
/* Some objects (e.g., With) delegate 'this' to another object. */
static inline JSObject *
CallThisObjectHook(JSContext *cx, HandleObject obj, Value *argv)
{
JSObject *thisp = JSObject::thisObject(cx, obj);
if (!thisp)
return NULL;
argv[-1].setObject(*thisp);
return thisp;
}
/* /*
* Note: when Clang 3.2 (32-bit) inlines the two functions below in Interpret, * Note: when Clang 3.2 (32-bit) inlines the two functions below in Interpret,
* the conservative stack scanner leaks a ton of memory and this negatively * the conservative stack scanner leaks a ton of memory and this negatively

View File

@ -1302,11 +1302,6 @@ template<> inline const int TypeIDOfType<float>() { return ScalarTypeRepresentat
template<> inline const int TypeIDOfType<double>() { return ScalarTypeRepresentation::TYPE_FLOAT64; } template<> inline const int TypeIDOfType<double>() { return ScalarTypeRepresentation::TYPE_FLOAT64; }
template<> inline const int TypeIDOfType<uint8_clamped>() { return ScalarTypeRepresentation::TYPE_UINT8_CLAMPED; } template<> inline const int TypeIDOfType<uint8_clamped>() { return ScalarTypeRepresentation::TYPE_UINT8_CLAMPED; }
template<typename NativeType> static inline const bool ElementTypeMayBeDouble() { return false; }
template<> inline const bool ElementTypeMayBeDouble<uint32_t>() { return true; }
template<> inline const bool ElementTypeMayBeDouble<float>() { return true; }
template<> inline const bool ElementTypeMayBeDouble<double>() { return true; }
template<typename ElementType> template<typename ElementType>
static inline JSObject * static inline JSObject *
NewArray(JSContext *cx, uint32_t nelements); NewArray(JSContext *cx, uint32_t nelements);
@ -1334,7 +1329,6 @@ class TypedArrayObjectTemplate : public TypedArrayObject
static const int ArrayTypeID() { return TypeIDOfType<NativeType>(); } static const int ArrayTypeID() { return TypeIDOfType<NativeType>(); }
static const bool ArrayTypeIsUnsigned() { return TypeIsUnsigned<NativeType>(); } static const bool ArrayTypeIsUnsigned() { return TypeIsUnsigned<NativeType>(); }
static const bool ArrayTypeIsFloatingPoint() { return TypeIsFloatingPoint<NativeType>(); } static const bool ArrayTypeIsFloatingPoint() { return TypeIsFloatingPoint<NativeType>(); }
static const bool ArrayElementTypeMayBeDouble() { return ElementTypeMayBeDouble<NativeType>(); }
static const size_t BYTES_PER_ELEMENT = sizeof(ThisType); static const size_t BYTES_PER_ELEMENT = sizeof(ThisType);

View File

@ -127,7 +127,7 @@
#include "nsXPIDLString.h" #include "nsXPIDLString.h"
#include "nsAutoJSValHolder.h" #include "nsAutoJSValHolder.h"
#include "nsThreadUtils.h" #include "MainThreadUtils.h"
#include "nsIJSEngineTelemetryStats.h" #include "nsIJSEngineTelemetryStats.h"
#include "nsIConsoleService.h" #include "nsIConsoleService.h"

View File

@ -6,7 +6,9 @@
#define nsLayoutStatics_h__ #define nsLayoutStatics_h__
#include "nscore.h" #include "nscore.h"
#include "nsThreadUtils.h" #include "MainThreadUtils.h"
#include "nsTraceRefcnt.h"
#include "nsDebug.h"
// This isn't really a class, it's a namespace for static methods. // This isn't really a class, it's a namespace for static methods.
// Documents and other objects can hold a reference to the layout static // Documents and other objects can hold a reference to the layout static

View File

@ -16,7 +16,12 @@
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
setTimeout(focusing, 0); if (navigator.userAgent.indexOf("Windows NT 6.2") >= 0) {
todo(false, "Too many intermittent failures on Windows 8 (bug 886781)");
SimpleTest.finish();
} else {
setTimeout(focusing, 0);
}
function focusing() { function focusing() {
document.getElementById("editor").focus(); document.getElementById("editor").focus();

View File

@ -1490,7 +1490,7 @@ skip-if(B2G) fuzzy-if(Android&&AndroidVersion>=15,12,300) == 551463-1.html 55146
# 553571 depends on MS Indic shaping behavior and Win7 font support; # 553571 depends on MS Indic shaping behavior and Win7 font support;
# not expected to be reliable on XP or non-Windows platforms # not expected to be reliable on XP or non-Windows platforms
random-if(!winWidget) random-if(/^Windows\x20NT\x205/.test(http.oscpu)) != 553571-1.html 553571-1-notref.html # expect dotted circle in test, not in ref random-if(!winWidget) random-if(/^Windows\x20NT\x205/.test(http.oscpu)) != 553571-1.html 553571-1-notref.html # expect dotted circle in test, not in ref
fuzzy-if(!contentSameGfxBackendAsCanvas,2,91) random-if(d2d) skip-if(azureSkiaGL) == 555388-1.html 555388-1-ref.html fuzzy-if(!contentSameGfxBackendAsCanvas,128,91) random-if(d2d) skip-if(azureSkiaGL) == 555388-1.html 555388-1-ref.html
== 556661-1.html 556661-1-ref.html == 556661-1.html 556661-1-ref.html
skip-if(B2G) fails-if(Android) == 557087-1.html 557087-ref.html skip-if(B2G) fails-if(Android) == 557087-1.html 557087-ref.html
skip-if(B2G) fails-if(Android) == 557087-2.html 557087-ref.html skip-if(B2G) fails-if(Android) == 557087-2.html 557087-ref.html
@ -1715,8 +1715,8 @@ skip-if(B2G) == 751012-1a.html 751012-1-ref.html
skip-if(B2G) == 751012-1b.html 751012-1-ref.html skip-if(B2G) == 751012-1b.html 751012-1-ref.html
random-if(Android) == 753329-1.html about:blank random-if(Android) == 753329-1.html about:blank
== 758561-1.html 758561-1-ref.html == 758561-1.html 758561-1-ref.html
fuzzy-if(true,1,19) fails-if(d2d) == 759036-1.html 759036-1-ref.html fuzzy-if(true,1,19) fails-if(d2d) random-if(Android&&AndroidVersion<15) == 759036-1.html 759036-1-ref.html
fuzzy-if(true,17,5860) == 759036-2.html 759036-2-ref.html fuzzy-if(true,17,5860) random-if(Android&&AndroidVersion<15) == 759036-2.html 759036-2-ref.html
== 776265-1a.html 776265-1-ref.html == 776265-1a.html 776265-1-ref.html
== 776265-1b.html 776265-1-ref.html == 776265-1b.html 776265-1-ref.html
== 776265-1c.html 776265-1-ref.html == 776265-1c.html 776265-1-ref.html

View File

@ -213,7 +213,7 @@ class ReftestServer:
self._process = self._automation.Process([xpcshell] + args, env = env) self._process = self._automation.Process([xpcshell] + args, env = env)
pid = self._process.pid pid = self._process.pid
if pid < 0: if pid < 0:
print "Error starting server." print "TEST-UNEXPECTED-FAIL | remotereftests.py | Error starting server."
return 2 return 2
self._automation.log.info("INFO | remotereftests.py | Server pid: %d", pid) self._automation.log.info("INFO | remotereftests.py | Server pid: %d", pid)
@ -233,7 +233,7 @@ class ReftestServer:
time.sleep(1) time.sleep(1)
i += 1 i += 1
else: else:
print "Timed out while waiting for server startup." print "TEST-UNEXPECTED-FAIL | remotereftests.py | Timed out while waiting for server startup."
self.stop() self.stop()
return 1 return 1
@ -369,6 +369,9 @@ class RemoteReftest(RefTest):
# Make sure that opening the plugins check page won't hit the network # Make sure that opening the plugins check page won't hit the network
prefs["plugins.update.url"] = "http://127.0.0.1:8888/plugins-dummy/updateCheckURL" prefs["plugins.update.url"] = "http://127.0.0.1:8888/plugins-dummy/updateCheckURL"
# Disable skia-gl: see bug 907351
prefs["gfx.canvas.azure.accelerated"] = False
# Set the extra prefs. # Set the extra prefs.
profile.set_preferences(prefs) profile.set_preferences(prefs)
@ -438,7 +441,7 @@ def main(args):
else: else:
dm = droid.DroidSUT(options.deviceIP, options.devicePort, deviceRoot=options.remoteTestRoot) dm = droid.DroidSUT(options.deviceIP, options.devicePort, deviceRoot=options.remoteTestRoot)
except devicemanager.DMError: except devicemanager.DMError:
print "Error: exception while initializing devicemanager. Most likely the device is not in a testable state." print "Automation Error: exception while initializing devicemanager. Most likely the device is not in a testable state."
return 1 return 1
automation.setDeviceManager(dm) automation.setDeviceManager(dm)

View File

@ -584,7 +584,7 @@ pulse_stream_get_latency(cubeb_stream * stm, uint32_t * latency)
return CUBEB_ERROR; return CUBEB_ERROR;
} }
*latency = (r_usec * stm->sample_spec.rate) / PR_NSEC_PER_SEC; *latency = r_usec * stm->sample_spec.rate / PA_USEC_PER_SEC;
return CUBEB_OK; return CUBEB_OK;
} }

View File

@ -11,6 +11,7 @@
#include <algorithm> #include <algorithm>
#include <mozilla/Scoped.h> #include <mozilla/Scoped.h>
#include <m_cpp_utils.h> #include <m_cpp_utils.h>
#include <nsISupportsImpl.h>
namespace mozilla { namespace mozilla {

View File

@ -31,6 +31,10 @@
#include "nrinterfaceprioritizer.h" #include "nrinterfaceprioritizer.h"
#include "mtransport_test_utils.h" #include "mtransport_test_utils.h"
#include "runnable_utils.h" #include "runnable_utils.h"
#include "stunserver.h"
// TODO(bcampen@mozilla.com): Big fat hack since the build system doesn't give
// us a clean way to add object files to a single executable.
#include "stunserver.cpp"
#define GTEST_HAS_RTTI 0 #define GTEST_HAS_RTTI 0
#include "gtest/gtest.h" #include "gtest/gtest.h"
@ -187,6 +191,7 @@ class IceTestPeer : public sigslot::has_slots<> {
PRNetAddr addr; PRNetAddr addr;
PRStatus status = PR_StringToNetAddr(kDefaultStunServerAddress.c_str(), PRStatus status = PR_StringToNetAddr(kDefaultStunServerAddress.c_str(),
&addr); &addr);
addr.inet.port = kDefaultStunServerPort;
ASSERT_EQ(PR_SUCCESS, status); ASSERT_EQ(PR_SUCCESS, status);
fake_resolver_.SetAddr(kDefaultStunServerHostname, addr); fake_resolver_.SetAddr(kDefaultStunServerHostname, addr);
ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->SetResolver( ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->SetResolver(
@ -586,6 +591,9 @@ class IceTestPeer : public sigslot::has_slots<> {
class IceGatherTest : public ::testing::Test { class IceGatherTest : public ::testing::Test {
public: public:
void SetUp() { void SetUp() {
test_utils->sts_target()->Dispatch(WrapRunnable(TestStunServer::GetInstance(),
&TestStunServer::Reset),
NS_DISPATCH_SYNC);
peer_ = new IceTestPeer("P1", true, false); peer_ = new IceTestPeer("P1", true, false);
peer_->AddStream(1); peer_->AddStream(1);
} }
@ -595,6 +603,28 @@ class IceGatherTest : public ::testing::Test {
ASSERT_TRUE_WAIT(peer_->gathering_complete(), 10000); ASSERT_TRUE_WAIT(peer_->gathering_complete(), 10000);
} }
void UseFakeStunServerWithResponse(const std::string& fake_addr,
uint16_t fake_port) {
TestStunServer::GetInstance()->SetResponseAddr(fake_addr, fake_port);
// Sets an additional stun server
peer_->SetStunServer(TestStunServer::GetInstance()->addr(),
TestStunServer::GetInstance()->port());
}
// NB: Only does substring matching, watch out for stuff like "1.2.3.4"
// matching "21.2.3.47". " 1.2.3.4 " should not have false positives.
bool StreamHasMatchingCandidate(unsigned int stream,
const std::string& match) {
std::vector<std::string> candidates = peer_->GetCandidates(stream);
for (size_t c = 0; c < candidates.size(); ++c) {
if (std::string::npos != candidates[c].find(match)) {
return true;
}
}
return false;
}
protected: protected:
mozilla::ScopedDeletePtr<IceTestPeer> peer_; mozilla::ScopedDeletePtr<IceTestPeer> peer_;
}; };
@ -869,6 +899,30 @@ TEST_F(IceGatherTest, TestBogusCandidate) {
peer_->ParseCandidate(0, kBogusIceCandidate); peer_->ParseCandidate(0, kBogusIceCandidate);
} }
TEST_F(IceGatherTest, VerifyTestStunServer) {
UseFakeStunServerWithResponse("192.0.2.133", 3333);
Gather();
ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.2.133 3333 "));
}
TEST_F(IceGatherTest, TestStunServerReturnsWildcardAddr) {
UseFakeStunServerWithResponse("0.0.0.0", 3333);
Gather();
ASSERT_FALSE(StreamHasMatchingCandidate(0, " 0.0.0.0 "));
}
TEST_F(IceGatherTest, TestStunServerReturnsPort0) {
UseFakeStunServerWithResponse("192.0.2.133", 0);
Gather();
ASSERT_FALSE(StreamHasMatchingCandidate(0, " 192.0.2.133 0 "));
}
TEST_F(IceGatherTest, TestStunServerReturnsLoopbackAddr) {
UseFakeStunServerWithResponse("127.0.0.133", 3333);
Gather();
ASSERT_FALSE(StreamHasMatchingCandidate(0, " 127.0.0.133 "));
}
TEST_F(IceConnectTest, TestGather) { TEST_F(IceConnectTest, TestGather) {
AddStream("first", 1); AddStream("first", 1);
ASSERT_TRUE(Gather(true)); ASSERT_TRUE(Gather(true));
@ -1148,7 +1202,14 @@ int main(int argc, char **argv)
// Start the tests // Start the tests
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
test_utils->sts_target()->Dispatch(
WrapRunnableNM(&TestStunServer::GetInstance), NS_DISPATCH_SYNC);
int rv = RUN_ALL_TESTS(); int rv = RUN_ALL_TESTS();
test_utils->sts_target()->Dispatch(
WrapRunnableNM(&TestStunServer::ShutdownInstance), NS_DISPATCH_SYNC);
delete test_utils; delete test_utils;
return rv; return rv;
} }

View File

@ -0,0 +1,430 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
// Original author: ekr@rtfm.com
/*
Original code from nICEr and nrappkit.
nICEr copyright:
Copyright (c) 2007, Adobe Systems, Incorporated
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Adobe Systems, Network Resonance nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
nrappkit copyright:
Copyright (C) 2001-2003, Network Resonance, Inc.
Copyright (C) 2006, Network Resonance, Inc.
All Rights Reserved
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of Network Resonance, Inc. nor the name of any
contributors to this software may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
ekr@rtfm.com Thu Dec 20 20:14:49 2001
*/
#include "logging.h"
#include "mozilla/Scoped.h"
#include "databuffer.h"
extern "C" {
#include "nr_api.h"
#include "async_wait.h"
#include "async_timer.h"
#include "nr_socket.h"
#include "nr_socket_local.h"
#include "transport_addr.h"
#include "addrs.h"
#include "local_addr.h"
#include "stun_util.h"
#include "registry.h"
}
#include "stunserver.h"
#include <string>
MOZ_MTLOG_MODULE("stunserver");
namespace mozilla {
// Wrapper nr_socket which allows us to lie to the stun server about the
// IP address.
struct nr_socket_wrapped {
nr_socket *sock_;
nr_transport_addr addr_;
};
static int nr_socket_wrapped_destroy(void **objp) {
if (!objp || !*objp)
return 0;
nr_socket_wrapped *wrapped = static_cast<nr_socket_wrapped *>(*objp);
*objp = 0;
delete wrapped;
return 0;
}
static int nr_socket_wrapped_sendto(void *obj, const void *msg, size_t len, int flags,
nr_transport_addr *addr) {
nr_socket_wrapped *wrapped = static_cast<nr_socket_wrapped *>(obj);
return nr_socket_sendto(wrapped->sock_, msg, len, flags, &wrapped->addr_);
}
static int nr_socket_wrapped_recvfrom(void *obj, void * restrict buf, size_t maxlen,
size_t *len, int flags, nr_transport_addr *addr) {
MOZ_CRASH();
}
static int nr_socket_wrapped_getfd(void *obj, NR_SOCKET *fd) {
MOZ_CRASH();
}
static int nr_socket_wrapped_getaddr(void *obj, nr_transport_addr *addrp) {
nr_socket_wrapped *wrapped = static_cast<nr_socket_wrapped *>(obj);
return nr_socket_getaddr(wrapped->sock_, addrp);
}
static int nr_socket_wrapped_close(void *obj) {
MOZ_CRASH();
}
static int nr_socket_wrapped_set_send_addr(nr_socket *sock, nr_transport_addr *addr) {
nr_socket_wrapped *wrapped = static_cast<nr_socket_wrapped *>(sock->obj);
return nr_transport_addr_copy(&wrapped->addr_, addr);
}
static nr_socket_vtbl nr_socket_wrapped_vtbl = {
nr_socket_wrapped_destroy,
nr_socket_wrapped_sendto,
nr_socket_wrapped_recvfrom,
nr_socket_wrapped_getfd,
nr_socket_wrapped_getaddr,
nr_socket_wrapped_close
};
int nr_socket_wrapped_create(nr_socket *inner, nr_socket **outp) {
ScopedDeletePtr<nr_socket_wrapped> wrapped(new nr_socket_wrapped());
wrapped->sock_ = inner;
int r = nr_socket_create_int(wrapped.get(), &nr_socket_wrapped_vtbl, outp);
if (r)
return r;
wrapped.forget();
return 0;
}
// Instance static.
// Note: Calling Create() at static init time is not going to be safe, since
// we have no reason to expect this will be initted to a nullptr yet.
TestStunServer* TestStunServer::instance;
uint16_t TestStunServer::instance_port = 3478;
TestStunServer::~TestStunServer() {
// TODO(ekr@rtfm.com): Put this on the right thread.
// Unhook callback from our listen socket.
NR_SOCKET fd;
if (!nr_socket_getfd(listen_sock_, &fd)) {
NR_ASYNC_CANCEL(fd, NR_ASYNC_WAIT_READ);
}
// Free up stun context and network resources
nr_stun_server_ctx_destroy(&stun_server_);
nr_socket_destroy(&listen_sock_);
nr_socket_destroy(&send_sock_);
// Make sure we aren't still waiting on a deferred response timer to pop
if (timer_handle_)
NR_async_timer_cancel(timer_handle_);
delete response_addr_;
}
TestStunServer* TestStunServer::Create() {
NR_reg_init(NR_REG_MODE_LOCAL);
ScopedDeletePtr<TestStunServer> server(new TestStunServer());
nr_local_addr addrs[100];
int addr_ct;
int r;
r = nr_stun_find_local_addresses(addrs, 100, &addr_ct);
if (r) {
MOZ_MTLOG(ML_ERROR, "Couldn't retrieve addresses");
return nullptr;
}
if (addr_ct < 1) {
MOZ_MTLOG(ML_ERROR, "No local addresses");
return nullptr;
}
// Bind to the first address (arbitrarily) on configured port (default 3478)
r = nr_transport_addr_set_port(&addrs[0].addr, instance_port);
if (r) {
MOZ_MTLOG(ML_ERROR, "Couldn't set port");
return nullptr;
}
r = nr_transport_addr_fmt_addr_string(&addrs[0].addr);
if (r) {
MOZ_MTLOG(ML_ERROR, "Couldn't re-set addr string");
return nullptr;
}
r = nr_socket_local_create(&addrs[0].addr, &server->listen_sock_);
if (r) {
MOZ_MTLOG(ML_ERROR, "Couldn't create listen socket");
return nullptr;
}
NR_SOCKET fd;
r = nr_socket_getfd(server->listen_sock_, &fd);
if (r) {
MOZ_MTLOG(ML_ERROR, "Couldn't get fd");
return nullptr;
}
r = nr_socket_wrapped_create(server->listen_sock_, &server->send_sock_);
if (r) {
MOZ_MTLOG(ML_ERROR, "Couldn't create send socket");
return nullptr;
}
r = nr_stun_server_ctx_create(const_cast<char *>("Test STUN server"),
server->send_sock_,
&server->stun_server_);
if (r) {
MOZ_MTLOG(ML_ERROR, "Couldn't create STUN server");
return nullptr;
}
// Cache the address and port.
char addr_string[INET6_ADDRSTRLEN];
r = nr_transport_addr_get_addrstring(&addrs[0].addr, addr_string,
sizeof(addr_string));
if (r) {
MOZ_MTLOG(ML_ERROR, "Failed to convert listen addr to a string representation");
return nullptr;
}
server->listen_addr_ = addr_string;
server->listen_port_ = instance_port;
NR_ASYNC_WAIT(fd, NR_ASYNC_WAIT_READ, &TestStunServer::readable_cb, server.get());
return server.forget();
}
void TestStunServer::ConfigurePort(uint16_t port) {
instance_port = port;
}
TestStunServer* TestStunServer::GetInstance() {
if (!instance)
instance = Create();
return instance;
}
void TestStunServer::ShutdownInstance() {
delete instance;
instance = nullptr;
}
struct DeferredStunOperation {
DeferredStunOperation(TestStunServer *server,
const char *data, size_t len,
nr_transport_addr *addr) :
server_(server),
buffer_(reinterpret_cast<const uint8_t *>(data), len) {
nr_transport_addr_copy(&addr_, addr);
}
TestStunServer *server_;
DataBuffer buffer_;
nr_transport_addr addr_;
};
void TestStunServer::Process(const uint8_t *msg, size_t len, nr_transport_addr *addr) {
// Set the wrapped address so that the response goes to the right place.
nr_socket_wrapped_set_send_addr(send_sock_, addr);
nr_stun_server_process_request(stun_server_, send_sock_,
const_cast<char *>(reinterpret_cast<const char *>(msg)),
len,
response_addr_ ?
response_addr_ : addr,
NR_STUN_AUTH_RULE_OPTIONAL);
}
void TestStunServer::process_cb(NR_SOCKET s, int how, void *cb_arg) {
DeferredStunOperation *op = static_cast<DeferredStunOperation *>(cb_arg);
op->server_->timer_handle_ = nullptr;
op->server_->Process(op->buffer_.data(), op->buffer_.len(), &op->addr_);
delete op;
}
void TestStunServer::readable_cb(NR_SOCKET s, int how, void *cb_arg) {
TestStunServer* server = static_cast<TestStunServer*>(cb_arg);
char message[4096];
size_t message_len;
nr_transport_addr addr;
int r = nr_socket_recvfrom(server->listen_sock_, message, sizeof(message),
&message_len, 0, &addr);
if (r) {
MOZ_MTLOG(ML_ERROR, "Couldn't read STUN message");
return;
}
MOZ_MTLOG(ML_DEBUG, "Received data of length " << message_len);
// Re-arm.
NR_ASYNC_WAIT(s, NR_ASYNC_WAIT_READ, &TestStunServer::readable_cb, server);
// If we have initial dropping set, check at this point.
std::string key(addr.as_string);
if (server->received_ct_.count(key) == 0) {
server->received_ct_[key] = 0;
}
++server->received_ct_[key];
if (!server->active_ || (server->received_ct_[key] <= server->initial_ct_)) {
MOZ_MTLOG(ML_DEBUG, "Dropping message #"
<< server->received_ct_[key] << " from " << key);
return;
}
if (server->delay_ms_) {
NR_ASYNC_TIMER_SET(server->delay_ms_,
process_cb,
new DeferredStunOperation(
server,
message, message_len,
&addr),
&server->timer_handle_);
} else {
server->Process(reinterpret_cast<const uint8_t *>(message), message_len, &addr);
}
}
void TestStunServer::SetActive(bool active) {
active_ = active;
}
void TestStunServer::SetDelay(uint32_t delay_ms) {
delay_ms_ = delay_ms;
}
void TestStunServer::SetDropInitialPackets(uint32_t count) {
initial_ct_ = count;
}
nsresult TestStunServer::SetResponseAddr(nr_transport_addr *addr) {
delete response_addr_;
response_addr_ = new nr_transport_addr();
int r = nr_transport_addr_copy(response_addr_, addr);
if (r)
return NS_ERROR_FAILURE;
return NS_OK;
}
nsresult TestStunServer::SetResponseAddr(const std::string& addr,
uint16_t port) {
nr_transport_addr addr2;
int r = nr_ip4_str_port_to_transport_addr(addr.c_str(),
port, IPPROTO_UDP,
&addr2);
if (r)
return NS_ERROR_FAILURE;
return SetResponseAddr(&addr2);
}
void TestStunServer::Reset() {
delay_ms_ = 0;
if (timer_handle_) {
NR_async_timer_cancel(timer_handle_);
timer_handle_ = nullptr;
}
delete response_addr_;
response_addr_ = nullptr;
}
} // close namespace

View File

@ -0,0 +1,83 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
// Original author: ekr@rtfm.com
#ifndef stunserver_h__
#define stunserver_h__
#include <map>
#include <string>
#include "prio.h"
#include "nsError.h"
typedef struct nr_stun_server_ctx_ nr_stun_server_ctx;
typedef struct nr_socket_ nr_socket;
namespace mozilla {
class TestStunServer {
public:
// Generally, you should only call API in this class from the same thread that
// the initial |GetInstance| call was made from.
static TestStunServer *GetInstance();
static void ShutdownInstance();
// |ConfigurePort| will only have an effect if called before the first call
// to |GetInstance| (possibly following a |ShutdownInstance| call)
static void ConfigurePort(uint16_t port);
static TestStunServer *Create();
~TestStunServer();
void SetActive(bool active);
void SetDelay(uint32_t delay_ms);
void SetDropInitialPackets(uint32_t count);
const std::string& addr() const { return listen_addr_; }
uint16_t port() const { return listen_port_; }
// These should only be called from the same thread as the initial
// |GetInstance| call.
nsresult SetResponseAddr(nr_transport_addr *addr);
nsresult SetResponseAddr(const std::string& addr, uint16_t port);
void Reset();
private:
TestStunServer()
: listen_sock_(nullptr),
send_sock_(nullptr),
stun_server_(nullptr),
active_(true),
delay_ms_(0),
initial_ct_(0),
response_addr_(nullptr),
timer_handle_(nullptr),
listen_port_(0) {}
void Process(const uint8_t *msg, size_t len, nr_transport_addr *addr_in);
static void readable_cb(NR_SOCKET sock, int how, void *cb_arg);
static void process_cb(NR_SOCKET sock, int how, void *cb_arg);
nr_socket *listen_sock_;
nr_socket *send_sock_;
nr_stun_server_ctx *stun_server_;
bool active_;
uint32_t delay_ms_;
uint32_t initial_ct_;
nr_transport_addr *response_addr_;
void *timer_handle_;
std::map<std::string, uint32_t> received_ct_;
std::string listen_addr_;
uint16_t listen_port_;
static TestStunServer* instance;
static uint16_t instance_port;
};
} // End of namespace mozilla
#endif

View File

@ -18,6 +18,7 @@
#include "mozilla/Scoped.h" #include "mozilla/Scoped.h"
#include "transportlayer.h" #include "transportlayer.h"
#include "m_cpp_utils.h" #include "m_cpp_utils.h"
#include "nsAutoPtr.h"
// A stack of transport layers acts as a flow. // A stack of transport layers acts as a flow.
// Generally, one reads and writes to the top layer. // Generally, one reads and writes to the top layer.

View File

@ -8,6 +8,7 @@
#include "logging.h" #include "logging.h"
#include "transportflow.h" #include "transportflow.h"
#include "transportlayer.h" #include "transportlayer.h"
#include "nsThreadUtils.h"
// Logging context // Logging context
namespace mozilla { namespace mozilla {
@ -46,4 +47,19 @@ void TransportLayer::SetState(State state) {
} }
} }
nsresult TransportLayer::RunOnThread(nsIRunnable *event) {
if (target_) {
nsIThread *thr;
DebugOnly<nsresult> rv = NS_GetCurrentThread(&thr);
MOZ_ASSERT(NS_SUCCEEDED(rv));
if (target_ != thr) {
return target_->Dispatch(event, NS_DISPATCH_SYNC);
}
}
return event->Run();
}
} // close namespace } // close namespace

View File

@ -15,7 +15,6 @@
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsIEventTarget.h" #include "nsIEventTarget.h"
#include "nsThreadUtils.h"
#include "m_cpp_utils.h" #include "m_cpp_utils.h"
@ -62,20 +61,7 @@ class TransportLayer : public sigslot::has_slots<> {
// Dispatch a call onto our thread (or run on the same thread if // Dispatch a call onto our thread (or run on the same thread if
// thread is not set). This is always synchronous. // thread is not set). This is always synchronous.
nsresult RunOnThread(nsIRunnable *event) { nsresult RunOnThread(nsIRunnable *event);
if (target_) {
nsIThread *thr;
DebugOnly<nsresult> rv = NS_GetCurrentThread(&thr);
MOZ_ASSERT(NS_SUCCEEDED(rv));
if (target_ != thr) {
return target_->Dispatch(event, NS_DISPATCH_SYNC);
}
}
return event->Run();
}
// Get the state // Get the state
State state() const { return state_; } State state() const { return state_; }

Some files were not shown because too many files have changed in this diff Show More